Работа с расширениями OpenGL с использованием NVIDIA OpenGL SDK 5.1. (Часть 6) (2 стр)
Автор: Сергей Гайдуков
Работа с файлами формата jpg
Во всех примерах этого цикла статей мы сохраняли текстуры в файлах формата tga. Но tga относится к классу форматов, которые сжимают файлы без потери информации. По идее, это очень хорошо, но не надо забывать и о читателях, которые вынуждены "скачивать" эти примеры с сайта, да и место на винчестере бесконечно только в течение месяца, после покупки. Поэтому, начиная с этой статьи, все текстуры будут храниться в файлах формата .jpg с качеством в районе 65%-100% в зависимости от размера текстуры.
За работу с файлами формата jpg в NVIDIA OpenGL SDK отвечает функция read(), находящаяся "\OpenGLSDK\include\nv_util\nv_jpeg.h". Функция определена в пространстве имён jpeg, поэтому вам придётся либо использовать директиву using namespace jpeg, либо вызывать её как jpeg::read().
Рассмотрим определение этой функции:
int read(const char * filename, int * width, int * height, unsigned char ** pixels, int * components);
В качестве первого параметра эта функция принимает название файла. Остальные параметры - указатели на переменные, в которые будет занесена информация о загруженном файле: ширина и высота изображения, указатель на массив пикселей и количество цветовых компонентов в изображении (RGB=3, RGBA=4 и т.д.).
К сожалению, в файле "nv_jpeg.h" нет какой-либо структуры наподобие tga::tgaImage для хранения информации из jpg-файлов. Поэтому, что бы сделать программу более понятной и облегчить модификацию примеров, я решил хранить информацию из jpg-файлов в структуре tga::tgaImage. Ниже приведён фрагмент кода из примера Ex01, отвечающий за загрузку файлов в память:
tga::tgaImage textureImage0; jpeg::read("..\\Yellobrk1.jpg", &textureImage0.width, &textureImage0.height, &textureImage0.pixels, &textureImage0.components); if ( textureImage0.components==3) textureImage0.format=GL_RGB; else { console.add( "Unsupported format of .jpg file"); console.exit( -1); }
Обратите внимание, что в класс консоли добавлен метод exit(), который может использоваться для аварийного завершения программы. Необходимость в нём обусловлена тем, что если мы попытаемся завершить работу программы с использованием "классической" функции exit(), то пользователь не сможет прочитать информацию, которая была занесена в консоль. Метод exit() отключает обработку событий всеми интеракторами списка интеракторов, кроме самого себя, и выводит на экран консоль:
void glut_console::exit(int Value)
{
exiting=true;
for(std::list<glut_interactor *>::iterator itor=interactors.begin();
itor!=interactors.end(); itor++)
(*itor)->disable();
visible=true;
enable();
glutPostRedisplay();
}В настоящее время значение Value игнорируется, но чуть позже, когда мы "сцепим" между собой интеракторы glut_console и glut_simple_user_interface, это значение будет передаваться функции exit() в обработчике клавиши ESC интерактора glut_simple_user_interface.
Если вы попробуете загрузить при помощи функции read() какое-либо изображение, то обнаружите, что эта функция имеет один недостаток - она загружает перевёрнутое изображение. Следовательно, это полученную текстуру надо как-нибудь "перевернуть" обратно. Это можно сделать двумя способами:
1. Перевернуть текстуру путём реальной перестановки пикселей.
2. Умножить текущую матрицу текстуры на матрицу отражения относительно прямой t=0.5.
Мы воспользуемся вторым способом:
glMatrixMode(GL_TEXTURE); glPushMatrix( ); glTranslatef( 0, 0.5, 0); glScalef( 1, -1, 1); glTranslatef( 0, -0.5, 0); glCallList( mylist); glPopMatrix( ); glMatrixMode( GL_MODELVIEW);
#расширения OpenGL, #NVIDIA, #OpenGL
13 апреля 2003 (Обновление: 6 окт 2009)