Cherno视频:https://www.youtube.com/watch?v=akxevYYWd9g&list=PLlrATfBNZ98dC-V-N3m0Go4deliWHPFwT&index=33
完整代码:https://github.com/DXT00/Hazel_study/tree/c63132b50cd6a94d151cab2faff84b9ec15c310b
A Renderer : (比如渲染一个 3D Cube)
分为两部分:
1.The Object
2.The Environment
需要一下这些:
1.The Object
A VertexBuffer-->定义顶点属性
A IndexBuffer-->定义顶点间的关系
A Shader--->着色
2.The Environment
A Camera System (A Projection Matrix and A View Matrix)
The position of the Cube in World Space (A Transformation Matrix)
Surface Material
Environment (lights) irradiance map
Command:
1.Renderer.BeginSences(lights,camera,environment)
-- include Camera and Environment
2.Dispatch DrawCall (DrawCall 调度,通过Command队列)
Renderer.SubmitGeo()
Renderer.SubmitMesh()
......
3.Renderer.EndSences()
原Application::Run:
void Application::Run()
{
while (m_Running)
{
glClearColor(0.1f, 0.1f, 0.1f, 1);
glClear(GL_COLOR_BUFFER_BIT);
m_SquareShader->Bind();
m_SquareVA->Bind();
glDrawElements(GL_TRIANGLES, m_SquareVA->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr);
m_Shader->Bind();
m_VertexArray->Bind();
glDrawElements(GL_TRIANGLES, m_VertexArray->GetIndexBuffer()->GetCount(), GL_UNSIGNED_INT, nullptr);
for (Layer* layer : m_LayerStack)
layer->OnUpdate();
m_ImGuiLayer->Begin();
for (Layer* layer : m_LayerStack)
layer->OnImGuiRender();
m_ImGuiLayer->End();
m_Window->OnUpdate();
}
}
现添加Renderer:
void Application::Run()
{
while (m_Running)
{
RendereCommand::SetClearColor();
RendereCommand::Clear();
Renderer::BeginScene();
m_SquareShader->Bind();
m_SquareVA->Bind();
Renderer::Submit(m_SquareVA);
m_Shader->Bind();
m_VertexArray->Bind();
Renderer::Submit(m_VertexArray);
Renderer::EndScene();
for (Layer* layer : m_LayerStack)
layer->OnUpdate();
m_ImGuiLayer->Begin();
for (Layer* layer : m_LayerStack)
layer->OnImGuiRender();
m_ImGuiLayer->End();
m_Window->OnUpdate();
}
}
3个类:
Renderer --->RenderCommand--->RendererAPI
Renderer 提交渲染命令给RenderCommand
RenderCommand通过调用RendererAPI执行渲染命令!
Renderer.h
#pragma once
#include "RenderCommand.h"
namespace Hazel {
class Renderer {
public:
static void BeginScene();
static void EndScene();
//dispatch to the RenderCommand,and submit it into Command Queue!
static void Submit(const std::shared_ptr<VertexArray>& vertexArray);
inline static RendererAPI::API GetAPI() { return RendererAPI::GetAPI(); }
};
}
RenderCommand.h 每个命令只执行一个操作!RenderCommand包含指向一个RendererAPI的指针
#pragma once
#include"RendererAPI.h"
namespace Hazel {
//static wrapper for the actual implementation
//One Command do one thing!
class RenderCommand
{
public:
inline static void DrawIndex(const std::shared_ptr<VertexArray>& vertexArray) {
s_RenderAPI->DrawIndex(vertexArray);
}
inline static void SetClearColor(const glm::vec4& color) {
s_RenderAPI->SetClearColor(color);
}
inline static void Clear() {
s_RenderAPI->Clear();
}
private:
//包含指向一个RendererAPI的指针,这个指针可以指向OpenGLRendererAPI,或者DirectXRendrerAPI...
//s_RenderAPI is a pointer to a class with no member! so it is just one Byte memery leak
static RendererAPI* s_RenderAPI;
};
}
RenderCommand.cpp:
#include "hzpch.h"
#include "RenderCommand.h"
#include "Platform/OpenGL/OpenGLRendererAPI.h"
namespace Hazel {
RendererAPI* RenderCommand::s_RenderAPI = new OpenGLRendererAPI;
}
RendererAPI.h是个抽象类,子类由OpenGLRendererAPI, DirectXRendererAPI..
#pragma once
#include "VertexArray.h"
#include "glm/glm.hpp"
namespace Hazel {
class RendererAPI //just an Interface 抽象类
{
public:
enum class API {
None = 0, OpenGL = 1
};
RendererAPI();
virtual ~RendererAPI();
static const API &GetAPI(){return s_API;}
virtual void SetClearColor(const glm::vec4& color) = 0;
virtual void Clear() = 0;
virtual void DrawIndex(const std::shared_ptr<VertexArray> &vertexArray)=0;
private:
static API s_API;
};
}
Application.cpp
void Application::Run()
{
while (m_Running)
{
RenderCommand::SetClearColor({ 0.1f, 0.1f, 0.1f, 1 });
RenderCommand::Clear();
Renderer::BeginScene();
m_SquareShader->Bind();
Renderer::Submit(m_SquareVA);
m_Shader->Bind();
Renderer::Submit(m_VertexArray);
Renderer::EndScene();
for (Layer* layer : m_LayerStack)
layer->OnUpdate();
m_ImGuiLayer->Begin();
for (Layer* layer : m_LayerStack)
layer->OnImGuiRender();
m_ImGuiLayer->End();
m_Window->OnUpdate();
}
}
F5成功运行: