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

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

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

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

    或者

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

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

有帮助吗?

解决方案

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

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

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

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

其他提示

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top