2016-01-19 11 views
0

Я смущен тем, как заполнить массив вершин, чтобы он был правильно нарисован. Код OpenGL, который я использую:Как правильно заполнить массив вершин

float vertices[size]; 
//Here I have a method to populate the array with my values from a 2D matrix 

glGenVertexArrays(1, &vaoID[0]); // Create our Vertex Array Object 
glBindVertexArray(vaoID[0]); // Bind our Vertex Array Object so we can use it 

glGenBuffers(1, vboID); // Generate our Vertex Buffer Object 
glBindBuffer(GL_ARRAY_BUFFER, vboID[0]); // Bind our Vertex Buffer Object 
glBufferData(GL_ARRAY_BUFFER, (size) * sizeof(GLfloat), vertices, GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW 

glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); // Set up our vertex attributes pointer 
glEnableVertexAttribArray(0); // Disable our Vertex Array Object 
glBindVertexArray(0); // Disable our Vertex Buffer Object 

glBindVertexArray(vaoID[0]); // Bind our Vertex Array Object 
glDrawArrays(GL_TRIANGLES, 0, size/3); // Draw 
glBindVertexArray(0); // Unbind our Vertex Array Object 

Надеюсь, изображение станет легче понять. На изображении «A» матрица 3x3 слева показывает, что я сейчас получаю, когда рисую треугольники, а матрица справа - это то, чего я пытаюсь достичь.

В настоящее время, когда я создаю массив вершин для рисования, я заполняю его в порядке, показанном на изображении 'B'. Я добавляю значения в массив, когда я работаю по строке, а затем удаляю столбцы и повторяю. Так, например:

vertexArray[0] = matrixElement[0].x 
vertexArray[1] = matrixElement[0].y 
vertexArray[2] = matrixElement[0].z 
vertexArray[3] = matrixElement[1].x 
vertexArray[4] = matrixElement[1].y 
vertexArray[5] = matrixElement[1].z 

Этот порядок ввода в vertexArray дает результаты, которые можно увидеть в образе «C», где создаются неправильные треугольники.

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

Image of issue

ответ

1

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

  • GL_TRIANGLE_STRIP как примитивный тип.
  • Указанный рисунок.
  • Примитивный перезапуск (требуется OpenGL 3.1 или новее).

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

0 3 1 4 2 5 
3 6 4 7 5 8 

активации и настройке примитивную перезагрузка может быть сделано с этими вызовами:

glEnable(GL_PRIMITIVE_RESTART); 
glPrimitiveRestartIndex(0xFFFF); 

Вы можете выбрать индекс, но общая политика (и только опция, поддерживаемая в OpenGL ES) заключается в использовании максимально возможного значения, которое равно 0xFFFF, если вы используете GLushort как тип индексов.

После включения примитивного перезапуска, «специальный» индекс начнет новую треугольную полосу.Таким образом, два треугольник полоска выше теперь может быть предоставлена ​​по одной индексной последовательности:

0 3 1 4 2 5 0xFFFF 3 6 4 7 5 8 

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

glDrawElements(GL_TRIANGLE_STRIP, 0, 13, GL_UNSIGNED_SHORT, 0); 

где 13 - количество используемых индексов.

Есть альтернативы использования примитивного рестарт:

  • Используйте повторяющиеся вершины. Это был общий трюк, прежде чем простой рестарт был широко доступен. Я бы больше не рекомендовал. Только для иллюстрации, последовательность индекса в этом случае будет:

    0 3 1 4 2 5 5 3 3 6 4 7 5 8 
    

    Два повторяющихся индексы приведут к вырожденному (0 пикселя) треугольник, который «соединяет» две полоски треугольников.

  • Используйте glMultiDrawElements(), чтобы нарисовать несколько треугольных полос с помощью одного вызова.
2

Вы используете GL_TRIANGLES и glDrawArrays() поэтому вам нужно добавить 3 вершины для каждого треугольника вы хотите:

// first vertex 
vertexArray.push_back(matrixElement[0].x); 
vertexArray.push_back(matrixElement[0].y); 
vertexArray.push_back(matrixElement[0].z); 

// second vertex 
vertexArray.push_back(matrixElement[3].x); 
vertexArray.push_back(matrixElement[3].y); 
vertexArray.push_back(matrixElement[3].z); 

// third vertex 
vertexArray.push_back(matrixElement[1].x); 
vertexArray.push_back(matrixElement[1].y); 
vertexArray.push_back(matrixElement[1].z); 
... 
+0

Значительное дублирование данных? Есть ли способ сохранить вершины один раз, но ссылаться на них несколько раз? – Calco

+0

@Calco: Конечно, используя 'GL_TRIANGLE_STRIP' и проиндексированную вершинную передачу через' glDrawElements() '. – genpfault

+0

@Calco Да, есть такой способ, и таким образом это 'glDrawElements' и буферы массива элементов (также называемые буферами индексов или объектами буфера индексирования). – immibis

1

За то, что вы ищете, GL_TRIANGLE_STRIP бы лучше выбор, чем GL_TRIANGLES. Для примера о том, как организовать вершины, см here

 Смежные вопросы

  • Нет связанных вопросов^_^