跟着cherno手搓游戏引擎【27】升级2DRenderer(添加旋转)

水节,添加了旋转的DrawQuad:

Renderer2D.h:

cpp 复制代码
#pragma once
#include "OrthographicCamera.h"
#include"Texture.h"
namespace YOTO {
	class Renderer2D
	{
	public:
		//为什么渲染器是静态的:
		static void Init();
		static void ShutDown();
		static void BeginScene(const OrthographicCamera& camera);
		static void EndScene();

		static void DrawQuad(const glm::vec2& position, const glm::vec2& size ,const glm::vec4& color);
		static void DrawQuad(const glm::vec3& position, const glm::vec2& size ,const glm::vec4& color);
		static void DrawQuad(const glm::vec2& position, const glm::vec2& size ,const Ref<Texture2D> texture,float tilingFactor=1.0f,const glm::vec4& tintColor=glm::vec4(1.0f));
		static void DrawQuad(const glm::vec3& position, const glm::vec2& size ,const Ref<Texture2D> texture,float tilingFactor=1.0f,const glm::vec4& tintColor=glm::vec4(1.0f));

		static void DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation,const glm::vec4& color);
		static void DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation,const glm::vec4& color);
		static void DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation,const Ref<Texture2D> texture, float tilingFactor = 1.0f,  const glm::vec4& tintColor = glm::vec4(1.0f));
		static void DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation,const Ref<Texture2D> texture, float tilingFactor = 1.0f, const glm::vec4& tintColor = glm::vec4(1.0f));
	};
}

Renderer2D.cpp:

cpp 复制代码
#include "ytpch.h"
#include "Renderer2D.h"
#include"VertexArray.h"
#include"Shader.h"
//#include "Platform/OpenGL/OpenGLShader.h"
#include <glm/gtc/matrix_transform.hpp>
#include "RenderCommand.h"
namespace YOTO {
	struct  Renderer2DStorage {
		Ref<VertexArray> QuadVertexArray;
		//Ref<Shader> FlatColorShader;
		Ref<Shader> TextureShader;
		Ref<Texture2D> WhiteTexture;
	};
	static Renderer2DStorage* s_Data;
	void Renderer2D::Init()
	{
		YT_PROFILE_FUNCTION();
		s_Data = new  Renderer2DStorage();
		s_Data->QuadVertexArray = VertexArray::Create();

		float squareVertices[5 * 4] = {
			-0.5f,-0.5f,0.0f,0.0f,0.0f,
			0.5f,-0.5f,0.0f,1.0f,0.0f,
			0.5f,0.5f,0.0f,1.0f,1.0f,
			-0.5f,0.5f,0.0f,0.0f,1.0f,
		};
		Ref<VertexBuffer> squareVB;
		squareVB.reset(VertexBuffer::Create(squareVertices, sizeof(squareVertices)));
		squareVB->SetLayout({
			{ShaderDataType::Float3,"a_Position"},
				{ShaderDataType::Float2,"a_TexCoord"}
			});
		s_Data->QuadVertexArray->AddVertexBuffer(squareVB);
		uint32_t squareIndices[6] = { 0,1,2,2,3,0 };
		Ref<IndexBuffer> squareIB;

		squareIB.reset((IndexBuffer::Create(squareIndices, sizeof(squareIndices) / sizeof(uint32_t))));

		s_Data->QuadVertexArray->AddIndexBuffer(squareIB);

		s_Data->WhiteTexture = Texture2D::Create(1, 1);
		uint32_t whiteTextureData = 0xffffffff;
		s_Data->WhiteTexture->SetData(&whiteTextureData,sizeof(uint32_t));

		//s_Data->FlatColorShader =Shader::Create("assets/shaders/FlatColor.glsl");
		s_Data->TextureShader= Shader::Create("assets/shaders/Texture.glsl");
		s_Data->TextureShader->Bind();
		s_Data->TextureShader->SetInt("u_Texture", 0);

	}
	void Renderer2D::ShutDown()
	{
		YT_PROFILE_FUNCTION();
		delete s_Data;
	}
	void Renderer2D::BeginScene(const OrthographicCamera& camera)
	{
		YT_PROFILE_FUNCTION();
		/*s_Data->FlatColorShader->Bind();
		s_Data->FlatColorShader->SetMat4("u_ViewProjection",camera.GetViewProjectionMatrix());*/
		s_Data->TextureShader->Bind();
		s_Data->TextureShader->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
	
	}
	void Renderer2D::EndScene()
	{
		YT_PROFILE_FUNCTION();
	}
	void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const glm::vec4& color)
	{
		DrawQuad({ position.x,position.y,0.0f }, size, color);
	}
	void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const glm::vec4& color)
	{
		YT_PROFILE_FUNCTION();
		//s_Data->FlatColorShader->Bind();
		//s_Data->FlatColorShader->SetFloat4("u_Color", color);
		//s_Data->TextureShader->Bind();
		s_Data->TextureShader->SetFloat4("u_Color", color);
		s_Data->TextureShader->SetFloat("m_TilingFactor", 1.0f);
		s_Data->WhiteTexture->Bind();

		glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) /**rotation*/ * glm::scale(glm::mat4(1.0f), {size.x,size.y,1.0f});
		s_Data->TextureShader->SetMat4("u_Transform", transform);
		s_Data->QuadVertexArray->Bind();
		RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
	}
	void Renderer2D::DrawQuad(const glm::vec2& position, const glm::vec2& size, const Ref<Texture2D> texture,  float tilingFactor, const glm::vec4& tintColor)
	{
		DrawQuad({ position.x,position.y,0.0f }, size, texture, tilingFactor, tintColor);
	}
	void Renderer2D::DrawQuad(const glm::vec3& position, const glm::vec2& size, const Ref<Texture2D> texture, float tilingFactor, const glm::vec4& tintColor)
	{
		YT_PROFILE_FUNCTION();
		//s_Data->TextureShader->Bind();
		s_Data->TextureShader->SetFloat4("u_Color", tintColor);
		s_Data->TextureShader->SetFloat("m_TilingFactor",tilingFactor);
		texture->Bind();


		glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) /**rotation*/ * glm::scale(glm::mat4(1.0f), { size.x,size.y,1.0f });
		s_Data->TextureShader->SetMat4("u_Transform", transform);

		s_Data->QuadVertexArray->Bind();
		RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
		
	}
	void Renderer2D::DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const glm::vec4& color)
	{
		DrawRotatedQuad({ position.x,position.y,0.0f }, size, rotation,color);
	}
	void Renderer2D::DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const glm::vec4& color)
	{
		YT_PROFILE_FUNCTION();

		s_Data->TextureShader->SetFloat4("u_Color", color);
		s_Data->TextureShader->SetFloat("m_TilingFactor", 1.0f);
		s_Data->WhiteTexture->Bind();

		glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::rotate(glm::mat4(1.0f), rotation, {0.0f,0.0f,1.0f}) * glm::scale(glm::mat4(1.0f), { size.x,size.y,1.0f });
		s_Data->TextureShader->SetMat4("u_Transform", transform);
		s_Data->QuadVertexArray->Bind();
		RenderCommand::DrawIndexed(s_Data->QuadVertexArray);

	}
	void Renderer2D::DrawRotatedQuad(const glm::vec2& position, const glm::vec2& size, float rotation, const Ref<Texture2D> texture, float tilingFactor, const glm::vec4& tintColor)
	{
		DrawRotatedQuad({ position.x,position.y,0.0f }, size, rotation, texture, tilingFactor, tintColor);
	}
	void Renderer2D::DrawRotatedQuad(const glm::vec3& position, const glm::vec2& size, float rotation, const Ref<Texture2D> texture, float tilingFactor, const glm::vec4& tintColor)
	{
		YT_PROFILE_FUNCTION();
		//s_Data->TextureShader->Bind();
		s_Data->TextureShader->SetFloat4("u_Color", tintColor);
		s_Data->TextureShader->SetFloat("m_TilingFactor", tilingFactor);
		texture->Bind();


		glm::mat4 transform = glm::translate(glm::mat4(1.0f), position) * glm::rotate(glm::mat4(1.0f), rotation, { 0.0f,0.0f,1.0f }) * glm::scale(glm::mat4(1.0f), { size.x,size.y,1.0f });
		s_Data->TextureShader->SetMat4("u_Transform", transform);

		s_Data->QuadVertexArray->Bind();
		RenderCommand::DrawIndexed(s_Data->QuadVertexArray);
	}
}

