我的问题是我想在渲染时切换帧缓冲区,并在我切换回来时立即使用帧缓冲区。实际上,这会导致一个空的帧缓冲区,这不是您可以想象的预期结果。
因为我已经使用了帧缓冲区,然后才发现如果要显示的帧缓冲区在我开始渲染另一个要渲染到的帧缓冲区之前渲染,它就可以工作。
不工作的渲染路径
- 渲染到 FBO0
- 开始渲染到 FBO1
- 切换回 FBO0
- 将 FBO1 渲染到 FB0
工作路径
- 渲染到 FBO1
- 渲染到 FBO0
- 将 FBO1 渲染为 FBO0
因为它看起来像一个同步问题,我想知道如何防止这种情况?是否有任何命令可以确保对前一个渲染缓冲区的渲染已经完成?虽然它目前正在工作,但它不是我所说的安全解决方案,因为我认为如果要渲染到 FBO1 的内容变得更大,以后可能会出现同样的问题。
代码
这是开始渲染的代码:
GLFramebuffer.BindFramebuffer(FramebufferTarget.FRAMEBUFFER, _FramebufferHandle);
#if DEBUG
FramebufferStatus status = GLFramebuffer.CheckFramebufferStatus(FramebufferTarget.FRAMEBUFFER);
if (status != FramebufferStatus.FRAMEBUFFER_COMPLETE)
{
GLFramebuffer.BindFramebuffer(FramebufferTarget.FRAMEBUFFER, FramebufferHandle.Default);
throw new OpenGLException(GLFramebuffer.GetStatusString(status));
}
#endif
RenderStack.Push(Tuple.Create(this, attachments));
GL.Viewport(0, 0, Width, Height);
以及停止渲染的代码:
Tuple<Framebuffer, FramebufferAttachement[]> peeked;
if (RenderStack.Count == 0 || (peeked = RenderStack.Peek()).Item1 != this)
{
if (RenderStack.Any(p => p.Item1 == this))
{
throw new InvalidOperationException("Framebuffer is not the top framebuffer, you must call 'StopRendering()' on all previous used buffers");
}
else throw new InvalidOperationException("Framebuffer is not in the rendering stack, please use 'StartRendering(...)' to use the current framebuffer");
}
AssertDisposed();
RenderStack.Pop();
if (RenderStack.Count == 0)
{
GLFramebuffer.BindFramebuffer(FramebufferTarget.FRAMEBUFFER, FramebufferHandle.Default);
}
else
{
Rebind(peeked);
}
以及重新绑定方法:
GLFramebuffer.BindFramebuffer(FramebufferTarget.FRAMEBUFFER, peeked.Item1._FramebufferHandle);
var attachments = peeked.Item2;
if (attachments.Length > 1)
{
GLFramebuffer.DrawBuffers(attachments.Select(p => (DrawBuffersEnum)p).ToArray());
}
GL.Viewport(0, 0, peeked.Item1.Width, peeked.Item1.Height);
这些方法只是被包装了,所以GLFramebuffer.DrawBuffers
等于glDrawBuffers
.