opengl:基于着色器的渲染到帧缓冲区,然后是固定管道渲染

时间:2014-05-07 12:54:15

标签: c++ qt opengl glsl shader

我有一个应用程序,它使用OpenGl的固定管道在屏幕上渲染图像以及一些GUI。在此之前,我想使用基于着色器的管道,对图像进行一些图像处理操作,并将其渲染为纹理。然后我将这个纹理传递给现有的应用程序。基本上当前的流程如下:

cpu image --> gpu texture --> fixed-pipeline processing --> display on screen

我希望看起来像这样:

cpu image --> gpu texture --> rendering passes to enhance the image --> gpu texture --> fixed-pipeline processing --> display on screen

我的问题是:如何在这些不同的操作模式之间切换? 我之前已经看过一些问题(1234),但没有人回答我的具体问题。也许只是解开Vertex Arrays的一个简单问题?


修改

现在我对@Reto Koradi的这个问题有了一个很好的答案,我还有另一个问题:你知道这种模式改变需要花多少时间吗?有什么'冲洗'当我切换回固定管道时继续?

1 个答案:

答案 0 :(得分:1)

从基于着色器的渲染切换回固定管道:

glUseProgram(0);

从FBO渲染切换回渲染到默认帧缓冲:

glBindFramebuffer(GL_FRAMEBUFFER, 0);

您可以在固定管道中使用顶点数组。但是如果你想取消绑定你的顶点数组/缓冲区,那就是同样的事情。只需绑定0即可释放绑定,例如:

glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

编辑:回答关于开销的后续问题。

简单的答案是......这取决于。某些操作的开销可能因平台/硬件而异。至于它可以用相对一般的术语来回答:

  • 我还没有发现任何硬件,即使是最近仍然有完整的固定管道。在过去的5到10年内制作的所有东西都经常使用着色器。如果使用旧版固定管道,则驱动程序会为您生成着色器。当您切换到固定管道时,着色器生成可能需要一些时间,但往往会进行大量优化(只要人们仍然运行旧的基准测试),并且很可能使用缓存着色器。所以它不应该是非常重要的。
  • 编译着色器很昂贵。简单地切换着色器的开销很低。我在我工作的平台上以亚微秒的速度对其进行了基准测试,与绑定顶点缓冲区相当。我想,可能在其他平台上更高,但是现代游戏使用许多不同的着色器,并且能够以低开销绑定它们是至关重要的。
  • 绑定/解除绑定顶点缓冲区的开销很低。并且在驱动程序中进行了非常优化,因为它对许多常用基准测试产生了很大影响,特别是那些没有产生足够着色器负载以保持GPU完全忙碌的基准测试
  • 用于绑定不同绘制目标的开销(例如,从FBO切换到默认帧缓冲区)高度依赖于平台。但是在大多数平台上它至少是中等价位的,并且在一些平台上应该是一个非常糟糕的性能杀手,它将重命名无名。没有理由担心,如果你不经常切换,但你绝对不希望这样做比需要更频繁。