c++ - texturas - Cargar PNG con stb_image para la textura OpenGL da colores incorrectos
texturas en opengl ejemplos (2)
Estoy usando stb_image para cargar un archivo PNG de 32 bits (RGBA) y estoy creando una textura OpenGL con él.
Funciona bien para archivos PNG de 24 bits (sin canal alfa), pero cuando uso un archivo PNG de 32 bits, algo va mal.
Así es como debería verse la textura:
Y así es como se ve cuando se procesa con OpenGL (las partes negras deben ser transparentes, y cuando habilito la mezcla):
Así es como se carga la textura:
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);
Y estos son los parámetros de la ventana (usando 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);
¿Que esta pasando?
El cambio de STBI_rgb a STBI_rgb_alpha en la función stbi_load lo solucionó.
Probablemente sea mejor no especificar RGB cuando su RGBA: D
Su error real es que utiliza comp
para determinar su parámetro de format
( GL_RBA
/ GL_RGBA
) para glTexImage2D
. Esto sucede porque cuando carga una imagen con stbi_load
, el valor devuelto en comp
siempre coincidirá con la imagen de origen, no con los datos de imagen devueltos.
Más específicamente, su error es que usa STBI_rgb
, lo que hace que stbi_load
devuelva 3 bytes de píxeles, pero luego lo carga con glTexImage2D
como 4 bytes con GL_RGBA
porque comp
es 4 cuando carga una imagen de 32 bits.
Debe configurar el formato en su llamada a glTexImage2D
a GL_RGB
si usa STBI_rgb
y a GL_RGBA
si usa STBI_rgb_alpha
.
Bono a otros lectores
¿Está teniendo un problema similar y lo anterior todavía no ayuda? Entonces, sus datos de imagen podrían no tener filas en la alineación que espera OpenGL. Pruebe glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
Antes de llamar a glTexImage2D
. Consulte https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout para obtener más información.