Работа с расширениями OpenGL с использованием NVIDIA OpenGL SDK 5.1. (Часть 6)
Автор: Сергей Гайдуков
Работа со сжатыми текстурами
Работа с файлами формата jpg
Расширение ARB_texture_compression
Расширение EXT_texture_compression_s3tc
Сравнение форматов сжатия S3TC
Использование расширения EXT_texture_compression_s3tc
Работа со сжатыми текстурами
В настоящее время в программах, работающих с трёхмерной графикой, как правило, используются 32-х битные текстуры высокого разрешения (512x512 и выше). Платой за высокое качество текстур являются повышенные требования, как к объёму видеопамяти, так и к её пропускной способности. Казалось бы - есть шина AGP, которая позволяет хранить текстуры большого размера в ОЗУ компьютера. Но на самом деле это не так - быстродействие видеопамяти видеокарты и ОЗУ компьютера различаются почти на порядок, поэтому шина AGP фактически только упрощает программирование, позволяя загружать больший объём текстур при инициализации программы. Если же все текстуры текущего кадра не поместятся в видеопамяти, производительность видеокарты очень сильно упадаёт.
В результате производителям видеокарт пришлось решать "неразрешимую" задачу: как увеличить качество текстур без увеличения объёма видеопамяти. Выход был найден довольно быстро - фирмы S3 и 3dfx предложили форматы сжатия текстур S3TC и FXT1, которые позволяют сжимать текстуры в 6 и 8 раз соответственно (имеется в виду максимальная степень сжатия). Оба этих метода реализуют сжатие с потерей информации. Но в большинстве случаев качество сжатых текстур с увеличенной детализацией лучше качества несжатых текстур того же объёма.
Перед тем как перейти к работе со сжатыми текстурами, мы сначала рассмотрим два небольших раздела, которые значительно облегчат нам программирование.
Классы семейства tex_object_XXXX для работы с текстурами.
Во время работы с текстурами нам постоянно необходимо выполнять ряд одних и тех же операций: запросить имя для текстуры командой glGenTextures(), создать поименованную текстуру командой glBindTexture(), удалить текстуру командой glDeleteTexture(). При этом приходится постоянно "помнить" имя текстуры и её тип (GL_TEXTURE_1D и т.д.).
После создания нескольких приложений программист начинает ощущать потребность в классе, который бы умел самостоятельно создавать текстуру при первом обращении к ней, уничтожать её при выходе за пределы видимости и "помнить свои параметры".
Поэтому в состав NVIDIA OpenGL включён набор классов tex_object_XXXX, которые предназначены для работы с текстурами различных видов. Сейчас для нас интересны только классы tex_object_1D, tex_object_2D и tex_object_rectangle, которые работают с текстурами GL_TEXTURE_1D, GL_TEXTURE_2D и GL_NV_texture_rectangle соответственно. Если мы откроем файл " \OpenGLSDK \include\glh\glh_obs.h", то увидим, что все эти классы являются производными от tex_object и различаются только конструктором, который заносит в поле target (тип класса) соответствующий идентификатор. Помимо этого поля в классе определены ещё поля texture (имя текстуры) и valid (показывает, ссылается ли класс на реальную текстуру). Основные методы класса приведены в таблице 1.
| Метод | Аналогичная команда OpenGL | Назначение |
| Bind | glBindTexture(target, texture) | Устанавливает текстуру в качестве текущей.
Если текстура ещё не существует (valid=false), то перед этим получает её имя командой glGenTextures. |
| Del | glDeleteTextures(1, &texture) | Удаляет текстуру |
| Parameter | glTexParameter[ i][f][iv][fv] | Устанавливает параметры текстуры |
| Enable | glEnable(target) | Включает режим наложения текстуры |
| Disable | glDisable(target) | Выключает режим наложения текстуры |
Таблица 1: основные методы класса tex_object
Для демонстрации использования этого класса ниже приведены фрагменты программы, выводящей на экран плоскость с нанесённой на неё текстурой (Ex01) (рисунок 1).
Рисунок 1
Ниже приведены фрагменты кода, отвечающие за работу с текстурами:
tex_object_2D texture0; tga::tgaImage textureImage0; void Init() { //Загрузка изображения в textureImage0 //---------------------- texture0.bind( ); glTexImage2D( texture0.target, 0, GL_RGBA, textureImage0.width, textureImage0.height, 0, textureImage0.format, GL_UNSIGNED_BYTE, textureImage0.pixels); texture0.parameter( GL_TEXTURE_MIN_FILTER, GL_LINEAR); texture0.parameter( GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); } void Display( ) { ... texture0.enable( ); glCallList( mylist); texture0.disable( ); }
Как видно, применение этого класса практически не изменяет структуру программы. Но пользователю теперь не надо следить за загрузкой/выгрузкой текстур, а так же постоянно указывать тип текстуры (GL_TEXTURE_2D) в командах OpenGL. Это позволяет очень легко модифицировать в программу. Например, для изменения типа текстуры на GL_NV_texture_rectangle достаточно заменить класса tex_object_2D на tex_object_rectangle (и пересчитать координаты текстур).
#расширения OpenGL, #NVIDIA, #OpenGL
13 апреля 2003 (Обновление: 6 окт 2009)