Похоже, что я загружаю изображение неправильно. Изображение появляется весь зашифрованный. Что я здесь не так делаю?
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
}
что я вижу при запуске программы
что я ожидаю увидеть при запуске программы (растровое изображение, которое я загружаю)
Часть проблемы здесь, кажется, заключается в несоответствии между форматом пиксельных данных, которые вы получаете от 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
будет шагом в правильном направлении.
Вы делаете изображение с 32 битами на дюйм, поэтому вам нужно иметь правильные объявления текстуры:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight,
0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(pImage));
Так же FreeImage_GetBits
функция возвращает данные, которые обычно выровнены так, что каждая строка заканчивается 4-байтовой границей. Таким образом, если ваше изображение 32 бит на дюйм (как есть), или если ширина вашего изображения равна степени двойки, все будет в порядке, но в противном случае вам нужно будет соответствующим образом установить выравнивание распаковки.