2D Camera Works. Working on 3D Camera.

This commit is contained in:
elipzer 2018-09-12 09:46:55 -04:00
parent 90bac19849
commit ee7f2e4006
8 changed files with 96 additions and 25 deletions

View File

@ -6,21 +6,18 @@
using namespace glm;
class Camera : public Poseable
class Camera
{
public:
Camera(
const vec3& position,
const vec3& forward = vec3(0.0f, 0.0f, 1.0f),
const vec3& up = vec3(0.0f, 1.0f, 0.0f),
const vec3& right = vec3(1.0f, 0.0f, 0.0f)
) : Poseable(position, forward, up, right), m_projection_matrix(1.0f)
{}
Camera() : m_view_matrix(1.0f), m_projection_matrix(1.0f) {}
mat4x4 get_world_to_view_matrix() const { return m_projection_matrix * m_orientation_matrix; }
mat4x4 get_world_to_view_matrix() const { return m_projection_matrix * m_view_matrix; }
const mat4x4& get_view_matrix() const { return m_view_matrix; }
const mat4x4& get_projection_matrix() const { return m_projection_matrix; }
protected:
mat4x4 m_view_matrix;
mat4x4 m_projection_matrix;
};

View File

@ -6,7 +6,6 @@ Camera2D::Camera2D(const vec2& size, const vec2& position)
: Camera2D(vec3(size.x, size.y, 2.0f), vec3(position.x, position.y, 0.0f)) {}
Camera2D::Camera2D(const vec3& size, const vec3& position)
: Camera(position)
{
update_size(size);
update_position(position);
@ -21,18 +20,23 @@ void Camera2D::update_size(const vec3& size)
void Camera2D::update_position(const vec3& position)
{
m_position = position;
Poseable::update_position(-position);
}
void Camera2D::translate(const vec2& position)
void Camera2D::translate(const vec2& translation)
{
translate(vec3(position.x, position.y, 0.0f));
translate(vec3(translation.x, translation.y, 0.0f));
}
void Camera2D::translate(const vec3& position)
void Camera2D::translate(const vec3& translation)
{
m_position += position;
Poseable::translate(-position);
m_position += translation;
}
void Camera2D::prerender()
{
m_view_matrix[3][0] = -m_position.x;
m_view_matrix[3][1] = -m_position.y;
m_view_matrix[3][2] = -m_position.z;
}
void Camera2D::update_scale()

View File

@ -18,6 +18,8 @@ public:
void translate(const vec2& translation);
void translate(const vec3& translation);
void prerender();
const vec3& get_size() const { return m_size; }
const vec3& get_position() const { return m_position; }

View File

@ -12,9 +12,10 @@ Camera3D::Camera3D(
const vec3& up,
const vec3& right
)
: Camera(position, forward, up, right)
{
update_frustum(fov_y, aspect_ratio, znear, zfar);
update_position(position);
update_orientation(forward, up, right);
}
void Camera3D::update_frustum(float fov_y, float aspect_ratio, float znear, float zfar)
@ -22,8 +23,60 @@ void Camera3D::update_frustum(float fov_y, float aspect_ratio, float znear, floa
m_projection_matrix = glm::perspective(fov_y, aspect_ratio, znear, zfar);
}
void Camera3D::update_position(const vec3& position)
{
m_position = position;
}
void Camera3D::update_orientation(const vec3& forward, const vec3& up, const vec3& right)
{
vec3 real_forward;
vec3 real_up;
vec3 real_right;
if (right == vec3(0.0f))
real_right = glm::normalize(glm::cross(forward, up));
else
real_right = right;
real_forward = glm::normalize(forward);
real_up = glm::cross(real_right, real_forward);
m_forward = vec4(real_forward, 0.0f);
m_up = vec4(real_up, 0.0f);
m_right = vec4(real_right, 0.0f);
}
void Camera3D::direct_update_orientation(const vec3& forward, const vec3& up, const vec3& right)
{
m_forward = vec4(forward, 0.0f);
m_up = vec4(up, 0.0f);
m_right = vec4(right, 0.0f);
}
void Camera3D::translate(const vec3& translation)
{
m_position += translation;
Poseable::translate(-translation);
}
void Camera3D::rotate(const vec3& axis, float angle)
{
mat4 rotation = glm::rotate(mat4(1.0f), angle, axis);
m_forward = rotation * m_forward;
m_up = rotation * m_up;
m_right = rotation * m_right;
}
void Camera3D::prerender()
{
// This works but it is backwards.
m_view_matrix = glm::lookAt(m_position, m_position + vec3(m_forward), vec3(m_up));
/*
m_view_matrix = mat4(
vec4(m_right.x, m_up.x, -m_forward.x, 0.0f),
vec4(m_right.y, m_up.y, -m_forward.y, 0.0f),
vec4(m_right.z, m_up.z, -m_forward.z, 0.0f),
vec4(glm::dot(vec3(m_right), -m_position), glm::dot(vec3(m_up), -m_position), glm::dot(vec3(m_forward), -m_position), 1.0f)
);
*/
}

View File

@ -9,8 +9,6 @@ using namespace glm;
class Camera3D : public Camera
{
public:
// Creates a Camera3D.
// Will throw if direction, up, and right are not orthogonal
Camera3D(
float fov_y,
float aspect_ratio,
@ -19,18 +17,31 @@ public:
const vec3& position,
const vec3& forward = vec3(0.0f, 0.0f, 1.0f),
const vec3& up = vec3(0.0f, 1.0f, 0.0f),
const vec3& right = vec3(1.0f, 0.0f, 0.0f)
const vec3& right = vec3(0.0f) // Zero for auto-calculated
);
void update_frustum(float fov_y, float aspect_ratio, float znear, float zfar);
void update_position(const vec3& position);
// Updates the orientation based on three vectors.
// If right is equal to zero it is calculated with glm::cross(forward, up).
// Then the true up is calculated with glm::cross(right, forward)
void update_orientation(const vec3& forward = vec3(0.0f, 0.0f, 1.0f), const vec3& up = vec3(0.0f, 1.0f, 0.0f), const vec3& right = vec3(0.0f));
// Directly sets the forward, up, and right values.
void direct_update_orientation(const vec3& forward, const vec3& up, const vec3& right);
void translate(const vec3& translation);
void rotate(const vec3& axis, float angle);
void prerender();
const vec3& get_position() const { return m_position; }
vec3 get_forward() const { return vec3(m_orientation_matrix[2]); }
vec3 get_up() const { return vec3(m_orientation_matrix[1]); }
vec3 get_right() const { return vec3(m_orientation_matrix[0]); }
vec3 get_forward() const { return vec3(m_forward); }
vec3 get_up() const { return vec3(m_up); }
vec3 get_right() const { return vec3(m_right); }
private:
vec3 m_position;
vec4 m_forward;
vec4 m_up;
vec4 m_right;
};

View File

@ -90,6 +90,7 @@ void MySimple2DScene::update(float delta_time, clock_t clock)
m_camera.translate(camera_translation * delta_time * 100.0f);
// TODO: Make a prerender function or move this to render
m_camera.prerender();
m_batch.prerender();
}

