帧缓冲整理

参考地址:

  1. https://learnopengl-cn.readthedocs.io/zh/latest/04%20Advanced%20OpenGL/05%20Framebuffers/
  2. https://www.jianshu.com/p/69c7707afb6f
  • 颜色缓冲:写入颜色值
  • 深度缓冲:写入深度信息
  • 模版缓冲:允许我们基于一些条件丢弃指定片段

组合起来叫做帧缓冲(Framebuffer)。

建构一个完整的帧缓冲必须满足以下条件:

  • 我们必须往里面加入至少一个附件(颜色、深度、模板缓冲)。
  • 其中至少有一个是颜色附件。
  • 所有的附件都应该是已经完全做好的(已经存储在内存之中)。
  • 每个缓冲都应该有同样数目的样本。

渲染缓冲(Renderbuffer Object),简称 RBO,由应用程序分配的 2D 图像缓冲区,可以用于分配和存储 深度模板

1.创建帧缓冲

    unsigned int framebuffer;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    // create a color attachment texture创建颜色附件
    unsigned int textureColorbuffer;
    glGenTextures(1, &textureColorbuffer);
    glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 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);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);
    // create a renderbuffer object for depth and stencil attachment (we won't be sampling these)
    //创建深度和模版附件
    unsigned int rbo;
    glGenRenderbuffers(1, &rbo);
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    // use a single renderbuffer object for both a depth AND stencil buffer.
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); 
    // now actually attach it
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); 
    // now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl;
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

2.使用帧缓冲并保存为图片

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); //使用创建的帧缓冲

    //绘制完成后保存图片
    uchar *data = new uchar[SCR_WIDTH*SCR_HEIGHT*3];
    //glReadBuffer(GL_COLOR_ATTACHMENT0);
    //glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glReadPixels(0, 0, SCR_WIDTH, SCR_HEIGHT, GLenum(GL_RGB),GLenum(GL_UNSIGNED_BYTE), data);
    QImage image(data, SCR_WIDTH, SCR_HEIGHT, QImage::Format_RGB888);
    image.save("./framebuffer.jpg", "JPG");
    delete[] data;

你可能感兴趣的:(opengl/vulkan)