2013-06-15 4 views
8

J'apprends OpenGL en C++ en utilisant des tutoriels NeHe, mais j'essaie de les faire avec la librairie FreeImage, au lieu de Glaux ou SOIL. Le bon point que je vois dans l'utilisation de FreeImage est que sa dernière mise à jour date d'octobre de l'année dernière, alors que SOIL n'a pas été mise à jour depuis 5 ans. Le problème que j'ai est que je ne suis pas capable de charger les textures correctement.Comment charger des textures dans OpenGL en utilisant la librairie FreeImage?

Voici mon code:

static GLuint texture = 0; 
if (texture == 0) 
{ 
    FIBITMAP* bitmap = FreeImage_Load(
     FreeImage_GetFileType("textures/test/nehe_06.png", 0), 
     "textures/test/nehe_06.png"); 

    glGenTextures(1, &texture); 

    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

    glTexImage2D(GL_TEXTURE_2D, 0, 3, FreeImage_GetWidth(bitmap), FreeImage_GetHeight(bitmap), 
     0, GL_RGB, GL_UNSIGNED_BYTE, FreeImage_ConvertTo32Bits(bitmap)); 

    FreeImage_Unload(bitmap); 
} 

En utilisant ce code, la texture que je reçois est faux: il est noir, avec des points colorés et des bandes, et en changeant l'image donne le même résultat, donc je suppose que je » Je ne charge pas la texture correctement.

J'ai essayé d'échanger les bits rouges et bleus (lire les charges FreeImage dans BGR) sans meilleur résultat. Enfin, si je change le * FreeImage_ConvertTo32Bits (bitmap) * par * FreeImage_GetBits (bitmap) * je reçois un segfault.

Qu'est-ce que je fais mal?

Répondre

17

Votre code comporte deux problèmes: l'un est la conversion en image vers 32 bits, mais vous spécifiez un format de texture 24 bits pour openGL (GL_RGB). La seconde est que vous passez l'objet FreeImage lui-même à la texture plutôt qu'aux bits convertis.

Vous devez faire quelque chose comme ça à la place

FIBITMAP *pImage = FreeImage_ConvertTo32Bits(bitmap); 
int nWidth = FreeImage_GetWidth(pImage); 
int nHeight = FreeImage_GetHeight(pImage); 

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight, 
    0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(pImage)); 

FreeImage_Unload(pImage); 
+0

Cela ne fonctionnera pas pour toutes les images en raison des exigences d'alignement de ligne de balayage. –

+0

@SergeyK. Avec des pixels de 32 bits, toutes les tailles de lignes de balayage sont de toute façon alignées sur 4 octets. Dans quelles situations pensez-vous que cela ne fonctionnera pas? –

13

Pour étendre la réponse précédente: fonction

FreeImage_GetBits() renvoie un pointeur vers les données stockées dans un format FreeImage interne. Où chaque ligne de balayage est généralement alignée sur une limite de 4 octets. Cela fonctionnera bien pendant que vous avez des textures de puissance de deux. Cependant, pour les textures NPOT, vous devrez spécifier l'alignement de désallocation correct pour OpenGL.

Il y a une autre fonction FreeImage qui vous permettra d'obtenir unaligned tableau bien rempli de pixels: FreeImage_ConvertToRawBits()