Уроки OpenGL. Часть 3. 2D-фигуры и массивы вершин.

Компьютерная графика

Как и обещал в конце второго урока (ссылка), сегодняшняя статья будет посвящена построению 2D-примитивов в OpenGL при помощи массивов вершин. Поставим такую задачу – реализовать все то, что мы сделали в прошлый раз, но только без использования функций glBegin() / glEnd().

Итак, для решения поставленной задачи нам понадобится создать три массива:

  • массив вершин
  • массив индексов
  • массив цветов

Но для начала разберемся что это такое и зачем вообще эти массивы нужны.

В массивы вершин мы заносим декартовы координаты вершин фигуры, которую мы собираемся нарисовать. С этим все ясно. Но мало знать координаты, необходимо еще определить, в какой последовательности эти вершины нужно соединять линиями. И для этого как раз и нужен массив индексов вершин. Ну а с массивом цветов и так понятно, там мы будем задавать цвета вершин нашей 2D-фигуры. Сейчас напишем небольшой пример и все сразу станет понятно 🙂

Итак, объявляем массивы:

GLfloat triangleVertexArray[3][3];
GLfloat triangleColorArray[3][3];
GLubyte triangleIndexArray[1][3];

У нашего треугольника три вершины, а у каждой вершины по три координаты, следовательно двумерный массив вершин должен иметь размер – 3 * 3. Аналогично с массивом цветов – три вершины по три составляющие цвета на каждую (RGB). Треугольник у нас будет всего один, поэтому triangleIndexArray имеет размер – 1 * 3. Теперь заполним их данными:

triangleVertexArray[0][0] = 0.0;
triangleVertexArray[0][1] = 0.0;
triangleVertexArray[0][2] = 0.0;

triangleVertexArray[1][0] = 1.0;
triangleVertexArray[1][1] = 1.0;
triangleVertexArray[1][2] = 0.0;

triangleVertexArray[2][0] = 1.0;
triangleVertexArray[2][1] = 0.0;
triangleVertexArray[2][2] = 0.0;

triangleColorArray[0][0] = 0.25;
triangleColorArray[0][1] = 0.87;
triangleColorArray[0][2] = 0.81;

triangleColorArray[1][0] = 0.25;
triangleColorArray[1][1] = 0.87;
triangleColorArray[1][2] = 0.81;

triangleColorArray[2][0] = 0.25;
triangleColorArray[2][1] = 0.87;
triangleColorArray[2][2] = 0.81;

triangleIndexArray[0][0] = 0;
triangleIndexArray[0][1] = 1;
triangleIndexArray[0][2] = 2;

glVertexPointer(3, GL_FLOAT, 0, triangleVertexArray);
glColorPointer(3, GL_FLOAT, 0, triangleColorArray);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, triangleIndexArray);

Задаем все координаты вершин и цвет (цвет треугольника у нас будет однородным, так что все вершины должны иметь одинаковый цвет). В массив индексов просто заносим последовательные номера вершин. С исходными данными на этом все. Двигаемся дальше!

Помимо, собственно, заполнения массивов необходимо вызвать функции, непосредственно отвечающие за прорисовку фигуры.

Функция glVertexPointer() делает активным созданный массив вершин. Первый параметр функции – количество координат на каждую вершину, у нас их три (x, y, z), хотя строго говоря в нашем примере можно было обойтись и двумя координатами (мы пока работаем в 2D-пространстве). Второй параметр – тип данных, сохраненных в массиве. Третий – определяет шаг (в байтах) между данными с координатами для вершин, у нас данные идут плотно друг за другом, поэтому передаем в функцию аргумент 0. Ну и последний, четвертый, параметр – собственно наш массив вершин.

Полностью аналогичные параметры и у функции glColorPointer().

И, наконец, третья функция – glDrawElements(). В качестве аргументов мы передаем тип рисуемой фигуры, количество элементов в массиве индексов, тип данных и сам массив.

Казалось бы на этом все, но нет, необходимо еще активизировать массивы вершин и цветов. Для этого в функции initializeGL() вызовем:

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

Напоминаю, что в прошлых статьях курса по OpenGL мы уже создали пустой проект, а потом заполнили его всем необходимым, поэтому в сегодняшней статье я буду комментировать только то, что касается нашей сегодняшней темы. Подразумевается, что все нужное из проекта прошлой статьи перенесено и в этот новый проект. Собираем проект, запускаем и видим:

OpenGL 2D-объекты.

Треугольник на месте, давайте двигаться дальше 🙂 Отрисовка одного треугольника на самом деле не позволяет нам в полной мере почувствовать как используется массив индексов вершин, поэтому давайте нарисуем следующее:

Массивы вершин в OpenGL.

У нас имеется 6 вершин и 3 треугольника. Сразу же меняем размеры массивов:

GLfloat triangleVertexArray[6][3];
GLfloat triangleColorArray[6][3];
GLubyte triangleIndexArray[3][3];

Забиваем координаты вершин, а также цвета. Первоначальные три вершины (0, 1 и 2) оставим прежнего цвета, вершина 3 у нас будет красная, а вершины 4 и 5 – зеленые:

triangleVertexArray[0][0] = 0.0;
triangleVertexArray[0][1] = 0.0;
triangleVertexArray[0][2] = 0.0;

triangleVertexArray[1][0] = 1.0;
triangleVertexArray[1][1] = 1.0;
triangleVertexArray[1][2] = 0.0;

triangleVertexArray[2][0] = 1.0;
triangleVertexArray[2][1] = 0.0;
triangleVertexArray[2][2] = 0.0;

triangleVertexArray[3][0] = 0.0;
triangleVertexArray[3][1] = 1.0;
triangleVertexArray[3][2] = 0.0;

triangleVertexArray[4][0] = 0.75;
triangleVertexArray[4][1] = 0.75;
triangleVertexArray[4][2] = 0.0;

triangleVertexArray[5][0] = 0.25;
triangleVertexArray[5][1] = 0.25;
triangleVertexArray[5][2] = 0.0;

triangleColorArray[0][0] = 0.25;
triangleColorArray[0][1] = 0.87;
triangleColorArray[0][2] = 0.81;

triangleColorArray[1][0] = 0.25;
triangleColorArray[1][1] = 0.87;
triangleColorArray[1][2] = 0.81;

triangleColorArray[2][0] = 0.25;
triangleColorArray[2][1] = 0.87;
triangleColorArray[2][2] = 0.81;

triangleColorArray[3][0] = 1.0;
triangleColorArray[3][1] = 0.0;
triangleColorArray[3][2] = 0.0;

triangleColorArray[4][0] = 0.0;
triangleColorArray[4][1] = 1.0;
triangleColorArray[4][2] = 0.0;

triangleColorArray[5][0] = 0.0;
triangleColorArray[5][1] = 1.0;
triangleColorArray[5][2] = 0.0;

Теперь самое интересное – массив индексов вершин. Необходимо определить, какие именно вершины участвуют при создании наших трех треугольников. Итак:

  • Первый треугольник – вершины 0, 1, 2
  • Второй треугольник – вершины 0, 3, 5
  • Третий треугольник – вершины 1, 3, 4

Так и задаем в массиве индексов, а заодно немного корректируем аргументы функций:

triangleIndexArray[0][0] = 0;
triangleIndexArray[0][1] = 1;
triangleIndexArray[0][2] = 2;

triangleIndexArray[1][0] = 0;
triangleIndexArray[1][1] = 3;
triangleIndexArray[1][2] = 5;

triangleIndexArray[2][0] = 1;
triangleIndexArray[2][1] = 3;
triangleIndexArray[2][2] = 4;

glVertexPointer(3, GL_FLOAT, 0, triangleVertexArray);
glColorPointer(3, GL_FLOAT, 0, triangleColorArray);
glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_BYTE, triangleIndexArray);

Запускаем программу и видим результат, абсолютно совпадающий с нашим заданием 🙂 Значит все сделано правильно! Сегодняшнюю статью на этом заканчиваем, в ближайших уроках по OpenGL начнем строить объемные 3D фигуры и разберемся с текстурами, оставайтесь на связи!

Поделиться!

Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments

Присоединяйтесь!

Profile Profile Profile Profile Profile
Vkontakte
Twitter

Язык сайта

Август 2020
Пн Вт Ср Чт Пт Сб Вс
 12
3456789
10111213141516
17181920212223
24252627282930
31  

© 2013-2020 MicroTechnics.ru