Полигональные сетки

Mesh (полигональная сетка) представляет собой набор вершин (и возможно индексов), которые описывают геометрию для визуализации. Вершины хранятся либо в оперативной памяти видео устройства в виде объектов буфера вершин (VBO) или в оперативной памяти в виде массива вершин. VBO быстрее и используется по умолчанию, если это поддерживается аппаратно. Как и текстуры, полигональные сетки управляемые и будут автоматически перезагружены после потери контекста.

В libgdx полигональные сетки используются многими классами графического ядра, такими как SpriteBatch и DecalBatch, а также различными разгрузчиками 3D форматов. Одним из ключевых принципов дизайна libgdx является хранение геометрии в виде полигональной сетки, чтобы для визуализации загружать информацию о всех вершинах одной группой. Особенно на мобильных платформах, где значительный прирост производительности в группировании, путем уменьшения накладных расходом при отдельных вызовах визуализации.

Создание полигональной сетки

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

public Mesh createFullScreenQuad() {

    float[] verts = new float[20];
    int i = 0;

    verts[i++] = -1; // x1
    verts[i++] = -1; // y1
    verts[i++] = 0;
    verts[i++] = 0f; // u1
    verts[i++] = 0f; // v1

    verts[i++] = 1f; // x2
    verts[i++] = -1; // y2
    verts[i++] = 0;
    verts[i++] = 1f; // u2
    verts[i++] = 0f; // v2

    verts[i++] = 1f; // x3
    verts[i++] = 1f; // y2
    verts[i++] = 0;
    verts[i++] = 1f; // u3
    verts[i++] = 1f; // v3

    verts[i++] = -1; // x4
    verts[i++] = 1f; // y4
    verts[i++] = 0;
    verts[i++] = 0f; // u4
    verts[i++] = 1f; // v4

    // статическая полигональная сетка с четырьмя вершинами и без индексов
    Mesh mesh = new Mesh( true, 4, 0,
            new VertexAttribute( Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE ),
            new VertexAttribute( Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE+"0" ) );

    mesh.setVertices( verts );
    return mesh;
}

Обратите внимание на использование простого float массива для построения основной информации о вершинах. Мы определите четыре вершины, где каждая состоит из позиции в координатах окна, а так же из текстурных координат. Далее мы сообщаем конструктору полигональной сетки, что это будет статическая сетка с четырьмя вершинами и без индексов. Мы определили два вершинных атрибута, с указанием их соответствующих размеров и описания их свойств, с помощью встроенных в Libgdx констант для распространенных типов атрибута. Использование констант сообщает libgdx о том, как интерпретировать каждое значение, так чтобы указать OpenGL нужные данные при визуализации. Обратите внимание, что использование шейдеров в OpenGL ES 2, позволяет свободно включать другие атрибуты в вершины (значение освещенности вершины или даже физические свойства, такие как гибкость сетки от простого ветра, основанного на анимации вершин). В конце мы устанавливает вершины сетки, используя наш ранее созданный float массив.

Обратите внимание на использование ShaderProgram констант для именования атрибутов. Хотя это и не обязательно, это может быть полезно для обеспечения одинаковых имен атрибутов шейдеров для распространенных свойств, таких как позиция вершины, нормали, текстурные координаты, так как существуют имена используемые среди общих libgdx шейдеров. Это именование может помочь, когда у той же сетки нужно поменять шейдер. Смотрите шейдеры для получения дополнительной информации.

Визуализация

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

mesh.render( GL10.GL_TRIANGLE_FAN );

Более того, мы сделаем визуализацию используя другие примитивы:

mesh.render( GL10.GL_TRIANGLES );           // OpenGL ES1.0/1.1

mesh.render( shader, GL20.GL_TRIANGLES );   // OpenGL ES2 требует шейдер

mesh.render( shader, GL20.GL_LINES );       // Визуализация линий

По умолчанию, сетка будет автоматически привязывать данные при вызове render() метода. Перед вызовом render(), вам нужно будет привязать текстуру и установить модель преобразования и при использовании OpenGL ES 2, вам нужно будет привязать соответствующий шейдер и если нужно передать необходимые однородные элементы (uniform).