【问题标题】:OpenGL geometry performanceOpenGL 几何性能
【发布时间】:2013-11-27 21:19:19
【问题描述】:

我有一个应用程序,它使用 OpenGL 以 2D 形式呈现许多填充的多边形。填充是通过镶嵌完成的,但性能不是最佳的。由 122000 个顶点组成的 1900 个多边形(即每个多边形大约 64 个顶点)在大约 3 秒内显示出来。

显然,CPU 不是瓶颈,就好像我用 glColor 调用代替了对 gluTessVertex 的调用——只是为了测试瓶颈在哪里,性能翻了一番。 我在加载许多小纹理时遇到了同样的问题。 现在,哪些是提高性能的选项?似乎大部分时间都花在几何子系统上。渲染速度足够快。

我已经有一个工作线程在一个上下文中执行加载(因此镶嵌、纹理绑定),另一个线程在另一个上下文中执行绘制。这两个上下文通过 wglShareLists 共享对象,它就像一个魅力。 我可以在第三个上下文中使用第三个线程来处理一半多边形的镶嵌吗?有人试过吗?安全吗?在三个上下文之间共享对象的任何示例?

忘了说,我有一个 ATI Radeon HD 4550 显卡,假设它可以处理超过 39kB/s 的数据。

【问题讨论】:

  • 您为什么使用 2D 细分?
  • 瓶颈是缺乏异步性。具有共享上下文的工作线程使问题变得更糟,而不是更好(更多同步点)。请参阅 Vallentin 的答案,了解您必须做什么。

标签: multithreading opengl


【解决方案1】:

提高性能

听起来您正在使用旧的固定功能管道。

如果您不确定那是什么,那么,以下函数是固定函数管道的一部分。

  • glBegin()
  • glEnd()
  • glVertex*()
  • glTexCoord*()
  • glNormal*()
  • glColor*()

这些函数是旧的,可​​以立即渲染几何图形。这意味着每次调用上述函数时,几何图形都会发送到 GPU。通过多次这样做,您可以通过渲染简单的东西轻松地将 FPS 降至 60 以下。

现在您需要使用缓冲区,更准确地说是 VAOs 和/或 VBOs(和 IBO)。

VBO 或顶点缓冲区对象,是一个缓冲区,可以存储您可以渲染的顶点。这比glBegin()glEnd() 使用起来更快更好。当你创建一个 VBO 时,你为它提供了顶点,它们只需要发送到 GPU 一次,这基本上就是它们速度快的原因,因为它们已经在 GPU 中并且只需要一个绘制调用而不是多个。

我说“with/or”的原因是因为在较新的版本中,您需要创建一个 VAO,然后使用 VBO,在此之前您可以简单地渲染 VBO。


镶嵌

有多种方法可以进行曲面细分,并且看起来/会产生曲面细分效果的事物。

例如,您还可以根据所需的LOD (Level of Detail) 简单地渲染不同的模型,因此当您靠近一个对象时,您可以渲染模型的所有细节,这些细节可能会有很高的顶点数。然后,您离模型越远,您只需渲染该模型的另一个版本,但顶点越少,这也等于细节越少。 虽然如果你真的不能在地形之类的东西上做到这一点,并且绝对不应该在动态地形和/或程序生成的地形上做到这一点。

您也可以进行实际的几何细分,您可以通过Shader 来实现。由于曲面细分是一个非常庞大的主题,我将为您提供 2 个网址,它们既可以解释也有代码。

这两篇文章都使用现代 4.0/4.0+ OpenGL。

  1. http://prideout.net/blog/?p=48
  2. http://antongerdelan.net/opengl/tessellation.html

纹理

生成和绑定纹理仍然相同。

如果我没记错的话,你可以使用glGenerateMipmap(GL_TEXTURE_2D);,而不是使用gluBuild2DMipmaps(),它是在OpenGL 3.0'ish 中添加的。

再次,您可以(并且应该)使用 VAO 和 VBO 更改您的所有 glBegin() - glEnd()(以及介于两者之间的所有内容)调用。您可以在缓冲区顶点、纹理坐标、法线、颜色等中存储所有内容。您可以将这些内容存储在单独的缓冲区中,也可以将它们存储在单个缓冲区中,通常称为 交错缓冲区交错VBO

您将不再需要 glEnable(GL_TEXTURE_2D)glDisable(GL_TEXTURE_2D),因为您在 Shader 中执行此操作,您绑定纹理并在 Shader 中使用它们,并且由于您创建了 Shader Program,您可以让它按照您的方式进行操作想要。

【讨论】:

  • 我明白这一点,但有没有使用 VBO 的 GLUtesselator 的替代品?我的多边形可能是凹的。
  • 太棒了!非常感谢。纹理加载怎么样?有没有glGenTextures(1, &mIndex); glBindTexture(GL_TEXTURE_2D, mIndex); gluBuild2DMipmaps(...)的替代品,然后在绘图时:glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mIndex); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3d(x,y,z); .... glEnd(); glDisable(GL_TEXTURE_2D);
  • @user3004069 查看已编辑的答案,尽管您不应该在问题中添加更多内容,而是应该编写一个新问题,除非它与您的主要问题相关。但既然你是新来的,我还是回答了你的评论! :)
  • 感谢您的回答。我关闭问题
猜你喜欢
  • 2011-03-15
  • 2011-04-04
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多