我创建了一个帧缓冲区:
glBindFramebuffer(GL.GL_FRAMEBUFFER, &fbo);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
通过
从帧缓冲区读取像素glBindFramebuffer(GL_FRAMEBUFFER, &fbo);
glReadPixels(0, 0, w, h, GL_RGBA, GL_FLOAT, &data);
相当于
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(0, 0, w, h, GL_RGBA, GL_FLOAT, &data);
答案 0 :(得分:3)
它不等同,阅读GL_COLOR_ATTACHMENT0
会从当前绑定的帧缓冲区获取数据,这可能与您创建的帧缓冲区完全不同。
所以基本上你需要保证你通过调用
绑定你的帧缓冲区glBindFramebuffer(GL_FRAMEBUFFER, &fbo);
在使用它之前的任何操作。
GL_COLOR_ATTACHMENT0只是Frame缓冲区对象的一个属性,它与任何特定的帧缓冲区无关。通过使用另一个帧缓冲区绑定它,您将读取其不是您想要的数据。
答案 1 :(得分:1)
这些是完全不同的电话。让我提供一些关于FBO真正希望如何使这一点更加清晰的背景。
帧缓冲对象(又名FBO)只是状态的集合。以下调用更改当前绑定的FBO中跟踪的状态:
glFramebufferTexture2D()
glFramebufferRenderbuffer()
glDrawBuffers()
glReadBuffer()
这意味着无论何时进行其中一个调用,都会更新当前绑定的FBO中跟踪的状态以反映调用的更改。例如,如果调用glDrawBuffers()
,则会更新当前绑定的FBO中的绘制缓冲区列表。
然后,无论何时绑定FBO,FBO中跟踪的状态将再次变为活动状态。因此,如果您之前在绑定FBO glDrawBuffers()
时调用了foo
,然后再次绑定foo
,则之前调用的绘制缓冲区设置将再次处于活动状态。
请注意,FBO不拥有附加到它的渲染缓冲区/纹理。 FBO仅包含的信息,其中渲染缓冲区附加到给定连接点处的FBO。在您的代码中,FBO foo
存储了渲染缓冲区rbo
附加到附着点GL_COLOR_ATTACHMENT0
的事实。例如,将相同的渲染缓冲区附加到多个FBO是完全合法的。
现在,更具体地说,您的代码:
glBindFramebuffer()
次调用的参数类型错误:
glBindFramebuffer(GL.GL_FRAMEBUFFER, &fbo);
第二个参数是FBO的名称(id),而不是地址。所以电话是:
glBindFramebuffer(GL.GL_FRAMEBUFFER, fbo);
此调用不执行任何操作:
glReadBuffer(GL_COLOR_ATTACHMENT0);
GL_COLOR_ATTACHMENT0
是FBO的默认读缓冲区。因此,除非您之前将其设置为不同的值,否则此调用是多余的,并且仅设置与默认值相同的值。正如命名所暗示的那样,FBO可以有多个附件,如果你将一个渲染缓冲区/纹理附加到glReadBuffer()
以外的附件,并且想从那个附件中读取,你可以使用ATTACHMENT0
。
只要您只为FBO使用一个附件,您唯一需要做的就是绑定您想要阅读的FBO:
glBindFramebuffer(GL.GL_FRAMEBUFFER, fbo);
glReadPixels(...);
glReadPixels()
总是从当前绑定的FBO中读取,因此无法解决此问题。
答案 2 :(得分:0)
glReadBuffer(GL_COLOR_ATTACHMENT0); glReadPixels(0,0,w,h,GL_RGBA,GL_FLOAT和& data);
这里的数据将从当前有界帧缓冲区读取,这不等于
glBindFramebuffer(GL_FRAMEBUFFER,& fbo); glReadPixels(0,0,w,h,GL_RGBA,GL_FLOAT和& data); (如果帧缓冲区在第一种情况下没有限制到相应的fbo)
我认为这就是为什么提供glNamedFramebufferReadBuffer API,直接从作为第一个参数提到的帧缓冲区读取数据。