Каков предпочтительный способ отображения больших изображений в 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" для идей здесь.