OpenGL C++ 使用FrameBuffer将渲染结果保存到纹理

3 篇文章 0 订阅

如果我们需要对颜色进行混合,一种做法是将需要混合的元素各自做成纹理,然后将纹理叠加,那么如何将实时渲染的结果保存到纹理中呢?答案是用FrameBuffer. 一旦启用了FrameBuffer并绑定到纹理,当前渲染的结果就会保存在纹理中,用不同的FrameBuffer绑定不同的纹理插槽就能实现多个纹理的混合。


    class FrameBuffer
    {
    public:
      GLuint m_ID = 0;

      FrameBuffer(int texIndex, int w, int h)
      {
        glGenFramebuffers(1, &m_ID); Bind();
        GLuint renderedTexture; glGenTextures(1, &renderedTexture);
        glActiveTexture(GL_TEXTURE0 + texIndex); glBindTexture(GL_TEXTURE_2D, renderedTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);
      }
      ~FrameBuffer() { if (m_ID > 0) glDeleteFramebuffers(1, &m_ID); }



      // GL_FRAMEBUFFER is both GL_READ_FRAMEBUFFER and GL_DRAW_FRAMEBUFFER
      void Bind() const { glBindFramebuffer(GL_FRAMEBUFFER, m_ID); }
      void Unbind() const { glBindFramebuffer(GL_FRAMEBUFFER, 0); }
      bool IsCompleted() { return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE; }

    };

将渲染结果保存到FrameBufer绑定的纹理插槽,其中w和h为glViewPort的宽高

          FrameBuffer fb1(0, w, h);
          s_red.Bind(); s_red.Render();

其中s_red的片元着色器必须写成这样,就是将FragColor输出到 layout(location=0) color,这是因为将纹理插槽绑定到FrameBuffer的时候指定的GL_COLOR_ATTACHMENT0对应的就是这里的 layout(location=0) color

        m_FragmentShaderSource = (char*)"#version 460 core\n"
          "layout(location = 0) out vec3 color; "
          "out vec4 FragColor;\n"
          "in vec4 v_Color;\n"
          "void main()\n"
          "{\n"
          "  FragColor = v_Color; color=vec3(FragColor.xyz); \n"
          "}\n\0";

用同样的方法做第二个纹理,然后将当前的FrameBuffer恢复到可视的渲染buffer, 这时两个纹理已经做好了,分别位于第一个和第二个插槽,在s_combine的着色器中直接将两个纹理叠加即可。

          FrameBuffer fb1(0, w, h);
          s_red.Bind(); s_red.Render();
          FrameBuffer fb2(1, w, h);
          s_green.Bind(); s_green.Render();

          glBindFramebuffer(GL_FRAMEBUFFER, 0);

          s_combine.Bind(); s_combine.Render();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值