OpenGLShader.h:添加SetFloat(父类Shader.h也要添加):

cpp 复制代码
	void OpenGLShader::SetFloat(const std::string& name, float value)
	{
		YT_PROFILE_FUNCTION();
		UploadUniformFloat(name, value);
	}

修改测试:

Texture.glsl:

cpp 复制代码
		#type vertex
		#version 330 core
		layout(location = 0) in vec3 a_Position;
		layout(location = 1) in vec2 a_TexCoord;

		uniform mat4 u_ViewProjection;
		uniform mat4 u_Transform;
		
		out vec2 v_TexCoord;
		out vec3 v_Position;

		void main(){
		v_TexCoord=a_TexCoord;
		v_Position=a_Position;
		gl_Position =u_ViewProjection*u_Transform*vec4( a_Position,1.0);
		}

		#type fragment
		#version 330 core
		layout(location = 0) out vec4 color;
		in vec3 v_Position;
	
		in vec2 v_TexCoord;

		uniform vec4 u_Color ;
		uniform float m_TilingFactor;
		uniform sampler2D u_Texture ;
		void main(){
		color = texture(u_Texture, v_TexCoord*m_TilingFactor)*u_Color;	
		}
		

Sandbox2D.cpp:

cpp 复制代码
#include "Sandbox2D.h"
#include <imgui/imgui.h>
#include <glm/gtc/matrix_transform.hpp>
//#include <Platform/OpenGL/OpenGLShader.h>
#include <glm/gtc/type_ptr.hpp>
#include<vector>
#include<chrono>
template<typename Fn>
class Timer {
public:
	Timer(const char* name, Fn&&func)
		:m_Name(name),m_Func(func),m_Stopped(false)
	{
		m_StartTimepoint = std::chrono::high_resolution_clock::now();
	}
	~Timer() {
		if (!m_Stopped) {
			Stop();
		}
	}
	void Stop() {
		auto endTimepoint= std::chrono::high_resolution_clock::now();
		long long start = std::chrono::time_point_cast<std::chrono::microseconds>(m_StartTimepoint).time_since_epoch().count();
		long long end = std::chrono::time_point_cast<std::chrono::microseconds>(endTimepoint).time_since_epoch().count();
		m_Stopped = true;
		float duration = (end - start)*0.001f;
		m_Func({m_Name,duration});
		//std::cout << "Timer:"<< m_Name << "时差:" << duration << "ms" << std::endl;
	}
private:
	const char* m_Name;
	std::chrono::time_point<std::chrono::steady_clock>m_StartTimepoint;
	bool m_Stopped;
	Fn m_Func;
};
//未找到匹配的重载:auto的问题,改回原来的类型就好了
#define PROFILE_SCOPE(name) Timer timer##__LINE__(name,[&](ProfileResult profileResult) {m_ProfileResults.push_back(profileResult);})
Sandbox2D::Sandbox2D()
:Layer("Sandbox2D"), m_CameraController(1280.0f / 720.0f, true) 
{
}
void Sandbox2D::OnAttach()
{
	YT_PROFILE_FUNCTION();
	m_CheckerboardTexture = YOTO::Texture2D::Create("assets/textures/Checkerboard.png");

}
void Sandbox2D::OnDetach()
{
	YT_PROFILE_FUNCTION();
}

