【问题标题】:Simple 2D Culling in OpenGL using VBOs使用 VBO 在 OpenGL 中进行简单的 2D 剔除
【发布时间】:2012-06-13 22:48:29
【问题描述】:

出于性能原因,我正在考虑使用 VBO 而不是立即模式。我正在创建一个充满精灵的 2D 正交场景。我不想绘制屏幕外的精灵。我通过根据屏幕尺寸和相机位置检查它们的位置来做到这一点。

在即时模式下,这很简单;每个精灵都有绘制方法。使用 VBO 这似乎很重要;我一次渲染 VBO 的整个部分。我(我能想到的)没有办法选择不在屏幕外的渲染精灵。

【问题讨论】:

  • 精灵在 CPU 上动画的假设是否正确?另外,我们在谈论什么数字?如果你有例如几百个精灵,然后剔除几乎不值得考虑(显卡会为你做,算了)。

标签: opengl vbo orthographic culling


【解决方案1】:

我只是假设您确实确实为 CPU 上的精灵设置了动画,因为根据您的问题,这是唯一有意义的事情(否则,您最初将如何以即时模式绘制它们,以及您将如何跳过画一些)。

从性能的角度来看,AGP/PCIe 的行为很像硬盘。带宽很大,但访问时间非常明显。换句话说,进行传输是很痛苦的,但是一旦你这样做了,再多几千字节并没有什么区别。上传 500 个精灵和上传 1000 个精灵是一回事。

由于您在 CPU 上为精灵设置动画,您已经必须每帧执行一次传输(glBufferSubData 或 glMapBuffer/glUnmapBuffer),没有其他方法。

请务必使用“新鲜”缓冲区,例如通过应用glBufferData(null) idiom。这通过允许 OpenGL 继续使用(从)缓冲区同时为您提供不同的缓冲区(您不知道)来避免管道停顿。稍后当它完成绘图时,它只是偷偷地翻转缓冲区并将旧缓冲区扔掉。这样,您就可以实现良好的并行性(这是性能的关键,比剔除几千个顶点更重要)。

此外,显卡在剔除几何体方面相当出色(这包括在生成片段之前丢弃屏幕外的整个三角形)。数百?数千?十万?没有任何问题。让显卡来做吧。

除非您有一百万个 sprite,其中一半一次可见而另一半不可见,否则不太可能连续且无分支地写入整个缓冲区不仅仅是一样快,但由于缓存和管道效应,速度更快。

【讨论】:

  • 所以根据文档,我将使用 GL_STREAM_DRAW_ARB 使用标志。这将表明 VBO 应该针对这种确切情况进行优化。这是正确的吗?
  • 是的。 “流”的意思是“定义一次,使用一次或几次”。这并不意味着您不能做其他事情,但这是您给司机的提示(它可能或可能不会 尊重,是否有所作为,这取决于驱动程序、硬件和您所做的事情。例如,在进行回读时,我发现使用正确标志和错误标志之间的差异大约为 1:100)。另一半(“绘制”)暗示您打算从应用提供的数据中进行绘制。请注意,在以后的版本中(如果我没记错的话,从 3.2 开始),这个“提示”是一个硬性要求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多