完整代码:
https://github.com/DXT00/Hazel_study/tree/cc47879c0c24156514b93c9dcdcdc23cf46bc4ac/Hazel
Camera属性:
position(x,y,z),rotation(a1,a2,a3)Field of view(FOV)
respect ratio
position,rotation : View matrix -->the Inverse transform of the actual camera (view transform 和camera transform是相反的!比如 camera向左移,看到的Object就会向右移 OpenGL by itself is not familiar with the concept of a camera, but we can try to simulate one by moving all objects in the scene in the reverse direction, giving the illusion that we are moving. )
respect ratio : Projection matrix
所以最终像素点的位置 : gl_Position = (Projection matrix * View matrix * Model Matrix)* VertexPosition
Model Matrix : Object的转换矩阵
相机位置固定 --->Projection matrix * View matrix 固定
Model Matrix --->每个Object不一样
Projection matrix * View matrix ---> VP matrix
Projection matrix * View matrix * Model Matrix ---> MVP matrix
如果 VP * Model * vertex 写到shader里,那每个vertex都要乘一次
VP是个定值
可以这样:
把VP matrix 通过Uniform写入Shader
MyCode:
添加Camera类:
#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; }
inline void SetViewMatrix(glm::mat4 view) { m_ViewMatix = view; }
inline void SetProjectionMatrix(glm::mat4 projection) { m_ProjectionMatrix = projection; }
inline const glm::mat4 &GetViewMatrix()const { return m_ViewMatix; };
inline const glm::mat4 &GetProjectionMatrix()const { return m_ProjectionMatrix; };
~OrthographicCamera();
private:
float m_zFar, m_zClose;
float m_FOV;
glm::vec3 m_Position;
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
};
}
Shader中添加 view,projection,model矩阵
const std::string vertexSrc = R"(
#version 330 core
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec4 a_Color;
out vec3 v_Position;
out vec4 v_Color;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
v_Position = a_Position;
v_Color = a_Color;
gl_Position = projection*view*model*vec4(a_Position,1.0f);
}
)";
const std::string fragmentSrc = R"(
#version 330 core
layout(location = 0) out vec4 color;
layout(location = 1) out vec4 color1;
in vec3 v_Position;
in vec4 v_Color;
void main()
{
color = v_Color;//vec4(v_Position*0.5+0.5, 1.0);
}
)";
渲染:
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();
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("view", view);
m_Shader->setUniformMat4("projection", projection);
m_Shader->setUniformMat4("model", model);
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.cpp添加SetUniform:
uint32_t Shader::GetUniformLocation(const std::string& name) const
{
return glGetUniformLocation(m_RendererID, name.c_str());
}
void Shader::setUniformMat4(const std::string &name, const glm::mat4 &mat) const
{
glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, &mat[0][0]);
}
}
F5运行,可以看到三角形绕轴 vec3(0.5f, 1.0f, 0.0f)旋转