OpenGL - 为 glDrawArrays 自动生成索引/步幅参数

Posted

技术标签:

【中文标题】OpenGL - 为 glDrawArrays 自动生成索引/步幅参数【英文标题】:OpenGL - auto generation of indices / stride parameter for glDrawArrays 【发布时间】:2014-11-05 10:45:04 【问题描述】:

我正在渲染一个包含大量数据点 (>1M) 的网格结构。我的数据结构在图片中。

所以我的索引缓冲区的内容看起来像这样0, 100, 1, 101, 2, 102, 3, 103, ...

我对我需要定义我的三角形条的索引缓冲区的巨大尺寸感到有点恼火。是否有可能告诉 OpenGL 以所示方式自动生成这些索引?或者也许我没有想到的 glVertexAttribPointer 的一些技巧?

【问题讨论】:

不应该从0开始(或者循环回101) 我不知道。您可以在没有任何绑定属性的情况下使用glDrawArrays,并从采样器或图像(texelFetch/imageLoad)读取顶点数据,索引为gl_VertexID。由于拉取数据和缓存未命中,它可能会变慢,但不能确定。 @ratchetfreak:你是对的。它应该以 0 开头! 【参考方案1】:

确实有这样的功能:glDrawElementsBaseVertex

所以你可以用:

for(int i=0; i < height-1; i++)
    glDrawElementsBaseVertex(GL_TRIANGLE_STRIP, 200, GL_UNSIGNED_INT, 0, i*100);

那么索引缓冲区就是:0, 100, 1, 101, 2, 102, 3, 103,... 98, 198, 99, 199

通过一些调整,您甚至可以使用glMultiDrawElementsBaseVertex

GLsizei *count = new GLsizei[height-1];
GLvoid **indices = new GLvoid[height-1];
GLint *basevertex​ = new GLint[height-1];
for(int i = 0; i< height-1; i++)
    count[i]=200;
    indices[i]=0;
    basevertex​[i]=i*100;

glMultiDrawElementsBaseVertex(GL_TRIANGLE_STRIP, count, indices, height-1, basevertex​);

【讨论】:

生成索引而不是渲染元素数组缓冲区中的内容不是问题吗? @legends2k 它(在两行之间)是关于减小此解决方案允许的元素数组缓冲区的大小。当您包含 OP 的最后一段时,会出现一点 X-Y 问题。 @ratchetfreak:嗯,这是一个有趣的方法。但我仍然对 GL 调用的增加有些担忧。每次绘图多调用 1000-gl 对 cpu 来说是很多工作...... @ratchetfreak:当然可以,但我必须在每一帧都将它们发送到显卡。我不认为我可以为这些使用缓冲区...? @ThomasSpanger:还有来自GL_ARB_multi_draw_indirectglMultiDrawElementsIndirect(),它允许您将这些数组放入缓冲区对象中,并通过这种方法进一步减少CPU 开销。【参考方案2】:

我能找到的最佳解决方案是使用 glMultiDrawElementsIndirect。缓冲区大小比原始缓冲区小很多,您可以通过一次 gl 调用传递所有绘制命令。 感谢derhass的提示!

【讨论】:

以上是关于OpenGL - 为 glDrawArrays 自动生成索引/步幅参数的主要内容,如果未能解决你的问题,请参考以下文章

我可以在调用 glDrawArrays 后删除 OpenGL 顶点数组吗?

调用 glDrawArrays() 时的 OpenGL VBO Segfault

glDrawArrays上的OpenGL Segfaulting

不同形状的OpenGL glDrawArrays

OpenGL 3.3 - glDrawArrays 后的无效操作错误 (1282)

在 Opengl ES 中在 FBO 上调用多个 glReadPixels 和 glDrawArrays