简体   繁体   English

读取包含Heightmap的.raw文件

[英]Reading .raw file containing Heightmap

I am using the libnoise library to generate a random terrain and saving it in a .raw file that has its elevation points measured in meters. 我正在使用libnoise库生成随机地形,并将其保存在高程以米为单位的.raw文件中。 This terrain file contains 16-bit signed big-endian values, in row-major order, ordered south to north. 该地形文件包含16位带符号的big-endian值,按行优先顺序排列,从南到北排序。 This is the code I am using for reading the file. 这是我用来读取文件的代码。

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;
}

The code does not return any error but this is the result rendered: rawFileRendering . 该代码未返回任何错误,但这是呈现的结果: rawFileRendering

I tested the code with another heightmap saved in a raw file (given by rastertek) and it works. 我使用保存在原始文件(由rastertek提供)中的另一个高度图对代码进行了测试,并且可以正常工作。

Do you know why the rendered scene is like this? 您知道渲染的场景为什么会这样吗? Thank you for your help. 谢谢您的帮助。

Two problems: 两个问题:

  1. You use unsigned short , but you said in the description that the numbers are signed. 您使用unsigned short ,但是在描述中您说数字是带符号的。 So you should use signed short instead 因此,您应该使用带signed short代替
  2. You don't do anything with endianness. 您不会对字节序进行任何操作。 If you are on a little endian machine, you should convert your values from big endian to little endian. 如果您使用的是小端字节序计算机,则应将值从大端字节序转换为小端字节序。

You can convert endianness with this: 您可以通过以下方式转换字节序:

short endianConvert(short x) {
    unsigned short v = (unsigned short)x;
    return (short)(v>>8|v<<8);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM