2016-01-19 80 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”,在那里创建了错误的三角形可以看到结果。

我的问题是:以一种看起来像图像'A'中的右手图的方式,按照将在顶点的大矩阵上创建三角形的顺序,填充顶点数组的明智方式是什么。

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); 

您可以选择索引,但是如果使用GLushort作为索引的类型,常用策略(以及OpenGL ES中支持的唯一选项)将使用最大可能值,即0xFFFF。

启用原始重启后,“特殊”索引将启动一个新的三角形条。所以上面现在可以通过一个单一的指数序列给出的两个三角形带:

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_TRIANGLESglDrawArrays()所以你需要追加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