绘制渲染缓冲区对象的内容

Posted

技术标签:

【中文标题】绘制渲染缓冲区对象的内容【英文标题】:Draw the contents of the render buffer Object 【发布时间】:2014-02-28 18:04:10 【问题描述】:

不太了解render buffer对象的操作。例如,如果我想显示渲染缓冲区中的内容,我必须对纹理进行渲染?

    GLuint fbo,color_rbo,depth_rbo;

    glGenFramebuffers(1,&fbo);
    glBindFramebuffer(GL_FRAMEBUFFER,fbo);

    glGenRenderbuffersEXT(1, &color_rb);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, color_rb);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, 256, 256);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_RENDERBUFFER_EXT, color_rb);

    glGenRenderbuffersEXT(1, &depth_rb);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 256, 256);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, depth_rb);

    if(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)!=GL_FRAMEBUFFER_COMPLETE_EXT)return 1;

    glBindFramebuffer(GL_FRAMEBUFFER,0);

    //main loop    

    //This does not work :-(
    glBindFramebuffer(GL_FRAMEBUFFER,fbo);
    glClearColor(0.0,0.0,0.0,1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    drawCube();
    glBindFramebuffer(GL_FRAMEBUFFER,0);

有什么想法吗?

【问题讨论】:

【参考方案1】:

当您绘制到 FBO 而不是默认帧缓冲区时,您将看不到任何东西,这是 FBO 要点的一部分。

您的选择是:

    将渲染缓冲区blit到另一个帧缓冲区(在这种情况下,默认后缓冲区可能是GL_BACK

    如果您想查看结果,请绘制到纹理附件中,然后绘制纹理映射的图元(例如三角形/四边形)。

由于 2 是不言自明的,我将更详细地解释选项 1:

/* We are going to blit into the window (default framebuffer)                     */
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffer      (GL_BACK);              /* Use backbuffer as color dst.         */

/* Read from your FBO */
glBindFramebuffer (GL_READ_FRAMEBUFFER, fbo);
glReadBuffer      (GL_COLOR_ATTACHMENT0); /* Use Color Attachment 0 as color src. */

/* Copy the color and depth buffer from your FBO to the default framebuffer       */
glBlitFramebuffer (0,0, width,height,
                   0,0, width,height,
                   GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
                   GL_NEAREST);

这里有几点值得一提:

首先,从一个帧缓冲区到另一个帧缓冲区的块传输通常比绘制两个填充整个视口的纹理三角形要慢得多。 第二,当您对深度或模板图像进行 blit 时,您不能使用线性过滤...但是如果您采用纹理映射方法,则可以使用(这只有在源缓冲区和目标缓冲区的分辨率不同时才真正重要)位时)。

总体而言,绘制带纹理的图元是更灵活的解决方案。如果您需要进行多重采样抗锯齿处理,则 Blitting 最有用,因为否则您必须在着色器中实现它,并且在 帧缓冲区对象之后添加多重采样纹理;一些较旧的硬件/驱动程序支持 FBO,但不支持多重采样颜色(需要 DX10 硬件)或深度(需要 DX10.1 硬件)纹理。

【讨论】:

非常感谢您的精彩解释朋友:-) 是否可以从渲染缓冲区对象到 fbo?

以上是关于绘制渲染缓冲区对象的内容的主要内容,如果未能解决你的问题,请参考以下文章

iOS界面的绘制和渲染

使用统一缓冲区对象进行批量渲染

理解UIView的绘制

在OpenGL中绘制到半透明帧缓冲区时如何抗锯齿? [复制]

如何执行异步离屏查询?

是否可以在 opengl 中从 2 个不同的线程渲染 2 个不同的帧缓冲区对象?