Каков предпочтительный способ отображения больших изображений в OpenGL
У меня была эта проблема пару раз. Предположим, я хочу отобразить заставку или что-то в контексте OpenGL (или DirectX, если на то пошло, это скорее концептуальная вещь), теперь я мог бы просто загрузить текстуру 2048x2048 и надеяться, что графическая карта справится с этим (большинство из них в настоящее время, я полагаю), но, растя со старой школьной видеокартой, у меня есть эта нечистая совесть, склоняющаяся надо мной и говорящая мне, что я не должен использовать такие большие текстуры.
Что такое предпочтительный способ в наши дни? Это просто втиснуть эту вещь в видеопамять, выложить ее плиткой или позволить процессору делать работу и glDrawPixels? Или что-то более сложное?
2 ответов
Если это один кадр всплеск изображения без анимации, то нет никакого вреда с помощью glDrawPixels
. Если производительность имеет решающее значение и требуется использовать текстуру, то правильный способ сделать это-определить во время выполнения максимальный поддерживаемый размер текстуры, используя текстуру прокси.
GLint width = 0;
while ( 0 == width ) { /* use a better condition to prevent possible endless loop */
glTexImage2D(GL_PROXY_TEXTURE_2D,
0, /* mip map level */
GL_RGBA, /* internal format */
desiredWidth, /* width of image */
desiredHeight, /* height of image */
0, /* texture border */
GL_RGBA /* pixel data format, */
GL_UNSIGNED_BYTE, /* pixel data type */
NULL /* null pointer because this a proxy texture */
);
/* the queried width will NOT be 0, if the texture format is supported */
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
desiredWidth /= 2; desiredHeight /= 2;
}
как только вы знаете максимальный размер текстуры, поддерживаемый драйвером OpenGL системы, у вас есть по крайней мере два варианта, если ваше изображение не подходит:
-
изображения черепица: используйте несколько квадроциклов после разделения изображения на меньшие поддерживаемые куски. Плитка изображения для чего-то вроде заставки не должна быть слишком сложной. Вы можете использовать glPixelStorei ' s
GL_PACK_ROW_LENGTH
параметр для загрузки разделов большего изображения в текстуру. - изменение размера изображения: измените размер изображения в соответствии с максимальным поддерживаемым размером текстуры. Существует даже вспомогательная функция GLU, чтобы сделать это для вас, gluScaleImage.
Я не думаю, что есть встроенная функция opengl, но вы можете найти библиотеку (или написать функцию самостоятельно), чтобы разбить изображение на меньшие куски, а затем распечатать на экране меньшие куски (плитки 128x128 или аналогичные).
У меня были проблемы с этим использованием Slick2D для Java-игр. Вы можете проверить их класс "BigImage" для идей здесь.