Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Наложение текстуры на произвольную поверхность




В OpenGL есть режим автоматической генерации текстурных координат. Этот режим позволяет отказаться от использования glTexCoord2d() при решения нескольких типичных задач, таких, как демонстрация очертаний объекта с помощью контуров и построение отражения окружающей среды на блестящих объектах.

Для применения этого режима сначала требуется разрешить автоматическую генерацию координаты текстуры по одному или обоим направлениям с помощью вызова glEnable(GL_TEXTURE_GEN_S) и glEnable(GL_TEXTURE_GEN_T). После этого надо с помощью функции glTexGen() выбрать способ генерации текстурных координат.

void glTexGen{ifd}{v}(GLenum coord, GLenum pname, TYPE param);

Параметр coord выбирает координату GL_S или GL_T. Второй параметр pname равен GL_TEXTURE_GEN_MODE, а param задает функцию вычисления текстурных координат: GL_OBJECT_LINEAR, GL_EYE_LINEAR или GL_SPHERE_MAP.

Функции расчета текстурных координат GL_OBJECT_LINEAR и GL_EYE_LINEAR в основном применяются для нанесения контурных изображений на объект, чтобы показать его форму (например, с помощью одномерной текстуры в виде полоски).

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

Отображение GL_SPHERE_MAP строится в предположении, что предметы в комнате расположены достаточно далеко от поверхности блестящего объекта и этот объект очень мал по сравнению с размерами комнаты. В таком приближении, чтобы рассчитать цвет точки поверхности объекта, выполняется построение луча от наблюдателя до поверхности и затем рассчитывается отражение этого луча от поверхности объекта. Направление отраженного луча определяет цвет пиксела объекта. Для применения режима GL_SPHERE_MAP необходимо подготовить текстуру специальным образом, так, чтобы она была похожа на фотографию реального блестящего объекта, сделанную с помощью широкоугольного объектива.

В целом, применение любой из трех описанных функций для получения регулярной текстуры на объекте является довольно сложным делом. Наложение нерегулярных хаотических текстур выполняется значительно проще и в ряде случаев может дать приемлемые результаты. В приведенной ниже функции display() из программы 7.3 демонстрируется наложение двух текстур на стандартные объекты GLAUX с применением трех различных функций генерации текстурных координат.

 

void CALLBACK display()

{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

 

glEnable(GL_TEXTURE_2D);

glEnable(GL_TEXTURE_GEN_S);

glEnable(GL_TEXTURE_GEN_T);

 

glColor3d(1, 1, 1);

 

glPushMatrix();

glTranslated(-3, 3, 0);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

glBindTexture(GL_TEXTURE_2D, falls_tex);

auxSolidTeapot(1.5);

 

glTranslated(6, 0, 0);

glBindTexture(GL_TEXTURE_2D, sawdust_tex);

auxSolidTeapot(1.5);

glPopMatrix();

 

glPushMatrix();

glTranslated(-3, 0, 0);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

glBindTexture(GL_TEXTURE_2D, falls_tex);

auxSolidTeapot(1.5);

 

glTranslated(6, 0, 0);

glBindTexture(GL_TEXTURE_2D, sawdust_tex);

auxSolidTeapot(1.5);

glPopMatrix();

 

glPushMatrix();

glTranslated(-3, -3, 0);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);

glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);

glBindTexture(GL_TEXTURE_2D, falls_tex);

auxSolidTeapot(1.5);

 

glTranslated(6, 0, 0);

glBindTexture(GL_TEXTURE_2D, sawdust_tex);

auxSolidTeapot(1.5);

glPopMatrix();

 

glDisable(GL_TEXTURE_GEN_S);

glDisable(GL_TEXTURE_GEN_T);

glDisable(GL_TEXTURE_2D);

 

auxSwapBuffers();

}

Фрагмент программы 7.3. Автоматическое наложение текстур.

 

 

Сводка результатов

Изображения – это двумерные массивы пикселов. В библиотеке GLAUX есть функция для загрузки изображения из BMP-файла в буфер в оперативной памяти. Затем это изображение можно вывести в буфер кадра OpenGL. К изображениям нельзя применять модельные преобразования, но можно задавать координаты левого нижнего угла и масштаб.

