2013-06-15 6 views
8

Sto imparando OpenGL in C++ usando i tutorial di NeHe, ma sto provando a farli con la libreria di FreeImage, invece di Glaux o SOIL. Il punto positivo che vedo nell'utilizzo di FreeImage è che l'ultimo aggiornamento è stato nell'ottobre dell'anno scorso, mentre SOIL non è stato aggiornato tra 5 anni. Il problema che ho è che non riesco a caricare le trame correttamente.Come carico le trame su OpenGL usando la libreria FreeImage?

Ecco il mio codice:

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); 
} 

Utilizzando questo codice, la texture che ottengo è sbagliato: è nero, con punti colorati e strisce, e cambiando l'immagine dà lo stesso risultato, quindi suppongo I' m non sta caricando la texture correttamente.

Ho provato a scambiare i bit rosso e blu (leggi i carichi di FreeImage in BGR) senza risultati migliori. Infine, se cambio * FreeImage_ConvertTo32Bits (bitmap) * di * FreeImage_GetBits (bitmap) * Ottengo un segfault.

Cosa sto facendo male?

risposta

17

Ci sono due problemi con il codice: uno è che si sta convertendo in immagine a 32 bit ma si specifica un formato di trama a 24 bit per openGL (GL_RGB). Il secondo è che si passa l'oggetto FreeImage stesso alla trama anziché ai bit convertiti.

Hai bisogno di fare qualcosa di simile, invece

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

Questo non funziona per tutte le immagini a causa di requisiti di allineamento linea di scansione. –

+0

@SergeyK. Con i pixel a 32 bit, tutte le dimensioni della scanline sono comunque allineate a 4 byte. In quali situazioni pensi che non funzionerà? –

13

Per estendere la risposta precedente: funzione

FreeImage_GetBits() restituirà un puntatore ai dati memorizzati in un formato FreeImage-interno. Dove ogni linea di scansione è solitamente allineata a un limite di 4 byte. Questo funzionerà bene mentre hai texture di potenza di due. Tuttavia, per le trame NPOT è necessario specificare l'allineamento di decompressione corretto per OpenGL.

C'è un'altra funzione nella FreeImage che vi permetterà di ottenere non allineati gamma fitto di pixel: FreeImage_ConvertToRawBits()