如何正确填充顶点数组
How to correctly populate vertex array
我对如何填充我的顶点数组以正确绘制它感到困惑。我使用的 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'.
您正在使用 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 );
...
对于您正在寻找的内容,GL_TRIANGLE_STRIP
会比 GL_TRIANGLES
更好。有关如何排列顶点的示例,请参见 here
如果您想避免任何冗余,并通过单个绘制调用绘制整个网格,一种选择是使用以下组合:
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 中唯一支持的选项)是使用最大可能值,如果您使用 GLushort
作为索引类型,则为 0xFFFF。
一旦启用原始重启,"special" 索引将开始一个新的三角形带。所以上面的两个三角形带现在可以由一个索引序列给出:
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 像素)三角形,"connects" 两个三角形带。
- 使用
glMultiDrawElements()
通过单个绘制调用绘制多个三角形带。
我对如何填充我的顶点数组以正确绘制它感到困惑。我使用的 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'.
您正在使用 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 );
...
对于您正在寻找的内容,GL_TRIANGLE_STRIP
会比 GL_TRIANGLES
更好。有关如何排列顶点的示例,请参见 here
如果您想避免任何冗余,并通过单个绘制调用绘制整个网格,一种选择是使用以下组合:
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 中唯一支持的选项)是使用最大可能值,如果您使用 GLushort
作为索引类型,则为 0xFFFF。
一旦启用原始重启,"special" 索引将开始一个新的三角形带。所以上面的两个三角形带现在可以由一个索引序列给出:
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 像素)三角形,"connects" 两个三角形带。
- 使用
glMultiDrawElements()
通过单个绘制调用绘制多个三角形带。