在渲染和等待结果时切换帧缓冲区

时间:2013-11-07 12:30:10

标签: opengl

我有问题,我想在渲染时切换帧缓冲区,并在切换回时立即使用帧缓冲区。实际上这会产生一个空的帧缓冲,这不是你想象的预期结果。

因为我已经使用了framebuffers之前我发现它正在工作,如果我要显示的帧缓冲区在i开始渲染渲染另一个渲染到的帧缓冲区之前渲染。

不工作的渲染路径

  • 渲染到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

1 个答案:

答案 0 :(得分:3)

  

不工作的渲染路径

     
      
  • 渲染到FBO0
  •   
  • 开始渲染到FBO1
  •   
  • 切换回FBO0
  •   
  • 将FBO1渲染为FBO0
  •   

应该起作用,因为发布将FBO1内容呈现给FBO0的命令会在FBO0和FBO1发生的操作之前创建一个所谓的隐式同步点,以便在将数据合并到更多步骤之前完成。

您使用的OpenGL实现有错误,或者您做错了什么。我们需要看一些代码。