Главная страница

Лекция 6 Геометрические примитивы OpenGL


Скачать 268.23 Kb.
НазваниеЛекция 6 Геометрические примитивы OpenGL
Дата02.06.2018
Размер268.23 Kb.
Формат файлаpdf
Имя файла06.pdf
ТипЛекция
#45766

Модуль 1 «Основы компьютерной геометрии»
Лекция 6 «Геометрические примитивы OpenGL»
к.ф.-м.н., доц. каф. ФН-11, Захаров Андрей Алексеевич,
ауд.:930а(УЛК)
моб.: 8-910-461-70-04,
email: azaharov@bmstu.ru
МГТУ им. Н.Э. Баумана
12 декабря 2014 г.

Точки
Чтобы задать координаты единственной точки, используется следующая функция OpenGL:
glVertex*();
Здесь звёздочка (*) означает, что для данной функции необходимы индексные коды. Индексные коды обозначают размерность пространства,
тип числовых данных, которые используются в качестве значений координат, и возможность представления координат в виде вектора.
Функция glVertex должна находиться в программе между функциями glBegin и glEnd. Аргумент функции glBegin определяет тип графического примитива, который следует изобразить, а функция glEnd не требует аргументов. При выводе на экран точки аргументом функции glBegin является символьная константа GL_POINTS. Т.о., положение точки в OpenGL описывается так:
glBegin(GL_POINTS);
glVertex*();
glEnd();
Координаты точек в OpenGL могут задаваться в 2, 3 или 4-х измерениях.
Четырёхмерное описание указывает на представление с помощью однородных координат, где однородный параметр h (четвертая координата) — это масштабный коэффициент для значений декартовых координат.

Точки
Далее нужно обозначить какой тип данных используется для описания числовых значений координат. Это осуществляется с помощью второго индексного кода функции glVertex. Типы числовых данных обозначаются следующими индексами: i(int), s(short), f(float), d(double).
Наконец, значения координат glVertex могут перечисляться в явном виде,
или для них может использоваться массив. Если применяется описание координат в виде массива, нам нужно прибавить третий индекс: v(vector).
Например:
glBegin(GL_POINTS);
glVertex2i(50,100);
glEnd();
Аналогичный результат можно получить при помощи задания координат точки в виде массива:
int point1[] = {50,100};
glBegin(GL_POINTS);
glVertex2iv(point1);
glEnd();

Прямые линии (отрезки)
Каждый отрезок прямой определяется координатами двух его концов. В
пакете OpenGL координаты концов выбираются с помощью функции glVertex, точно также как это делалось для координат точки, т.е. между glBegin/glEnd. По умолчанию рисуются сплошные линии белого цвета.
Набор прямолинейных отрезков, соединяющих каждую последующую пару точек-концов из перечня, задаётся с помощью константы примитива линии — GL_LINES. В общем случае это даст набор несоединенных между собой линий, если только некоторые значения констант не повторяются.
Если задать только одну точку, то ничего изображаться не будет, а если число точек (концов отрезков) в списке будет нечётным, то последнее значение отбрасывается.
glBegin(GL_LINES);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p3);
glVertex2iv(p4);
glVertex2iv(p5);
glEnd();

Прямые линии (отрезки)
С помощью константы OpenGL GL_LINE_STRIP можно построить ломанную линию. В этом случае будет изображена последовательность соединённых между собой отрезков, которая начинается в первой точке перечня и заканчивается в последней.
Один из способов создания изображения простой кривой —
аппроксимировать её с помощью ломанной линии. Нужно всего лишь задать набор точек, расположенных на этой кривой, а затем соединить эти точки прямолинейными отрезками. Чем из большего числа отрезков будет состоять ломанная линия, тем более гладкой будет выглядеть кривая.
Третий примитив прямой линии в OpenGL — это GL_LINE_LOOP, который даёт замкнутую ломанную линию.

Примитивы символов
Графические изображения часто содержат текстовую информацию, как подписи на графиках и таблицах, вывески на зданиях или надписи на машинах, а также общая информация в приложениях, связанных с моделированием и визуализацией.
Растровый символ GLUT можно получить с помощью функции glutBitmapCharacter(font, character);
Здесь параметру font присваивается значение символьной константы
GLUT, которая указывает на определённый набор начертаний, а параметру character присваивается значение символа, который мы хотим изобразить, например ’A’. Возможны шрифты как с постоянной шириной символов, так и с пропорциональными промежутками. Моноширинный шрифт можно выбрать, присвоив параметру font значение
GLUT_BITMAP_8_BY_13 или GLUT_BITMAP_9_BY_15 (цифровые параметры определяют расстояние и размер символов). А пропорциональный шрифт размером 10pt можно выбрать с помощью команд
GLUT_BITMAP_TIMES_NEW_ROMAN_10 или GLUT_BITMAP_HELVETICA_10.
Возможен шрифт Times Roman размером 12pt, а также шрифты Helvetica размером 12и 18pt.
Символы изображаются в том цвете, который был задан до выполнения функции glutBitmapCharacter.

