美文网首页
opengl学习-帧缓冲

opengl学习-帧缓冲

作者: 小杰66 | 来源:发表于2021-04-25 08:18 被阅读0次

    创建一个帧缓冲

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

    完整的帧缓冲组成

    1. 附加至少一个缓冲(颜色、深度或模板缓冲)。
    2. 至少有一个颜色附件(Attachment)。
    3. 所有的附件都必须是完整的(保留了内存)。
    4. 每个缓冲都应该有相同的样本数。

    检查帧缓冲是否完整

    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)

    激活默认帧缓冲

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    删除帧缓冲对象

    glDeleteFramebuffers(1, &fbo);

    纹理附件

    1. 创建一个纹理
    unsigned int texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    1. 附加到帧缓冲
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    

    glFrameBufferTexture2D有以下的参数:

    • target:帧缓冲的目标(绘制、读取或者两者皆有)
    • attachment:我们想要附加的附件类型。当前我们正在附加一个颜色附件。注意最后的0意味着我们可以附加多个颜色附件。我们将在之后的教程中提到。
    • textarget:你希望附加的纹理类型
    • texture:要附加的纹理本身
    • level:多级渐远纹理的级别。我们将它保留为0。
    1. 附加深度缓冲,附件类型设为GL_DEPTH_ATTACHMENT。纹理格式和内部格式类型设为为GL_DEPTH_COMPONENT
    2. 附加模板缓冲,附件类型设为GL_STENCIL_ATTACHMENT,纹理格式设为GL_STENCIL_INDEX
    3. 附加深度模板缓冲,类型设为GL_DEPTH_STENCIL_ATTACHMEN。纹理的每32位数值将包含24位的深度信息和8位的模板信息
    glTexImage2D(
      GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 800, 600, 0, 
      GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL
    );
    
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);
    

    渲染缓冲对象附件

    渲染缓冲对象直接将所有的渲染数据储存到它的缓冲中,不会做任何纹理格式的转换,是一个更快的可写储存介质。
    渲染缓冲对象通常是只写的,常用于深度和模板附件,因为我们不需要从深度和模板缓冲中读取值,只关心深度和模板测试。

    1. 创建一个渲染缓冲对象
      unsigned int rbo;
      glGenRenderbuffers(1, &rbo);
    2. 绑定渲染缓冲对象
      glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    3. 创建一个深度和模板渲染缓冲对象
      glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);
    4. 附加渲染缓冲对象
      glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);

    如果你不需要从一个缓冲中采样数据,那么使用渲染缓冲对象;
    如果你需要从缓冲中采样颜色或深度值等数据,那么选择纹理附件。

    渲染到纹理

    将场景渲染到一个附加到帧缓冲对象上的颜色纹理中,之后在一个横跨整个屏幕的四边形上绘制这个纹理。
    绘制流程为:
    1.将新的帧缓冲绑定为激活的帧缓冲,和往常一样渲染场景
    2.绑定默认的帧缓冲
    3.绘制一个横跨整个屏幕的四边形,将帧缓冲的颜色缓冲作为它的纹理。

    //创建并绑定帧缓冲对象
    unsigned int framebuffer;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    
    //创建纹理图像,作为颜色附件附加到帧缓冲上
    unsigned int texColorBuffer;
    glGenTextures(1, &texColorBuffer);
    glBindTexture(GL_TEXTURE_2D, texColorBuffer);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
    //附加到当前绑定的帧缓冲对象
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0);  
    
    //使用渲染缓冲对象添加一个深度模板附件到帧缓冲中。
    unsigned int rbo;
    glGenRenderbuffers(1, &rbo);
    glBindRenderbuffer(GL_RENDERBUFFER, rbo); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);  
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    
    //将渲染缓冲对象附加到帧缓冲的深度模板附件
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
    
    //检查帧缓冲是否是完整
    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    
    
    image.png

    后期处理

    整个场景都被渲染到了一个纹理上,可以通过修改纹理数据创建出各种效果。例如 反相、灰度、 核效果、模糊、 边缘检测等。

    相关文章

      网友评论

          本文标题:opengl学习-帧缓冲

          本文链接:https://www.haomeiwen.com/subject/uxvlrltx.html