Прежде чем приступить к изложению материала второй части статьи, хотелось бы извиниться перед теми, кто читал первую. Дело в том, что в прошлую статью вкралась досадная оплошность, в результате которой при компиляции программы возникала ошибка в библиотеке GL. Чтобы этого впреть не повторялось, необходимо удалить все #include и оставить только два из них:
Покончив с возникшим недоразумением, давайте попробуем разобраться с синтаксисом команд, используемых в OpenGL.
Первое, что хочется сказать, в OpenGL названия типов данных отличаются от названий в Си++ (то есть эти типы переопределены). Например, тип Glint в OpenGL это тип int в Си++. Зачем? Очень просто для переносимости кода на другие платформы (операционные системы).
Итак, давайте рассмотрим основные типы данных:
GLint int
GLuint unsigned int
GLfloat float
GLdouble double
GLbyte char
С этим, я думаю, все ясно (то есть, мы просто к типу добавляем две буквы «GL»). Теперь разберем синтаксис всех команд. Для того чтобы все команды были понятны, они имеют следующий вид:
Таким образом, имя любой команды состоит из нескольких частей:
gl имя библиотеки, в которой находится данная функция. Мы можем использовать и другие библиотеки, а именно: glu библиотека GLU, glut функции из библиотеки GLUT, glaux библиотека GLAUX.
Comand_name имя команды, например, InitWindowSize (эта команда нам должна быть уже известна с прошлой статьи).
[n] число аргументов.
[type] тип аргумента. Возможные варианты:
f GLfloat
d GLdouble
s GLshort
us GLushort
b GLbyte
ub GLubyte
[v] если указан этот параметр, это означает, что в качестве параметров функции используется указатель на массив.
Теперь давайте рассмотрим пару функций, чтобы закрепить то, что мы только что выучили:
Функция glColor3d(0.1,0.5,0.3); означает, что мы используем функцию, которая находится в библиотеке GL (приставка gl). Эта функция состоит из трех параметров, типа GLdouble (3d).
Функция glVertex2f(1.5,0.9); 2f два параметра, типа float (GLfloat).
Помимо основной библиотеки, существует несколько других дополнительных библиотек, которые мы также будем использовать в нашей работе. Первая из таких библиотек это GLU (graphics utility library). Все функции этой библиотеки обращаются к функциям из GL, и в ее состав входят обычно функции для рисования сложных объектов вроде сфер, конуса, цилиндра и т. д. Входит во все версии OpenGL.
Вторая дополнительная библиотека ответственна за взаимодействия с системой окон. Называется она GLUT (GL Utility Toolkit). Она содержит функции, которые могут понадобится при работе с окнами.
Существует еще библиотека GLAUX. В общих чертах, ее назначение упростить разработчику жизнь. Например, с помощью этой библиотеки очень просто рисуются такие объекты как сферы, кубы, и другие сложные объекты. Но лучше для таких целей использовать библиотеку GLUT, так как в GLAUX есть некоторые ошибки (некоторые объекты не совсем правильно отображаются).
Наверное, пора уже приступать к рисованию. Для начала мы научимся рисовать точки, линии, квадраты, треугольники, четырехугольники и полигоны. Все это рисуется почти по одной же схеме. Для того чтобы научиться все это рисовать, мы должны разобраться с таким понятием как примитив.
Примитив это объединение вершин в одно целое. То есть, примитив задается набором вершин. Вершина (Vertex) это просто-напросто координата точки на экране. Например, треугольник можно нарисовать с помощью 3-х вершин (в двухмерной системе координат), для рисования линии нам хватит и двух, и т. д.
Синтаксис задания вершин таков:
Где * может быть [2,3][i,d,f,b], в зависимости от количества точек и от типа чисел, которые мы будет использовать при задании точки. Например, если мы будем рисовать в двухмерном пространстве и при этом использовать тип double, тогда функция будет иметь вид glVertex2d(x,y). Я думаю, с этим все ясно.
А теперь займемся самим рисованием. Первое, что мы будем рисовать, это точки. Но для начала давайте настроим наше приложение. Вот код, который мы написали в прошлый раз:
Как вы помните, у нас создалось некрасивое, прозрачное окно. Давайте теперь зададим цвет окна. Для этого в функцию main() допишем одну строку:
где r красный цвет, g зеленый, b голубой, t прозрачность. Значение цветов выставлять нужно в диапазоне от 0 до 1 (т. е. 0.01, 0.2, 0.5, 0.83 и т. д.). Итак, выставьте нужный вам цвет, например, поставим цвет фона белый.
И теперь нужно в функцию Display(void) добавить еще одну строку:
Этой командой мы закрашиваем цвет фона в тот цвет, который указали в функции glClearColor(r,g,b,t);
Давайте посмотрим на полный листинг нашей программы:
Запустите это приложение теперь. И что мы видим? Правильно, красивое белое окно! :-)
Теперь что-нибудь нарисуем. Итак, для рисования фигуры нам одной вершины не достаточно. Для это нам нужно объединить несколько вершин (то есть, как мы уже знаем, задать примитив). Задание примитива происходит внутри командных скобок:
Параметр mode определяет тип примитива, который задается внутри и может принимать следующие значения:
GL_POINTS каждая вершина задает координаты некоторой точки.
GL_LINES каждая отдельная пара вершин определяет отрезок; если задано нечетное число вершин, то последняя вершина игнорируется.
GL_LINE_STRIP каждая следующая вершина задает отрезок вместе с предыдущей.
GL_LINE_LOOP отличие от предыдущего примитива только в том, что последний отрезок определяется последней и первой вершиной, образуя замкнутую ломаную.
GL_TRIANGLES каждая отдельная тройка вершин определяет треугольник; если задано некратное трем число вершин, то остаток игнорируется.
GL_TRIANGLE_STRIP каждая следующая вершина задает треугольник вместе с двумя предыдущими.
GL_TRIANGLE_FAN треугольники задаются первой и каждой следующей парой вершин (пары не пересекаются).
GL_QUADS каждая отдельная четверка вершин определяет четырехугольник; если задано некратное четырем число вершин, то остаток игнорируется.
GL_POLYGON последовательно задаются вершины выпуклого многоугольника.
Теперь давайте разберем это на одном примере (нарисуем одну линию).
После запуска этого приложения мы с вами увидим окошко, в котором будет нарисована линия (см. Рис.). В следующий раз мы научимся делать анимацию и создадим свою первую игру «арканоидный теннис» (то есть, наша игра будет отличаться от арканоида тем, что в нее нужно будет играть вдвоем и стараться забить мячик друг другу).