Для имитации реальных объектов часто применяются текстуры – изображения, накладываемые "поверх" примитивов OpenGL. В лекции описан порядок работы с несколькими текстурами. У каждой текстуры есть числовой идентификатор и набор свойств. При наложении на объект можно задавать координаты текстуры в явном виде, сопоставляя координаты элементов текстуры (текселов) и пикселов объекта. OpenGL может автоматически повторять текстуру на плоской поверхности в одном или двух направлениях. Для наложения текстур на произвольную поверхность, состоящую из совокупности примитивов, в OpenGL есть режим автоматической генерации текстурных координат.

 

 

Упражнения

Упражнение 1

С помощью функций, описанных в п.1, напишите программу для вывода на экран изображения подсолнуха из файла SUNFLOWR.BMP. В начале координат нарисуйте единичную сферу. Попробуйте сначала поместить изображение позади сферы, а затем – перед сферой.

 

Упражнение 2

Измените программу из упражнения 1 так, чтобы изображение выводилось с прозрачным фоном. В изображении SUNFLOWR.BMP фоновые области специально выделены пурпурным цветом (255, 0, 255). Чтобы сделать их прозрачными, в программу потребуется добавить функцию, которая динамически создает массив для хранения изображения в формате RGBA и копирует в него изображение из файла с соответствующими компонентами прозрачности (пикселы фонового цвета прозрачные, остальные – непрозрачные). Изменения в программе будут заключаться в следующем:

1) Заведите глобальную переменную для изображения с прозрачным фоном:

AUX_RGBImageRec flowerImg;

2) Перед вызовом главного цикла разрешите обработку альфа-компонент и смешение цветов:

glEnable(GL_ALPHA_TEST);

glEnable(GL_BLEND)

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

3) Добавьте в программу функцию для инициализации изображения flowerImg (см. текст далее) и вызовите ее перед входом в главный цикл. После выхода из главного цикла выполните удаление данных изображения.

4) Измените вызов glDrawPixels() в функции display():

glDrawPixels(flowerImg.sizeX, flowerImg.sizeY,

GL_RGBA, GL_UNSIGNED_BYTE, flowerImg.data);

Далее приведен текст функции подготовки изображения prepare_image().

 

void prepare_image()

{

// Изображение из файла в формате RGB

AUX_RGBImageRec* pRGB_Image;

pRGB_Image = auxDIBImageLoad("sunflowr.bmp");

 

// Вспомогательные переменные для хранения размеров изображения

int w = pRGB_Image->sizeX, h = pRGB_Image->sizeY;

 

// Инициализация глобальной переменной изображения в формате RGBA

flowerImg.sizeX = w;

flowerImg.sizeY = h;

// Выделение памяти для изображения RGBA (4 байта на пиксел)

int flowerImgLen = w * h * 4;

flowerImg.data = new unsigned char[flowerImgLen];

 

// Компоненты RGB фонового цвета, который будет прозрачным

unsigned char transpClr[3] = { 255, 0, 255 };

 

for (int i = 0; i < h; i++)

for (int j = 0; j < w; j++)

{

// Индексы текущего пиксела в изображениях

int curSrcIdx = (i*w + j)*3; // Для исходного RGB-изображения

int curDestIdx = (i*w + j)*4; // Для результирующего RGBA-изобр-я.

// Копирование значений RGB

memcpy(flowerImg.data+curDestIdx, pRGB_Image->data+curSrcIdx, 3);

// Расчет прозрачности текущего пиксела

if (pRGB_Image->data[curSrcIdx] == transpClr[0] &&

pRGB_Image->data[curSrcIdx + 1] == transpClr[1] &&

pRGB_Image->data[curSrcIdx + 2] == transpClr[2])

flowerImg.data[curDestIdx + 3] = 0; // Прозрачный цвет

else

flowerImg.data[curDestIdx + 3] = 255; // Непрозрачный цвет

}

 

// Удаление RGB-изображения, т.к. оно уже преобразовано во flowerImg

delete pRGB_Image;

}

 

Упражнение 3

В программе 7.1 нарисуйте грани куба фиолетовым цветом. Выясните, как изменится вид изображений на гранях. Затем установите свойство взаимодействия текстуры с объектом таким образом, чтобы цвет объекта не учитывался.

 

Упражнение 4

Внесите изменения в программу 7.1, описанные в п.4. Выясните, что произойдет, если указать в качестве координат текстуры дробные числа. Затем попробуйте отключить режим автоповторения текстуры по одному или двум направлением, задавая соответствующим свойствам значение GL_CLAMP.

 

Упражнение 5

Напишите программу, показывающую фотографию, вращающуюся в плоскости XY и постепенно приближающуюся к наблюдателю, расположенному на оси Z.

 

Упражнение 6

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


Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...