Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C++Builder. Учебный курс

.pdf
Скачиваний:
14
Добавлен:
15.11.2022
Размер:
9.54 Mб
Скачать

11.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. Вывод графических примитивов

Здесь рассматриваются основные команды для рисования графических примитивов:

-точки;

-линии;

-треугольника;

g lV e rte x * ,

-прямоугольника;

-четырехугольника;

-многоугольника.

Все геометрические примитивы в 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. Многоугольник строится из связанных тре­ угольников с общей вершиной, в качестве которой берется первая среди перечисляемых в командных скобках. Код для рисования шестиугольника может выглядеть так: