C++ 使用 stb_image 为 OpenGL 纹理加载 PNG 会产生错误的颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23150123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Loading PNG with stb_image for OpenGL texture gives wrong colors
提问by developerbmw
I am using stb_image to load a 32-bit PNG file (RGBA) and I am creating an OpenGL texture with it.
我正在使用 stb_image 加载一个 32 位 PNG 文件 (RGBA),我正在用它创建一个 OpenGL 纹理。
It works fine for 24-bit PNG files (with no alpha channel), but when I use a 32-bit PNG file, something goes wrong.
它适用于 24 位 PNG 文件(没有 alpha 通道),但是当我使用 32 位 PNG 文件时,出现问题。
This is what the texture should look like:
纹理应该是这样的:
And this is what it looks like when rendered with OpenGL (the black parts are meant to be transparent, and are when I enable blending):
这就是用 OpenGL 渲染时的样子(黑色部分是透明的,当我启用混合时):
This is how I load the 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);
And these are the window parameters (using SDL)
这些是窗口参数(使用 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);
What is happening?
怎么了?
采纳答案by developerbmw
Changing the STBI_rgb to STBI_rgb_alpha in the stbi_load function call fixed it.
在 stbi_load 函数调用中将 STBI_rgb 更改为 STBI_rgb_alpha 修复了它。
Probably best not to specify RGB when its RGBA :D
可能最好不要在其 RGBA 时指定 RGB:D
回答by Sebastian ?rleryd
Your actual bug is that you use comp
to determine your format
(GL_RBA
/GL_RGBA
) parameter to glTexImage2D
. This happens because when you load an image using stbi_load
, the value returned in comp
will always match the source image, not the image data returned.
您的实际错误是您用于comp
将format
( GL_RBA
/ GL_RGBA
) 参数确定为glTexImage2D
. 发生这种情况是因为当您使用 加载图像时stbi_load
,返回的值comp
将始终与源图像匹配,而不是返回的图像数据。
More specifically, your bug is that you use STBI_rgb
, causing stbi_load
to return 3 byte pixels, but then you load it with glTexImage2D
as 4 byte pixels with GL_RGBA
because comp
is 4 when you load a 32 bit image.
更具体地说,您的错误是您使用STBI_rgb
,导致stbi_load
返回 3 字节像素,但随后您将其加载glTexImage2D
为 4 字节像素,GL_RGBA
因为comp
加载 32 位图像时为 4。
You must set the format in your call to glTexImage2D
to GL_RGB
if you use STBI_rgb
and to GL_RGBA
if you use STBI_rgb_alpha
.
您必须在调用中将格式设置为glTexImage2D
to GL_RGB
if you useSTBI_rgb
和 to GL_RGBA
if you use STBI_rgb_alpha
。
Bonus to other readers
奖励给其他读者
Are you having a similar problem and the above still doesn't help? Then your image data might not have rows on the alignment OpenGL expects. Try glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
before you call glTexImage2D
. See https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layoutfor more information.
您是否有类似的问题,但以上仍然没有帮助?那么您的图像数据可能没有 OpenGL 期望的对齐方式的行。glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
打电话之前先试试glTexImage2D
。有关更多信息,请参阅https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout。