Войти
ПрограммированиеСтатьиГрафика

Основы программирования OpenGL в Borland С++Builder и Delphi. (Часть 2)

Автор:

Рассматривая какой-либо трёхмерный объект, мы всегда определяем его положение и размеры относительно некоторой привычной, и удобной в настоящий момент системы координат, связанной с реальным миром. Такая исходная система координат в компьютерной графике называется мировой системой координат.

Системы координат
Вывод примитивов

Системы координат

Для того, чтобы можно было изобразить объект на экране, его необходимо предварительно перевести (или преобразовать) в другую систему координат, которая связана с точкой наблюдения и носит название видовой системы координат. И, наконец, любое трёхмерное изображение мы всегда рисуем на двумерном экране, который имеет свою экранную систему координат. (Этот абзац я списал у Ю.Тихомирова) (неточные выражения вырезаны wat-ом).

Системы координат могут быть правосторонними или левосторонними.

Правосторонняя система координат Левосторонняя система координат
ИзображениеИзображение

Переход к новым координатам

Для задания положения объекта в пространстве в OpenGL используют функцию:

glTranslate[f d](Dx, Dy, Dz) – сдвигает систему координат на вектор (Dx, Dy, Dz)

Для повторота объекта используют:

glRotate[f d](j, x,y,z) – поворачивает систему координат на угол j (в градусах) против часовой стрелки вокруг вектора (x,y,z)

ПРИМЕЧАНИЕ: [f d] – означает, что в конце может быть либо буква “f”, либо “d”.

Теперь стоит сказать ещё о двух процедурах:

glPushMatrix()

glPopMatrix()

Первая предназначена, для сохранения, а вторая – для восстановления текущей матрицы трансформации. Очень удобно с помощью glPushMatrix() сохранить текущие координаты, потом сдвигаться и вертеться как угодно, а после, вызовом glPopMatrix(), вернуться к исходным координатам. Параметров у этих процедур нет.

Простейшие объёмные фигуры

В примере из прошлой статьи мы создали сферу. Для этого мы использовали механизм из glu32.dll. Алгоритм был такой:
1.      Создаём объект типа GLUquadricObj
2.      Инициализируем его функцией gluNewQuadric()
3.      Устанавливаем стиль фигуры функцией gluQuadricDrawStyle(quadObj, GLU_FILL). Стиль может быть GLU_FILL, GLU_LINE, GLU_SILHOUETTE  или GLU_POINT. Что каждый из них значит, проверьте сами.
4.      Делаем из quadObj (объекта типа GLUquadricObj) сферу, цилиндр, конус, диск или часть диска. Для этого определены следующие функции:
·        gluSphere (quadObj, radius, slices, loops). Три последних параметра – это радиус и количество разбиений поперёк и вдоль оси Z соответственно.
·        gluCylinder (quadObj, baseRadius, topRadius, height, slices, loops). После quadObj идут следующие параметры: радиус нижнего основания, радиус верхнего основания, высота и количество разбиений поперёк и вдоль оси Z соответственно. Очевидно, что эта функция задаёт как цилиндр, так и конус.
·        gluDisk (quadObj, innerRadius, outerRadius, slices, loops). Здесь после quadObj указываются внутренний и внешний радиусы диска.
·        gluPartialDisk (quadObj, innerRadius, outerRadius, slices, loops, startAngle, sweepAngle). Здесь добавляются два параметра: угол (в градусах), с которого начнётся рисование диска, и угол, которым рисование закончится.
5.      Освобождаем память, занимаемую под quadObj функцией gluDeleteQuadric(quadObj).

Теперь вы можете рисовать простые трёхмерные фигуры!

Примитивы

Любую трёхмерную фигуру, какая бы сложная она не была, можно разбить на двухмерные (плоские) составляющие. Эти составляющие я и буду называть примитивами, хотя некоторые авторы считают, что примитивами следует обозвать вышеперечисленные трёхмерные фигуры.

Примитивы определяются одной или несколькими точками, которые в OpenGL задаются внутри командных скобок glBegin/glEnd:

void glBegin(mode);
void glEnd();
 
procedure glBegin(mode);
procedure glEnd;

Параметр mode показывает, какие примитивы будут рисоваться. Доступны следующие значения:

GL_POINTSКаждая вершина – отдельная точка
GL_LINESКаждая пара вершин – отдельная линия. Если число вершин нечётно, то последняя игнорируется
GL_LINE_STRIPПоследовательность связанных отрезков. Первые две вершины – первый отрезок. Третья вершина определяет второй отрезок с началом в конце первого и концом в этой вершине и т.д
GL_LINE_LOOPАналогичен GL_LINE_STRIP, только последняя вершина соединяется отрезком с первой.
GL_TRIANGLESКаждая тройка вершин – отдельный треугольник
GL_TRIANGLE_STRIPГруппа связанных треугольников. Первые три вершины – первый треугольник. Вторая, третья и четвёртая вершины - второй треугольник и т.д.
GL_TRIANGLE_FANТакже группа связанных треугольников. Первые три вершины – первый треугольник. Первая, вторая и четвёртая вершины - второй треугольник и т.д.
GL_QUADSКаждые четыре вершины – отдельный четырёхугольник.
GL_QUAD_STRIPГруппа связанных четырёхугольников. Первые четыре вершины – первый четырёхугольник. Третья, четвёртая, пятая и шестая вершины – второй четырёхугольник и т.д.
GL_POLYGONРисует отдельный выпуклый многоугольник (один).

Особое внимание нужно уделить GL_QUAD_STRIP. Здесь не совсем понятный, но очень удобный порядок указания вершин:

Изображение

У каждого примитива есть минимальное число вершин. Если указанное число вершин меньше минимального для данного примитива, то примитив не рисуется.

Осталось только сказать, как задать вершину. Для этого определена следующая процедура:

glVertex[2 3 4][s i f d][v](coord)

Вершина определяется четырьмя координатами - x, y, z и w. По умолчанию z=0, w=1, т.е когда вы вызываете, например, glVertex2f(1,1) на самом деле вызывается glVertex4f(1,1,0,1).

С каждой вершиной связаны некоторые данные:

· Текущий цвет – цвет вершины (окончательный цвет высчитывается с учётом света). Цвет задаётся процедурой glColor*

· Текущие координаты текстуры – координаты текстуры, соответствующие этой вершине. Задаются процедурой glTexCoord*

· Текущая нормаль – вектор нормали, соответствующий данной вершине. Задаётся процедурой glNormal*

ПРИМЕЧАНИЕ: вместо звёздочки ‘*’ ставятся соответствующие суффиксы; такое сокращение принято во многих документациях по OpenGL.

Страницы: 1 2 Следующая »

#Delphi, #OpenGL, #основы

16 августа 2003 (Обновление: 5 фев. 2011)