OpenGL и Delphi. Урок 3 - Линии
Введение
Здравствуйте, мы приступаем к третьему уроку OpenGL в Delphi, в котором мы поговорим о линиях. В конце этого урока вы увидите примеры с линиями, и можете скачать игру, в которой используются линии. В OpenGL линия это то же самое, что в математике отрезок. В OpenGL существует несколько методов рисований линий, в ниже мы рассмотрим все способы рисований линий.
Серия несвязных линий.
Чтобы нарисовать линию необходимо между командными скобками OpenGl glBegin/glEnd указать две вершины, начало отрезка и конец отрезка. При этом команду glBegin надо вызвать с параметром GL_LINES. Откройте наш шаблон и в процедуре render после команды glTranslate(0.0,0.0,-5.0) напишите следующий код :
glBegin(GL_LINES);
//говорим что будем рисовать отрывистые линии
glVertex3f(-1.0,0.0,0.0);
//начало отрезка
glVertex3f(1.0,0.0,0.0);
//конец отрезка
glEnd;
откомпилируйте проект и вы должны увидеть горизонтальную линию.
Примечание: возможно при компиляции у вас может возникнуть ошибка или отобразится пустое окно, в котором ничего не нарисовано. Проверьте, сколько форм у вас создается, для этого в меню Project выберете пункт View Source. У вас откроется файл проекта, в нем должна быть только одна строка: Application.CreateForm(TfrmGL, frmGL); если вы увидите две такие строки то, одну необходимо удалить.
Чтобы нарисовать две линии необходимо между командными скобками указать еще две вершины, начало отрезка и конец отрезка. Если вы укажите только одну вершину, то она проигнорируется, поэтому следует следить, чтобы количество вершин между glBegin(GL_LINES) и glEnd было всегда четным. Например, в представленном ниже коде ошибка не произойдет, но рисоваться будет только один отрезок, третья вершина проигнорируется.
glBegin(GL_LINES);
glVertex3f(-1.0,0.0,0.0);
//начало первого отрезка
glVertex3f(1.0,0.0,0.0);//конец
первого отрезка
glVertex3f(0.0,-1.0,0.0);//эта
команда проигнорируется
glEnd;
Чтобы отобразить вторую линию необходимо, дописать еще одну вершину, вот так будет правильнее:
glBegin(GL_LINES);
glVertex3f(-1.0,0.0,0.0);
//начало первого отрезка
glVertex3f(1.0,0.0,0.0);//конец
первого отрезка
glVertex3f(0.0,-1.0,0.0);//начало
второго отрезка
glVertex3f(0.0,1.0,0.0);//конец
второго отрезка
glEnd;
если откомпилируете проект, то можно увидеть координатную сетку.
Последовательные отрезки
Следующий метод рисования линий заключается в том, что отрезки между собой последовательно соединяются. Чтобы рисовать такую линию необходимо команду glBegin вызывать с аргументом GL_LINE_STRIP. Откройте новый шаблон и в процедуре render после команды glTranslatef(0.0,0.0,-5.0) напишите код, представленный выше, но только с аргументом GL_LINE_STRIP и вы увидите разницу:
glBegin(GL_LINE_STRIP);//рисуем
последовательные линии
glVertex3f(-1.0,0.0,0.0);
//начало первого отрезка
glVertex3f(1.0,0.0,0.0);//конец
первого отрезка, и начало второго отрезка
glVertex3f(0.0,-1.0,0.0);//конец
второго отрезка и начало третьего отрезка
glVertex3f(0.0,1.0,0.0);//конец
третьего отрезка
glEnd;
Как видите, при рисовании линии при аргументе GL_LINE_STRIP нет никаких ограничений на описание вершин. Линии могут свободно пересекаться, но только не должна быть указана одна вершина.
Замкнутая линия
Замкнутая линия в OpenGL рисуется между командными скобками, и при указанном аргументе GL_LINE_LOOP. Здесь линии рисуются так же, как и при параметре GL_LINE_STRIP, за исключением того, что последний отрезок соединяется с первым. Откройте новый шаблон запишите тот же самый код, но только с параметром GL_LINE_LOOP и вы снова увидите разницу:
glBegin(GL_LINE_LOOP);//рисуем
замкнутую линию
glVertex3f(-1.0,0.0,0.0);
//начало первого отрезка и конец четвертого отрезка
glVertex3f(1.0,0.0,0.0);//конец
первого отрезка, и начало второго отрезка
glVertex3f(0.0,-1.0,0.0);//конец
второго отрезка и начало третьего отрезка
glVertex3f(0.0,1.0,0.0);//конец
третьего отрезка и начало четвертого отрезка
glEnd;
Подробно о линиях
Толщина рисуемой линии устанавливается командой glLineWidth(width), где width – толщина линии типа GLFloat. Параметр width должен быть больше 0.0 и по умолчанию равен 1.0. Чтобы убрать ступенчатость нарисованной линии необходимо перед её рисованием ввести команду glEnable(GL_LINE_SMOOTH);. Для определения диапазона толщины сглаженной линии можно использовать команда glGetFloatv() со значением GL_ALIASED_LINE_WIDTH_RANGE, для определения диапазона значений толщины, не сглаженной точки используется функция glGetFloatv() со значением GL_SMOOTH_LINE_WIDTH_RANGE. Для определения степени точности (с каким шагом может увеличиваться линия) используется функция glGetFloatv со значением GL_SMOOTH_LINE_WIDTH_GRANULARITY. Для создания прерывистых линий (пунктирных или штрихованных) используется команда glLineStripple(), определяющая тип штриховки. Но чтобы эта команда обрабатывалась, необходимо включить режим командой glEnable(GL_LINE_STIPPLE);.Синтаксис команды рисования прерывистой линии следующий:
glLineStipple(factor,pattern);
где pattern - 16 битная последовательность 0 и 1, которая повторяется необходимое для протяженности линии число раз, называемый образец. Единица означает, что текущий пиксел будет закрашен, 0 — нет. Параметр factor — принимает значения от 1 до 256, который может удлинить образец. Например, если в образце стоит значение 0xCF0F (1100111100001111 в двоичном виде), то сначала нарисуется 4 пикселя, потом 4 пикселя пропустится, затем снова 4 пикселя нарисуется, затем 2 пикселя пропустится и снова два пикселя нарисуется. Отчет идет с младшего бита. При значении factor = 2, образец удвоится, то есть вначале нарисуется 8 пикселей, потом 8 пикселей пропустится, затем снова 8 пикселей нарисуется, 4 пикселя пропустится и снова 4 пикселя нарисуется. При отключенном режиме рисования штриховых линий, образец по умолчанию равен 0xFFFF, то есть рисуется сплошная линия. Таким образом, алгоритм рисования прерывистых линий следующий:
начинаем рисовать линию, при каждом рисовании пикселя образец сдвигается на 1 бит ( или на factor пикселей, если factor не равен 1). Когда рисуется серия соединенных отрезков между одиночными командными скобками glBegin() и glEnd(), при переходе от одного отрезка к другому возврата к младшему биту не происходит, и образец продолжает сдвигаться. При выполнении функции glEnd() образец сбрасывается в начало. Также если рисуются линии с использованием GL_LINES, образец сбрасывается для каждой независимой линии. С этого сайта вы можете скачать утилиту, которая вам поможет определять значение образца.
Скачать утилиту!! * одним архивом