FaceFighter - сфотай, загрузи, побей :) Видео обзор: FaceFighter - создаем врага и колбасим его…
Июн 16

Базовые фигуры (примитивы) — основные элементы, из которых при рисовании выстраиваются сложные объекты. В OpenGL ES такими примитивами выступают объекты Point (Точка), Line (Линия), Triangle (Треугольник). Думаю, их названия говорят сами за себя.

В этом уроке мы будем анализировать код, на основании которого впоследствии можно будет создавать собственные проекты.

Примитив №1 — треугольники

Треугольники — самые сложные из базовых фигур, но они настолько удобны и полезны, что с них мы и начнем. Чтобы нарисовать треугольник, необходимо указать OpenGL три координаты трехмерного пространства — остальное программа сделает сама.

Первым делом создайте копию проекта из урока “OpenGL ES: настройка проекта в Xcode” или загрузите исходный код отсюда. Открыв проект в Xcode, перейдите к файлу “EAGLView.m” и найдите метод “drawView“. Начинается настоящее волшебство!

Первым шагом зададим параметры треугольника. Сразу обращаю внимание на то, что мы будем работать с координатами двух типов: Model и World. Координаты Model относятся к отрисовываемому примитиву, а координаты World сообщают OpenGL о его местонахождении относительно зрителя (который в пространстве World всегда находится в точке (0.0, 0.0, 0.0)).

Итак, задаем координаты треугольника в пространстве Model через три трехмерные координаты (X, Y, Z):

1
2
3
4
5
const GLfloat triangleVertices[] = {
0.0, 1.0, -6.0,// Верхняя центральная точка треугольника
-1.0, -1.0, -6.0,// нижняя левая
1.0, -1.0, -6.0,// нижняя правая
};

Заметьте, что координаты описаны последовательно, в направлении против часовой стрелки (оно может быть и противоположным — главное, задавать их последовательно и придерживаться единой схемы). Для начала я бы рекомендовал работу по схеме “против часовой стрелки”, поскольку именно такой порядок требуется для некоторых рассматриваемых ниже функций.

Хотя наш урок посвящен технологии iPhone OpenGL ES, для новичков я вкратце остановлюсь на трехмерной системе координат. Взгляните на рисунок:

worldspace

Отвлечемся от моих художественных способностей и посмотрим, как выглядит пространство Model (или World). Представьте себе, что это компьютерный монитор, где X и Y — соответственно, горизонтальная и вертикальная оси, а Z — глубина. Центральная точка соответствует координатам (0.0, 0.0, 0.0).

Если теперь рассмотреть треугольник в применении к этим осям, то первая точка (0.0, 1.0, -6.0) будет его центром на оси Y, смещенная вверх на один пункт и на шесть пунктов в глубину экрана. Вторая координата находится на один пункт правее оси Y, ниже оси X (поскольку значение Y составляет -1.0) и на шесть пунктов в глубину экрана (-6.0). Точно по такому же принципу анализируется и третья координата.

Величина Z сделана отрицательной, чтобы отодвинуть объект назад и сделать его видимым (не забывайте, что “камера” находится в точке (0.0, 0.0, 0.0), поэтому в ином случае объект не пройдет тест OpenGL на глубину и не будет визуализирован).

Кое-кто сразу заметит: “Так ведь сказано было, что мы работаем с координатами Model, а не World!” Это действительно так, но когда мы доберемся до визуализации треугольника, OpenGL сразу поместит объект в точку (0.0, 0.0, 0.0). Поэтому уже сейчас отодвигаем его в глубину экрана, делая видимым. Позже, рассматривая трансформации (перемещение, вращение и пр.), что добиться такого результата можно, не прибегая к отрицательным величинам. А до тех пор оставим для координаты Z значение -6.0.

Код рисования

Теперь мы готовы описывать треугольник, сообщив OpenGL, где хранятся данные и как рисовать примитив. Для этого нам хватит нескольких строк кода. Вернитесь к методу “drawView” и реализуйте его, как показано ниже:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- (void)drawView {

const GLfloat triangleVertices[] = {
0.0, 1.0, -6.0, // Верхняя центральная точка треугольника
-1.0, -1.0, -6.0, // нижняя левая
1.0, -1.0, -6.0 // нижняя правая
};

[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);

// -- НАЧАЛО НОВОГО КОДА

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glVertexPointer(3, GL_FLOAT, 0, triangleVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, 3);

// -- КОНЕЦ НОВОГО КОДА

glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];

[self checkGLError:NO];
}

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

1
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Эта строка очищает экран. Управляющие биты сообщают OpenGL о необходимости использовать черный цвет, заданный на прошлом уроке в методе “setupView“, и очистить буфер глубины. Если буфер подключить, не сделав этого, сцена визуализирована не будет. Если буфер не подключать, в передаче glClear() сообщения GL_DEPTH_BUFFER_BIT необходимости нет.

Итак, мы очистили все, что прежде рисовалось в буфере (Не забыли о двойной буферизации? В одном буфере рисуем, другой отображаем).

1
glVertexPointer(3, GL_FLOAT, 0, triangleVertices);

Функция сообщает OpenGL о местонахождении данных и их формате. У нее четыре параметра, которые максимально просты:

1. Размер: число значений в каждой координате. В нашем случае их три (X, Y, Z). При рисовании двухмерных объектов без глубины (т.е. величины Z) будет указана цифра 2.
2. Тип данных: GL_FLOAT означает величину с плавающей запятой. При желании допустимы и целые числа, но в трехмерных пространствах без плавающих точек не обойтись.
3. Величина шага вычислений: сообщает OpenGL об игнорировании определенного количества байт между координатами. Пусть этот параметр пока не волнует — оставьте его равным нулю. Работать с ним будете при загрузке данных по вершинам из файла, формат которого предусматривает  заполняющую пробелы информацию или данные по цвету, например, из 3D-приложения Blender.
4. Указатель данных — собственно, сами данные.

Итак, мы предложили OpenGL очистить буфер, указали данные для объекта и сообщили его формат. Настало время крайне важного сообщения.

1
glEnableClientState(GL_VERTEX_ARRAY);

OpenGL работает с состояниями. Это означает, что функции активируются и отключаются соответствующими командами. Выше мы применили команду “glEnable()“, работающую с “серверным” режимом OpenGL. Команда “glEnableClientState()” включает “программный” режим (т.е. клиентское состояние). На текущий момент мы сообщили OpenGL, что данные по вершинам находятся в отдельном массиве и активировали функцию OpenGL для рисования вершины. Теоретически, вершина может быть массивом цвета (в этом случае стоит обратиться к “glEnableClientState(GL_COLOR_ARRAY)”) или массивом текстурных координат при наложении текстур (хватит вздыхать! чтобы накладывать текстуры, нужно для начала освоить основы!).

По мере освоения OpenGL нам предстоит работа с разными клиентскими состояниями, поэтому время на разбор данной темы еще будет.

Настало время команды для визуализации треугольника:

1
glDrawArrays(GL_TRIANGLES, 0, 3);

При вызове данной функции OpenGL обрабатывает полученную из двух предыдущих функций информацию. На экране появится треугольник с белой заливкой (белый — цвет по умолчанию при рисовании). Треугольники — объекты с заливкой. Для рисования пустого треугольника понадобится иная техника.

Разбираем три аргумента данной функции:
1. Метод рисования: в данном случае “GL_TRIANGLES“, название которого само по себе достаточно красноречиво. Возможность оценить потенциал первого аргумента нам представится позже, когда с помощью этой функции мы будем рисовать квадрат.
2. Первая вершина: наш массив состоит всего из трех точек. Мы хотим, чтобы OpenGL отталкивался от первой точки в массиве, указанной как ноль (стандартный доступ к массиву). Если бы в массиве вершин содержалось несколько примитивов, было бы уместным смещение. Подробнее об этом — в последующих уроках, где речь пойдет о создании сложных объектов. Пока пусть будет ноль.
3. Количество вершин: сообщает OpenGL, сколько в массиве рисуемых вершин. Для треугольника их, само собой, три, для квадрата — 4, для линии — 3 (и более), для точки — одна (и более при визуализации многочисленных точек).

После того, как код набран, а метод “drawView” приведен к указанному выше виду, кнопкой “Build and Go” запустите проект в симуляторе. Результат будет выглядеть примерно так, как и предполагалось — белый треугольник в центре экрана.

triangle

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

Для нескольких строк кода пояснений получилось немало, но, думаю, это того стоило. Надеюсь, что те, кому уже приходилось спотыкаться о “типовые” уроки по OpenGL, уже поняли разницу между OpenGL и OpenGL ES.

В следующем уроке мы дополним рассмотренный код и нарисуем квадрат.

Исходный код скачать можно [здесь]

Текст оригинальной статьи на английском языке [здесь]

Уважаемые читатели, данный материал был переведен и подготовлен к публикации проектом LookApp.ru, при публикации на другом сайте ссылка на LookApp.ru обязательна.

1 звезда2 звезд3 звезд4 звезд5 звезд (4 голосов, средний: 4.00 из 5)
Загрузка ... Загрузка ...


4 Responses to “Уроки iPhone SDK: (Часть 2) OpenGL ES: рисование базовых фигур (треугольники)”

  1. 1. MoHTu Says:

    Добрый день! Подскажите пожалуйста, как загрузить модели из блендера в проект? Заранее благодарен)

  2. 2. akuba Says:

    исходники все издохли

  3. 3. Nitrogen Says:

    перезалейте исходники, пожалуйста.

  4. 4. mugik Says:

    поделитесь исходниками , please!

Оставьте комментарий