OpenGL. Урок 3. Массивы вершин.

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

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

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

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

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

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

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

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, массивы вершин

Треугольник на месте, давайте двигаться дальше 😉

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

OpenGL, массив вершин

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

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 фигуры и разберемся с текстурами, оставайтесь на связи )

Понравилась статья? Поделись с друзьями!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *