了解OpenGLES iOS中的缓冲区

时间:2013-05-06 13:53:09

标签: iphone ios opengl-es framebuffer

我的理解:有一种所谓的帧缓冲。它是缓冲对象的指针数组。缓冲区对象可以是例如渲染缓冲区,纹理缓冲区或其他。如果我想画一些东西,我将渲染缓冲区附加到帧缓冲区,绘制到它,最后调用一个方法将其发送到屏幕。

1)到目前为止这是否正确?

我不明白:

2)我想我在某处创建了在创建上下文时创建帧缓冲区的地方。唉,我看不到我看到的地方了。但是,如果帧缓冲区真的被创建,为什么我必须调用glGenFramebuffersOES(1, &framebuffer)glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer)?据我所知,第一个创建一个新的帧缓冲区,其中一个空间用于附件,第二行将上下文的帧缓冲区指针设置为framebuffer。但假设我已经在上下文中有一个帧缓冲区,为什么我无法检索它并将我的渲染缓冲区附加到那个呢?

3)什么是“默认帧缓冲区”?它是一个名为0的帧缓冲区。如果已经有一个默认的帧缓冲区,为什么我要绘制时必须创建一个新缓冲区?

1 个答案:

答案 0 :(得分:6)

  

1)到目前为止这是否正确?

嗯,或多或少。从概念上讲,帧缓冲区是一组具有特定语义的缓冲区,一个(甚至零)或更多颜色缓冲区,可能是一个深度缓冲区,可能还有一个模板缓冲区。这些是写入片段的相应值的目标。

但要回答2)和3),您必须了解默认帧缓冲区帧缓冲区对象(FBO)之间的区别。对于每个OpenGL上下文,都有一个默认的帧缓冲区(其属性是在通过某些特定于平台的方法创建上下文时指定的),它包含一个颜色缓冲区(让我们忽略现在的双重和立体缓冲),其中包含实际显示的内容和可能的内容其相应的深度和模板缓冲区。所以无论你想在显示器上看到什么,迟早都要找到进入默认帧缓冲区的方法。但是这个默认帧缓冲区的各个缓冲区是固定的,即你不能只是将纹理或渲染缓冲区绑定到它,或者将其深度缓冲区切换为另一个缓冲区缓冲区(假设你只能将东西复制到其中或从中复制出来但不会将它们重定向到某些缓冲区。其他记忆区域。)

除此之外,您还可以自己创建所谓的帧缓冲对象(FBO)(与所有gl...Framebuffer...函数一起创建和使用的对象)。这些是最终的轻量级OpenGL对象(即没有重型数据容器),它们为各个缓冲通道(多个颜色附件,深度和模板附件)提供一组连接点,您可以将实际数据容器附加到这些连接点,像纹理或渲染缓冲区。并且所有这些附件一起定义了一个实际的帧缓冲区,类似于默认的帧缓冲区。但是FBO的优势在于,您可以将任意容器附加到它上面,因此可以直接渲染到纹理中。同样,它不受某些OS资源或显示的约束,因此通常允许屏幕外渲染。

因此,对于在屏幕上显示(可能是深度和模板测试)基元的日常工作,默认帧缓冲完全足够,您根本不需要混淆FBO。如果您使用FBO,则使用FBO想在屏幕外绘制一些不会被显示的东西,通常直接绘制到用于进一步处理的纹理中,或者从CPU读取并在那里处理。很好的例子是阴影贴图创建(将场景渲染为深度纹理,然后在将要阴影​​的对象渲染到屏幕时使用)或后处理效果(将场景渲染为颜色纹理以进行渲染)一些额外的后处理着色器,最后放到屏幕上)。但用例最终无数。

那么让我们再看看你的问题(谨防重复;);)

  

2)我想我在某处读到了帧缓冲区的创建时间   上下文已经创建。

是的,但是帧缓冲与帧缓冲对象不同。

  

但是如果帧缓冲区真的被创建了,为什么我必须调用   glGenFramebuffersOES(1, &framebuffer)和   glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer)

这反过来又创建了自己的帧缓冲区对象,与默认的帧缓冲区不同。

  

但假设我已经在上下文中有一个帧缓冲区,为什么我不能   检索并将我的渲染缓冲区附加到那个?

因为默认的帧缓冲区不具备完全成熟的帧缓冲区对象的功能,并且不允许将其数据重新编写到某些其他数据容器(如renderbuffer)中。它只有预定义的存储空间,它连接到实际的显示操作系统资源。

  

3)什么是“默认帧缓冲区”?它是一个带有名称的帧缓冲区   0.如果已经有一个默认的帧缓冲区,为什么我要绘制一个新的?

与上述相同。 FBO ID 0是默认帧缓冲区的占位符,因此意味着“根本没有FBO”。这意味着当执行glBindFramebuffer(GL_FRAMEBUFFER, 0)(这是你可以用ID为0调用的唯一函数)时,你告诉GL,你从现在开始想要工作(读取和绘制)默认帧缓冲而不是某些自定义FBO。

所以底线是,在上下文创建时创建的默认帧缓冲区不具有帧缓冲区对象的全部功能,即将任意内存区域作为单独的缓冲区附加,这在某些(但不是全部)渲染场景中是必需的。如果您需要此功能,则必须使用您在问题中列出的功能创建和管理帧缓冲对象(FBO)。