Геометрични примитиви на OpenGL

Върховете трябва задължително да бъдат зададени по отношение на някакъв примитив. Изчертаването на примитива започва с извикване на функцията glBegin(), която се предава като параметър константа, обозначаваща типа на примитива. Примитивът завършва с функцията glEnd(). Прототипите на тези функции са:

void glBegin(режим Glenum);

void glEnd(void);

Между извикванията към glBegin() и glEnd() се правят извиквания към glVertex*(). Например, за да се опише многоъгълникът, показан на фиг. 3.5 отляво, трябва да извикате следните функции:

glVertex2d(0.0, 0.0);

glVertex2d(0.0, 3.0);

glVertex2d(3.0, 3.0);

glVertex2d(4.0, 1.5);

glVertex2d(3.0, 0.0);

Фиг. 3.5. Примитиви от два вида: многоъгълник и набор от точки.

Ако зададете GL_POINTS като примитивен тип вместо GL_POLYGON, тогава ще бъде изчертан набор от 5 точки (фиг. 3.5, вдясно). В табл. 3.1 изброява всички разрешени примитивни типове, които могат да бъдат посочени при извикване на glBegin().

Таблица 3.1. Имена и предназначение на геометричните примитиви.

Постоянно имеПредназначение
GL_POINTSотделни точки
GL_LINESДвойки върхове, които са краища на сегменти
GL_POLYGONГраница на прост изпъкнал многоъгълник
GL_ТРИЪГЪЛНИЦИТройки от върхове, които се интерпретират като върхове на триъгълници
GL_QUADSЧетворки от върхове, които се интерпретират като върхове на четириъгълници
GL_LINE_STRIPВърхове на полилиния
GL_LINE_LOOPЗатворени върхове на полилиния (същите като предишния тип, но последният и първият връх се свързват автоматично)
GL_TRIANGLE_STRIPСвързана лента от триъгълници (триъгълна лента)
GL_TRIANGLE_FANВетрило на триъгълници
GL_QUAD_STRIPСвързана лента от четириъгълници (квадратна лента)

На фиг. 3.6 показва примери на примитивите, изброени в таблица. 3.1.nвърховете (v0, v1, v2, .vn-1) трябва да бъдат изброени между glBegin() и glEnd(). Както следва от фиг. 3.6, в допълнение към точки, линии и полигони,OpenGL има няколко други специални типа примитиви.

геометрични

Фиг. 3.6. Видове геометрични примитиви.

Свойства на точки, линии и многоъгълници

По подразбиране точката се показва на екрана като единичен пиксел. Сегментите се изчертават като плътни с дебелина 1 пиксел. Многоъгълниците се изчертават запълнени. Следващите параграфи описват как можете да промените тези свойства на дисплея.

Точки

Размерът на точката на екрана се задава с помощта на функцията:

void glPointSize(плаващ размер);

където размерът е диаметърът на точката в пиксели (трябва да бъде по-голям от 0,0, по подразбиране 1,0).

Броят пиксели, които ще бъдат нарисувани на екрана, когато се покаже дадена точка, зависи от това дали анти-алиасингът е активиран или не. Ако изглаждането е деактивирано, тогава размерът се закръгля до цяло число и квадрат със страна от размер пиксели се запълва на екрана с текущия цвят.

Когато анти-алиасингът е активиран, точката се показва като кръг и интензитетът на пикселите вътре в кръга намалява от центъра към краищата. В режим на изглаждане,OpenGL предоставя частични размери за точки и ширини на линии. Начините за промяна на свойствата на точките са демонстрирани в програма 3.1.

void CALLBACK display();

auxInitDisplayMode(AUX_SINGLE AUX_RGBA);

auxInitPosition(0, 0, 200, 200);

auxInitWindow( "Лекция 3, Програма 3.1" );

glClearColor(0.0, 0.0, 0.0, 0.0);

void CALLBACK display()

// В първия ред има три точки с диаметър 2 пиксела, без анти-алиасинг

glColor3d(1, 0, 0);

glVertex2d(50, 180);

glColor3d(0, 1, 0);

glVertex2d(100, 180);

glColor3d(0, 0, 1);

glVertex2d(150, 180);

// Във втория ред има три точки с диаметър 5 пиксела, без антиалиас

glColor3d(1, 0, 0);

glVertex2d(50, 100);

glColor3d(0, 1, 0);

glVertex2d(100, 100);

glColor3d(0, 0, 1);

glVertex2d(150, 100);

// В 3-ти ред има три точки с диаметър 10 пиксела, с антиалиасинг

glColor3d(1, 0, 0);

glVertex2d(50, 20);

glColor3d(0, 1, 0);

glVertex2d(100, 20);

glColor3d(0, 0, 1);

glVertex2d(150, 20);

// Принудително прекратяване на всички операции по чертане

Програма 3.1. Рисуване на точки с различни размери при

изключване и включване на изглаждането.

Сегменти

Линейните сегменти вOpenGL могат да имат дебелина и стил (пунктирана линия, пунктирана линия, пунктирана точка и т.н.). Дебелината на линията (в пиксели) е 1.0 по подразбиране, има функция за промяна:

void glLineWidth(ширина на GLfloat);

Стилът на линията (тип пунктирана линия) се задава от функцията glLineStipple():

void glLineStipple(фактор GLint, шаблон GLushort);

След като извикате тази функция, не забравяйте да активирате стила с помощта на glEnable(), например:

