读取包含高度图的 .raw 文件
Reading .raw file containing Heightmap
我正在使用 libnoise 库生成随机地形并将其保存在一个 .raw 文件中,该文件的高程点以米为单位。此地形文件包含 16 位带符号的大端值,按行优先顺序,从南到北排序。这是我用来读取文件的代码。
struct HeightMapType
{
float x, y, z;
float nx, ny, nz;
float r, g, b;
};
bool Terrain::LoadRawFile()
{
int error, i, j, index;
FILE* filePtr;
unsigned long long imageSize, count;
unsigned short* rawImage;
// Create the float array to hold the height map data.
m_heightMap = new HeightMapType[m_terrainWidth * m_terrainHeight];
if(!m_heightMap)
{
return false;
}
// Open the 16 bit raw height map file for reading in binary.
error = fopen_s(&filePtr, m_terrainFilename, "rb");
if(error != 0)
{
return false;
}
// Calculate the size of the raw image data.
imageSize = m_terrainHeight * m_terrainWidth;
// Allocate memory for the raw image data.
rawImage = new unsigned short[imageSize];
if(!rawImage)
{
return false;
}
// Read in the raw image data.
count = fread(rawImage, sizeof(unsigned short), imageSize, filePtr);
if(count != imageSize)
{
return false;
}
// Close the file.
error = fclose(filePtr);
if(error != 0)
{
return false;
}
// Copy the image data into the height map array.
for(j=0; j<m_terrainHeight; j++)
{
for(i=0; i<m_terrainWidth; i++)
{
index = (m_terrainWidth * j) + i;
// Store the height at this point in the height map array.
m_heightMap[index].y = (float)rawImage[index];
}
}
// Release the bitmap image data.
delete [] rawImage;
rawImage = 0;
// Release the terrain filename now that it has been read in.
delete [] m_terrainFilename;
m_terrainFilename = 0;
return true;
}
代码没有 return 任何错误,但这是呈现的结果:rawFileRendering。
我用保存在原始文件(由 rastertek 提供)中的另一个高度图测试了代码并且它有效。
你知道渲染出来的场景为什么是这样吗?
感谢您的帮助。
两个问题:
- 你用的是
unsigned short
,但是你在描述中说数字是有符号的。所以你应该使用 signed short
而不是
- 你不做任何字节序。如果您使用的是小端计算机,则应将您的值从大端转换为小端。
你可以用这个转换字节顺序:
short endianConvert(short x) {
unsigned short v = (unsigned short)x;
return (short)(v>>8|v<<8);
}
我正在使用 libnoise 库生成随机地形并将其保存在一个 .raw 文件中,该文件的高程点以米为单位。此地形文件包含 16 位带符号的大端值,按行优先顺序,从南到北排序。这是我用来读取文件的代码。
struct HeightMapType
{
float x, y, z;
float nx, ny, nz;
float r, g, b;
};
bool Terrain::LoadRawFile()
{
int error, i, j, index;
FILE* filePtr;
unsigned long long imageSize, count;
unsigned short* rawImage;
// Create the float array to hold the height map data.
m_heightMap = new HeightMapType[m_terrainWidth * m_terrainHeight];
if(!m_heightMap)
{
return false;
}
// Open the 16 bit raw height map file for reading in binary.
error = fopen_s(&filePtr, m_terrainFilename, "rb");
if(error != 0)
{
return false;
}
// Calculate the size of the raw image data.
imageSize = m_terrainHeight * m_terrainWidth;
// Allocate memory for the raw image data.
rawImage = new unsigned short[imageSize];
if(!rawImage)
{
return false;
}
// Read in the raw image data.
count = fread(rawImage, sizeof(unsigned short), imageSize, filePtr);
if(count != imageSize)
{
return false;
}
// Close the file.
error = fclose(filePtr);
if(error != 0)
{
return false;
}
// Copy the image data into the height map array.
for(j=0; j<m_terrainHeight; j++)
{
for(i=0; i<m_terrainWidth; i++)
{
index = (m_terrainWidth * j) + i;
// Store the height at this point in the height map array.
m_heightMap[index].y = (float)rawImage[index];
}
}
// Release the bitmap image data.
delete [] rawImage;
rawImage = 0;
// Release the terrain filename now that it has been read in.
delete [] m_terrainFilename;
m_terrainFilename = 0;
return true;
}
代码没有 return 任何错误,但这是呈现的结果:rawFileRendering。
我用保存在原始文件(由 rastertek 提供)中的另一个高度图测试了代码并且它有效。
你知道渲染出来的场景为什么是这样吗? 感谢您的帮助。
两个问题:
- 你用的是
unsigned short
,但是你在描述中说数字是有符号的。所以你应该使用signed short
而不是 - 你不做任何字节序。如果您使用的是小端计算机,则应将您的值从大端转换为小端。
你可以用这个转换字节顺序:
short endianConvert(short x) {
unsigned short v = (unsigned short)x;
return (short)(v>>8|v<<8);
}