Hazel Game Engine (071) Frame Buffer

If there are errors in the code, terminology, etc. in the text, please correct me

foreword

  • Introduction to framebuffer (my understanding)
    1. The scene rendered by OpenGL can be placed in this frame buffer
    2. This framebuffer can then be treated as a color or texture sampling area (depending on the type of buffer attachment attached to the framebuffer )
    3. Elsewhere (Imgui) render this frame buffer as a color texture, and the scene that should be displayed on the screen is displayed on the ImGui interface
  • Framebuffer Reference URL

Framebuffer Essentials

  • Need to manually create a frame buffer, just like creating a vertex buffer

  • Additional information is required when creating a framebuffer

    Whether to store color textures, stencils, or depth buffers

    Additional buffers require additional buffer IDs

  • Must be unbound every frame after binding

code flow

  • Create a framebuffer and attach textures, depth and stencilbuffer textures

    void OpenGLFramebuffer::Invalidate()
    {
          
          
        // 1.创建帧缓冲
        glCreateFramebuffers(1, &m_RendererID);
        glBindFramebuffer(GL_FRAMEBUFFER, m_RendererID); // 绑定这个帧缓冲
    
        // 2.创建纹理
        glCreateTextures(GL_TEXTURE_2D, 1, &m_ColorAttachment);;
        glBindTexture(GL_TEXTURE_2D, m_ColorAttachment);
        // 旧的api吧
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Specification.Width, m_Specification.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        // 这里写错过,将glTexParameteri 写错成glTextureParameteri!!
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
        // 1.1纹理附加到帧缓冲
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_ColorAttachment, 0);
    
        // 3.创建深度模板缓冲纹理附加到帧缓冲中
        glCreateTextures(GL_TEXTURE_2D, 1, &m_DepthAttachment);;
        glBindTexture(GL_TEXTURE_2D, m_DepthAttachment);
        // 新api吧
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height);
        //glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_Specification.Width, m_Specification.Height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
    
        // 1.2深度模板缓冲纹理附加到帧缓冲中
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_DepthAttachment, 0);
    
        HZ_CORE_ASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "帧缓冲未创建完成");
    
        glBindFramebuffer(GL_FRAMEBUFFER, 0);// 取消绑定这个帧缓冲,以免不小心渲染到错误的帧缓冲上,比如深度、模板缓冲不会渲染到这里
    }
    
  • Write data to the created framebuffer

    1. Bind a custom framebuffer (equivalent to unbinding to render to the default framebuffer)
    2. Render graphics normally (write the image originally rendered on the screen by OpenGL to a custom framebuffer (no longer the default framebuffer ))
    3. unbind framebuffer
    void Sandbox2D::OnUpdate(Hazel::Timestep ts)
    {
          
          
        HZ_PROFILE_FUNCTION();
    
        m_CameraController.OnUpdate(ts);
    
        // 渲染信息初始化
        Hazel::Renderer2D::ResetStats();
        {
          
          
            ///
            ///
            // 这里
            HZ_PROFILE_SCOPE("Renderer Prep");
            // 1.绑定自定义的帧缓冲(等于解绑到渲染到默认的帧缓冲中)
            m_Framebuffer->Bind();
            // 2.正常渲染图形(将本由OpenGL渲染在屏幕上的图像写入到自定义的帧缓冲中(不再是**默认的帧缓冲**中))
            Hazel::RenderCommand::SetClearColor({
          
           0.1f, 0.1f, 0.1f, 1 });
            Hazel::RenderCommand::Clear();
    		......
            Hazel::Renderer2D::DrawrRotatedQuad({
          
           1.0f, 0.5f }, {
          
           0.8f, 0.8f },30.0f, m_FlatColor);
            Hazel::Renderer2D::DrawQuad({
          
           -1.0f, 0.0f }, {
          
           0.8f, 0.8f }, m_FlatColor);
           .......
            // 3.解绑帧缓冲
            m_Framebuffer->Unbind();
        }
        ......
    
  • Imgui renders a custom framebuffer

    ImGui::Begin("Settings");
    auto stats = Hazel::Renderer2D::GetStats();
    ImGui::Text("Renderer2D Stats:");
    ImGui::Text("Draw Calls: %d", stats.DrawCalls);
    ImGui::Text("Quads: %d", stats.QuadCount);
    ImGui::Text("Vertices: %d", stats.GetTotalVertexCount());
    ImGui::Text("Indices: %d", stats.GetTotalIndexCount());
    
    ImGui::ColorEdit4("Square Color", glm::value_ptr(m_FlatColor));
    // 这里/
    // imgui渲染帧缓冲中的东西(附在帧缓冲上的颜色纹理缓冲)
    uint32_t textureID = m_Framebuffer->GetColorAttachmentRendererID();
    ImGui::Image((void*)textureID, ImVec2{
          
           1280, 720 });
    
    ImGui::End();
    
  • Effect

    Please add a picture description

test framebuffer

  • Do not unbind the framebuffer every frame

    The rendered framebuffer is a gray image

  • Create framebuffer without attaching depth, stencilbuffer textures

    Depth detection failed , the one drawn later overrides the one drawn earlier

    Please add a picture description

Guess you like

Origin blog.csdn.net/qq_34060370/article/details/132013378