glLineStipple(1, 0x3F07);

Видът на пунктираната линия се определя от шаблон - 16-битов числов модел, в който битове, равни на 0 и 1, означават празни изасенчени пиксели. Размерът на шаблона може да бъде увеличен с помощта на коефициента, който определя броя на повторенията на всеки бит от шаблона.

В примера по-горе моделът е 0x3F07 (в двоичен е 0011111100000111). Когато чертаете сегмент, първо 3 пиксела се рисуват, след това 5 се пропускат, след това 6 се рисуват, 2 се пропускат (моделът се обработва от дясно на ляво, от ниски битове към високи битове). Ако зададете фактор=2, тогава шаблонът ще зададе следното правило за рисуване: боядисване на 6 пиксела, пропускане на 10, боядисване на 12, пропускане на 4. На фиг. 3.7 показва сегменти от различни стилове и съответните стойности на шаблона и множителя.

opengl

Фиг. 3.7. Пунктирани линии.

Чертането на линейни сегменти с няколко стила и различни дебелини е демонстрирано в програма 3.2. Резултатът от тази програма е показан на фиг. 3.8. Интересно е да се отбележи ефектът, който програма 3.2 постига благодарение на това, че отсечката се чертае не наведнъж цялата, а от няколко отделни отсечки.

Фиг. 3.8. Сегменти с различни стилове и дебелини.

void drawOneLine( двойно x1, двойно y1, двойно x2, двойно y2);

void CALLBACK display();

auxInitDisplayMode(AUX_SINGLE AUX_RGBA);

auxInitPosition(0, 0, 400, 150);

auxInitWindow( "Лекция 3, Програма 3.2" );

glClearColor(0.0, 0.0, 0.0, 0.0);

void drawOneLine( двойно x1, двойно y1, двойно x2, двойно y2)

glVertex2d(x1, y1);

glVertex2d(x2, y2);

void CALLBACK display()

glColor3d(1.0, 1.0, 1.0); // Всички сегменти са начертани в бяло

// В първия ред има 3 сегмента с различни стилове

glLineStipple(1, 0x0101); // пунктирана линия

drawOneLine(50.0, 125.0, 150.0, 125.0);

glLineStipple(1, 0x00FF);// прекъсната линия

drawOneLine(150.0, 125.0, 250.0, 125.0);

glLineStipple(1, 0x1C47); // Тире-точка-тире

drawOneLine( 250.0, 125.0, 350.0, 125.0);

// Във втория ред има 3 сегмента с дебелина 5 пиксела и различни стилове

glLineStipple(1, 0x0101);

drawOneLine(50.0, 100.0, 150.0, 100.0);

glLineStipple(1, 0x00FF);

drawOneLine(150.0, 100.0, 250.0, 100.0);

glLineStipple(1, 0x1C47);

drawOneLine(250.0, 100.0, 350.0, 100.0);

// В 3-тия ред има 6 сегмента от стила тире-точка-тире, които

// образуват един голям сегмент

glLineStipple(1, 0x1C47);

за ( int i = 0; i 0), което се изчислява по формулата:

,

където xi и yi са екранните координати на i-тия връх на n-ъгълника. Операцията Å е обичайното събиране, с изключение на това, чеnÅ 1 = 1:

.

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

void glCullFace(режим GLenum);

Параметърът на режима е GL_FRONT, GL_BACK или GL_FRONT_AND_BACK. Преди да извикате тази функция, трябва да активирате отстраняването на страните на полигона, като извикате glEnable( GL_CULL_FACE).

Програма 3.3 илюстрира начините за изчертаване на различни страни на многоъгълници на примера на 6-странна пирамида без основа. С курсорните клавиши тя може да се завърта под различни ъгли, като разликата между външната и вътрешната повърхност на пирамидата е ясно видима. забележи, чеако зададете различни цветове на върховете на многоъгълника, тогаваOpenGL автоматично извършва цветова интерполация при запълване на многоъгълника.

void CALLBACK resize( int width, int height );

void CALLBACK display();

void CALLBACK addAngleX();

void CALLBACK subAngleX();

void CALLBACK addAngleY();

void CALLBACK subAngleY();

// Местоположение на пирамидата спрямо осите X и Y

int ъгъл_x = 0, ъгъл_y = 0;

auxInitDisplayMode(AUX_RGBA AUX_DEPTH AUX_DOUBLE);

auxInitPosition(50, 10, 400, 400);

auxInitWindow( "Лекция 3, Програма 3.3" );

// Активирайте някои опции на OpenGL

// Задайте позицията и посоката на нулевия източник на светлина

glLightfv(GL_LIGHT0, GL_POSITION, pos);

glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, реж.);

// Регистриране на манипулатори на събития

auxKeyFunc(AUX_UP, subAngleX);

auxKeyFunc(AUX_DOWN, addAngleX);

auxKeyFunc(AUX_RIGHT, addAngleY ​​​​);

auxKeyFunc(AUX_LEFT, subAngleY ​​​​);

void CALLBACK преоразмеряване (int ширина, int височина)

glViewport(0, 0, ширина, височина);

gluPerspective(60.0, (двойна)ширина/(двойна)височина, 1.0, 20.0);

gluLookAt(0.0.5, 0.0.0, 0.1.0);

void CALLBACK display()

const двойно BASE_R = 1; // Основен радиус

const двойна ПИРАМА >

const двойно PI = 3.14159;

glClear( GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT);