Как известно любые текстуры можно разделить на две категории — сжатые и несжатые. Сжатые соответственно делятся на два типа сжатия — looseless и lossy (без потери качества и с потерей качества соответственно.

В современных видео картах есть поддержка нескольких форматов lossy сжатия текстур. Наиболее распростаненный из них — это формат сжатия DXTn.

Немного подробностей.

Алгоритм сжатия DXT был разработан компанией S3 Graphics, Ltd для видеокарты Savage3D.

Данный алгоритм обладает рядом удобных свойств для его использования в видео картах:

  • Алгоритм обеспечивает фиксированную степень сжатия для любой исходной картинки (8:1 для DXT1 и 4:1 для DXT2-5)
  • Алгоритм является блочным, он оперирует с блоками 4*4 пикселя исходной картники

Даный стандарт описывает только алгоритм распаковки, что позволяет реализовать алгоритм сжатия, который будет подходить для конкретных нужд.

Алгоритмы DXT1-5 отличаются только тем, как в них обрабатывается прозрачность. Обычно для изображений с прозрачностью рекомендуется использовать сжатие DXT5. Сжатие DXT1 не поддерживает прозрачность, либо позволяет задать пиксели с абсолютной прозрачностью

Сжатие текстур.

Для сжатия текстур можно использовать либо сторонные утилиты, такие как NVTexTools, либо использовать сжатие сресдствами OpenGL.

Несмотря на то что сжатие текстур средствами OpenGL возможно выполнять во время загрузки делать это не рекомендуется, потомучто процесс сжатия достаточно долог.

Сжатие средствами OpenGL.

Для сжатия средствами OpenGL потребуется примерно такой кусок кода:

//Создаем текстуру.  
GLuint texid;  
glGenTextures( 1, &texid );  
glBindTexture(GL_TEXTURE_2D, texid);   
glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, width, height, 
0, GL_RGB, GL_UNSIGNED_BYTE, source_texture);   
 
//Проверим - смогли ли мы сжать текстуру  
int compressed;  
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, 
&compressed);  
if(compressed != GL_TRUE)  
{     
 //Сжать текстуру не удалось      
return 1;  
}   
 
//Теперь осталось только вытащить текстур и сохранить ее.  
int32_t compressed_size;  
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, 
&compressed_size);  
char* compressed_texture = new char[compressed_size];  
glGetCompressedTexImage(GL_TEXTURE_2D, 0, img);

После сжатия стоит сохранить результирующий формат сжатия, размеры текстуры.

Загрузка сжатой текстуры.

Для работы со сжатыми текстурами в OpenGL предусмотрена дополнительная функция: glCompressedTexImage . Справку по ее параметрам вы сможете получить в документации на OpenGL а я приведу пример использвания ее для загрузки сжатой текстуры:

glGenTextures( 1, &_tex_id_ );
glBindTexture ( GL_TEXTURE_2D, _tex_id_ );
glCompressedTexImage2D ( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, width, height, 
0, texture_size, texture_pointer);

Надо отметить что для текстур DXTn размер не может быть меньше чем 4*4 пикселя.

Тестирование скорости рендеринга с DXTn

Реализовав поддержку сжатых текстур мне захотелось узнать какой прирост производительности дает их использование. Найти аналогичную информацию, на стадии анализа необходимости реализации данной поддержки, я не смог.

Для тестирования использовалась RGB текстура размером 1024*1024. Она была сохранена в нескольких форматах: RGB8, RGB5, R3_G3_B2. Для каждой текстуры проводилось 2 замера:  в ситуации когда объект (модель с 7к полигонами) занимает меньше 10% экрана и в ситуации когда объект занимает около 50% экрана.

Рассчет FPS производился раз в 10000 кадров. Среднее выходное значение округлялось до 100.

Формат текстуры 10% заполнение 50% заполнение
FPS % %
DXT1 5000 4100
RGB8 5000 0 3400 -17%
RGB4 5000 0 3900 -4.8%
R3_G3_B2 5000 0 4100 0

Как следствие можно седелать вывод что если у вас есть текстура, которая не теряет в качестве при использовании DXT сжатия, либо теряет его в приемлемых масштабах — то можно получить хороший прирост производительности, использовав DXT сжатие.

Tags:

This entry was posted on Четверг, Июль 2nd, 2009 at 13:25 and is filed under OpenGL, Новости. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

One comment

 1 

Очень интересная статья, я даже и не знал, что с помощью OpenGL можно сжимать текстуры. теперь возьму на вооружение, спасибо!

Декабрь 29th, 2012 at 12:35