Примитивы символов
Каждый символ, созданный с помощью функции glutBitmapCharacter,
изображается так, что начало координат (нижний левый угол) битового массива находится в текущем растровом положении. После того как битовый массив символа загружается в буфер кадра, к координате x текущего растрового поля добавляется смещение, равное ширине символа.
В качестве примера изобразим текстовую строку, состоящую из 36
растровых символов:
glRasterPos2i(x,y);
for (k=0; k<36; k++)
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, text[k]);
Чтобы задать координаты текущего растрового положения, применяется следующая процедура:
glRasterPos* ( );
Параметры и индексы аналогичны тем, которые используются в функции glVertex. Текущее растровое положение задаётся во внешних координатах. По умолчанию значение текущего растрового положения совпадает с началом отсчёта (0,0,0) внешней системы координат.

Примитивы символов
Векторный символ изображается путём вызова следующей функции:
glutStrokeCharacter(font, character);
Для этой функции параметру font можно присвоить значение
GLUT_STROKE_ROMAN, чтобы изобразить пропорциональный шрифт, или
GLUT_STROKE_MONO_ROMAN, чтобы представить моноширинный шрифт.
Текстовые строки, полученные с помощью векторных шрифтов, являются частью геометрического описания двух- или трёхмерных сцен, поскольку они состоят из геометрических линий. Ширина линии задаётся с помощью функции glLineWidth, а тип линии — с помощью функции glLineStipple. Т.е. их можно без каких-либо искажений сжимать,
растягивать или преобразовывать каким-то другим способом. Однако они визуализируются медленнее, чем растровые шрифты.

Функции многоугольников в OpenGL
За одним исключением, все процедуры OpenGL описания многоугольников похожи на функции описания точек или ломанной линии. Функция glVertex используется для ввода координат одной вершины многоугольника, а весь многоугольник описывается с помощью списка вершин, расположенного между парой команд glBegin/glEnd.
По умолчанию внутренняя часть многоугольника изображается одним цветом, который определяется по текущим установкам цвета.
В OpenGL заполненная область должна задаваться в виде выпуклого простого многоугольника. Закрашенная область в виде одного многоугольника может задаваться с помощью одного только списка вершин, который должен содержать по меньшей мере три вер- шины. Конфигурации, содержащие отверстия во внутренней об- ласти многоугольника невозможно задать с помощью одного примитива (такие конфигурации можно описать с помощью двух наложенных друг на друга выпуклых многоугольников).
Каждый многоугольник имеет две стороны: переднюю и заднюю. В
OpenGL цвет заполнения и другие параметры можно задавать для каждой стороны отдельно. Передняя сторона многоугольника определяется вершинами, заданными в направлении против часовой стрелки.
Существует шесть различных символьных констант, которые используются в качестве аргумента функции glBegin для описания многоугольников.

Функции многоугольников в OpenGL
С помощью константы OpenGL GL_POLYGON можно получить изображение одного закрашенного многоугольника. Предположим, что задан массив координат (x, y) шести точек: p
1
, . . . p
6
– вершин двухмерного многоугольника, заданных в направлении против часовой стрелки. Тогда код, формирующий данный многоугольник, имеет вид:
glBegin(GL_POLYGON);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p3);
glVertex2iv(p4);
glVertex2iv(p5);
glVertex2iv(p6);
glEnd();
В списке вершин многоугольника должно быть как минимум три вершины.
В противном случае ничего изображено не будет.

Функции многоугольников в OpenGL
Если поменять порядок точек в списке вершин из предыдущего кода и воспользоваться другой константой примитива GL_TRIANGLES, то получится два отдельных закрашенных треугольника.
glBegin(GL_TRIANGLES);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p6);
glVertex2iv(p3);
glVertex2iv(p4);
glVertex2iv(p5);
glEnd();
В этом случае первые три точки обозначают вершины одного треугольника, следующие три точки задают следующий треугольник, и т.д. Для каждого закрашенного треугольника вершины задаются в направлении против часовой стрелки. Если количество заданных вершин не будет кратно трем, то последние две или одна точка просто не будут учитываться.

Функции многоугольников в OpenGL
Путём ещё одной перестановки вершин в списке и замены константы примитива на GL_TRIANGLE_STRIP (полоса треугольников) можно получить изображение соединённых треугольников.
glBegin(GL_TRIANGLE_STRIP);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p6);
glVertex2iv(p3);
glVertex2iv(p5);
glVertex2iv(p4);
glEnd();
У всех последовательных треугольников есть одна общая сторона с предыдущим треугольником. Первые три вершины должны указываться в направлении против часовой стрелки, если смотреть на переднюю
(внешнюю) поверхность треугольника. После этого каждый последующий треугольник формируется в направлении против часовой стрелки.

