загрузка текстуры из растрового изображения

Похоже, что я загружаю изображение неправильно. Изображение появляется весь зашифрованный. Что я здесь не так делаю?

int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity();   // Reset The Current Modelview Matrix

glEnable(GL_TEXTURE_2D);
GLuint texture = 0;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_2D, texture);

FIBITMAP* bitmap = FreeImage_Load(FreeImage_GetFileType("C:/Untitled.bmp", 0), "C:/Untitled.bmp", BMP_DEFAULT);
FIBITMAP *pImage = FreeImage_ConvertTo32Bits(bitmap);
int nWidth = FreeImage_GetWidth(pImage);
int nHeight = FreeImage_GetHeight(pImage);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, nWidth, nHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(pImage));
FreeImage_Unload(pImage);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, -1.0f);
glEnd();

RECT desktop;
const HWND hDesktop = GetDesktopWindow();
GetWindowRect(hDesktop, &desktop);
long horizontal = desktop.right;
long vertical = desktop.bottom;

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glDisable(GL_TEXTURE_2D);
return TRUE;    // Keep Going
}

что я вижу при запуске программы
Что я вижу при запуске программы
что я ожидаю увидеть при запуске программы (растровое изображение, которое я загружаю)
Что я ожидаю увидеть

1

Решение

Часть проблемы здесь, кажется, заключается в несоответствии между форматом пиксельных данных, которые вы получаете от FreeImage, и форматом, ожидаемым glTexImage2D,

FreeImage_ConvertTo32Bits собирается вернуть изображение с 32-битными пиксельными данными. Я не использовал FreeImage, но обычно это означает, что каждый пиксель будет иметь 4 8-битных компонента, представляющих красный, зеленый, синий и альфа (непрозрачность). Формат данных, которые вы получаете из файла BMP, зависит от файла и может иметь или не иметь альфа-канал в нем. Однако можно с уверенностью предположить, что FreeImage_ConvertTo32Bits вернет данные с альфа-каналом, равным 255, если исходное изображение полностью непрозрачно (либо потому, что в формате файла BMP отсутствовал альфа-канал, либо потому, что при создании файла вы установили непрозрачность).

Это все хорошо, но проблема приходит с призывом glTexImage2D, Эта функция может принимать данные пикселей в разных форматах. Формат, который он использует для интерпретации данных, определяется параметрами type а также format как описано Вот. Значение format в вашем коде есть GL_RGB, Это говорит о том, что каждый пиксель имеет три компонента, описывающие его красный, зеленый и синий компоненты, которые появляются в этом порядке в данных пикселей. Значение type (GL_UNSIGNED_BYTE) говорит, что каждый компонент имеет размер одного байта. Проблема в том, что альфа-канал отсутствует, поэтому glTexImage2D читает данные пикселей из неправильного места. Также кажется, что порядок цветов, которые производит FreeImage, сине-зелено-красный, как указал Роджер Роуланд. Исправить это просто: установите format в GL_BGRA сказать glTexImage2D об альфа-компонентах и ​​порядке данных:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, nWidth, nHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(pImage));

Чтобы увидеть, может ли эта проблема объяснить странные результаты, подумайте о больших блоках синего цвета на исходном изображении. Согласно GIMP это в основном синий с меньшим количеством зеленого (R = 0, G = 162, B ​​= 232). Итак, у нас есть что-то вроде этого:

B G R A B G R A B G R A ...   meaning of bytes from FreeImage_GetBits
1 - 0 1 1 - 0 1 1 - 0 1 ...   "values" of bytes (0 -> 0, - -> 162, 1 -> 232 or 255)
R G B R G B R G B R G B ...   what glTexImage2D thinks the bytes mean

Пиксельные цвета текстуры здесь: оранжевый, светло-желтый, ярко-голубой и пурпурный. Они повторяются, потому что чтение 4 пикселей занимает 12 байтов, что в точности равно 3 оригинальным пикселям. Это объясняет шаблон, который вы видите на большей части выходного изображения. (Изначально я прошел через это, используя порядок RGBA, но версия GBRA лучше подходит для изображения — разница особенно заметна в начале строк).

Однако я должен признать, что я не уверен, что происходит в начале и как связать это с розовым квадратом! Так что здесь могут быть и другие проблемы, но, надеюсь, GL_BGRA будет шагом в правильном направлении.

3

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

Вы делаете изображение с 32 битами на дюйм, поэтому вам нужно иметь правильные объявления текстуры:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight,
0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(pImage));

Так же FreeImage_GetBits функция возвращает данные, которые обычно выровнены так, что каждая строка заканчивается 4-байтовой границей. Таким образом, если ваше изображение 32 бит на дюйм (как есть), или если ширина вашего изображения равна степени двойки, все будет в порядке, но в противном случае вам нужно будет соответствующим образом установить выравнивание распаковки.

2

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