【问题标题】:opengl: shaders-based rendering to a frame-buffer, followed by fixed-pipeline renderingopengl:基于着色器的渲染到帧缓冲区,然后是固定管道渲染
【发布时间】:2014-05-09 13:06:30
【问题描述】:

我有一个应用程序,它使用 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 那里得到了这个问题的一个很好的答案,我还有另一个答案:知道这种模式改变可能需要多长时间吗?当我切换回固定管道时是否有任何“冲洗”?

【问题讨论】:

    标签: c++ qt opengl glsl shader


    【解决方案1】:

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

    glUseProgram(0);
    

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

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    

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

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

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

    简单的答案是……视情况而定。某些操作的开销可能因平台/硬件而异。就可以用相对笼统的术语来回答:

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

    【讨论】:

    • 就是这么简单!我已经验证这确实有效。非常感谢。
    • 再次感谢@Reto 的详细回答。我担心这种转换会成为我的瓶颈,但事实并非如此。干杯!
    猜你喜欢
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-28
    • 1970-01-01
    相关资源
    最近更新 更多