有没有办法创建一个立方体的顶点/索引,可以通过线条绘制模式很好地表示,以及在三角形模式下正确渲染?

时间:2014-09-05 00:49:30

标签: opengl 3d rendering vertex wireframe

当构建多维数据集的顶点数据主要用于GL_TRIANGLES时,尝试将绘图模式切换为GL_LINE,GL_LINE_STRIP或GL_LINE_LOOP会显示一些有趣的结果,但没有一个能够提供多维数据集的良好线框表示。

有没有办法构建立方体的顶点和索引数据,以便简单地在GL_LINES / GL_LINE_STRIP / GL_LINE_LOOP和GL_TRIANGLES之间切换绘制模式可以提供很好的结果?或者是获得良好线框以重新创建顶点的唯一方法,专门用于其中一种线模式?

1 个答案:

答案 0 :(得分:1)

最实用的方法很可能是最简单的方法:使用单独的索引数组进行线条和三角形渲染。当然不需要复制顶点属性,但绘制具有相同索引的完全不同的基本类型听起来很成问题。

要实现这一点,您可以使用两个不同的索引(GL_ELEMENT_ARRAY_BUFFER)缓冲区。或者,更优雅的恕我直言,使用单个缓冲区,并在其中存储两组索引。假设您需要使用triIdxCount索引进行三角形渲染,并使用lineIdxCount进行线渲染。然后,您可以使用以下命令设置索引缓冲区:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
             (triIdxCount + lineIdxCount) * sizeof(GLushort), 0,
             GL_STATIC_DRAW);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,
                0, triIdxCount * sizeof(GLushort), triIdxArray);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,
                triIdxCount * sizeof(GLushort), lineIdxCount * sizeof(GLushort),
                lineIdxArray);

然后,当您准备好绘制时,设置所有状态,包括索引缓冲区绑定(理想情况下使用VAO进行所有状态设置),然后有条件地渲染:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
if (renderTri) {
    glDrawElements(GL_TRIANGLES, triIndexCount, GL_UNSIGNED_SHORT, 0);
} else {
    glDrawElements(GL_LINES, lineIdxCount, GL_UNSIGNED_SHORT,
                   triIndexCount * sizeof(GLushort));
}

从内存使用的角度来看,拥有两组索引是适度的开销。实际的顶点属性数据通常比索引数据大得多,这里的关键点是不复制属性数据。

如果您不想严格渲染线条,但只需要线框类型的渲染,还有其他选项。例如,一种优雅的方法(从未实现过它,但它看起来很聪明),您只能绘制靠近多边形边界的像素,并根据到多边形边缘的距离丢弃片段着色器中的内部像素。这个问题(我提供了答案)详细阐述了方法:Wireframe shader - Issue with Barycentric coordinates when using shared vertices