当构建多维数据集的顶点数据主要用于GL_TRIANGLES时,尝试将绘图模式切换为GL_LINE,GL_LINE_STRIP或GL_LINE_LOOP会显示一些有趣的结果,但没有一个能够提供多维数据集的良好线框表示。
有没有办法构建立方体的顶点和索引数据,以便简单地在GL_LINES / GL_LINE_STRIP / GL_LINE_LOOP和GL_TRIANGLES之间切换绘制模式可以提供很好的结果?或者是获得良好线框以重新创建顶点的唯一方法,专门用于其中一种线模式?
答案 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。