Created
October 1, 2022 21:51
-
-
Save bit-hack/bf95d19f22bb1bb8d5b8346595219504 to your computer and use it in GitHub Desktop.
OpenGL camera class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdint> | |
#include <cmath> | |
#include <GLFW/glfw3.h> | |
#include "camera.h" | |
const float pi = 3.14159265359f; | |
static inline float rad2deg(float rad) { | |
return (rad / pi) * 180.f; | |
} | |
static inline float clamp(float min, float in, float max) { | |
return (in < min) ? min : | |
(in > max) ? max : in; | |
} | |
void cameraInit(camera_t &c, const int2 &viewport) { | |
c.aspect = (float)viewport.x / (float)viewport.y; | |
c.roll = 0.f; | |
c.pitch = 0.f; | |
c.yaw = 0.f; | |
c.znear = 1.f; | |
c.zfar = 500.f; | |
} | |
void cameraPosSet(camera_t &camera, const float3 &pos) { | |
camera.pos = pos; | |
} | |
void cameraTargetSet(camera_t &camera, const float3 &target) { | |
const float3 diff = target - camera.pos; | |
const float2 zx = normalize(float2{ -diff.z, diff.x }); | |
// find the angle of the vector on the xz plane | |
camera.yaw = atan2f(zx.y, zx.x); | |
// from the difference vector, look at the y component and turn it back | |
// into an angle | |
camera.pitch = -asinf( normalize(diff).y ); | |
// no roll involved here | |
camera.roll = 0.f; | |
} | |
void cameraBind(const camera_t &c) { | |
const float scale = 1.f; | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
glRotatef(rad2deg(c.roll), 0.f, 0.f, 1.f); | |
glRotatef(rad2deg(c.pitch), 1.f, 0.f, 0.f); | |
glRotatef(rad2deg(c.yaw), 0.f, 1.f, 0.f); | |
glTranslatef(-c.pos.x, -c.pos.y, -c.pos.z); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
glFrustum(-c.aspect * scale, | |
c.aspect * scale, | |
-scale, | |
scale, | |
c.znear, | |
c.zfar); | |
} | |
void cameraFly(camera_t& camera, const float3& acc) { | |
float16 m = { 0 }; | |
glGetFloatv(GL_MODELVIEW_MATRIX, m); | |
const float3 strafe = { m[0] * acc.x, m[4] * acc.x, m[8] * acc.x }; | |
const float3 up = { m[1] * acc.y, m[5] * acc.y, m[9] * acc.y }; | |
const float3 forward = { m[2] * acc.z, m[6] * acc.z, m[10] * acc.z }; | |
camera.pos = camera.pos + strafe + up + forward; | |
} | |
void cameraMove(camera_t& camera, const float3& acc) { | |
float16 m = { 0 }; | |
glGetFloatv(GL_MODELVIEW_MATRIX, m); | |
const float3 strafe = { m[0] * acc.x, 0.f, m[8] * acc.x }; | |
const float3 up = { 0.f, m[5] * acc.y, 0.f }; | |
const float3 forward = { m[2] * acc.z, 0.f, m[10] * acc.z }; | |
camera.pos = camera.pos + strafe + up + forward; | |
} | |
void cameraRotate(camera_t& camera, const float3& rot) { | |
camera.pitch += rot.x; // look up/down | |
camera.yaw += rot.y; // look left/right | |
camera.roll += rot.z; // twist | |
camera.pitch = clamp(-pi, camera.pitch, pi); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <stdint.h> | |
#include "util.h" | |
struct camera_t { | |
float3 pos; // position | |
float roll; // view twist | |
float pitch; // look up/down | |
float yaw; // look left/right | |
float aspect; // aspect ratio | |
float znear; // near plane | |
float zfar; // far plane | |
}; | |
void cameraInit(camera_t &camera, const int2 &viewport); | |
void cameraPosSet(camera_t& camera, const float3& pos); | |
void cameraTargetSet(camera_t& camera, const float3& pos); | |
void cameraBind(const camera_t& camera); | |
void cameraFly(camera_t& camera, const float3& move); | |
void cameraMove(camera_t& camera, const float3& acc); | |
void cameraRotate(camera_t& camera, const float3& rot); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment