aboutsummaryrefslogtreecommitdiffstats
path: root/faqe.c
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2018-05-03 13:49:44 +0100
committerTomasz Kramkowski <tk@the-tk.com>2018-05-03 13:49:44 +0100
commita1e93038af0a739b9af57bd40ffbee6963dc3242 (patch)
treeeebceb8f833c55fe8c9a1e15d4c26afd7defdfbc /faqe.c
parent362f70b04da8f8e9c0c159527bce7da65591c260 (diff)
downloadfaqe-a1e93038af0a739b9af57bd40ffbee6963dc3242.tar.gz
faqe-a1e93038af0a739b9af57bd40ffbee6963dc3242.tar.xz
faqe-a1e93038af0a739b9af57bd40ffbee6963dc3242.zip
Add a simple camera struct and camera controls
Diffstat (limited to 'faqe.c')
-rw-r--r--faqe.c64
1 files changed, 49 insertions, 15 deletions
diff --git a/faqe.c b/faqe.c
index 1983464..3b81e24 100644
--- a/faqe.c
+++ b/faqe.c
@@ -6,19 +6,20 @@
#include <stdbool.h>
#include "assets.h"
+#include "camera.h"
#include "eprintf.h"
#include "gl.h"
#include "glprog.h"
#include "linmath.h"
-#include "nelem.h"
+#include "math.h"
#include "model.h"
+#include "nelem.h"
enum {
WIDTH = 800,
HEIGHT = 600,
};
-#define PI 3.14159265358979323846
#define FOV (PI * 0.5)
void viewport(GLuint proj, int width, int height)
@@ -38,11 +39,14 @@ int main(int argc, char **argv)
struct {
GLint model, view, proj, tex;
} uni;
- mat4x4 view;
FILE *cube_file;
struct fmd cube_fmd;
struct model cube_model;
- vec3 pos = { 0, 0, 3 };
+ struct camera cam = { .pos = { 0.0, 0.0, 3.0 }, .yaw = -PI/2 };
+ struct {
+ bool w, a, s, d, spc, lct;
+ } key = { 0 };
+ float tlast;
setprogname(argc >= 1 && argv[0] != NULL ? argv[0] : "faqe");
@@ -61,6 +65,8 @@ int main(int argc, char **argv)
if (win == NULL)
eprintf("Failed to create window: %s", SDL_GetError());
+ SDL_SetRelativeMouseMode(SDL_TRUE);
+
glc = SDL_GL_CreateContext(win);
if (glc == NULL)
eprintf("Failed to create OpenGL context: %s", SDL_GetError());
@@ -97,20 +103,33 @@ int main(int argc, char **argv)
gl_enable(GL_FRAMEBUFFER_SRGB);
gl_enable(GL_CULL_FACE);
+ tlast = SDL_GetTicks() * 0.0001;
+
while (running) {
- mat4x4 model;
+ mat4x4 model, view;
+ vec3 dir, right, motion = { 0 }, strafe = { 0 };
SDL_Event ev;
- float secs;
-
- secs = SDL_GetTicks() * 0.0001;
-
- mat4x4_look_at(view, pos, (vec3){ 0, 0, 0 }, (vec3){ 0, 1, 0 });
- gl_uni_setm4fv(uni.view, 1, GL_FALSE, view[0]);
+ float tdiff, tnow;
while (SDL_PollEvent(&ev)) {
+ bool down;
switch (ev.type) {
+ case SDL_MOUSEMOTION:
+ cam.yaw += ev.motion.xrel * 0.005;
+ cam.pitch += ev.motion.yrel * -0.005;
+ camera_clamp(&cam);
+ break;
case SDL_KEYDOWN:
case SDL_KEYUP:
+ down = ev.key.state == SDL_PRESSED;
+ switch (ev.key.keysym.sym) {
+ case SDLK_w: key.w = down; break;
+ case SDLK_a: key.a = down; break;
+ case SDLK_s: key.s = down; break;
+ case SDLK_d: key.d = down; break;
+ case SDLK_SPACE: key.spc = down; break;
+ case SDLK_LCTRL: key.lct = down; break;
+ }
if (ev.key.state != SDL_RELEASED
|| ev.key.keysym.sym != SDLK_ESCAPE)
break;
@@ -129,13 +148,28 @@ int main(int argc, char **argv)
}
}
+ tnow = SDL_GetTicks() * 0.001;
+ tdiff = tnow - tlast;
+ tlast = tnow;
+
+ camera_dir(dir, &cam);
+ vec3_mul_cross(right, dir, CAM_UP);
+ vec3_norm(right, right);
+
+ if (key.w != key.s) vec3_scale(motion, dir, tdiff * (key.w ? 1 : -1));
+ if (key.a != key.d) vec3_scale(strafe, right, tdiff * (key.d ? 1 : -1));
+ if (key.spc != key.lct) cam.pos[1] += tdiff * (key.spc ? 1 : -1);
+ vec3_add(cam.pos, cam.pos, strafe);
+ vec3_add(cam.pos, cam.pos, motion);
+
+ camera_lookat(view, &cam);
+
gl_clearcolor(0.2, 0.3, 0.3, 1.0);
gl_clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- gl_prog_use(prog);
mat4x4_identity(model);
- mat4x4_rotate_X(model, model, secs * 3);
- mat4x4_rotate_Y(model, model, secs * 2);
- mat4x4_rotate_Z(model, model, secs * 4);
+
+ gl_prog_use(prog);
+ gl_uni_setm4fv(uni.view, 1, GL_FALSE, view[0]);
gl_uni_setm4fv(uni.model, 1, GL_FALSE, model[0]);
model_render(&cube_model);
gl_va_bind(0);