web-dev-qa-db-ja.com

OpenGLテクスチャのstb_imageでPNGをロードすると、間違った色が表示される

Stb_imageを使用して32ビットPNGファイル(RGBA)をロードし、OpenGLテクスチャを作成しています。

24ビットのPNGファイル(アルファチャネルなし)で正常に動作しますが、32ビットのPNGファイルを使用すると、何かがおかしくなります。

これは、テクスチャがどのように見えるかです。

Texture

そして、これはOpenGLでレンダリングされたときの外観です(黒い部分は透明にするためのもので、ブレンドを有効にしているときです):

Wrong Texture

これは私がテクスチャをロードする方法です:

int w;
int h;
int comp;
unsigned char* image = stbi_load(filename.c_str(), &w, &h, &comp, STBI_rgb);

if(image == nullptr)
    throw(std::string("Failed to load texture"));

glGenTextures(1, &m_texture);

glBindTexture(GL_TEXTURE_2D, m_texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

if(comp == 3)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
else if(comp == 4)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);

glBindTexture(GL_TEXTURE_2D, 0);

stbi_image_free(image);

そして、これらはウィンドウパラメーターです(SDLを使用)

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);

何が起こっている?

21
developerbmw

Stbi_load関数呼び出しでSTBI_rgbをSTBI_rgb_alphaに変更すると、修正されました。

RGBA:Dの場合、おそらくRGBを指定しないことが最善です

24
developerbmw

実際のバグは、compを使用してformat(_GL_RBA_/_GL_RGBA_)パラメーターを_glTexImage2D_に決定することです。これは、_stbi_load_を使用して画像を読み込むと、compに返される値が、返される画像データではなく、常にソース画像と一致するためです。

より具体的には、あなたのバグは_STBI_rgb_を使用して_stbi_load_が3バイトピクセルを返すことですが、それから_glTexImage2D_で4バイトピクセルとして_GL_RGBA_でロードするとcompになるためです32ビット画像を読み込むときは4です。

_glTexImage2D_を使用する場合は_GL_RGB_を使用する場合は_STBI_rgb_に、_GL_RGBA_を使用する場合は_STBI_rgb_alpha_にフォーマットを設定する必要があります。

他の読者へのボーナス

あなたは同様の問題を抱えていますが、上記はまだ解決しませんか?その場合、画像データには、OpenGLが期待する配置に行がない場合があります。 _glTexImage2D_を呼び出す前に、glPixelStorei(GL_UNPACK_ALIGNMENT, 1);を試してください。詳細については、 https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout を参照してください。

18