Moving To SandBox
本节主要是将 Application 中的代码移到 SandBox 中,因为毕竟我们之后的所有操作都是在客户端上进行的。
在 Application 中,我们只进行每个 Layer 的 OnUpdate,然后其余部分全部转移到 SandBox 中实现。
while (m_Running)
{
for (Layer* layer : m_LayerStack)
layer->OnUpdate();
m_ImGuiLayer->Begin();
for (Layer* layer : m_LayerStack)
layer->OnImGuiRender();
m_ImGuiLayer->End();
m_Window->OnUpdate();
}
}
为了在 SandBox 中使用各种在 Hazel 中定义的函数,需要在 Hazel.h
中添加一些头函数:
//--------Renderer ----------
#include "Hazel/Renderer/Renderer.h"
#include "Hazel/Renderer/RenderCommand.h"
#include "Hazel/Renderer/Buffer.h"
#include "Hazel/Renderer/Shader.h"
#include "Hazel/Renderer/VertexArray.h"
#include "Hazel/Renderer/OrthographicCamera.h"
//-----------------------------------------
在 ExampleLayer 中的 OnUpdate 进行场景加载和设置, 并且给函数加上命名空间:
Hazel::RenderCommand::SetClearColor({ 0.1f, 0.1f, 0.1f, 1 });
Hazel::RenderCommand::Clear();
m_Camera.SetPosition(m_CameraPosition);
m_Camera.SetRotation(m_CameraRotation);
Hazel::Renderer::BeginScene(m_Camera);
Hazel::Renderer::Submit(m_blueShader, m_SquareVA);
//m_Shader->Bind();
//m_Shader->UpLoadUniformMat4("u_ViewProjection", m_Camera.GetViewProjectionMatrix());
Hazel::Renderer::Submit(m_Shader, m_VertexArray);
Hazel::Renderer::EndScene();
ExampleLayer 中创建需要的成员变量:
private:
std::shared_ptr<Hazel::Shader> m_Shader;
std::shared_ptr<Hazel::VertexArray> m_VertexArray;
std::shared_ptr<Hazel::Shader> m_blueShader;
std::shared_ptr<Hazel::VertexArray> m_SquareVA;
Hazel::OrthographicCamera m_Camera;
glm::vec3 m_CameraPosition;
float m_CameraMoveSpeed = 0.1f; //控制相机移动
float m_CameraRotation = 0.0f;
float m_CameraRotationSpeed = 2.0f; //控制相机旋转
SandBox 类的构造函数中首先进行 Application构造函数的初始化:
SandBox()
:Application()
{
PushLayer(new ExampleLayer());
}
ExampleLayer 的构造函数中
ExampleLayer()
: Layer("Example"), m_Camera(-1.6f, 1.6f, -0.9f, 0.9f), m_CameraPosition(0.0f)
{
m_VertexArray.reset(Hazel::VertexArray::Create());
float vertices[3 * 7] = {
-0.5f, -0.5f, 0.0f, 0.8f, 0.2f, 0.8f, 1.0f,
0.5f, -0.5f, 0.0f, 0.2f, 0.3f, 0.8f, 1.0f,
0.0f, 0.5f, 0.0f, 0.3f, 0.8f, 0.0f, 1.0f
};
std::shared_ptr<Hazel::VertexBuffer> vertexBuffer;
vertexBuffer.reset(Hazel::VertexBuffer::Create(vertices, sizeof(vertices)));
Hazel::BufferLayout layout = {
{ Hazel::ShaderDataType::Float3, "a_Position", false},
{ Hazel::ShaderDataType::Float4, "a_Color", false}
};
vertexBuffer->SetLayout(layout);
m_VertexArray->AddVertexBuffer(vertexBuffer);
uint32_t indices[3] = { 0, 1, 2 };
std::shared_ptr<Hazel::IndexBuffer> indexBuffer;
indexBuffer.reset(Hazel::IndexBuffer::Create(indices, sizeof(indices) / sizeof(uint32_t)));
m_VertexArray->SetIndexBuffer(indexBuffer);
m_SquareVA.reset(Hazel::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
};
std::shared_ptr<Hazel::VertexBuffer> squareVB;
squareVB.reset(Hazel::VertexBuffer::Create(squareVertices, sizeof(squareVertices)));
squareVB->SetLayout({
{ Hazel::ShaderDataType::Float3, "a_Position", false }
});
m_SquareVA->AddVertexBuffer(squareVB);
uint32_t squareIndices[6] = { 0, 1, 2, 2, 3, 0 };
std::shared_ptr<Hazel::IndexBuffer> squareIB;
squareIB.reset(Hazel::IndexBuffer::Create(squareIndices, sizeof(squareIndices) / sizeof(uint32_t)));
m_SquareVA->SetIndexBuffer(squareIB);
std::string vertexSrc = R"(
#version 330 core
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec4 a_Color;
uniform mat4 u_ViewProjection;
out vec3 v_Position;
out vec4 v_Color;
void main()
{
v_Position = a_Position;
v_Color = a_Color;
gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
}
)";
std::string fragmentSrc = R"(
#version 330 core
layout(location = 0) out vec4 color;
in vec3 v_Position;
in vec4 v_Color;
void main()
{
color = v_Color;
}
)";
m_Shader.reset(new Hazel::Shader(vertexSrc, fragmentSrc));
std::string blue_vertexSrc = R"(
#version 330 core
layout(location = 0) in vec3 a_Position;
uniform mat4 u_ViewProjection;
out vec3 v_Position;
void main()
{
v_Position = a_Position;
gl_Position = u_ViewProjection * vec4(a_Position, 1.0);
}
)";
std::string blue_fragmentSrc = R"(
#version 330 core
layout(location = 0) out vec4 color;
in vec3 v_Position;
void main()
{
color = vec4(0.2, 0.3, 0.8, 1.0);
}
)";
m_blueShader.reset(new Hazel::Shader(blue_vertexSrc, blue_fragmentSrc));
}
然后我们想通过之前设置的 Input Polling 来控制相机进行移动和旋转,在 OnUpdate 中添加如下内容:
if (Hazel::Input::IsKeyPressed(HZ_KEY_LEFT))
m_CameraPosition.x -= m_CameraMoveSpeed;
else if (Hazel::Input::IsKeyPressed(HZ_KEY_RIGHT))
m_CameraPosition.x += m_CameraMoveSpeed;
if (Hazel::Input::IsKeyPressed(HZ_KEY_DOWN))
m_CameraPosition.y -= m_CameraMoveSpeed;
else if (Hazel::Input::IsKeyPressed(HZ_KEY_UP))
m_CameraPosition.y += m_CameraMoveSpeed;
if (Hazel::Input::IsKeyPressed(HZ_KEY_Q))
m_CameraRotation += m_CameraRotationSpeed;
else if (Hazel::Input::IsKeyPressed(HZ_KEY_E))
m_CameraRotation -= m_CameraRotationSpeed;
然后就可以控制相机移动了。
当然也可以通过 event 来实现,具体实现这里不多赘述。