Skip to content

Instantly share code, notes, and snippets.

@hanhanxue
Created May 4, 2020 21:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hanhanxue/f235cfbea08b0e1db7cc828608643b1f to your computer and use it in GitHub Desktop.
Save hanhanxue/f235cfbea08b0e1db7cc828608643b1f to your computer and use it in GitHub Desktop.
Camera in OpenGL
#include "cameraEuler.h"
cameraEuler::cameraEuler(float width, float height)
: position(glm::vec3(5.0f, 5.0f, 5.0f)), pivot(glm::vec3(0.0f, 0.0f, 0.0f)), aspectRatio(width / height)
{
updateCamera();
}
void cameraEuler::home()
{
position = glm::vec3(5.0f, 5.0f, 5.0f);
pivot = glm::vec3(0.0f, 0.0f, 0.0f);
fov = 45.0f;
updateCamera();
}
void cameraEuler::tumble(float delta_xpos, float delta_ypos)
{
delta_xpos *= TUMBLE_SPEED;
delta_ypos *= -TUMBLE_SPEED;
if (pitch + glm::degrees(delta_ypos) > PITCH_CONSTRAINT_UPPER)
{
delta_ypos = glm::radians(PITCH_CONSTRAINT_UPPER - pitch);
}
else if (pitch + glm::degrees(delta_ypos) < PITCH_CONSTRAINT_LOWER)
{
delta_ypos = glm::radians(PITCH_CONSTRAINT_LOWER - pitch);
}
glm::mat4 m_tumble = glm::mat4(1.0f);
m_tumble = glm::rotate(m_tumble, -delta_xpos, WORLDUP); // rotate on world Y
m_tumble = glm::rotate(m_tumble, -delta_ypos, right); // rotate on target X
glm::mat4 m_pivot = glm::mat4(1.0f);
m_pivot = glm::translate(m_pivot, pivot);
position = m_pivot * m_tumble * glm::inverse(m_pivot) * glm::vec4(position, 1.0f);
updateCamera();
}
void cameraEuler::track(float delta_xpos, float delta_ypos)
{
delta_xpos *= -TRACK_SPEED;
delta_ypos *= -TRACK_SPEED;
glm::mat4 m_track = glm::mat4(1.0f);
m_track = glm::translate(m_track, right * delta_xpos);
m_track = glm::translate(m_track, up * delta_ypos);
pivot = m_track * glm::vec4(pivot, 1.0f);
position = m_track * glm::vec4(position, 1.0f);
updateCamera();
//printf("pivot: %f %f %f position: %f %f %f\n", pivot.x, pivot.y, pivot.z, position.x, position.y, position.z);
}
void cameraEuler::dolly(float delta_xpos, float delta_ypos)
{
delta_xpos *= -DOLLY_SPEED;
delta_ypos *= -DOLLY_SPEED;
glm::mat4 m_dolly = glm::mat4(1.0f);
m_dolly = glm::translate(m_dolly, front * (delta_ypos - delta_xpos));
position = m_dolly * glm::vec4(position, 1.0f);
frontSwitch = glm::dot(glm::normalize(pivot - position), front);
updateCamera();
}
void cameraEuler::zoom(float delta_xpos, float delta_ypos)
{
delta_xpos *= ZOOM_SPEED;
delta_ypos *= ZOOM_SPEED;
fov += delta_ypos - delta_xpos;
fov = glm::clamp(fov, MIN_FOV, MAX_FOV);
//printf("%f\n", fov);
updateCamera();
}
void cameraEuler::setAspectRatio(float width, float height)
{
aspectRatio = width / height;
updateCamera();
}
glm::mat4 cameraEuler::getPivotMatrix() const
{
glm::mat4 m_pivot = glm::mat4(1.0f);
m_pivot = glm::translate(m_pivot, pivot);
return m_pivot;
}
glm::mat4 cameraEuler::getViewMatrix() const
{
return view;
}
glm::mat4 cameraEuler::getProjectionMatrix() const
{
return projection;
}
void cameraEuler::updateCamera()
{
front = glm::normalize((pivot - position) * frontSwitch);
right = glm::normalize(glm::cross(front, WORLDUP));
up = glm::normalize(glm::cross(right, front));
pitch = glm::degrees(acos(glm::dot(front, WORLDUP)));
view = glm::lookAt(position, position + front, up);
projection = glm::perspective(glm::radians(fov), aspectRatio, 0.1f, 100.0f);
}
cameraEuler::~cameraEuler()
{
}
#pragma once
#include <glm\glm.hpp>
#include <glm\gtc\matrix_transform.hpp>
class cameraEuler
{
public:
cameraEuler(float width = 1280.0f, float height = 720.0f);
void home();
void tumble(float delta_xpos, float delta_ypos);
void track(float delta_xpos, float delta_ypos);
void dolly(float delta_xpos, float delta_ypos);
void zoom(float delta_xpos, float delta_ypos);
void setAspectRatio(float width, float height);
glm::mat4 getPivotMatrix() const;
glm::mat4 getViewMatrix() const;
glm::mat4 getProjectionMatrix() const;
~cameraEuler();
private:
const float TUMBLE_SPEED = 0.005f;
const float TRACK_SPEED = 0.005f;
const float DOLLY_SPEED = 0.005f;
const float ZOOM_SPEED = 0.05f;
const float PITCH_CONSTRAINT_UPPER = 179.9f;
const float PITCH_CONSTRAINT_LOWER = 0.1f;
const glm::vec3 WORLDUP = glm::vec3(0.0f, 1.0f, 0.0f);
const float MIN_FOV = 18.0f;
const float MAX_FOV = 120.0f;
float frontSwitch = 1.0f;
// Camera params
float pitch;
float aspectRatio;
float fov = 45.0f;
glm::vec3 pivot;
glm::vec3 position;
glm::vec3 front;
glm::vec3 up;
glm::vec3 right;
glm::mat4 view;
glm::mat4 projection;
void updateCamera();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment