GLES20 Почему данные текстуры не связаны с индексами вершин?

Я пытался визуализировать куб и применить одну текстуру ко всем лицам. а также используя как можно меньше вершин, передавая индексы вершин грани. пример:

Вершины:

static final float FACE_VERTEX[] = {
        // front
        0.0f,  1.0f, 1.0f,     //0
        0.0f, 0.0f, 1.0f,     //1
        1.0f, 0.0f, 1.0f,      //2
        1.0f,  1.0f, 1.0f,      //3

        //back
        1.0f,  1.0f, 0.0f,      //4 - 3
        1.0f, 0.0f, 0.0f,      //5 - 2
        0.0f, 0.0f, 0.0f,     //6 - 1
        0.0f,  1.0f, 0.0f,     //7 - 0
}; 

Индексы:

static final int FACE_INDEX[] = {
        //front
        0,1,2, 0,2,3,
        //back
        4,5,6, 4,6,7,

        //left
        7,6,1, 7,1,0,

        //right
        3,2,5, 3,5,4,

        //top
        4,7,0, 4,0,3,

        //bottom
        1,6,5, 1,5,2

};

данные отображения текстуры:

final int textureCoordinateData[] =
        {
                // Front face
                0,0, 0,1, 1,1, 1,0,
                //back
                0,0, 0,1, 1,1, 1,0,
                //left
                0,0, 0,1, 1,1, 1,0,
                //right
                0,0, 0,1, 1,1, 1,0,
                //top
                0,0, 0,1, 1,1, 1,0,
                //bottom
                0,0, 0,1, 1,1, 1,0,
                //top
                0,0, 0,1, 1,1, 1,0,
                //bottom
                0,0, 0,1, 1,1, 1,0,


        };

Текстура отображается со всех сторон куба, кроме верхней и нижней. отображается только первый ряд пикселей передней грани вдоль всей верхней и нижней граней (см. скриншот):

введите описание изображения здесь

Я использую VBO для хранения данных вершин / индексов / текстур в графическом процессоре, и рендеринг с

glDrawElements(GL_TRIANGLES, indexLength, GL_UNSIGNED_INT, 0);

Однако эта проблема связана с тем, что данные текстуры должны быть сопоставлены с переданными данными вершин (что несколько раздражает модель куба) и не рассчитываются по индексу.

Мои вопросы будут: - Есть ли способ сохранить данные вершин как можно ниже и сопоставить текстуру с данными индекса? - Если бы я создал 36 вершин (некоторые повторяются), чтобы решить проблему с наложением текстур, но я создал правильные индексы для рендеринга куба, все равно это было бы быстрее, чем при использовании glDrawArrays? или я пойду с glDrawArrays и в любом случае уничтожить данные индексации?

связанный вопрос (который не ответил на мой вопрос):

OpenGL ES - текстура карты всех граней 8-вершинного куба?

Если вы прочитали первый комментарий к ответу:

Что вы имеете в виду, что вы должны использовать 24 вершины? Если вам нужно дублировать вершины, какой смысл использовать индексный буфер, если вы все еще отправляете повторные данные в графический процессор?

1 ответ

Решение

На самом деле нет разумного способа нарисовать куб с текстурными координатами с менее чем 24 вершинами. Это потому, что... у него 24 вершины, когда используется определение того, что образует вершину в OpenGL, которая представляет собой уникальную комбинацию атрибутов вершины (положение, координаты текстуры, нормаль и т. Д.).

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

Так стоит ли использовать индексы? Как вы уже обнаружили, вы можете легко придерживаться 24 вершин при использовании индексов, но вам нужно 36 вершин с самым простым использованием glDrawArrays()где вы используете один вызов с GL_TRIANGLES как примитивный тип. Таким образом, это уменьшает количество вершин.

Вы можете уменьшить его до 24 вершин с glDrawArrays() также, если вы делаете отдельный вызов для каждого лица и рисуете лицо, используя GL_TRIANGLE_STRIP примитивный тип с 4 вершинами в каждой. Это приведет к 6 вызовам на отрисовку, а также нежелательно иметь много небольших вызовов на отрисовку.

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

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

_____________
|  /|  /|  /|
| / | / | / |
|/__|/__|/__|
|  /|  /|  /|
| / | / | / |
|/__|/__|/__|

Вы можете видеть, что внутренние вершины разделены на 6 треугольников каждый. Таким образом, для относительно большой гладкой поверхности вы можете уменьшить количество вершин примерно в 6 раз, разделяя вершины, что позволяет делать использование индексного массива. Сокращение использования памяти почти в 6 раз может быть существенным преимуществом, если ваша геометрия достаточно велика.

Другие вопросы по тегам