1 « » 7 « OpenGL» - МГТУ им. Н. Э. Баумана

advertisement
Модуль 1 «Основы компьютерной геометрии»
Лекция 7 «Атрибуты примитивов OpenGL»
к.ф.-м.н., доц. каф. ФН-11, Захаров Андрей Алексеевич,
ауд.:930а(УЛК)
моб.: 8-910-461-70-04,
email: azaharov@bmstu.ru
МГТУ им. Н.Э. Баумана
6 октября 2015 г.
Параметры состояния в OpenGL
Значения атрибутов и настройки других параметров задаются с помощью
отдельных функций, которые описывают текущее состояние пакета
OpenGL. К параметрам состояния в OpenGL относятся цвет, тип линий и
многоугольников, методы отображения многоугольников и другие. Все
параметры в OpenGL имеют свои значения по умолчанию, которые
действуют до тех пор, пока не будут заданы новые значения. В любой
момент можно запросить текущее значение любого параметра состояния.
Многие параметры состояния связаны с режимами, которые включаются
и выключаются командами glEnable( ) и glDisable( ).
Все графические примитивы в OpenGL изображаются с атрибутами из
списка текущего состояния. Изменение одного или нескольких атрибутов
повлияет только на те примитивы, которые будут задаваться после
изменения состояния OpenGL. Атрибуты примитивов, которые были
описаны до смены состояния системы, не изменятся. Таким образом,
можно изобразить линию текущим цветом, например, зелёным, поменять
текущий цвет на красный, и нарисовать ещё одну линию. В этом случае
получится изображение и зелёной и красной линии. Кроме того,
некоторые значения параметров состояния OpenGL могут задаваться
внутри пары функций glBegin/glEnd вместе со значениями координат,
так что настройки параметров могут изменяться при переходе от одной
точки к другой.
Цветовые режимы RGB и RGBA
Большинство настроек цветов примитивов OpenGL выполняется в режиме
RGB или в режиме RGBA, отличающиеся использованием для
смешивания цветов при наложении объектов друг на друга значения
альфа для моделирования эффекта прозрачности.
Текущие цветовые компоненты выбираются с помощью функции:
glColor*(colorComponents);
Для выбора режима RGB или RGBA используются индексы 3 или 4
соответственно. Для типов числовых данных возможны такие индексы:
b(byte), i(int), f(float), d(double), а также числовые значения без знака.
Значения цвета могут задаваться с помощью массива. В этом случае
нужно прибавить третий индекс: v(vector).
По умолчанию устанавливается белый цвет и альфа: (1.0,1.0,1.0,1.0).
Описание цветовых компонентов с помощью целых чисел зависит от
возможностей системы. Для полноцветной системы, в которой выделяется
8 бит на пиксель (256 уровней для каждого цветового компонента),
целочисленные значения цветовых компонентов принадлежат диапазону
от 0 до 255. Они соответствуют цветовым компонентам с плавающей
запятой 0; 1/255; 2/255; . . . ; 255/255 = 1.
В действительности в позициях буфера кадра хранятся целочисленные
значения, поэтому при описании цветовых значений с помощью целых
чисел можно избежать преобразований.
Смешивание цветов в OpenGL
Во многих приложениях требуется сочетать цвета накладывающихся друг
на друга объектов или смешивать цвет объекта с цветом фона, например,
при моделировании эффектов прозрачности. Данные функции носят
название функций смешивания цветов. В пакете OpenGL цвета двух
объектов можно смешать, сначала загрузив в буфер кадра один цвет, а
затем объединив цвет второго объекта с цветом из буфера кадра.
Текущий цвет в буфере кадра называется в OpenGL цветом назначения, а
цвет второго объекта — цветом источника. Смешивание можно выполнять
только в режиме RGB или RGBA. Чтобы применить смешивание цветов в
приложении, сначала нужно активизировать эту возможность пакета
OpenGL с помощью такой функции:
glEnable (GL_BLEND);
Чтобы отключить стандартные процедуры смешивания цветов, в OpenGL
используется функция
glDisable (GL_BLEND);
Если возможность смешивания цветов не активизирована, цвет объекта
просто заменит цвет, записанный в буфере кадра в положении этого
объекта.
Смешивание цветов в OpenGL
Цвета можно смешивать несколькими различными способами, в
зависимости от эффекта, которого требуется достичь, с помощью задания
двух наборов коэффициентов смешивания. Один набор коэффициентов
смешивания задаётся для текущего объекта в буфере кадра
(«получатель»), а второй набор коэффициентов — для нового объекта
(«источник»). Новый смешанный цвет, который затем загружается в
буфер кадра, находится как
(Sr Rs + Dr Rd , Sg Gs + Dg Gd , Sb Bs + Db Bd , Sa As + Da Ad ),
где цветовые компоненты RGBA источника — (Rs , Gs , Bs , As ), цветовые
компоненты получателя — (Rd , Gd , Bd , Ad ), коэффициенты смешивания
источника — (Sr , Sg , Sb , Sa ), а коэффициенты смешивания получателя —
(Dr , Dg , Db , Da ). Найденные значения компонентов комбинированного
цвета должны попадать в диапазон от 0.0 до 1.0. Любой сумме,
превышающей 1.0, присваивается значение 1.0, меньшей 0.0 — 0.0.
Значения коэффициентов смешивания выбираются с помощью следующей
функции OpenGL:
glBlendFunc (sFactor, dFactor);
Коэффициентам источника sFactor и получателя dFactor присваиваются
символьные константы OpenGL, задающие предопределённый набор из
четырёх коэффициентов смешивания.
Смешивание цветов в OpenGL
Например, константа GL_ZERO даёт коэффициенты смешивания
(0.0, 0.0, 0.0, 0.0), а константа GL_ONE даёт набор (1.0, 1.0, 1.0, 1.0). Можно
присвоить всем четырём коэффициентам смешивания либо значение
альфа получателя, либо значение альфа источника, что делается с
помощью константы GL_DST_ALPHA или GL_SRC_ALPHA. К числу остальных
констант OpenGL, с помощью которых задаются коэффициенты
смешивания, относятся GL_ONE_MINUS_DST_ALPHA,
GL_ONE_MINUS_SRC_ALPHA, GL_DST_COLOR и GL_SRC_COLOR. По умолчанию
параметру sFactor присваивается значение GL_ONE, а значение параметра
dFactor по умолчанию равно GL_ZERO. Следовательно, по умолчанию
значения коэффициентов смешивания приводят к тому, что новые
цветовые значения заменяют текущие значения в буфере кадра.
Предположим, что нужно нарисовать рисунок, составленный из трёх
полупрозрачных поверхностей на залитом фоне, частично
перекрывающихся. Пусть самая дальняя поверхность пропускает 80%
цвета за ней, следующая пропускает 40%, а ближняя — 90%. Для
получения этого изображения сначала рисуется фон с факторами влияния
источника и получателя по умолчанию, затем меняем коэффициенты
смешивания на GL_SRC_ALPHA (для источника) и GL_ONE_MINUS_SRC_ALPHA
(для получателя). Теперь рисуем дальнюю поверхность с A = 0.2, затем
промежуточную поверхность с A = 0.6 и, наконец, ближнюю поверхность
с A = 0.1.
Функции атрибутов точек в OpenGL
Цвет изображаемой точки зависит от текущих цветовых значений в списке
состояний, заданных с помощью функции glColor.
Размер примитива «точка» устанавливается с помощью функции:
glPointSize(size);
Например:
glPointSize(2.0); //размер равен 2 пикселям
Точка изображается как квадратный блок пикселей. Параметру size
присваивается положительное значение с плавающей запятой, которое
округляется до целого числа (если только не нужно устранять неровности
краев точки). Параметром size определяется количество горизонтальных
и вертикальных пикселей, составляющих изображение точки. Таким
образом, при размере точки 1.0 изображается один пиксель, а при размере
точки 2.0 — массив пикселей 2 × 2. По умолчанию размер точки равен 1.0.
При включении режима сглаживания (по умолчанию — отключен)
рисуется группа пикселов в виде круга, и пикселы на границе обычно
рисуются бледнее остальных, чтобы придать границе плавный вид. В этом
режиме дробные значения ширины не округляются.
Функции атрибутов прямых линий в OpenGL
В OpenGL ширина линии задаётся с помощью функции
glLineWidth(width);
Параметру width присваивается значение с плавающей запятой, которое
затем округляется до ближайшего неотрицательного целого числа
(минимальное значение 1.0). По умолчанию прямолинейный отрезок
изображается в виде сплошной линии толщиной 1.0.
В то же время можно изображать пунктирные, штриховые и
штрихпунктирные линии. Кроме того, можно варьировать длину штрихов
и расстояние между точками и штрихами. Текущий стиль изображения
линий задаётся с помощью следующей функции OpenGL:
glLineStipple(repeatFactor, pattern);
параметр pattern (шестнадцатеричное целое число) указывает, как
должна изображаться та или иная линия. В этом шаблоне 1 означает
положение пикселя «включено», а 0 —«выключено». Данный шаблон
применяется к пикселям, расположенным на прямой, начиная с младших
разрядов шаблона. По умолчанию шаблон имеет вид 0xFFFF (в каждом
положении стоит значение 1), что соответствует сплошной линии.
Целочисленный параметр repeatFactor сообщает, сколько раз должен
повторяться каждый разряд в шаблоне перед применением следующего
разряда. По умолчанию число повторов равно 1.
Функции атрибутов прямых линий в OpenGL
Код Множитель
0x00FF
1
0x00FF
2
0x0C0F
1
0x0C0F
3
0xAAAA
1
0xAAAA
2
0xAAAA
3
0xAAAA
4
Например,
glLineStipple(1, 0x3F07);
Образец 0x3F07 имеет двоичный вид 0011111100000111. Т.е. сначала
рисуются 3 пикселя, затем следует промежуток в 5 пикселей, затем
рисуются 6 пикселов и пропускаются 2 пикселя. При значении
repeatFactor=2 подсвечиваются 6 пикселей, затем промежуток в 10
пикселей, подсвечиваются 12 пикселов и снова промежуток в 4 пикселя.
Функции атрибутов прямых линий в OpenGL
Для ломанной линии заданный узор стиля линии не возобновляется в
начале каждого отрезка (возврата к младшему биту не происходит). Он
непрерывно продолжается на протяжении всех отрезков, начинаясь в
первой точке ломанной линии и заканчиваясь в последней точке
последнего отрезка данной серии. При выполнении функции glEnd( )
образец сбрасывается в начало. Если рисуются линии с использованием
GL_LINES, образец сбрасывается для каждой независимой линии.
Перед изображением линии с помощью текущего шаблона нужно
активизировать возможность OpenGL построения линий различного
стиля. Для этого в программу вводится следующая команда:
glEnable (GL_LINE_STIPPLE);
В любой момент возможность построения линий различного стиля можно
отключить, воспользовавшись такой функцией:
glDisable (GL_LINE_STIPPLE);
Функции атрибутов прямых линий в OpenGL
Градацию цветовых оттенков вдоль линии можно осуществить задавая
различные цветовые значения разным концам отрезка. В следующем
фрагменте программы эта возможность иллюстрируется следующим
образом: на одном конце линии задаётся синий цвет, а на другом —
красный. Затем сплошная линия изображается с помощью линейной
интерполяции кодов заданных концов линии.
glShadeModel (GL_SMOOTH);
glBegin (GL_LINES);
glColor3f (0.0, 0.0, 1.0);
glVertex2i (50, 50);
glColor3f (1.0, 0.0, 0.0);
glVertex2i (250, 250);
glEnd ( );
Аргумент GL_SMOOTH задаётся по умолчанию, поэтому отрезок с
непрерывной градацией цвета получается даже тогда, когда в программу
эта функция не включена. Другим аргументом функции glShadeModel
может быть GL_FLAT. В этом случае прямолинейный отрезок
изображается одним цветом — цветом второго конца (250, 250).
Следовательно, получается красная линия.
Функции атрибутов закрашенных фигур в OpenGL
Обычно многоугольники рисуются со сплошной закраской. Заполнение
многоугольника осуществляется вплоть до сторон многоугольника,
включая сами эти стороны. Таким образом, вокруг закрашенной области
не будет никаких линий границ, если только не добавить их к
изображению специально.
Чтобы получить градиентную закраску внутренней области
многоугольника различным вершинам многоугольника присваиваются
различные цветовые значения. В следующем фрагменте кода трем
вершинам треугольника присваивается синий, красный и зелёный цвет.
после этого многоугольник закрашивается с помощью линейной
интерполяции цветов этих вершин.
glShadeModel (GL_SMOOTH);
glBegin (GL_TRIANGLES);
glColor3f (0.0, 0.0, 1.0);
glColor3f (1.0, 0.0, 0.0);
glColor3f (0.0, 1.0, 0.0);
glEnd ( );
glVertex2i (50, 50);
glVertex2i (150, 50);
glVertex2i (75, 150);
Если в этом примере изменить аргумент функции glShadeModel на
GL_FLAT, то многоугольник будет закрашиваться последним заданным
цветом (зелёным). Значение GL_SMOOTH используется по умолчанию.
Функции атрибутов закрашенных фигур в OpenGL
Иногда требуется показать только стороны многоугольников. При этом
получаются контурные изображения многоугольников. Также можно
изобразить многоугольник, указав только точки в его вершинах. Для
реализации этих опций используется следующая функция
glPolygonMode (face, displayMode);
Параметр face обозначает какую поверхность многоугольника нужно
показать с помощью только сторон или вершин. Этому параметру
присваивается значение GL_FRONT, GL_BACK или GL_FRONT_AND_BACK.
После этого, если требуется изобразить только одни стороны
многоугольника, параметру displayMode присваивается значение GL_LINE.
Чтобы получить изображение одних только вершин многоугольника,
параметру displayMode присваивается значение GL_POINT. Третья
альтернатива — GL_FILL, которая является режимом по умолчанию,
поэтому, как правило, функция glPolygonMode вызывается только тогда,
когда нужно задать атрибуты для сторон и вершин многоугольника.
Для изображения сторон (или вершин) многоугольника другим цветом,
отличным от цвета внутренней заливки, требуется два раза вызвать
функцию рисования многоугольника: один раз с параметром GL_FILL в
функции displayMode, а второй раз — с параметром GL_LINE (или
GL_POINT) в этой же функции displayMode.
Функции атрибутов закрашенных фигур в OpenGL
Чтобы с помощью стандартных процедур OpenGL изобразить невыпуклый
многоугольник, его сначала нужно разделить на набор выпуклых
многоугольников. Как правило, невыпуклый многоугольник делится на
набор треугольников. Для того, чтобы изобразить исходный невыпуклый
многоугольник в виде контура, нельзя просто задать режим отображения
как GL_LINE, поскольку при этом будут изображаться все стороны
треугольников, из которых состоит исходный невыпуклый многоугольник.
В пакете OpenGL есть функция, которая позволяет удалять выделенные
стороны контурного изображения:
glEdgeFlag (flag);
Если флаг переведен в положение GL_FALSE, то тогда сторона, следующая
за этой вершиной, изображаться не будет. Функция glEdgeFlag может
помещаться внутри пары glBegin/glEnd.
Функции атрибутов закрашенных фигур в OpenGL
Рассмотрим пример применения флагов сторон, в котором изображаются
две стороны заданного треугольника:
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glBegin (GL_POLYGON);
glVertex3fv (v1);
glEdgeFlag (GL_FALSE);
glVertex3fv (v2);
glEdgeFlag (GL_TRUE);
glVertex3fv (v3);
glEnd ( );
Функции атрибутов закрашенных фигур в OpenGL
Хотя по умолчанию передняя и задняя стороны идентифицируются при
задании вершин этого многоугольника, существует возможность
изменения ориентации («выворачивания наизнанку»):
glFrontFace(vertexOrder);
Если параметру vertexOrder присвоить значение константы OpenGL
GL_CW, то задающийся после этого многоугольник, вершины которого
расположены в направлении по часовой стрелке, будет считаться
повернутым лицевой стороной. Константа GL_CCW означает, что лицевой
стороне многоугольника соответствует задание вершин в направлении
против часовой стрелки, что и является порядком задания вершин по
умолчанию.
Функции запроса в OpenGL
Текущие значения любого параметра состояния, в том числе настройки
атрибутов, можно извлекать с помощью функций запроса OpenGL. Эти
функции применяются для копирования заданных значений состояния в
массив, который можно сохранить для последующего повторного
использования или проверки текущего состояния системы, если возникает
какая-то ошибка.
Для текущих значений атрибутов используется соответствующая функция
«glGet»:
glGetBooleanv(); glGetFloatv(); glGetIntegerv(); glGetDoublev();
В каждой из этих функций задаётся два аргумента. Первый аргумент —
символьная константа OpenGL, которая определяет атрибут или другой
параметр состояния. Второй аргумент — ссылка на массив того типа
данных, который указан в имени функции. Например, текущие цветовые
настройки в режиме RGBA с плавающей запятой можно извлечь в массив
colorValues с помощью функции:
glGetFloatv (GL_CURRENT_COLOR, colorValues);
Чтобы найти целочисленные значения цветовых компонентов, вызывается
функция glGetIntegerv. В некоторых случаях для возвращения
заданного типа данных может понадобиться преобразование типа данных.
Группы атрибутов в OpenGL
В пакете OpenGL предлагаются также функции для сохранения групп
атрибутов и повторного использования их значений. Каждая группа
содержит набор взаимосвязанных параметров состояния. Существуют
более двадцати различных групп атрибутов, например, группы атрибутов
точек (GL_POINT_BIT), группы атрибутов прямых линий (GL_LINE_BIT),
группы атрибутов многоугольников (GL_POLYGON_BIT). Поскольку цвет
является атрибутом всех примитивов, он относится к своей группе
атрибутов (GL_CURRENT_BIT).
Чтобы сохранить все параметры, которые относятся к заданной группе,
используется следующая команда:
glPushAttrib (attrGroup);
Все параметры состояния во всех группах атрибутов можно сохранить с
помощью константы GL_ALL_ATTRIB_BITS.
Можно также сохранять параметры из двух или нескольких групп:
glPushAttrib (GL_POINT_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
Функция glPopAttrib восстанавливает значения параметров состояния,
сохранённых последним вызовом функции glPushAttrib.
При временном изменении состояний использование этих команд
предпочтительнее, так как они более эффективны.
Download