Hazel游戏引擎(033)渲染器架构抽象

文中若有代码、术语等错误,欢迎指正

前言

  • 此节目的

    Application绘制层存在OpenGL->gl开头的原始函数代码,想删掉它,并用封装的渲染架构来调用drawcall命令(glDrawElements)。

  • 渲染器架构抽象前要讨论的工作方式才能更好设计

    • 渲染一个物体需要什么

      材质信息、转换矩阵信息等

    • 渲染一个场景需要什么

      光的信息、环境的信息、摄像机等

    • 渲染一个场景中两个物体的大概流程

      • 文字描述

        绘制一个场景,并且这个场景中有两个物体,应该是从一台相机上查看场景,场景负责渲染2个物体,渲染这2个物体拥有共有场景的环境信息、光的信息

      • 总结描述

        开始场景(设置场景的信息)->绘制物体(设置物体的信息=提交物体到场景)->结束场景

        结束场景后的一步代表提交到场景的物体要渲染。

        • 在多线程游戏引擎中,关于结束场景后

          不会立即渲染,只是被提交到渲染中,就像命令队列一样,可以在单独的渲染线程上进行计算

  • API设计

    // 光、环境、摄像机暂未有,这里只是一个通用设计
    Renderer::BeginScene(camera, lights, environment);
    m_Shader1->Bind();
    Renderer::Submit(VertexArray1);// 给场景提交要渲染的物体
    m_Shader2->Bind();
    Renderer::Submit(VertexArray2);// 给场景提交要渲染的物体
    Renderer::EndScene();
    Renderer::Flush();
    
  • 此节完成后的类图

    请添加图片描述

    解释:

    • 照样动态多态

      RendererCommand有静态RendererAPI*,在cpp中可以根据选择的渲染API,来基类指针指向子类对象OpenGlRendererAPI、D3DRendererAPI,C++的动态多态。

    • 此节并未写D3DRendererAPI类,但为了完整,还是这样画的类图

项目相关

代码修改

  • 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
    	}
    }
    
  • RendererAPI

    #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();
            .......
    

效果

没变

请添加图片描述

猜你喜欢

转载自blog.csdn.net/qq_34060370/article/details/131447268