Как загрузить текстуры в OpenGL с помощью библиотеки FreeImage?

Я изучаю OpenGL на C ++, используя учебные пособия NeHe, но я пытаюсь сделать это с помощью библиотеки FreeImage вместо Glaux или SOIL. Хорошее замечание, которое я вижу в использовании FreeImage, заключается в том, что его последнее обновление было в октябре прошлого года, в то время как SOIL не обновлялся в течение 5 лет. Проблема в том, что я не могу правильно загрузить текстуры.

Вот мой код:

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

Используя этот код, полученная текстура неправильна: она черная, с цветными точками и полосами, и изменение изображения дает тот же результат, поэтому я предполагаю, что не загружаю текстуру правильно.

Я пытался поменять местами красные и синие биты (читай, что FreeImage загружается в BGR), но безрезультатнее. Наконец, если я изменяю * FreeImage_ConvertTo32Bits (растровое изображение) * на * FreeImage_GetBits (растровое изображение) *, я получаю ошибку сегмента.

Что я делаю не так?

9

Решение

С вашим кодом есть две проблемы — одна из них заключается в том, что вы конвертируете изображение в 32-битное, но вы указываете 24-битный формат текстуры для openGL (GL_RGB). Во-вторых, вы передаете сам объект FreeImage в текстуру, а не в преобразованные биты.

Вам нужно сделать что-то подобное вместо этого

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

Другие решения

Чтобы расширить предыдущий ответ:

FreeImage_GetBits() Функция вернет указатель на данные, хранящиеся во внутреннем формате FreeImage. Где каждая линия сканирования обычно выровнена по границе 4 байта. Это будет хорошо работать, пока у вас есть власть двух текстур. Однако для текстур NPOT вам нужно будет указать правильное выравнивание распаковки для OpenGL.

В FreeImage есть еще одна функция, которая позволит вам получить невыровненный плотно упакованный массив пикселей: FreeImage_ConvertToRawBits()

13

По вопросам рекламы [email protected]