J'utilise stb_image pour charger un fichier PNG 32 bits (RGBA) et je crée une texture OpenGL avec.
Cela fonctionne bien pour les fichiers PNG 24 bits (sans canal alpha), mais lorsque j'utilise un fichier PNG 32 bits, quelque chose ne va pas.
Voici à quoi devrait ressembler la texture:
Et voici à quoi cela ressemble lorsqu'il est rendu avec OpenGL (les parties noires sont censées être transparentes, et le sont lorsque j'active le mélange):
Voici comment je charge la 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);
Et ce sont les paramètres de la fenêtre (en utilisant 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);
Qu'est-ce qui se passe?
La modification de STBI_rgb en STBI_rgb_alpha dans l'appel de fonction stbi_load l'a corrigé.
Il est probablement préférable de ne pas spécifier RGB lorsque son RGBA: D
Votre bogue réel est que vous utilisez comp
pour déterminer votre paramètre format
(GL_RBA
/GL_RGBA
) Sur glTexImage2D
. Cela se produit car lorsque vous chargez une image à l'aide de stbi_load
, La valeur renvoyée dans comp
correspondra toujours à l'image source, pas aux données d'image renvoyées.
Plus précisément, votre bogue est que vous utilisez STBI_rgb
, Ce qui fait que stbi_load
Renvoie 3 pixels d'octets, mais vous le chargez ensuite avec glTexImage2D
Comme pixels de 4 octets avec GL_RGBA
car comp
vaut 4 lorsque vous chargez une image 32 bits.
Vous devez définir le format de votre appel sur glTexImage2D
Sur GL_RGB
Si vous utilisez STBI_rgb
Et sur GL_RGBA
Si vous utilisez STBI_rgb_alpha
.
Bonus pour les autres lecteurs
Vous rencontrez un problème similaire et ce qui précède n'aide toujours pas? Vos données d'image pourraient alors ne pas avoir de lignes sur l'alignement qu'OpenGL attend. Essayez glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
avant d'appeler glTexImage2D
. Voir https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout pour plus d'informations.