我正在尝试在iOS(> = 8.0)上编写一个使用多个渲染目标(MRT)的OpenGLES-3.0 Swift应用程序。为了获得适当的抗锯齿功能,我启用了多重采样。
详细说明,我的渲染架构如下所示:
显示帧缓冲区附加了一个渲染缓冲区:
Sample framebuffer 附加了两个渲染缓冲区:
每当我的图层更改其边界时,我会调整所有渲染缓冲区的大小,就像Apple在GLPaint示例中所做的那样。
我为你创建了一个最小的例子。渲染本身如下所示:
//Set the GL context, bind the sample framebuffer and specify the viewport:
EAGLContext.setCurrentContext(context)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), self.sampleFramebuffer)
glViewport(0, 0, self.layerWidth, self.layerHeight)
//Clear both render targets:
glClearBufferfv(GLenum(GL_COLOR), 0, self.colorRenderbufferIClearColor)
glClearBufferfv(GLenum(GL_COLOR), 1, self.colorRenderbufferIIClearColor)
//Specify the vertex attribute (only position, 6 floats for a triangle):
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(2 * sizeof(GLfloat)), nil)
//Use the shader program and render a single triangle:
glUseProgram(self.program)
glDrawArrays(GLenum(GL_TRIANGLES), 0, 3)
//Prepare both framebuffers as source and destination to do multisampling:
glBindFramebuffer(GLenum(GL_READ_FRAMEBUFFER), self.sampleFramebuffer)
glBindFramebuffer(GLenum(GL_DRAW_FRAMEBUFFER), self.displayFramebuffer)
//Specify from which of the attachments we do the multisampling.
//This is GL_COLOR_ATTACHMENT0 or GL_COLOR_ATTACHMENT1.
glReadBuffer(self.blitAttachment)
//Transfer data between framebuffers and do multisampling:
glBlitFramebuffer(0, 0, self.layerWidth, self.layerHeight, 0, 0, self.layerWidth, self.layerHeight, GLbitfield(GL_COLOR_BUFFER_BIT), GLenum(GL_LINEAR))
//Invalidate the sample framebuffer for this pass:
glInvalidateFramebuffer(GLenum(GL_READ_FRAMEBUFFER), 2, [GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_COLOR_ATTACHMENT1)])
//Bind the display renderbuffer and present it:
glBindRenderbuffer(GLenum(GL_RENDERBUFFER), self.displayRenderbuffer)
self.eaglContext.presentRenderbuffer(Int(GL_RENDERBUFFER))
现在问题:我的示例项目在红色背景上绘制一个蓝色三角形到第一个渲染目标(颜色渲染缓冲区I)和绿色背景上的紫色三角形到第二个渲染目标(颜色渲染缓冲区II)。通过在代码中设置 blitAttachment ,您可以选择将两个附件中的哪一个解析为显示帧缓冲区。
您可以使用我附加的sample code (DropBox)重现该问题。 所以有两个问题:
提前致谢!
答案 0 :(得分:0)
此API中似乎有一些奇怪的行为。您链接的代码确实可以在模拟器上运行,但模拟器与实际设备完全不同,所以我建议您永远不要将它用作参考。
所以似乎发生的事情是渲染缓冲区被丢弃的速度太快了。为什么以及如何发生这种情况我不知道。您将缓冲区blit然后使它们无效,因此只需删除缓冲区失效就可以解决问题。但是不建议删除缓冲区失效,而是确保GPU在使它们无效之前执行了所有任务。这意味着只需拨打flush
。
在致电glInvalidateFramebuffer(GLenum(GL_READ_FRAMEBUFFER), 2, [GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_COLOR_ATTACHMENT1)])
之前,只需致电glFlush()
:
//Resolve from source to destination while applying multisampling:
glBlitFramebuffer(0, 0, self.layerWidth, self.layerHeight, 0, 0, self.layerWidth, self.layerHeight, GLbitfield(GL_COLOR_BUFFER_BIT), GLenum(GL_LINEAR))
OpenGLESView.checkError(dbgDomain, andDbgText: "Failed to blit between framebuffers")
glFlush()
//Invalidate the whole sample framebuffer:
glInvalidateFramebuffer(GLenum(GL_READ_FRAMEBUFFER), 2, [GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_COLOR_ATTACHMENT1)])
OpenGLESView.checkError(dbgDomain, andDbgText: "Failed to invalidate sample framebuffer")