If there are errors in the code, terminology, etc. in the text, please correct me
Article directory
foreword
- Introduction to framebuffer (my understanding)
- The scene rendered by OpenGL can be placed in this frame buffer
- This framebuffer can then be treated as a color or texture sampling area (depending on the type of buffer attachment attached to the framebuffer )
- 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
- Bind a custom framebuffer (equivalent to unbinding to render to the default framebuffer)
- Render graphics normally (write the image originally rendered on the screen by OpenGL to a custom framebuffer (no longer the default framebuffer ))
- 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
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