OpenGL ES - glDrawElements - Проблема понимания индексов - PullRequest
6 голосов
/ 14 февраля 2012

Интересно, кто-нибудь может помочь мне понять, как индексы работают с glDrawElements. В приведенном ниже примере (взятом из http://www.everita.com/lightwave-collada-and-opengles-on-the-iphone) автор упоминает, что вы можете иметь только один набор индексов, в данном случае

const GLushort tigerBottomIndices[] = {
0,1,2,
3,0,4,
1,5,6,
…

};

Мой вопрос: что описывают эти индексы? Правильно ли я считаю, что первые три - это позиции вершин, вторые три - это соответствующие нормали, а последние три - ко-орды текстуры?

Заранее спасибо!

#import "OpenGLCommon.h"

const Vertex3D tigerBottomPositions[] = {
{0.176567, 0.143711, 0.264963},
{0.176567, 0.137939, 0.177312},
{0.198811, 0.135518, 0.179324},
…
};
const Vertex3D tigerBottomNormals[] = {
{-0.425880, -0.327633, 0.350967},
{-0.480159, -0.592888, 0.042138},
{-0.113803, -0.991356, 0.065283},
…
};
const GLfloat tigerBottomTextureCoords[] = {
0.867291, 0.359728,
0.779855, 0.359494,
0.781798, 0.337223,
…
};
const GLushort tigerBottomIndices[] = {
0,1,2,
3,0,4,
1,5,6,
…
};

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);    

glBindTexture(GL_TEXTURE_2D, tigerTextures[5]);
glVertexPointer(3, GL_FLOAT, 0, tigerBottomPositions);
glNormalPointer(GL_FLOAT, 0, tigerBottomNormals);
glTexCoordPointer(2, GL_FLOAT, 0, tigerBottomTextureCoords);
glDrawElements(GL_TRIANGLES, 210, GL_UNSIGNED_SHORT, tigerBottomIndices);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableEnableClientState(GL_TEXTURE_COORD_ARRAY);

Ответы [ 2 ]

26 голосов
/ 14 февраля 2012

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

Они организованы только в группы по 3, потому что они просто описывают вершины треугольника, поэтому 3 вершины = 1 треугольник, конечно.

const GLushort tigerBottomIndices[] = {
0,1,2, // #1 Triangle
3,0,4, // #2 Triangle
1,5,6, // #3 Triangle
…

Итак, давайте выберем первое значение этих индексов, это 0 .

Это означает:

Выберите номер позиции вершины 0

Также выберите нормальное число вершины 0

И выбрать координаты текстуры с номером 0

const Vertex3D tigerBottomPositions[] = {
{0.176567, 0.143711, 0.264963}, // This is the position number 0
{0.176567, 0.137939, 0.177312},
{0.198811, 0.135518, 0.179324},
…
};
const Vertex3D tigerBottomNormals[] = {
{-0.425880, -0.327633, 0.350967}, // This is the normal number 0
{-0.480159, -0.592888, 0.042138},
{-0.113803, -0.991356, 0.065283},
…
};
const GLfloat tigerBottomTextureCoords[] = {
0.867291, 0.359728, // These are the tex-coords number 0
0.779855, 0.359494,
0.781798, 0.337223,
…
};

Итак, эта информация отправляется в вершинный шейдер:

VertexPosition: 0,176567, 0,143711, 0,264963

VertexNormal: -0,425880, -0,327633, 0,350967

VertexTextureCoordinates: 0,867291, 0,359728

...

Если вы не используете индексы, opengl будет отправлять эти данные вершин линейно, поэтому после отправки данных вершин номер 0 он будет отправлять данные в позиции 1 массивов, а затем в 2, 3, 4 и т.д ...

Это хорошо, но иногда ваши треугольники заканчиваются одной или двумя одинаковыми вершинами. Учтите это:

enter image description here

Вы можете видеть 2 треугольника, образующих квадрат, и у них есть 2 общие вершины, 0 и 2. Таким образом, вместо 6 вершин, которые равны 3 для каждого треугольника, у нас есть только 4, и 2 трэнгла используют одни и те же данные для 2 их вершины. Это хорошо для производительности, особенно когда у вас большие модели с сотнями треугольников.

Чтобы нарисовать первый треугольник, нам нужны вершины с номерами 0, 1 и 2, а для второго треугольника нам понадобятся вершины с номерами 0, 2 и 3.

Видите, без массива индекса opengl будет пытаться использовать вершины 0, 1 и 2 (нормально для первого треугольника), но для второго треугольника opengl будет искать вершины 3, 4 и 5. Что неверно.

И именно поэтому мы создаем индексный массив, чтобы opengl мог отправлять вершины для вершинного шейдера. В нашем случае наш индексный массив будет выглядеть так:

const GLushort tigerBottomIndices[] = {
0,1,2,
0,2,3,
}
1 голос
/ 14 февраля 2012

Индексы подразумеваются в смысле индексов элементов в массиве.Индекс 0 обращается к первому элементу в массиве, индекс 1 - к второму и т. Д.

В вашем примере первые индексы 0, 1, 2 относятся к первым трем вершинам, которые имеют позиции первых трех Vertex3D элементы массива tigerBottomPositions, нормали первых трех элементов tigerBottomNormals (с 3 поплавками, образующими один вектор нормали) и одинаковые для координат текстуры.

Первый аргумент в вызове glDrawElementsговорит OpenGL, как формировать примитивы из проиндексированных вершин.GL_TRIANGLES означает, что каждые три индексированные вершины образуют треугольник.

Таким образом, вершины с индексами 0, 1, 2 образуют треугольник, 3,0,4 - следующий, 1,5,6 - другой треугольник и т. Д.на.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...