Transforms

引言

上一节我们探讨了时间步长和一些时间问题,今天我们来加入 Transform 变换。

我们的下一步是考虑如何将对象放置在我们世界的不同地方。Transform 变换就像一个模型矩阵,本质上它就像一个世界矩阵,描述了位置、旋转和缩放变换。

大多数游戏引擎使用 ECS 架构作为组件系统,许多组件组合在一起形成一个游戏对象。很显然 Transfrom 实际上是一个组件,它是存储数据的地方。

Submit函数修改

修改 Infinite/Renderer/Renderer.h,输入参数加入 transform 矩阵:


@@ -13,7 +13,7 @@ namespace Infinite {
static void BeginScene(OrthographicCamera& camera);
static void EndScene();

- static void Submit(const std::shared_ptr<Shader>& shader, const std::shared_ptr<VertexArray>& vertexArray);
+ static void Submit(const std::shared_ptr<Shader>& shader, const std::shared_ptr<VertexArray>& vertexArray, const glm::mat4& transform = glm::mat4(1.0f));


inline static RendererAPI::API GetAPI() { return RendererAPI::GetAPI(); }

Renderer.cpp 也稍作修改:

	{
}

- void Renderer::Submit(const std::shared_ptr<Shader>& shader, const std::shared_ptr<VertexArray>& vertexArray)
+ void Renderer::Submit(const std::shared_ptr<Shader>& shader, const std::shared_ptr<VertexArray>& vertexArray, const glm::mat4& transform)
{
shader->Bind();
shader->UploadUniformMat4("u_ViewProjection", s_SceneData->ViewProjectionMatrix);
+ shader->UploadUniformMat4("u_Transform", transform);

vertexArray->Bind();
RenderCommand::DrawIndexed(vertexArray);

Shader修改

@@ -2,6 +2,8 @@

#include "../imgui/imgui.h"

+#include <glm/gtc/matrix_transform.hpp>

class ExampleLayer : public Infinite::Layer
{
public:
@@ -36,10 +38,10 @@ class ExampleLayer : public Infinite::Layer
m_SquareVertexArray.reset(Infinite::VertexArray::Create());

float squareVertices[3 * 4] = {
- -0.75f, -0.75f, 0.0f,
- 0.75f, -0.75f, 0.0f,
- 0.75f, 0.75f, 0.0f,
- -0.75f, 0.75f, 0.0f
+ -0.5f, -0.5f, 0.0f,
+ 0.5f, -0.5f, 0.0f,
+ 0.5f, 0.5f, 0.0f,
+ -0.5f, 0.5f, 0.0f
};
std::shared_ptr<Infinite::VertexBuffer> squareVertexBuffer;
squareVertexBuffer.reset(Infinite::VertexBuffer::Create(squareVertices, sizeof(squareVertices)));
@@ -62,6 +64,7 @@ class ExampleLayer : public Infinite::Layer
layout(location = 1) in vec4 a_Color;
uniform mat4 u_ViewProjection;
+ uniform mat4 u_Transform;
out vec3 v_Position;
out vec4 v_Color;
@@ -70,7 +73,7 @@ class ExampleLayer : public Infinite::Layer
{
v_Position = a_Position;
v_Color = a_Color;
- gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
+ gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0);
}
)";

@@ -99,12 +102,13 @@ class ExampleLayer : public Infinite::Layer
layout(location = 0) in vec3 a_Position;
uniform mat4 u_ViewProjection;
+ uniform mat4 u_Transform;
out vec3 v_Position;
void main()
{
v_Position = a_Position;
- gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
+ gl_Position = u_ViewProjection * u_Transform * vec4(a_Position, 1.0);
}
)";

@@ -131,12 +135,12 @@ class ExampleLayer : public Infinite::Layer
m_CameraPosition.x -= m_CameraMoveSpeed * ts;
else if (Infinite::Input::IsKeyPressed(IFN_KEY_RIGHT))
m_CameraPosition.x += m_CameraMoveSpeed * ts;


if (Infinite::Input::IsKeyPressed(IFN_KEY_DOWN))
m_CameraPosition.y -= m_CameraMoveSpeed * ts;
else if (Infinite::Input::IsKeyPressed(IFN_KEY_UP))
m_CameraPosition.y += m_CameraMoveSpeed * ts;


if (Infinite::Input::IsKeyPressed(IFN_KEY_A))
m_CameraRotation += m_CameraRotationSpeed * ts;
else if (Infinite::Input::IsKeyPressed(IFN_KEY_D))
@@ -151,7 +155,20 @@ class ExampleLayer : public Infinite::Layer

Infinite::Renderer::BeginScene(m_Camera);

- Infinite::Renderer::Submit(m_BlueShader, m_SquareVertexArray);
+ glm::mat4 scale = glm::scale(glm::mat4(1.0f), glm::vec3(0.1f));
+
+ for (int y = 0; y < 20; y++)
+ {
+ for (int x = 0; x < 20; x++)
+ {
+ glm::vec3 pos(x * 0.11f, y * 0.11f, 0.0f);
+ glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos) * scale;
+ Infinite::Renderer::Submit(m_BlueShader, m_SquareVertexArray, transform);
+ }
+ }



Infinite::Renderer::Submit(m_Shader, m_VertexArray);

Infinite::Renderer::EndScene();
@@ -183,7 +200,7 @@ class ExampleLayer : public Infinite::Layer
glm::vec3 m_CameraPosition;
float m_CameraRotation = 0.0f;
float m_CameraMoveSpeed = 5.0f;
- float m_CameraRotationSpeed = 180.0f;
+ float m_CameraRotationSpeed = 3.0f;
};

class Sandbox : public Infinite::Application {

调试