View File

@ -92,6 +92,7 @@ void MySimple3DScene::update(float delta_time, clock_t clock)
m_camera.translate(camera_translation * delta_time);
// TODO: Make a prerender function or move this to render
m_camera.prerender();
m_batch.prerender();
}

View File

@ -19,7 +19,7 @@ MySimpleCubeScene::MySimpleCubeScene(Application& application)
MySimpleShaderProgram::Vertex( 1.0f, -1.0f, 1.0f)
), DrawMode::DRAW_TRIANGLES),
m_batch(&m_shape, 1),
m_camera((float)egm::TAU_1_4, (float)m_screen_size.x / m_screen_size.y, 1.0f, 10.0f, vec3(0.0f, 0.0f, -5.0f))
m_camera((float)egm::TAU_1_8, (float)m_screen_size.x / m_screen_size.y, 1.0f, 10.0f, vec3(0.0f, 0.0f, -5.0f))
{}
MySimpleCubeScene::~MySimpleCubeScene()
@ -65,6 +65,7 @@ void MySimpleCubeScene::update(float delta_time, clock_t clock)
color.a = 1.0f;
Poseable& pose = m_batch.get_pose(0);
pose.rotate(glm::normalize(vec3(1.0f, 1.0f, 0.0f)), (float)egm::TAU_1_2 * delta_time);
pose.update_position(vec3(3 * (float)cos(radians), 0.0f, 0.0f));
}
@ -80,6 +81,7 @@ void MySimpleCubeScene::update(float delta_time, clock_t clock)
m_camera.translate(camera_translation * delta_time);
// TODO: Make a prerender function or move this to render
m_camera.prerender();
m_batch.prerender();
}