Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 理解OpenGLES iOS中的缓冲区_Iphone_Ios_Opengl Es_Framebuffer - Fatal编程技术网

Iphone 理解OpenGLES iOS中的缓冲区

Iphone 理解OpenGLES iOS中的缓冲区,iphone,ios,opengl-es,framebuffer,Iphone,Ios,Opengl Es,Framebuffer,我的理解是:有所谓的帧缓冲区。它是指向缓冲区对象的指针数组。缓冲区对象可以是渲染缓冲区、纹理缓冲区或其他对象。如果我想画一些东西,我会在帧缓冲区中附加一个渲染缓冲区,然后画进去,最后调用一个方法将它发送到屏幕上 1) 到目前为止这是正确的吗 我不明白的是: 2) 我想我在某个地方读到,在创建上下文时创建了帧缓冲区。唉,我再也找不到我在哪里看到这个了。但是,如果帧缓冲区真的被创建了,为什么我必须调用glGenFramebuffersOES(1,&framebuffer)和glBindFramebu

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

1) 到目前为止这是正确的吗

我不明白的是:

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

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

1) 到目前为止这是正确的吗

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

但要回答2)和3),您必须理解默认帧缓冲区和帧缓冲区对象(FBO)之间的区别。对于每个OpenGL上下文,都有一个默认的帧缓冲区(其属性在通过特定于平台的方式创建上下文时指定),它包括一个颜色缓冲区(现在我们忽略双缓冲区和立体缓冲区),其中包含实际显示的内容,可能还有相应的深度和模具缓冲区。因此,无论您希望在显示器上看到什么,迟早都必须找到进入默认帧缓冲区的方式。但此默认帧缓冲区的各个缓冲区是固定的,即,您不能仅将纹理或renderbuffer绑定到它,或将其say深度缓冲区切换到另一个缓冲区(例如,您只能将内容复制到或复制出它们,但不能将其重定向到其他内存区域)

除此之外,您还可以自己创建所谓的帧缓冲区对象(FBO)(那些创建并与所有这些
gl…framebuffer…
函数一起使用的对象)。这些最终是轻量级OpenGL对象(即,没有重型数据容器),它们为单个缓冲区通道(可变颜色附件、深度和模具附件)提供了一组附着点,您可以将实际数据容器(如纹理或渲染缓冲区)附着到这些缓冲区通道。所有这些附件一起定义了一个实际的帧缓冲区,类似于默认的帧缓冲区。但是FBO的优点是,您可以将任意容器附加到它,从而允许直接渲染到纹理中。同样,它不绑定到某些操作系统资源或显示器,因此通常允许屏幕外渲染

因此,对于在屏幕上显示(可能是经过深度和模具测试的)基本体的日常工作,默认帧缓冲区就足够了,您根本不需要干扰FBO。如果您希望在屏幕外绘制不显示的内容,通常直接绘制到纹理中以供进一步处理,或从CPU读取并在那里处理,则使用FBO。很好的示例包括阴影贴图创建(将场景渲染为深度纹理,然后在将要被阴影的对象渲染到屏幕上时使用)或后处理效果(将场景渲染为颜色纹理,以便在最终放置到屏幕上之前通过一些附加的后处理着色器提供)。但是使用案例最终是数不清的

那么让我们再看看你的问题(不过要注意重复;):

2) 我想我在某处读到,帧缓冲区是在 上下文被创建

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

但是如果真的创建了帧缓冲区,为什么我要调用
glGenFramebuffersOES(1,&framebuffer)
glBindFramebufferOES(GL\u FRAMEBUFFER\u OES,FRAMEBUFFER)

这反过来用于创建与默认帧缓冲区不同的自己的帧缓冲区对象

但是假设我在上下文中已经有了一个帧缓冲区,为什么我不能呢 取回它并将我的渲染缓冲区附加到它

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

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

同上。FBO ID
0
是默认帧缓冲区的占位符,因此表示“根本没有FBO”。这意味着在执行
glBindFramebuffer(GL\u FRAMEBUFFER,0)
(这是您可以使用ID为0调用的唯一函数)时,您会告诉GL,从现在开始,您希望使用默认帧缓冲区,而不是某些自定义FBO(从中读取和绘制)

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