OpenGL中的顶点限制
Posted
技术标签:
【中文标题】OpenGL中的顶点限制【英文标题】:Vertices limitation in OpenGL 【发布时间】:2011-08-19 14:32:25 【问题描述】:我有一个包含数千个顶点的 OpenGL 场景,并希望将它们作为 VBO/IBO 传递。 执行 glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxVertices) 命令显示最大顶点数限制为 2048,尽管事实上我有一个最近的视频卡。 除此之外,C 中的数组仅限于 int,因此最多 32k 个顶点。
如何解决这些限制以显示我的所有对象?
【问题讨论】:
C 中的数组仅限于 int? 当我在括号中使用除整数以外的其他内容时(例如 MyArray[double_variable]),它告诉我“数组下标不是整数”。double
s 不能是数组索引,但 long
可以。 int
和 long
都是整数。在具有最新视频卡的平台上,int
也很少有 16 位那么小。
这是什么OpenGL实现和平台/编译器?
您必须在非常旧的硬件上进行开发才能在 GL_MAX_ELEMENTS_VERTICES
上获得 2048 大小。
【参考方案1】:
GL_MAX_ELEMENTS_VERTICES
常量仅适用于glDrawRangeElements
调用,即使如此,大于该值的值也肯定不会使glDrawRangeElements
比glDrawElements
慢。手动将批次拆分成更小的部分并不是一个好主意,因为批次应该尽可能大,并且绘制调用尽可能少。忘记这个值吧,它已经没有真正的意义了。
顺便说一句,我很确定您的 int 可以保存比 32k 大得多的值,因为在现代平台上(至少是那些具有支持 VBO 的图形设备的平台),int 应至少为 32 位宽(因此能够保持 2G/4G 等值)。尽管在嵌入式设备上(使用 OpenGL ES),您可能仍受限于 16 位顶点索引。
【讨论】:
谢谢,但 C 中的数组只接受整数作为索引,因此有 32k 个元素。那我怎样才能达到你的2M呢? @Laurent 就像我(和 awoodland 的评论)说的,int
在 C 中只有 16 位宽(相当于 +/-32k 范围)在现代平台上是不太可能的,它通常应至少为 32 位宽(意味着 +/- 2G 范围,而不仅仅是 2M)。你从哪里得到关于 int
只有 16 位的信息?
谢谢,我开始慢慢明白了!我不知道我从哪里得到这个 32k 的 int 限制,也许确实在过去。我正在 Cocoa/Xcode 上开发。无论如何,让我尝试使用 int。
@Christian Rau:您能否确认不再使用 GL_MAX_ELEMENTS_VERTICES 和 GL_MAX_ELEMENTS_INDICES ?你还会用什么来决定何时拆分draw call?你会在 OpenGL ES 中使用什么?请参阅我的问题here。【参考方案2】:
GL_MAX_ELEMENTS_VERTICES 不只是告诉您可以传递给一次 glDrawRangeElements 调用的最多顶点数吗?您是否有理由无法将场景拆分为位并逐位渲染?
【讨论】:
所以基本上我可以有一个 30k 元素的 VBO,并使用 glDrawRangeElement 逐个传递它? 是的,我想是的。请参阅文档:opengl.org/sdk/docs/man/xhtml/glDrawRangeElements.xml 为避免可能的性能下降,您只需要为您使用的索引的位置提供界限。【参考方案3】:将您的顶点总数除以 2048 并创建比许多 VBO
void glGenBuffersARB(GLsizei n, GLuint* ids)
所以 n 将是 (total / 2048)+1 并且 ids 将是包含 (total / 2048)+1 的 GLuint 数组
【讨论】:
谢谢。然后我应该为每个 VBO 执行 glBindBuffer、glBufferData、glVertexPointer 和 glDrawElements,还是只运行一次就足够了?以上是关于OpenGL中的顶点限制的主要内容,如果未能解决你的问题,请参考以下文章