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

opengl: shaders-based rendering to a frame-buffer, followed by fixed-pipeline rendering

本文关键字:然后 管道 缓冲区 于着色 Opengl      更新时间:2023-10-16

我有一个应用程序,它使用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

我的问题是:我如何在这些不同的操作模式之间切换?我已经看到了前面的一些问题(1,2,3,4),但没有一个回答我的具体问题。也许这只是解除顶点数组绑定的一个简单问题?


编辑

现在我对@Reto Koradi的问题有了一个很好的答案,我还有另一个问题:你知道这种模式改变需要多长时间吗?当我切换回固定管道时,是否有任何"冲洗"?

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

glUseProgram(0);

从FBO渲染切换回渲染到默认的framebuffer:

glBindFramebuffer(GL_FRAMEBUFFER, 0);

可以在固定管道中使用顶点数组。但如果你想解除顶点数组/缓冲区的绑定,也是一样的。只需绑定0来释放你的绑定,例如:

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

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

简单的答案是……视情况而定。根据平台/硬件的不同,某些操作的开销可能会有很大的不同。只要能用比较一般的话来回答:

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