在OpenGL中自引用Renderbuffers

时间:2009-03-06 04:13:36

标签: opengl rendering textures

我有一些OpenGL代码在不同的行为中表现不一致 硬件。我有一些代码:

  1. 创建渲染缓冲区并将纹理绑定到其颜色缓冲区(纹理A)
  2. 将此渲染缓冲区设置为活动状态,并调整视口等
  3. 激活像素着色器(在本例中为高斯模糊)。
  4. 将四边形绘制为全屏,其上带有纹理A.
  5. 取消绑定渲染缓冲区等。
  6. 在我的开发机器上,这个工作正常,并且具有预期的功能 然而,在其他硬件上模糊“就地”纹理的效果 这似乎不起作用。

    我已经把它归结为两种可能性。

    A)使渲染缓冲区渲染到自身不应该工作,并且 由于某种侥幸,它只适用于我的开发机器。

    或者

    B)这种方法应该有效,但其他方法出错了。

    有什么想法吗?老实说,我很难找到关于这个问题的具体细节。

2 个答案:

答案 0 :(得分:2)

A)是正确的答案。在读取时从同一缓冲区渲染是未定义的。它可能会起作用,也可能不起作用 - 这正是发生的事情。

在OpenGL的情况下,framebuffer_object extension有“4.4.3渲染当绑定纹理对象的图像也附加到帧缓冲区时”,它告诉发生了什么(基本上,未定义)。在Direct3D9中,如果您使用该设置,调试运行时会大声抱怨(但它可能会取决于硬件/驱动程序)。在D3D10中,我认为运行时总是取消绑定用作目标的目标。

为什么这是未定义的? GPU非常快的原因之一是它们可以做出很多假设。例如,他们可以假设获取像素的单元不需要与写入像素的单元通信。因此可以读取表面,N个循环之后读取完成,N个循环之后像素着色器结束它的执行,然后它放入GPU上的某些输出合并缓冲区,最后在某些时候它被写入内存。最重要的是,GPU以“未定义”顺序进行光栅化(一个GPU可能在行中光栅化,另一个GPU在某些缓存友好的顺序中,另一个在完全另一个顺序中),因此您不知道将写入表面的哪些部分首先。

所以你应该做的是创建几个缓冲区。在模糊/发光的情况下,两个通常是足够的 - 渲染到第一个,然后读取&写到第二个时模糊了。如果需要乒乓方式,请重复此过程。

答案 1 :(得分:0)

在某些特殊情况下,即使是后备缓冲也可能就足够了。你根本就不做glClear,而你之前绘制的内容仍然存在。当然,需要注意的是,您无法真正从后备缓冲区读取。但对于淡入和淡出等效果,这可行。