That is a good point.
Here is my OpenGLCamera class (both header and implementation):
OpenGLCamera.h:
#ifndef OPENGLCAMERA_H_
#define OPENGLCAMERA_H_
#include <string>
#include <ctime>
#ifndef OPENGL_INCLUDES_
#define OPENGL_INCLUDES_
// include GLEW extension handling library
#include "GL/glew.h"
#endif
#ifndef GLM_INCLUDES_
#define GLM_INCLUDES_
#include <glm/glm.hpp>
#include <glm/gtx/rotate_vector.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/quaternion.hpp>
#endif
class OpenGLCamera;
class OpenGLCamera {
private:
protected:
glm::mat4 CurrentCameraMatrix;
glm::mat4 CurrentProjectionMatrix;
glm::vec3 CurrentCameraPosition;
glm::vec3 CurrentViewingPosition;
glm::vec3 CurrentCameraPositionDelta;
glm::vec3 CurrentViewingDirection;
glm::vec3 CurrentRightDirection;
glm::vec3 CurrentUpDirection;
glm::vec3 HomeCameraPosition;
GLfloat FieldOfView;
bool FixedAspectRatio;
GLfloat AspectRatio;
GLfloat NearPlane;
GLfloat FarPlane;
GLfloat CurrentMovementSpeed;
GLfloat CurrentMovementDamping;
GLfloat CurrentMouseMovementSpeed;
GLfloat HorizontalAngle;
GLfloat VerticalAngle;
GLfloat* deltaTime;
GLint* CurrentScreenWidth;
GLint* CurrentScreenHeight;
std::string NameOfCamera;
public:
OpenGLCamera();
OpenGLCamera(glm::vec3 InitialPosition);
~OpenGLCamera();
virtual void RecalibrateCamera();
virtual void SetCurrentMousePosition(double MouseX, double MouseY);
virtual void SetScreenPointers(GLint* WidthPointer, GLint* HeightPointer);
virtual void SetDeltaTimePointer(GLfloat* DeltaTimePointerToSet);
virtual void SetCameraPosition(glm::vec3 NewCameraPosition);
virtual void MoveToHomeCameraPosition();
virtual void SetHomeCameraPosition(glm::vec3 HomeCameraPositionToSet);
virtual void SetLookAt(glm::vec3 NewCameraLookAt);
virtual void SetUp(glm::vec3 NewCameraUp);
virtual void CalculateProjection();
virtual void CalculateView();
virtual void Calculate();
virtual void Calculate(GLint EyeToCalculate);
virtual GLfloat GetScreenScaleX();
virtual GLfloat GetScreenScaleY();
virtual glm::mat4 GetProjectionViewMatrix();
virtual glm::mat4* GetProjectionMatrixPointer();
virtual glm::mat4* GetViewMatrixPointer();
virtual glm::vec3* GetViewingDirection();
virtual glm::vec3* GetCurrentPosition();
virtual std::string GetName();
virtual void SetName(std::string CameraNameToSet);
virtual GLfloat CalculateAspectRatio();
virtual void SetFOVRadians(GLfloat FOV);
virtual void SetFOVDegrees(GLfloat FOV);
virtual void SetNearPlane(GLfloat NearPlaneToSet);
virtual void SetFarPlane(GLfloat FarPlaneToSet);
virtual void SetAspectRatio(GLfloat AspectRatioToSet);
virtual void RotateLeft();
virtual void RotateRight();
virtual void MoveFaster();
virtual void MoveSlower();
virtual void MoveUp();
virtual void MoveDown();
virtual void MoveForward();
virtual void MoveBackward();
virtual void MoveLeft();
virtual void MoveRight();
};
#endif
And here is the implementation:
#include "OpenGLCamera.h"
OpenGLCamera::OpenGLCamera() {
CurrentCameraMatrix = glm::mat4(1.0f);
CurrentProjectionMatrix = glm::mat4(1.0f);
FieldOfView = 55.0f;
FixedAspectRatio = false;
NearPlane = 1.0f;
FarPlane = 6000.0f;
CurrentMovementSpeed = 0.10f;
CurrentMovementDamping = 0.85f;
CurrentMouseMovementSpeed = 0.005f;
HorizontalAngle = 3.14f;
VerticalAngle = 0.0f;
CurrentCameraPosition = glm::vec3(0.0f, 0.0f, 0.0f);
CurrentViewingPosition = glm::vec3(0.0f, 0.0f, 0.0f);
CurrentCameraPositionDelta = glm::vec3(0.0f, 0.0f, 0.0f);
CurrentViewingDirection = glm::vec3(0.0f, 0.0f, 0.0f);
CurrentRightDirection = glm::vec3(0.0f, 0.0f, 0.0f);
CurrentUpDirection = glm::vec3(0.0f, 1.0f, 0.0f);
HomeCameraPosition = glm::vec3(0.0f, 0.0f, 0.0f);
}
OpenGLCamera::OpenGLCamera(glm::vec3 InitialPosition) {
CurrentCameraMatrix = glm::mat4(1.0f);
CurrentProjectionMatrix = glm::mat4(1.0f);
FieldOfView = 55.0f;
FixedAspectRatio = false;
NearPlane = 1.0f;
FarPlane = 1000.0f;
CurrentMovementSpeed = 0.10f;
CurrentMovementDamping = 0.85f;
CurrentMouseMovementSpeed = 0.005f;
HorizontalAngle = 3.14f;
VerticalAngle = 0.0f;
CurrentCameraPosition = InitialPosition;
CurrentCameraPositionDelta = glm::vec3(0.0f, 0.0f, 0.0f);
CurrentViewingDirection = glm::vec3(0.0f, 0.0f, 0.0f);
CurrentRightDirection = glm::vec3(0.0f, 0.0f, 0.0f);
CurrentUpDirection = glm::vec3(0.0f, 1.0f, 0.0f);
}
OpenGLCamera::~OpenGLCamera() {
}
void OpenGLCamera::RecalibrateCamera() {
HorizontalAngle = 0.0f;
VerticalAngle = 0.0f;
}
std::string OpenGLCamera::GetName() {
return NameOfCamera;
}
void OpenGLCamera::SetName(std::string CameraNameToSet) {
NameOfCamera = CameraNameToSet;
}
void OpenGLCamera::SetCameraPosition(glm::vec3 NewCameraPosition) {
CurrentCameraPosition = NewCameraPosition;
}
void OpenGLCamera::SetLookAt(glm::vec3 NewCameraLookAt) {
CurrentViewingDirection = NewCameraLookAt;
}
void OpenGLCamera::SetUp(glm::vec3 NewCameraUp) {
CurrentUpDirection = NewCameraUp;
}
void OpenGLCamera::SetScreenPointers(GLint* WidthPointer, GLint* HeightPointer) {
CurrentScreenWidth = WidthPointer;
CurrentScreenHeight = HeightPointer;
}
void OpenGLCamera::SetDeltaTimePointer(GLfloat* DeltaTimePointerToSet) {
deltaTime = DeltaTimePointerToSet;
}
void OpenGLCamera::SetCurrentMousePosition(double MouseX, double MouseY) {
GLfloat CurrentMouseX = (GLfloat)MouseX;
GLfloat CurrentMouseY = (GLfloat)MouseY;
GLfloat ScreenWidth = (GLfloat)(*CurrentScreenWidth);
GLfloat ScreenHeight = (GLfloat)(*CurrentScreenHeight);
GLfloat ChangeInHorizontalAngle = CurrentMouseMovementSpeed * (*deltaTime) * (ScreenWidth / 2 - CurrentMouseX);
GLfloat ChangeInVerticalAngle = CurrentMouseMovementSpeed * (*deltaTime) * (ScreenHeight / 2 - CurrentMouseY);
GLfloat HorizontalAngleDelta = abs(ChangeInHorizontalAngle);
GLfloat VerticalAngleDelta = abs(ChangeInVerticalAngle);
if (HorizontalAngleDelta > 10.0f) {
if (ChangeInHorizontalAngle > 0) {
ChangeInHorizontalAngle = 10.0f;
} else {
ChangeInHorizontalAngle = -10.0f;
}
}
if (VerticalAngleDelta > 10.0f) {
if (ChangeInVerticalAngle > 0) {
ChangeInVerticalAngle = 10.0f;
}
else {
ChangeInVerticalAngle = -10.0f;
}
}
HorizontalAngle += ChangeInHorizontalAngle;
VerticalAngle += ChangeInVerticalAngle;
}
void OpenGLCamera::CalculateView() {
CurrentCameraPosition += CurrentCameraPositionDelta;
CurrentCameraPositionDelta *= CurrentMovementDamping;
CurrentViewingDirection = glm::vec3(
cos(VerticalAngle) * sin(HorizontalAngle),
sin(VerticalAngle),
cos(VerticalAngle) * cos(HorizontalAngle)
);
CurrentRightDirection = glm::vec3(
sin(HorizontalAngle - 3.14f / 2.0f),
0.0f,
cos(HorizontalAngle - 3.14 / 2.0f)
);
CurrentUpDirection = glm::cross(CurrentRightDirection, CurrentViewingDirection);
CurrentCameraMatrix = glm::lookAt(CurrentCameraPosition, CurrentCameraPosition + CurrentViewingDirection, CurrentUpDirection);
}
void OpenGLCamera::SetFOVRadians(GLfloat FOV) {
FOV *= 2.0f;
FieldOfView = FOV * 57.2957795f;
}
void OpenGLCamera::SetFOVDegrees(GLfloat FOV) {
FieldOfView = FOV;
}
void OpenGLCamera::SetAspectRatio(GLfloat AspectRatioToSet) {
FixedAspectRatio = true;
if (AspectRatioToSet > 0) {
AspectRatio = AspectRatioToSet;
}
}
void OpenGLCamera::SetNearPlane(GLfloat NearPlaneToSet) {
NearPlane = NearPlaneToSet;
}
void OpenGLCamera::SetFarPlane(GLfloat FarPlaneToSet) {
FarPlane = FarPlaneToSet;
}
void OpenGLCamera::RotateLeft() {
HorizontalAngle -= 10.0f;
}
void OpenGLCamera::RotateRight() {
HorizontalAngle += 10.0f;
}
void OpenGLCamera::MoveFaster() {
CurrentMovementSpeed += 0.15f;
}
void OpenGLCamera::MoveSlower() {
CurrentMovementSpeed -= 0.15f;
if (CurrentMovementSpeed < 0.10f) {
CurrentMovementSpeed = 0.10f;
}
}
void OpenGLCamera::MoveForward() {
CurrentCameraPositionDelta += CurrentViewingDirection * (*deltaTime) * CurrentMovementSpeed;
}
void OpenGLCamera::MoveBackward() {
CurrentCameraPositionDelta -= CurrentViewingDirection * (*deltaTime) * CurrentMovementSpeed;
}
void OpenGLCamera::MoveLeft() {
CurrentCameraPositionDelta -= CurrentRightDirection * (*deltaTime) * CurrentMovementSpeed;
}
void OpenGLCamera::MoveRight() {
CurrentCameraPositionDelta += CurrentRightDirection * (*deltaTime) * CurrentMovementSpeed;
}
void OpenGLCamera::MoveUp() {
CurrentCameraPositionDelta += CurrentUpDirection * (*deltaTime) * CurrentMovementSpeed;
}
void OpenGLCamera::MoveDown() {
CurrentCameraPositionDelta -= CurrentUpDirection * (*deltaTime) * CurrentMovementSpeed;
}
void OpenGLCamera::CalculateProjection() {
CurrentProjectionMatrix = glm::perspective(
FieldOfView,
CalculateAspectRatio(),
NearPlane,
FarPlane
);
}
void OpenGLCamera::Calculate() {
CalculateProjection();
CalculateView();
}
void OpenGLCamera::Calculate(GLint) {
CalculateProjection();
CalculateView();
}
GLfloat OpenGLCamera::CalculateAspectRatio() {
if (!FixedAspectRatio) {
if ((GLfloat)(*CurrentScreenWidth) > 0 && (GLfloat)(*CurrentScreenHeight) > 0) {
AspectRatio = (GLfloat)(*CurrentScreenWidth) / (GLfloat)(*CurrentScreenHeight);
}
else {
AspectRatio = 1.78f;
}
}
return AspectRatio;
}
glm::mat4* OpenGLCamera::GetProjectionMatrixPointer() {
return &CurrentProjectionMatrix;
}
glm::mat4* OpenGLCamera::GetViewMatrixPointer() {
return &CurrentCameraMatrix;
}
glm::mat4 OpenGLCamera::GetProjectionViewMatrix() {
return CurrentProjectionMatrix * CurrentCameraMatrix;
}
GLfloat OpenGLCamera::GetScreenScaleX() {
return 2.0f / (float)(*CurrentScreenWidth);
}
GLfloat OpenGLCamera::GetScreenScaleY() {
return 2.0f / (float)(*CurrentScreenHeight);
}
glm::vec3* OpenGLCamera::GetViewingDirection() {
return &CurrentViewingDirection;
}
glm::vec3* OpenGLCamera::GetCurrentPosition() {
return &CurrentCameraPosition;
}
void OpenGLCamera::MoveToHomeCameraPosition() {
CurrentCameraPosition = HomeCameraPosition;
}
void OpenGLCamera::SetHomeCameraPosition(glm::vec3 HomeCameraPositionToSet) {
HomeCameraPosition = HomeCameraPositionToSet;
}