2013-06-15 21 views
8

Uczę się OpenGL w C++ przy użyciu samouczków NeHe, ale próbuję zrobić to z biblioteką FreeImage, zamiast Glaux lub SOIL. Dobrym punktem, jaki widzę przy korzystaniu z FreeImage, jest jego ostatnia aktualizacja w październiku zeszłego roku, podczas gdy SOIL nie była aktualizowana od 5 lat. Problem polega na tym, że nie mogę poprawnie załadować tekstur.Jak załadować tekstury do OpenGL za pomocą biblioteki FreeImage?

Oto mój kod:

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

Za pomocą tego kodu, tekstury mogę to źle: to czarny, z kolorowymi kropkami i paskami i zmienia obraz daje ten sam wynik, więc zakładam, że I” m nie ładuje poprawnie tekstury.

Próbowałem zamienić czerwony i niebieski bit (przeczytaj, że FreeImage ładuje się w BGR) bez lepszego wyniku. Na koniec, jeśli zmienię * FreeImage_ConvertTo32Bits (bitmap) * o * FreeImage_GetBits (bitmap) * otrzymam błąd segfault.

Co robię źle?

Odpowiedz

17

Występują dwa problemy z kodem - jednym jest to, że konwertujesz obraz na 32 bity, ale określasz 24-bitowy format tekstury, aby otworzyćGL (GL_RGB). Po drugie, przekazujesz sam obiekt FreeImage do tekstury, a nie do skonwertowanych bitów.

Trzeba zrobić coś takiego zamiast

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

To nie będzie działać dla wszystkich obrazów ze względu na wymagania wyrównania Scanline. –

+0

@SergeyK. W przypadku 32-bitowych pikseli wszystkie rozmiary linii skanowania są wyrównane do 4 bajtów. W jakich sytuacjach uważasz, że to nie zadziała? –

13

przedłużyć poprzedniej odpowiedzi:

FreeImage_GetBits() funkcja zwraca wskaźnik do danych zapisanych w formacie FreeImage-wewnętrznego. Tam, gdzie każda linia jest zazwyczaj wyrównana do granicy 4-bajtowej. Będzie to działało dobrze, gdy masz tekstury power-of-two. Jednak w przypadku tekstur NPOT należy określić poprawne wyrównanie rozpakowania dla OpenGL.

Jest jeszcze inna funkcja w FreeImage który pozwoli Ci uzyskać aligné szczelnie zapakowany tablicę pikseli: FreeImage_ConvertToRawBits()

Powiązane problemy