Как загрузить текстуры в OpenGL с помощью библиотеки FreeImage?
Я изучаю OpenGL на C++, используя учебники NeHe, но я пытаюсь сделать их с помощью библиотеки FreeImage, а не Glaux или SOIL. Хороший момент, который я вижу в использовании FreeImage, - это последнее обновление в октябре прошлого года, в то время как почва не обновлялась в течение 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(bitmap)* на *FreeImage_GetBits (bitmap)*, я получу segfault.
что я делаю не так?
2 ответов
есть две проблемы с вашим кодом-одна из них заключается в том, что вы конвертируете изображение в 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);
чтобы продлить предыдущий ответ:
FreeImage_GetBits()
функция вернет указатель на данные, хранящиеся в формате FreeImage-internal. Где каждая линия развертки обычно выравнивается по границе 4 байта. Это будет работать нормально, пока у вас есть Power-of-two текстуры. Однако для текстур NPOT вам нужно будет указать правильное выравнивание распаковки для OpenGL.
в FreeImage есть еще одна функция, которая позволит вам получить несогласованный плотно упакованный массив пиксели:FreeImage_ConvertToRawBits()