Haxel Engine learning 20-- OrthographicCamera

本文介绍了一个正交相机类的实现细节,包括如何根据相机的位置和旋转角度重新计算视图矩阵,并将其用于渲染流程中。文章还展示了如何在渲染循环中使用此相机的视图投影矩阵。

完整代码:https://github.com/DXT00/Hazel_study/tree/31a50ebca4a91220d1149858e0f1590d7000b303/Hazel

Uniform is per DrawCall

 

每次改变Camera的Position和rotation 都要更新 ViewMatrix

注意:ViewMatrix是 Camera的transform Matrix的逆矩阵(Camera上移,看到的物体下移,所以是相反的!)

OrthographicCamera.cpp

#include "hzpch.h"
#include "OrthographicCamera.h"
#include <glm/gtc/matrix_transform.hpp>
namespace Hazel {


	OrthographicCamera::OrthographicCamera(float left, float right, float bottom, float top)
		:m_ProjectionMatrix(glm::ortho(left,right,bottom,top,-1.0f,1.0f)),m_ViewMatix(glm::mat4(1.0f))
	{
		m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatix;
	}

	OrthographicCamera::~OrthographicCamera()
	{
	}

	void OrthographicCamera::RecalculateViewMatrix()
	{
		glm::mat4 transform = glm::translate(glm::mat4(1.0f), m_Position)*
			glm::rotate(glm::mat4(1.0f),glm::radians(m_Rotation) , glm::vec3(0, 0, 1));
		m_ViewMatix = glm::inverse(transform);
		m_ViewProjectionMatrix = m_ProjectionMatrix * m_ViewMatix;
	}

}

OrthographicCamera.h

#pragma once
#include "glm/glm.hpp"
namespace Hazel {
	class OrthographicCamera
	{
	public:
		OrthographicCamera(){}
		OrthographicCamera(float left, float right, float bottom, float top);
	
		void SetPosition(const glm::vec3& position) { m_Position = position; RecalculateViewMatrix(); }
		const glm::vec3& GetPosition() const{ return m_Position; }
		void SetRotation(float rotation) { m_Rotation = rotation; RecalculateViewMatrix(); }
		float GetRotation()const { return m_Rotation; }

		inline void SetViewMatrix(glm::mat4 view) {m_ViewMatix = view;}
		inline void SetProjectionMatrix(glm::mat4 projection) {m_ProjectionMatrix = projection;}
		inline void SetViewProjectionMatrix(glm::mat4 viewProjection) { m_ViewProjectionMatrix = viewProjection; }

		inline const glm::mat4 &GetViewMatrix()const { return m_ViewMatix; };
		inline const glm::mat4 &GetProjectionMatrix()const { return m_ProjectionMatrix; };
		inline const glm::mat4 &GetViewProjectionMatrix()const { return m_ViewProjectionMatrix; };


		~OrthographicCamera();
	private:
		void RecalculateViewMatrix();
	private:
		float m_zFar, m_zClose;
		float m_FOV;
		glm::vec3 m_Position = { 0.0f,0.0f,0.0f };
		glm::mat4 m_ViewMatix;// is the inverse of the transformMatrix of the Camera!
		glm::mat4 m_ProjectionMatrix;
		glm::mat4 m_ViewProjectionMatrix;

		float m_Rotation = 0.0f;//rotate along z axis


	};

}

Camera: 

transformMatrix =translateMatrix * rotateMatrix

Application::Run

void Application::Run()
	{
		while (m_Running)
		{
			
			RenderCommand::SetClearColor({ 0.1f, 0.1f, 0.1f, 1 });
			RenderCommand::Clear();
			Renderer::BeginScene(m_Camera);
			
			m_SquareShader->Bind();
			m_SquareShader->SetUniformMat4("u_ViewProjection", m_Camera.GetViewProjectionMatrix());
			Renderer::Submit(m_SquareVA);

			m_Shader->Bind();
			//glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first
			//glm::mat4 view = glm::mat4(1.0f);
			//glm::mat4 projection = glm::mat4(1.0f);
			//model = glm::rotate(model, (float)glfwGetTime(), glm::vec3(0.5f, 1.0f, 0.0f));
			//view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
			//projection = glm::perspective(glm::radians(45.0f), (float)m_Window->GetWidth() / (float)m_Window->GetHeight(), 0.1f, 100.0f);
			m_Shader->SetUniformMat4("u_ViewProjection", m_Camera.GetViewProjectionMatrix());
			
			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();
		}
	}

 把shader也加进submit里:

Renderer.h

#pragma once
#include "RenderCommand.h"
#include "Shader.h"
#include "OrthographicCamera.h"
namespace Hazel {

	class Renderer {
	public:
		static void BeginScene(OrthographicCamera &camera);
		static void EndScene();

		//dispatch to the RenderCommand,and submit it into Command Queue!
		static void Submit(const std::shared_ptr<VertexArray>& vertexArray, const std::shared_ptr<Shader>& shader);

		inline static RendererAPI::API GetAPI() { return RendererAPI::GetAPI(); }
	private:
		struct SceneData
		{
			glm::mat4 ViewProjectionMatrix;
		};
		static SceneData * s_SceneData;

	};

}

Renderer.cpp

#include "hzpch.h"
#include "Renderer.h"
#include "OrthographicCamera.h"

namespace Hazel {

	Renderer::SceneData *  Renderer::s_SceneData = new Renderer::SceneData;
	void Renderer::BeginScene(OrthographicCamera &camera)
	{
		s_SceneData->ViewProjectionMatrix = camera.GetViewProjectionMatrix();
	}

	void Renderer::EndScene()
	{

	}

	void Renderer::Submit(const std::shared_ptr<VertexArray>& vertexArray, const std::shared_ptr<Shader>& shader)
	{
		shader->Bind();
		shader->SetUniformMat4("u_ViewProjection", s_SceneData->ViewProjectionMatrix);
		vertexArray->Bind();
		RenderCommand::DrawIndex(vertexArray);

	}

}

Application::Run

void Application::Run()
	{
		while (m_Running)
		{
			
			RenderCommand::SetClearColor({ 0.1f, 0.1f, 0.1f, 1 });
			RenderCommand::Clear();
			m_Camera.SetPosition({0.5f,0.5f,0.0f});
			m_Camera.SetRotation(45);

			Renderer::BeginScene(m_Camera);
			
			/*m_SquareShader->Bind();
			m_SquareShader->SetUniformMat4("u_ViewProjection", m_Camera.GetViewProjectionMatrix());*/
			Renderer::Submit(m_SquareVA,m_SquareShader);

			/*m_Shader->Bind();
			m_Shader->SetUniformMat4("u_ViewProjection", m_Camera.GetViewProjectionMatrix());*/
			
			Renderer::Submit(m_VertexArray,m_Shader);

			

			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();
		}
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值