Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (1124366), страница 9
Текст из файла (страница 9)
} else
Error () ;
6.3. Текстурные координаты
Перед нанесением текстуры на объект необходимо установить соответствие между точками на поверхности объекта и на самой текстуре. Задавать это соответствие можно двумя методами: отдельно для каждой вершины или сразу для всех вершин, задав
6.3. Текстурные координаты
85
параметры специальной функции отображения. Первый метод реализуется с помощью команд
void glTexCoord[l 2 3 4][s i f d] (type coord) void glTexCoord[l 2 3 4][s i f d]v (type *coord)
Чаще всего используются команды glTexCoord2*(type s, type t), задающие текущие координаты текстуры. Понятие текущих координат текстуры аналогично понятиям текущего цвета и текущей нормали и является атрибутом вершины. Однако даже для куба нахождение соответствующих координат текстуры является довольно трудоемким занятием, поэтому в библиотеке GLU помимо команд, проводящих построение таких примитивов как сфера, цилиндр и диск, предусмотрено также наложение на них текстур. Для этого достаточно вызвать команду
void gluQuadricTexture ( GLUquadricObj * quadObject , GLboolean textureCoords)
с параметром textureCoords равным GL_TRUE, и тогда текущая текстура будет автоматически накладываться на примитив. Второй метод реализуется с помощью команд
void glTexGen [ i f d] (GLenum coord, GLenum pname,
GLtype param) void glTexGen [ i f d]v (GLenum coord, GLenum pname,
const GLtype *params)
Параметр coord определяет для какой координаты задается формула, и может принимать значение GL_S, GL_T; pname может быть равен одному из следующих значений:
GL_TEXTURE_GEN_MODE —задает функцию для наложения текстуры. В этом случае аргумент param принимает значения:
GL_OBJECT_LINEAR —значение соответствующей текстурной координаты определяется расстоянием до
86
Глава 6. Текстурирование
плоскости, задаваемой с помощью значения pname GL_OBJECT_PLANE (см. ниже). Формула выглядит следующим образом:
g = x*Xp + y*yp + z*Zp + w*wp
где д — соответствующая текстурная координата (s или р), x,y,z,w — координаты соответствующей точки. xp,yp,Zp,Wp — коэффициенты уравнения плоскости. В формуле используются координаты объекта.
GL_EYE_LINEAR — аналогично GL_OBJECT_LINEAR,
только в формуле используются видовые координаты. Т.е. координаты текстуры объекта в этом случае зависят от положения этого объекта.
GL_SPHERE_MAP —позволяет эмулировать отражение от поверхности объекта. Текстура как бы «оборачивается» вокруг объекта. Для данного метода используются видовые координаты и необходимо задание нормалей.
GL_OBJECT_PLANE —позволяет задать плоскость, расстояние до которой будет использоваться при генерации координат, если установлен режим GL_OBJECT_LINEAR. В этом случае параметр params является указателем на массив из четырех коэффициентов уравнения плоскости.
GL_EYE_PLANE — аналогично предыдущему значению. Позволяет задать плоскость для режима GL_EYE_LINEAR.
Для установки автоматического режима задания текстурных координат необходимо вызвать команду glEnable с параметром GL_TEXTURE_GEN_Sили GL_TEXTURE_GEN_P.
Программа, использующая наложение текстуры и анимацию, приведена в приложении Б.
6.4- Контрольные вопросы
87
6.4. Контрольные вопросы
-
Что такое текстура и для чего используются текстуры?
-
Что такое текстурные координаты и как задать их для объекта?
-
Какой метод взаимодействия с материалом нужно использовать, если текстура представляет собой картину, висящую на стене (GL_MODULATE, GL_REPLACE)?
-
Перечислите известные вам методы генерации текстурных координат в OpenGL.
-
Для чего используются уровни детализации текстуры (mip-mapping)?
-
Что такое режимы фильтрации текстуры и как задать их в OpenGL?
Глава 7.
Операции с пикселями
После проведения всех операций по преобразованию координат вершин, вычисления цвета и т.п., OpenGL переходит к этапу растеризации, на котором происходит растеризация всех примитивов, наложение текстуры, наложение эффекта тумана. Для каждого примитива результатом этого процесса является занимаемая им в буфере кадра область, каждому пикселю этой области приписывается цвет и значение глубины.
OpenGL использует эту информацию, чтобы записать обновленные данные в буфер кадра. Для этого OpenGL имеет не только отдельный конвейер обработки пикселей, но и несколько дополнительных буферов различного назначения. Это позволяет программисту гибко контролировать процесс визуализации на самом низком уровне.
Графическая библиотека OpenGL поддерживает работу со следующими буферами:
-
несколько буферов цвета;
-
буфер глубины;
-
буфер-накопитель (аккумулятор);
89
90
Глава 7. Операции с пикселями
• буфер маски.
Группа буферов цвета включает буфер кадра, но таких буферов может быть несколько. При использовании двойной буферизации говорят о рабочем (front) и фоновом (back) буферах. Как правило, в фоновом буфере программа создает изображение, которое затем разом копируется в рабочий буфер. На экране может появиться информация только из буферов цвета.
Буфер глубины используется для удаления невидимых поверхностей и прямая работа с ним требуется крайне редко.
Буфер-накопитель можно применять для различных операций. Более подробно работа с ним описана в разделе 7.2.
Буфер маски используется для формирования пиксельных масок (трафаретов), служащих для вырезания из общего массива тех пикселей, которые следует вывести на экран. Буфер маски и работа с ним более подробно рассмотрены в разделах 7.3, 8.2 и 8.3.
7.1. Смешивание изображений и прозрачность
Разнообразные прозрачные объекты — стекла, прозрачная посуда и т.д. часто встречаются в реальности, поэтому важно уметь создавать такие объекты в интерактивной графике. OpenGL предоставляет программисту механизм работы с полупрозрачными объектами, который и будет кратко описан в этом разделе.
Прозрачность реализуется с помощью специального режима смешивания цветов (blending). Алгоритм смешивания комбинирует цвета так называемых входящих пикселей (т.е. «кандидатов» на помещение в буфер кадра) с цветами соответствующих пикселей, уже хранящихся в буфере. Для смешивания используется четвертая компонента цвета — альфа-компонента,
7.1. Смешивание изображений и прозрачность
91
поэтому этот режим называют еще альфа-смешиванием. Программа может управлять интенсивностью альфа-компоненты точно так же, как и интенсивностью основных цветов, т.е. задавать значение интенсивности для каждого пикселя или каждой вершины примитива. Режим включается с помощью команды glEnable(GL_BLEND).
Определить параметры смешивания можно с помощью команды:
void glBlendFunc (enum src ,enum dst)
Параметр src определяет как получить коэффициент к\ исходного цвета пикселя, a dst задает способ получения коэффициента &2 для цвета в буфере кадра. Для получения результирующего цвета используется следующая формула: res = csrc * к\ + Cdst * &2, где csrc — цвет исходного пикселя, Cdst — цвет пикселя в буфере кадра (res, к\, к\, csrc, Cdst ~четырехкомпонентные RGB А-векторы).
Приведем наиболее часто используемые значения агрументов src и dst.
GL_SRC_ALPHA к = (AS,AS,AS,AS)
GLSRCONEMINUSALPHA
к = (1,1,1,1) — (As, As, As, As)
GL_DST_COLOR k = (Rd,Gd,Bd) GLONEMINUSDSTCOLOR
к = (1,1,1,1)-(Rd,Gd,Bd,d) GL_DST_ALPHA к = (Ad, A-d,A-d, Ad) GLDSTONEMINUSALPHA
к = (1,1,1,1)-(Aa, Aa, Aa, Aa)
92
Глава 7. Операции с пикселями
GL_SRC_COLOR k = (Rs,Gs,Bs) GLONEMINUSSRCCOLOR
к = (1,1,1,1)-(R8,G8,B8,A8)
Пример: предположим, мы хотим реализовать вывод прозрачных объектов. Коэффициент прозрачности задается альфа-компонентой цвета. Пусть 1 — непрозрачный объект; 0 — абсолютно прозрачный, т.е. невидимый. Для реализации служит следующий код:
glEnable (GL_BLEND) ;
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MNUS_SRC_ALPHA);
Например, полупрозрачный треугольник можно задать следующим образом:
glColor3f(1.0, 0.0, 0.0, 0.5); glBegin (GLJTRIANGLES);
glVertex3f (0.0 , 0.0, 0.0);
glVertex3f (1.0 , 0.0, 0.0);
glVertex3f (1.0 , 1.0, 0.0); glEnd();
Если в сцене есть несколько прозрачных объектов, которые могут перекрывать друг друга, корректный вывод можно гарантировать только в случае выполнения следующих условий:
-
все прозрачные объекты выводятся после непрозрачных;
-
при выводе объекты с прозрачностью должны быть упорядочены по уменьшению глубины, т.е. выводиться, начиная с наиболее отдаленных от наблюдателя.
В OpenGL команды обрабатываются в порядке их поступления, поэтому для реализации перечисленных требований достаточно расставить в соответствующем порядке вызовы команд glVertex, но и это в общем случае нетривиально.
7.2. Буфер-накопитель
93
7.2. Буфер-накопитель
Буфер-накопитель (accumulation buffer) —это один из дополнительных буферов OpenGL. В нем можно сохранять визуализированное изображение, применяя при этом попиксельно специальные операции. Буфер-накопитель широко используется для создания различных спецэффектов.
Изображение берется из буфера, выбранного на чтение командой
void glReadBuffer (enum buf)
Аргумент buf определяет буфер для чтения. Значения buf, равные GL_BACK, GL_FRONT, определяют соответствующие буферы цвета для чтения. GL_BACK задает в качестве источника пикселей внеэкранный буфер; GL_FRONT — текущее содержимое окна вывода. Команда имеет значение, если используется дублирующая буферизация. В противном случае используется только один буфер, соответствующий окну вывода (строго говоря, OpenGL имеет набор дополнительных буферов, используемых, в частности, для работы со стереоизображениями, но здесь мы их рассматривать не будем).
Буфер-накопитель является дополнительным буфером цвета. Он не используется непосредственно для вывода образов, но они добавляются в него после вывода в один из буферов цвета. Применяя различные операции, описанные ниже, можно понемногу «накапливать» изображение в буфере.
Затем полученное изображение переносится из буфера-накопителя в один из буферов цвета, выбранный на запись командой
void glDrawBuffer (enum buf)
Значение buf аналогично значению соответствующего аргумента в команде glReadBuffer.
Все операции с буфером-накопителем контролируются командой
94
Глава 7. Операции с пикселями
void glAccum (enum op,GLfloat value)
Аргумент op задает операцию над пикселями и может принимать следующие значения: