C++Builder. Учебный курс
.pdf11.1.6. Синтаксис команд OpenGL
Все команды (функции) OpenGL начинаются с префикса g l, а все константы - с префикса GL_. Кроме того, в имена функций и процедур OpenGL входят суффиксы, несущие информацию о чис
ле передаваемых параметров и |
их типе. На примере команды |
g lC o lo r 3 f разберем синтаксис |
команд OpenGL. Эта функция |
задает цвет примитивов.
Из справки по этой команде вы узнаете, что она принадлежит к целому набору команд g lC o lo r с различными окончаниями: 3 f, 4 i и т.д. Цифра в окончании соответствует количеству тре буемых аргументов, а следующая за цифрой буква показывает тре буемый тип аргументов. То есть g lC o lo r3 f требует в качестве аргументов тройку вещественных ( f lo a t) чисел, a g lC o lo r3 i - тройку целых ( in t) чисел. Аналогичный синтаксис имеют и мно гие другие команды OpenGL.
Здесь же, в справке, выясняем, что при записи функции в ве щественной форме аргументы лежат в интервале [0;1], а в цело численной форме - линейно отображаются на этот интервал, т.е. для задания белого цвета целочисленная форма команды будет выглядеть так:
g lC o lo r 3 i(2147483647, 2147483647, 2147483647);
где максимальное 8-битное целое без знака соответствует пре дельному значению интервала.
Почти всегда предпочтительно использовать команду в веще ственной форме, поскольку OpenGL хранит данные именно в ве щественном формате. Исключения оговариваются в файле справки.
Если имя команды заканчивается на v (векторная форма), то аргументом ее служит указатель на структуру, содержащую дан ные, например массив. Например, если последние три символа в имени команды 3 f v, то ее аргумент - адрес массива трех вещест венных чисел. Например, конструкции
g lC o lo r3 f (1 .0 , 1 .0 , 1 .0 );
и
G L f lo a t c o l o r [] = { l .O , 1 . 0 , 1 . 0 } ; g l C o l o r 3 f v ( c o l o r ) ;
эквивалентны.
11.2. Двумерные построения
OpenGL является низкоуровневой библиотекой. В частности, это означает, что рисование объемных фигур сводится к последо вательному рисованию в пространстве плоских фигур, образую щих нужную объемную. Поэтому, даже если вас интересует толь ко использование 3D возможностей библиотеки, пропускать эту главу не рекомендуется.
11.2.1.Координаты области вывода
ВOpenGL левый нижний угол области вывода имеет коорди наты [-1; -1], правый верхний - [1, 1].
Для задания |
области вывода используется функция |
g lV ie w p o rt, обращение к которой имеет следующий вид: |
|
g l V i e w p o r t ( L e f t , |
Top, W id th , H e i g h t ) ; |
т.е. при вызове этой функции необходимо указать координаты ле вого верхнего угла, а также ширину и высоту области вывода в пикселах. Например, вызов функции с параметрами
g l V i e w p o r t (0, 0, C l ie n tW id th , C l i e n t H e i g h t ) ;
задает в качестве области вывода всю клиентскую часть окна.
11.2.2. Вывод графических примитивов
Здесь рассматриваются основные команды для рисования графических примитивов:
-точки;
-линии;
-треугольника;
-прямоугольника;
-четырехугольника;
-многоугольника.
Все геометрические примитивы в OpenGL задаются посредст вом вершин, а каждая вершина задается набором чисел с исполь зованием функций семейства например
g l V e r t e x 2 f .
Для задания цвета примитивов служит одна из команд семей ства g lC o lo r * , например g l C o l o r 3 f .
Многоугольники рисуются как заполненные области пиксе лов внутри границы, хотя их можно рисовать либо только как гра ничную линию, либо просто как набор граничных вершин.
Задание моделей закрашивания. Линия или заполненная грань могут быть нарисованы одним цветом (плоское закрашива ние, GL_FLAT) или путем интерполяции цветов в вершинах (за крашивание Гуро, GL_SMOOTH). Для задания режима закрашива ния служит команда
v o id glShadeM odel(G Lenum mode);
где |
параметр mode принимает значение GL_SMOOTH или |
GL |
FLAT. |
11.2.2.1. Рисование точки
Начнем наше знакомство с примитивами OpenGL с самого простого из них - точки. Нарисуем на экране пять точек, четыре по углам прямоугольника и одну в центре.
Пример 11.3
Обработчик события O n P a in t формы будет иметь следую щий вид:
v o id __f a s t c a l l T F o rm l: : F o rm P ain t(T O b ject *Sender)
{
/ / У становить ко н тек ст
w g lM ak e C u rren t (C an v a s -> H a n d le/ h rc ) ;
/ / |
О бласть |
вывода |
|
|
|
|
|
|
|
|
|
g l V i e w p o r t (0, |
0, |
C l ie n tW i d th , |
C l i e n t H e i g h t ) ; |
||||||||
g l C l e a r C o l o r ( 0 . 5 , |
0 . 5 , |
0 . 7 5 , |
1 . 0 ) ; |
/ / ц вет фона |
|||||||
/ / |
о ч и с тк а |
буфера |
ц в е т а |
|
|
|
|
|
|||
g l C l e a r (GL__COLOR_BUFFER_BIT) ; |
|
|
|
||||||||
/ / |
-------------------------------------------------- |
|
|
|
|
|
|
|
|
|
|
/ / |
Рисование |
то ч е к |
|
|
|
|
|
|
|
||
/ / |
-------------------------------------------------- |
|
|
|
|
|
|
|
|
|
|
g l P o i n t S i z e (2 0 ) ; |
/ / |
р азм ер |
то ч ек |
|
|
||||||
g l C o l o r 3 f ( 1 . 0 , 0 . 0 , 0 . 5 ) ; |
/ / |
текущий |
ц ве т примитивов |
||||||||
g lB egin(G L _ P O IN T S ); |
/ / |
откры ваем |
командную скобку |
||||||||
|
g l V e r t e x 2 f ( - 0 . 7 , - 0 . 7 ) ; |
|
|
|
|
||||||
|
g l V e r t e x 2 f ( - 0 . 7 , 0 . 7 ) ; |
|
|
|
|
|
|||||
|
g l V e r t e x 2 f (0, 0 ) ; |
|
|
|
|
|
|
|
|||
|
g l V e r t e x 2 f ( 0 . 7 , - 0 . 7 ) ; |
|
|
|
|
|
|||||
|
g l V e r t e x 2 f ( 0 . 7 , 0 . 7 ) ; |
|
|
|
|
|
|||||
g l E n d ( ) ; / / |
закры ваем |
командную |
скобку |
||||||||
/ / |
содержимое |
буфера |
|
на |
экран |
|
|
||||
S w a p B u f f e r s ( C a n v a s - > H a n d le ) ; |
|
|
|
||||||||
w g lM a k e C u r re n t(0, |
0 ) ; |
/ / |
о своб оди ть |
к о н т е к с т |
}
Разберем функции, используемые для вывода точек. Функции g lP o in t S iz e и g lC o lo r 3 f задают соответственно размер то чек в пикселах и их цвет. Далее в программе следуют функции (командные скобки) g lB e g in и glE n d , между которыми заклю чены собственно процедуры рисования. Это командные скобки библиотеки OpenGL. Большинство графических построений свя зано с использованием именно этой пары функций. Необходимо иметь ввиду, что ошибка при использовании командных скобок не распознается компилятором и проявится только в процессе диало га приложения с OpenGL. Поэтому при использовании командных скобок необходимо соблюдать следующие правила:
- н е допускается использование вложенных командных ско
бок;
-внутри этих скобок могут находиться любые операторы языка C++ и почти любые функции OpenGL (но не все). Включен ные в скобки команды OpenGL отрабатываются так же, как и за пределами этих скобок;
-вн утри командных скобок нельзя использовать команды
g l P o i n t S i z e и g lL in e W id th .
Главное назначение командных скобок - это задание режима (примитива) для команд g lV e r te x (вершина), определяющих ко ординаты вершин для рисования примитивов OpenGL.
В рассмотренном примере аргументом функции g lB e g in
используется символическая константа GL_POINTS. В этом слу чае все встретившиеся до закрывающей скобки g lE n d вершины (аргументы g lV e r te x ) задают координаты очередной отдельной точки. Команда g l V e r t e x в данном примере используется в фор ме с двумя вещественными аргументами. Получив справку по g l V e r te x , можно убедиться, что и эта команда имеет много раз новидностей.
В примере необходимо нарисовать четыре точки по углам ок на и одну в центре прямоугольника, поэтому между командными скобками располагаются пять строк с вызовом g lV e rte x , аргу менты которых соответствуют положениям точек в системе коор динат области вывода библиотеки OpenGL. По умолчанию точки рисуются в виде квадратиков. Чтобы получить точки в виде кру жочков необходимо перед командной скобкой g lB e g in вставить строку
g lE n a b l e (GL_POINT_SMOOTH) ; |
/ / режим сглаживания |
Пара команд g lE n a b le и |
g lD is a b le играет в OpenGL |
очень важную роль, включая и отключая режимы работы следую щих за ними команд.
Пример 11.4
Ниже приведен пример рисования 20 точек со случайными размерами, координатами и цветами.
R a n d o m iz e ( ) ;
f o r ( in t i =l ; i< = 2 0 ; i ++)
{
/ / ц ве т примитивов |
|
|
g lC o lo r 3 f ( R a n d o m ( ) , Random ( ) , |
Random( ) ) ; |
|
g l P o i n t S i z e ( r a n d o m ( 2 0 ) ) / |
/ / |
р азм ер то ч ек |
g lB egin(G L _ P O IN T S ); |
|
|
g l V e r te x 2 f ( 2 * R a n d o m ( ) - 1 , |
2 * R andom ()- 1 ) ; |
|
g l E n d ( ) ; |
|
|
}
В этом фрагменте используется функция Random, которая возвращает случайное число из диапазона от нуля до единицы, и функция R an d o m ize для инициализации датчика случайных чи сел (не путайте с известными функциями ran d o m и ra n d o m iz e ).
Упражнение
1. С использованием функций OpenGL написать программу для рисования графика функции y = s in ( х ) .
|
11.2.2.2. |
Рисование линий |
Для |
рисования линий |
необходимо в командной скобке |
g lB e g in |
указать в качестве аргумента одну из следующих симво |
|
лических констант: |
|
-GL_LINES - в этом случае следующие в командных скоб ках вершины задают попарно координаты начала и конца каждого отрезка прямой;
-GL_LIN E_STRIР - перечисляемые вершины последова тельно соединяются одна за другой (незамкнутая ломаная);
-GL_LINE_LOOP - вершины соединяются последователь но, однако в этом случае последняя вершина замыкается с первой (замкнутая ломаная).
Пример 11.5
g lL in e W id th (2 .5 ) ; g lB e g in (GL_LINES) ;
/ / |
д ве вершины |
п ервого |
о тр езк а |
g lV e r te x 2 f ( - 1 , 1 ) / |
|
||
g l V e r t e x 2 f (1, |
- 1 ) ; |
|
|
/ / |
д ве вершины |
второго |
о тр езк а |
g l V e r t e x 2 f ( - 1 , - 1 ) ; |
|
||
g l V e r t ех2 f (1, |
1 ) ; |
|
g l E n d ( ) ;
С помощью функции g lL in eW id th задается толщина линии в пикселах. Эта функция также должна выноситься за командные скобки. Включение режима g lE n a b le (GL_LINE_SMOOTH) уст раняет ступенчатость линий. По умолчанию строится сплошная линия. Для рисования, например, пунктирной линии необходимо перед командными скобками добавить следующие строки
g l L i n e S t i p p l e (1, OxFOFO); glEnable(GL _LINE _STIPPLE) ;
У функции g lL in e S t ip p le первый аргумент - масштабный множитель, второй аргумент задает шаблон штриховки (побито вым способом). Примеры использования функции
g l L i n e S t i p p l e |
(1, |
0x0 1 0 1 ); |
/ / |
точечная |
линия |
g l L i n e S t i p p l e (1, |
OxOOFF); |
/ / |
штриховая |
линия |
|
g l L i n e S t i p p l e |
(1, |
0х1С47) ; |
/ / |
штрихпунктирная линия |
Упражнение
1. С использованием функций OpenGL написать программу для рисования окружности.
11.2.2.3. Рисование треугольников
Для рисования треугольника необходимо в командной скобке g lB e g in указать в качестве аргумента одну из следующих симво лических констант:
- GL__TRI ANGLES - в этом случае последующие вершины берутся тройками (триплетами), по которым строится каждый от дельный треугольник;
-GL_TRIANGLE_STRIP - первые три вершины образуют первый треугольник, вершины со второй по четвертую - второй треугольник, с третьей по пятую - третий и т. д. (связанная группа треугольников);
-GL_TRIANGLE_FAN также задает последовательно свя занные треугольники, однако фигура строится по другому прин ципу: первая вершина является общей для всех остальных тре угольников, задаваемых перечислением вершин, т.е. треугольники связываются наподобие веера.
Ниже приводятся примеры рисования шестиугольника раз ными способами.
Пример 11.6 Способ 1:
g lB e g in (GL_TRIANGLES) ;
f o r ( i n t i = 0 ; i <6; i++)
{
g l V e r t e x 2 f (0, 0) ;
g l V e r t e x 2 f ( 0 . 7 * c o s ( 2 * M _ P I * i/6 ) , 0 . 7 * s i n ( 2 * M _ P I * i /6 ) ) ;
g l V e r t e x 2 f ( 0 . 7 * c o s ( 2 * M _ P I* ( i+ 1 )/ 6 ) , 0 . 7 * s in ( 2 * M _ P I * ( i+ 1 ) / 6 ) ) ;
}
g l E n d ( ) ;
Способ 2:
glBegin(GL_TRIANGLE_STRIP); f o r ( i n t i = 0 ; i < 6 ; i++)
{
g l V e r t e x 2 f (0, 0 ) ;
g l V e r t e x 2 f ( 0 . 7 * c o s ( 2 * M _ P I * i/6 ) , 0 . 7 * s i n ( 2 * M _ P I * i / 6 ) ) ;
}
g l E n d ( ) ;
Интересные результаты получаются при задании цвета тре угольников внутри цикла:
g lC o lo r 3 f ( R a n d o m ( ) , Random() , Random() ) ;
Способ 3:
g l B e g in (GL__TRIANGLE_FAN) ;
g lV e r te x 2 f |
(0, |
0) ; |
f o r ( in t i = 0 ; |
i< = 6 ; i++) |
|
g l V e r t e x |
2 f (0 .7 * c o s (2*M _PI-2*M _PI*i/6) f |
0 . 7 * s in (2*M__PI-2*M_PI*i/6) ) ;
g l E n d ( ) ;
Теперь поговорим о режимах вьшода многоугольников. Для устранения ступенчатости многоугольников используется команда:
g l E n a b l e (GL_POLYGON_SMOOTH) ;
Если в примеры на треугольники перед командными скобка ми поместить строку:
g lP olygonM ode (GL_FRONT_AND_BACK, GL_LINE) ;
то треугольники будут рисоваться контурно - только линии гра ниц.
Замечание. Запомните, что команда glPolygonM ode задает режим воспроизведения для всех типов многоугольников.
Ширину линий контура можно варьировать с |
помощью |
|
g lL in e W id th , пунктирные |
линии контура задаются |
командой |
g l L i n e S t i p p l e . Команда |
glP olygonM ode позволяет выво |
дить вместо заполненных и контурных многоугольников только их вершины, если ее вторым аргументом взять константу GL_POINT
(не путать с GL_POINTS). Размеры точек вершин и наличие сгла живания у них можно задавать так же, как и для обычных точек. По умолчанию многоугольники строятся заполненными (включен режим GL_FILL).
11.2.2.4. Рисование прямоугольников
Для рисования прямоугольника на плоскости можно восполь зоваться командой g l R e c t f . Это одна из версий команды g l R e c t . Ее аргументом являются координаты двух точек - проти воположных углов рисуемого прямоугольника.
Пример использования функции:
g l R e c t f ( - 0 . 7 , |
-0.1, 0.1, 0 . 7 ) ; |
Замечание. |
При использовании g l R e c t необходимо пом |
нить, что координата по оси Z в текущей системе координат для всех вершин равна нулю.
11.2.2.5. Рисование четырехугольников
Константа GL_QUADS задает примитив, когда перечисляемые вершины берутся по четыре и по ним строятся независимые четы рехугольники. Примитив, задаваемый константой GL_QUAD_STRIP, состоит из связанных четырехугольников. Пер вый четырехугольник формируется из вершин номер один, два, три и четыре. Второй четырехугольник в качестве опорных берет вторую, третью, четвертую и пятую вершины и т.д.
Пример рисования четырехугольника:
glBegin(GL_QUADS); |
|
g l V e r t ех2 f ( - 0 . 5 , |
- 0 . 5 ) ; |
g l V e r t e x 2 f ( 0 . 7 , |
- 0 . 5 ) ; |
g l V e r t e x 2 f ( 0 . 5 , |
0 . 5 ) ; |
g lV e r te x 2 f (- 0 .5 , |
0 . 5 ) ; |
g l E n d ( ) ; |
|
11.2.2.6. |
Рисование многоугольников |
Для рисования выпуклого многоугольника используется при митив GL_POLYGON. Многоугольник строится из связанных тре угольников с общей вершиной, в качестве которой берется первая среди перечисляемых в командных скобках. Код для рисования шестиугольника может выглядеть так: