2013-06-15 10 views
8

Ich lerne OpenGL in C++ mit NeHe-Tutorials, aber ich versuche, sie mit FreeImage-Bibliothek statt Glaux oder SOIL zu tun. Der gute Punkt, den ich bei der Verwendung von FreeImage sehe, ist die letzte Aktualisierung im Oktober letzten Jahres, während SOIL seit 5 Jahren nicht mehr aktualisiert wurde. Das Problem, das ich habe, ist, dass ich Texturen nicht richtig laden kann.Wie lade ich Texturen mit der FreeImage-Bibliothek zu OpenGL?

Hier ist mein 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); 
} 

diesen Code verwenden, die Textur ich erhalte, ist falsch: Es ist schwarz, mit farbigen Punkten und Streifen und gibt das Bild zu ändern das gleiche Ergebnis, so nehme ich an I‘ m lädt die Textur nicht korrekt.

Ich habe versucht, die roten und blauen Bits zu tauschen (lesen Sie, dass FreeImage in BGR geladen wird) mit keinem besseren Ergebnis. Schließlich, wenn ich die * FreeImage_ConvertTo32Bits (Bitmap) * um * FreeImage_GetBits (Bitmap) * ändere, bekomme ich einen segfault.

Was mache ich falsch?

Antwort

17

Es gibt zwei Probleme mit Ihrem Code - einer besteht darin, dass Sie in ein Bild mit 32 Bits konvertieren, aber Sie geben ein 24-Bit-Texturformat für openGL an (GL_RGB). Die zweite besteht darin, dass Sie das FreeImage-Objekt selbst an die Textur und nicht an die konvertierten Bits übergeben.

Sie brauchen so etwas wie diese statt

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

Das wird nicht funktionieren für alle Bilder aufgrund Scanline-Ausrichtungsanforderungen. –

+0

@SergeyK. Bei 32-Bit-Pixeln sind alle Scanline-Größen sowieso 4-Byte-ausgerichtet. In welchen Situationen wird es deiner Meinung nach nicht funktionieren? –

13

tun, um die vorherige Antwort zu verlängern:

FreeImage_GetBits() Funktion einen Zeiger auf die gespeicherten Daten in einem Freeimage-internes Format zurück. Dabei ist jede Scanline normalerweise auf eine 4-Byte-Grenze ausgerichtet. Dies funktioniert gut, wenn Sie Zwei-Potenz-Texturen haben. Für NPOT-Texturen müssen Sie jedoch die korrekte Entpackungsausrichtung für OpenGL angeben.

Es gibt eine weitere Funktion in Freeimage ist, die Sie nicht ausgerichtete dicht gepackten Anordnung von Pixeln erhalten können: FreeImage_ConvertToRawBits()

Verwandte Themen