我正在使用stb_image加载一个32位的PNG文件(RGBA),并且我正在用它创建一个OpenGL纹理。
它适用于24位PNG文件(没有alpha通道),但当我使用32位PNG文件时,出现问题。
这是纹理应该看起来的样子:
这是用OpenGL渲染时的样子(黑色部分是透明的,当我启用混合时):
这是我加载纹理的方式:
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);
这是怎么回事?
发布于 2014-04-18 19:09:30
在stbi_load函数调用中将STBI_rgb更改为STBI_rgb_alpha修复了该问题。
当它的RGBA :D时最好不要指定RGB
发布于 2018-03-06 16:29:14
您的实际缺陷是使用comp
来确定glTexImage2D
的format
(GL_RBA
/GL_RGBA
)参数。这是因为当您使用stbi_load
加载图像时,comp
中返回的值将始终与源图像匹配,而不是与返回的图像数据匹配。
更具体地说,您的bug是使用STBI_rgb
,导致stbi_load
返回3个字节的像素,然后使用glTexImage2D
和GL_RGBA
将其加载为4个字节的像素,因为当您加载32位图像时,comp
为4。
如果使用STBI_rgb
,则必须在调用glTexImage2D
时将格式设置为GL_RGB
,如果使用STBI_rgb_alpha
,则必须将格式设置为GL_RGBA
。
给其他读者的奖励
你有没有遇到类似的问题,而上面的问题仍然没有帮助?那么您的图像数据可能在OpenGL期望的对齐方式上没有行。在调用glTexImage2D
之前尝试使用glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
。有关详细信息,请参阅https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout。
https://stackoverflow.com/questions/23150123
复制相似问题