void Sandbox2D::OnUpdate(YOTO::Timestep ts)
{
	YT_PROFILE_FUNCTION();
		//update
		m_CameraController.OnUpdate(ts);
	
	
	{
		YT_PROFILE_SCOPE("Sandbox2D::Renderer Prep");
		//Render
		YOTO::RenderCommand::SetClearColor({ 0.2f, 0.2f, 0.2f, 1.0f });
		YOTO::RenderCommand::Clear();
	}
	
	{
		YT_PROFILE_SCOPE("Sandbox2D::Renderer Draw");
		YOTO::Renderer2D::BeginScene(m_CameraController.GetCamera());
		{
			static glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f));
			glm::vec4  redColor(0.8f, 0.3f, 0.3f, 1.0f);
			glm::vec4  blueColor(0.2f, 0.3f, 0.8f, 1.0f);


			/*std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_FlatColorShader)->Bind();
			std::dynamic_pointer_cast<YOTO::OpenGLShader>(m_FlatColorShader)->UploadUniformFloat4("u_Color", m_SquareColor);
			YOTO::Renderer::Submit(m_FlatColorShader, m_SquareVA, glm::scale(glm::mat4(1.0f), glm::vec3(1.5f)));*/

			YOTO::Renderer2D::DrawRotatedQuad({ -1.0f,0.0f }, { 0.8f,0.8f }, glm::radians(45.0f),{ 0.8f,0.2f,0.3f,1.0f });
			YOTO::Renderer2D::DrawQuad({ 0.5f,-0.5f }, { 0.5f,0.75f }, { 0.2f,0.3f,0.8f,1.0f });
			YOTO::Renderer2D::DrawQuad({ 0.0f,0.0f,-0.1f }, { 10.0f,10.0f }, m_CheckerboardTexture,10.0f,glm::vec4(1.0f,0.9f,0.9f,1.0f));
			YOTO::Renderer2D::EndScene();
		}
	}
	
}
void Sandbox2D::OnImGuiRender()
{
	YT_PROFILE_FUNCTION();
	ImGui::Begin("Setting");
	ImGui::ColorEdit4("Color", glm::value_ptr(m_SquareColor));
	for (auto& res : m_ProfileResults) {
		char lable[50];
		strcpy(lable, "%.3fms  ");
		strcat(lable, res.Name);
		ImGui::Text(lable, res.Time);
	}
	m_ProfileResults.clear();
	ImGui::End();
}

void Sandbox2D::OnEvent(YOTO::Event& e)
{
	YT_PROFILE_FUNCTION();
	m_CameraController.OnEvent(e);
}
相关推荐
郑寿昌9 小时前
UE5与UE6在Lumen和Nanite的差异解析
游戏引擎·图形渲染·着色器
郑寿昌19 小时前
UE6 AI加速Lumen光线追踪降噪技术解析
人工智能·游戏引擎
晴夏。19 小时前
GAS下的网络同步的全面分析【超级全面】
游戏引擎·ue·gas·网络同步
田鸡_19 小时前
Unity新输入系统(Input System)教学篇
unity·游戏引擎·游戏程序
EQ-雪梨蛋花汤19 小时前
【Unity笔记】Unity 音游模板与免费资源:高效构建节奏游戏开发全指南
笔记·unity·游戏引擎
微莱羽墨19 小时前
零、0基础入门Unity 安装详细教程(2026最新版教程,安装Unity看这一篇就够了!)
unity·游戏引擎·unity安装
nnsix20 小时前
Unity 刚体的 默认力、瞬时力 区别
unity·游戏引擎
nnsix20 小时前
Unity Sprite的 Generate Physics Shape 参数解释
unity·游戏引擎
魔士于安21 小时前
Unity完整小球迷宫项目
前端·unity·游戏引擎·贴图·模型
め.21 小时前
Unity协程的原理
unity·游戏引擎