If there are errors in the code, terminology, etc. in the text, please correct me
Article directory
foreword
-
of this program
The original function code at the beginning of OpenGL->gl exists in the Application drawing layer, and I want to delete it, and use the encapsulated rendering architecture to call the drawcall command (glDrawElements).
-
Before the renderer architecture is abstracted, it is necessary to discuss its working method in order to better design
-
what is needed to render an object
Material information, transformation matrix information, etc.
-
what is needed to render a scene
Light information, environment information, cameras, etc.
-
The approximate process of rendering two objects in a scene
-
word description
Draw a scene, and there are two objects in this scene, you should view the scene from a camera , the scene is responsible for rendering two objects, and rendering these two objects has the environment information and light information of the common scene
-
summary description
Start the scene (set the information of the scene) -> draw the object (set the information of the object = submit the object to the scene) -> end the scene
The step after ending the scene represents the objects submitted to the scene to be rendered.
-
In a multi-threaded game engine, after the end scene
Does not render immediately, but is submitted to the rendering, just like the command queue, can be calculated on a separate rendering thread
-
-
-
-
API design
// 光、环境、摄像机暂未有,这里只是一个通用设计 Renderer::BeginScene(camera, lights, environment); m_Shader1->Bind(); Renderer::Submit(VertexArray1);// 给场景提交要渲染的物体 m_Shader2->Bind(); Renderer::Submit(VertexArray2);// 给场景提交要渲染的物体 Renderer::EndScene(); Renderer::Flush();
-
The class diagram after completing this section
explain:
-
dynamic polymorphism
RendererCommand has static RendererAPI*. In cpp, according to the selected rendering API, the base class pointer can point to subclass objects OpenGlRendererAPI, D3DRendererAPI, and dynamic polymorphism of C++.
-
This section does not write the D3DRendererAPI class, but for completeness, the class diagram is still drawn like this
-
project related
code modification
-
RenderCommand
#pragma once #include "RendererAPI.h" namespace Hazel { class RenderCommand{ public: inline static void SetClearColor(const glm::vec4& color){ s_RendererAPI->SetClearColor(color); } inline static void Clear(){ s_RendererAPI->Clear(); } inline static void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray){ s_RendererAPI->DrawIndexed(vertexArray); } private: static RendererAPI* s_RendererAPI; }; }
#include "hzpch.h" #include "RenderCommand.h" #include "Platform/OpenGL/OpenGLRendererAPI.h" namespace Hazel { // 默认先指向OpenGLRendererAPI子类 RendererAPI* RenderCommand::s_RendererAPI = new OpenGLRendererAPI; // 基类指针指向子类对象 }
-
Renderer
#pragma once #include "RenderCommand.h" namespace Hazel { class Renderer{ public: static void BeginScene(); // 开始场景 static void EndScene(); // 结束场景 static void Submit(const std::shared_ptr<VertexArray>& vertexArray);// 提交物体的顶点数组 inline static RendererAPI::API GetAPI() { return RendererAPI::GetAPI(); } }; }
#include "hzpch.h" #include "Renderer.h" namespace Hazel { void Renderer::BeginScene(){ } void Renderer::EndScene(){ } void Renderer::Submit(const std::shared_ptr<VertexArray>& vertexArray){ vertexArray->Bind(); // 顶点数组绑定 RenderCommand::DrawIndexed(vertexArray);// 调用drawcall } }
-
Renderer API
#pragma once #include <glm/glm.hpp> #include "VertexArray.h" namespace Hazel { class RendererAPI{ public: enum class API{ None = 0, OpenGL = 1 }; public: virtual void SetClearColor(const glm::vec4& color) = 0; // 设置清除后的颜色 virtual void Clear() = 0; // 清除哪些缓冲 virtual void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray) = 0; inline static API GetAPI() { return s_API; } private: static API s_API; }; }
#include "hzpch.h" #include "RendererAPI.h" namespace Hazel { RendererAPI::API RendererAPI::s_API = RendererAPI::API::OpenGL; }
-
OpenGLRendererAPI
#pragma once #include "Hazel/Renderer/RendererAPI.h" namespace Hazel { class OpenGLRendererAPI : public RendererAPI{ public: virtual void SetClearColor(const glm::vec4& color) override;// 设置清除后的颜色 virtual void Clear() override; // 清除哪些缓冲 // 通过顶点数组绘制 virtual void DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray) override; }; }
#include "hzpch.h" #include "OpenGLRendererAPI.h" #include <glad/glad.h> namespace Hazel { void OpenGLRendererAPI::SetClearColor(const glm::vec4& color){ glClearColor(color.r, color.g, color.b, color.a); } void OpenGLRendererAPI::Clear(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } void OpenGLRendererAPI::DrawIndexed(const std::shared_ptr<VertexArray>& vertexArray){ glDrawElements(GL_TRIANGLES, vertexArray->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr); } }
-
Application
void Application::Run(){ while (m_Running){ / RenderCommand::SetClearColor({ 0.1f, 0.1f, 0.1f, 1 }); RenderCommand::Clear(); Renderer::BeginScene(); // 绘制四边形 m_BlueShader->Bind();// 绑定着色器 Renderer::Submit(m_SquareVA); // 绘制三角形 m_Shader->Bind();// 绑定着色器 Renderer::Submit(m_VertexArray); Renderer::EndScene(); .......
Effect
Unchanged