Функции многоугольников в OpenGL
Ещё один способ построения набора соединённых треугольников —
воспользоваться методом «веера», где все треугольники имеют одну общую вершину. Такое расположение треугольников можно получить с помощью константы примитива GL_TRIANGLE_FAN и такого порядка шести вершин:
glBegin(GL_TRIANGLE_FAN);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p3);
glVertex2iv(p4);
glVertex2iv(p5);
glVertex2iv(p6);
glEnd();
Вершины должны быть заданы в соответствующем порядке, чтобы можно было правильно определить переднюю и заднюю стороны каждого треугольника. Первое значение в списке (в данном случае, p
1
) — это вершина всех треугольников веера.

Функции многоугольников в OpenGL
OpenGL также предлагает средства описания двух типов четырёхугольников (многоугольников с четырьмя сторонами). С помощью константы примитива GL_QUADS и следующего списка из восьми вершин получится два отдельных закрашенных четырёхугольника:
glBegin(GL_QUADS);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p3);
glVertex2iv(p4);
glVertex2iv(p5);
glVertex2iv(p6);
glVertex2iv(p7);
glVertex2iv(p8);
glEnd();
Первые четыре точки определяют вершины одного четырёхугольника,
следующие четыре точки описывают следующий четырёхугольник и т.д.
Для каждого закрашенного четырёхугольника вершины задаются против часовой стрелки. Если число заданных вершин не будет кратно четырём,
то лишние значения просто не будут приниматься во внимание.

Функции многоугольников в OpenGL
Переставив вершины в списке из предыдущего примера и заменив константу примитива на GL_QUAD_STRIP (полоса четырёхугольников),
можно получить набор соединённых четырёхугольников:
glBegin(GL_QUAD_STRIP);
glVertex2iv(p1);
glVertex2iv(p2);
glVertex2iv(p4);
glVertex2iv(p3);
glVertex2iv(p5);
glVertex2iv(p6);
glVertex2iv(p8);
glVertex2iv(p7);
glEnd();
Вершины нужно перечислять таким образом, чтобы каждый многоугольник имел правильный порядок вершин (против часовой стрелки).

Функции многоугольников в OpenGL
Поскольку графические изображения очень часто содержат закрашенные прямоугольные области, пакет OpenGL предлагает специальную функцию изображения прямоугольника:
glRect* (x1, y1, x2, y2);
Один угол этого прямоугольника находится в точке с координатами
(x
1
, y
1
), а противоположный угол прямоугольника — в точке с координатами (x
2
, y
2
). Суффиксы функции glRect обозначают тип данных и то, выражаются ли координаты в виде элементов массива. Эти индексы — i, s, f, d и v. Прямоугольник изображается таким образом. что его стороны параллельны координатным осям плоскости xy. Например:
glRecti (50, 100, 200, 250);
//задание в виде массива данных int vertex1 [] = {50, 100};
int vertex2 [] = {200, 250};
glRectiv (vertex1, vertex2);
50 50 100 100 150 150 200 200 250
В этом примере список вершин формируется по часовой стрелке. Во многих двумерных приложениях различие между передней и задней стороной многоугольника несущественно. Если требуется приписать передним и задним сторонам различные свойства, то нужно изменить порядок следования двух вершин.

Функции многоугольников в OpenGL
Во многих графических пакетах криволинейные поверхности изображаются с помощью аппроксимирующих плоских граней. Это объясняется тем, что уравнения плоскости линейны, а обработка линейных уравнений выполняется намного быстрее, чем обработка квадратных уравнений или уравнений других типов кривых. Поэтому
OpenGL и другие пакеты предлагают примитивы сеток многоугольников,
которыми можно аппроксимировать криволинейные поверхности. В пакете
OpenGL для этой цели можно использовать такие примитивы, как полоса треугольников, веер треугольников или полоса четырёхугольников.
Высококачественные графические системы, способные изображать миллион или больше закрашенных многоугольников (как правило,
треугольников) в секунду, включая приложения, связанные с наложением текстур на поверхности и специальных эффектов освещения, имеют встроенные аппаратные средства визуализации многоугольников.
Несмотря на то что корневая библиотека OpenGL принимает только выпуклые многоугольники, библиотека OpenGL Utility (GLU) предлагает функции, позволяющие работать с невыпуклыми многоугольниками.
Существует набор стандартных процедур библиотеки GLU для мозаичного представления вогнутых многоугольников, которые позволяют преобразовать такие фигуры в набор треугольников и треугольные сетки.
Затем их можно обрабатывать с помощью основных функций OpenGL.


написать администратору сайта