【问题标题】:How to redraw partially in opengl Es 2.0如何在opengl Es 2.0中部分重绘
【发布时间】:2014-08-25 04:00:22
【问题描述】:

根据我的需要,我只想为每一帧重绘场景的一部分 仅在更新部分场景时才重绘整个场景。

在 OpenGL ES 2.0 中有没有办法做到这一点? 请对此的任何输入将非常有帮助

【问题讨论】:

  • 您可以设置视口以绘制到缓冲区的特定矩形。不过,您需要相应地设置矩阵。
  • Hi Matic 非常感谢您的回复。我对opengles比较陌生,请您详细解释一下您的答案。
  • 您的问题有点笼统,根本无法回答。关键是你可以设置一个特定的视口来设置你正在绘制的缓冲区的哪一部分。这通常设置为 (0, 0, bufferWidth, bufferHeight) 以绘制整个缓冲区。要绘制到缓冲区的特定部分,您可以为此方法设置一些其他参数,例如(bufferWidth*.5f、bufferHeight*.5f、bufferWidth*.5f、bufferHeight*.5f),它只会绘制到右下角的缓冲区。休息取决于您的矩阵系统,例如使用“正交”需要新的相对坐标,如“左”、“右”、“上”...
  • 我的确切要求是我只需要绘制动态更新的内容,同时保留每帧的静态数据。我可以使用 glDrawElements(..) 绘制更新的部分,并且只有它被渲染但不能保存和显示静态数据。请您在opengles中提出一种方法,使用它我可以保留静态数据并将其与动态数据一起呈现。提前感谢您的帮助。

标签: opengl-es 3d


【解决方案1】:

OpenGL 并不真正支持增量渲染。每次要求重绘时,您都需要绘制整个帧。

我能想到的最接近的方法是使用 FBO(帧缓冲区对象)将静态数据渲染到屏幕外帧缓冲区。如果您查找诸如“OpenGL FBO”之类的关键字,您应该能够在网上和书籍中找到大量示例。您将使用glGenFramebuffers()glBindFramebuffer()glFramebufferTexture2D() 等调用。

将静态内容渲染到 FBO 后,您可以在每次重绘开始时将其复制到默认帧缓冲区,然后在其上渲染动态内容。如果渲染静态内容非常昂贵,这可能是一种值得的方法。否则,从 FBO 复制到默认帧缓冲区可能比每次都重新渲染静态内容更昂贵。

如果静态内容在后台,而动态内容完全在其前面,上面的内容就很简单了。如果静态和动态内容重叠,就会变得更加棘手。然后,您必须在每次开始渲染动态内容之前恢复由渲染静态内容产生的深度缓冲区。我想不出在 ES 2.0 中做到这一点的好方法。相对平滑地执行此操作的功能(深度纹理,glBlitFramebuffer)仅在 ES 3.0 及更高版本中。

还有一个我认为不太吸引人的选项,但为了完整起见,我想提一下:EGL 定义了一个EGL_SWAP_BEHAVIOR 属性,该属性可以设置为EGL_BUFFER_PRESERVED。一个重要的警告是它是可选的,并非所有设备都支持。它也只保留颜色缓冲区,而不是辅助缓冲区,如深度缓冲区。如果您想继续阅读,请参阅 eglSwapBufferseglSurfaceAttrib

【讨论】:

  • 嗨,Reto,如果我使用单个缓冲区使用了一个查询,opengl FBO 可以正常工作吗?
  • OpenGL ES 不支持单缓冲。在完整的 OpenGL 中,您可以只有一个缓冲区,并直接绘制到前端缓冲区。但是 ES 中不存在该功能。
  • @Reto Koradi 非常感谢您的详细回答。只是一个澄清:如果我只需要显示一个图像 3 秒(窗口应该只显示那个图像,它永远不会改变),渲染图片 60 fps(从而加载 CPU/GPU)被认为可以吗?我的意思是每次从 libGDX 应用程序中 ScreenAdapter 的 render() 方法调用 mySprite.draw(myBatch) ?我应该关心性能并发明任何优化(在桌面应用程序中)吗?我的图片是在几乎全屏窗口上显示的 1920x1080,这是否意味着在我的情况下“渲染静态内容非常昂贵”?
猜你喜欢
  • 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
相关资源
最近更新 更多