c++ tga 解析 incorrect_color/distortion with some resolutions

标签 c++ parsing opengl distortion tga

我想就 .tga 文件格式解析问题获得一些帮助。我有我使用了很长时间的代码:

            int fileLength = Input.tellg();
            vector<char> tempData;
            tempData.resize(fileLength);

            Input.seekg(0);
            Input.read(&tempData[0], fileLength);
            Input.close();

            // Load information about the tga, aka the header.
            // Seek to the width.
            w = byteToUnsignedShort(tempData[12], tempData[13]);

            // Seek to the height.
            h = byteToUnsignedShort(tempData[14], tempData[15]);

            // Seek to the depth.
            depth = unsigned(tempData[16]);

            // Mode = components per pixel.
            md = depth / 8;

            // Total bytes = h * w * md.
            t = h * w * md;

            //Delete allocated data, if need to
            clear();

            //Allocate new storage
            data.resize(t);

            // Copy image data.
            for(unsigned i = 0, s = 18; s < t + 18; s++, i++)
                data[i] = unsigned char(tempData[s]);

            // Mode 3 = RGB, Mode 4 = RGBA
            // TGA stores RGB(A) as BGR(A) so
            // we need to swap red and blue.
            if(md > 2)
            {
                char aux;

                for(unsigned i = 0; i < t; i+= md)
                {
                    aux = data[i];
                    data[i] = data[i + 2];
                    data[i + 2] = aux;
                }
            }

但对于某些图像分辨率(主要是奇数和非 POT 分辨率),它偶尔会失败。它会导致图像失真(带有对角线图案)或颜色错误。上次我遇到它 - 它是 9x9 24bpp 图像,显示奇怪的颜色。

我在 Windows 上(所以它意味着小端),使用 opengl 渲染(当使用 glTexImage2D 传递图像数据时,我正在考虑 alpha channel 的存在)。我正在用 photoshop 保存我的图像,而不是设置 RLE 标志。此代码始终读取正确的图像分辨率和颜色深度。

导致问题的图片示例: http://pastie.org/private/p81wbh5sb6coldspln6mw

加载有问题的图像后,此代码:

for(unsigned f = 0; f < imageData.w * imageData.h * imageData.depth; f += imageData.depth)
{
    if(f % (imageData.w * imageData.depth) == 0)
        writeLog << endl;

    writeLog << "[" << unsigned(imageData.data[f]) << "," << unsigned(imageData.data[f + 1]) << "," << unsigned(imageData.data[f + 2]) << "]" << flush;
}

输出这个:

[37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40]
[37,40,40][173,166,164][93,90,88][93,90,88][93,90,88][93,90,88][93,90,88][88,85,83][37,40,40]
[37,40,40][228,221,219][221,212,209][221,212,209][221,212,209][221,212,209][221,212,209][140,134,132][37,40,40]
[37,40,40][228,221,219][221,212,209][221,212,209][221,212,209][221,212,209][221,212,209][140,134,132][37,40,40]
[37,40,40][228,221,219][221,212,209][221,212,209][221,212,209][221,212,209][221,212,209][140,134,132][37,40,40]
[37,40,40][228,221,219][221,212,209][221,212,209][221,212,209][221,212,209][221,212,209][140,134,132][37,40,40]
[37,40,40][228,221,219][221,212,209][221,212,209][221,212,209][221,212,209][221,212,209][140,134,132][37,40,40]
[37,40,40][237,232,230][235,229,228][235,229,228][235,229,228][235,229,228][235,229,228][223,214,212][37,40,40]
[37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40][37,40,40]

所以我猜它确实读取了正确的数据。 这将我们带到了 opengl;

glGenTextures(1, &textureObject);
glBindTexture(GL_TEXTURE_2D, textureObject);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

GLenum in_comp_mode, comp_mode;

if(linear) //false for that image
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
else
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

//i don't use 1 or 2 - channel textures, so it's always 24 or 32bpp
    if(imageData.depth == 24)
    {
        in_tex_mode = GL_RGB8;
        tex_mode = GL_RGB;
    }
    else
    {
        in_tex_mode = GL_RGBA8;
        tex_mode = GL_RGBA;
    }

glTexImage2D(GL_TEXTURE_2D, 0, in_tex_mode, imageData.w, imageData.h, 0, tex_mode, GL_UNSIGNED_BYTE, &imageData.data[0]);

glBindTexture(GL_TEXTURE_2D, NULL);

纹理压缩代码被省略,因为它对该纹理不活跃。

最佳答案

这可能是填充/对齐问题。

您正在加载一个没有行填充的 TGA,但将其传递给 GL,默认情况下,它希望将像素行填充为 4 字节的倍数。

可能的解决办法是:

  • 告诉 GL 你的纹理是如何打包的,使用(例如)glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  • 更改纹理的尺寸,这样就没有填充了。
  • 更改纹理的加载,使填充与 GL 期望的一致

关于c++ tga 解析 incorrect_color/distortion with some resolutions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14412772/

相关文章:

c++ - 自定义智能指针代码问题 - 智能指针不能在堆上结束吗?

c++ - STL 实现中是否有中心分配双端队列或 vector ?

c++ - 如何在不导入整个库的情况下在 C++ 中导入函数

arrays - 使用数组中对象的值解析 JSON 字符串

python - Windows 上的 Pandas read_csv 错误

c++ - 如何为 GL_SELECT 缓冲区启用深度测试?

c++ - OpenGL 中的着色器问题

c++ - 无法设置 CWinApp 上的 SetTimer 函数

jQuery 在多个级别上解析 JSON

opengl - Haskell OpenGL 程序生成