1

.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で画像データを渡すときに、アルファチャネルの存在を考慮しています)。RLEフラグを設定せずに、Photoshopで画像を保存しています。このコードは、常に正しい画像解像度と色深度を読み取ります。

問題を引き起こす画像の例: 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);

テクスチャ圧縮コードは、そのテクスチャに対してアクティブではないため、省略されています。

4

2 に答える 2

3

これはおそらくパディング/アライメントの問題です。

行のパディングがないTGAをロードしていますが、デフォルトでピクセルの行が4バイトの倍数にパディングされることを想定しているGLに渡します。

これに対する可能な修正は次のとおりです。

  • (たとえば)を使用して、テクスチャがどのようにパックされているかをGLに伝えますglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  • パディングがないように、テクスチャの寸法を変更します。
  • パディングがGLが期待するものと一致するように、テクスチャの読み込みを変更します
于 2013-01-19T11:05:17.060 に答える
0

ほとんどの画像形式は、画像データを整列して保存します(一般的に4バイト)。たとえば、解像度: 1rows 1columns 各行には 1 つのピクセルがあるため、RGB を使用する場合、各行には 3 バイトがあります。CPUがそれを好むため、アライメントのために4バイトに拡張されます。

英語は私の母国語ではないので、私の悪い文法はあなたを殺すでしょう. それを理解しようとするだけです。

于 2013-01-19T09:10:57.040 に答える