polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

commit 9576914fa6933bb5e8adcf4613a56bdf7daf19ab
parent 98ebaefddb0351101304f424205d3fae7f2e314f
Author: William Casarin <jb55@jb55.com>
Date:   Sun, 29 Apr 2018 14:17:22 -0700

wip

Diffstat:
MMakefile | 8++++----
Msrc/camera.c | 6++++++
Msrc/common.h | 3+++
Msrc/game.c | 6++++--
Msrc/game.h | 3+++
Asrc/mat4.c | 325+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Rsrc/mat4/mat4.h -> src/mat4.h | 0
Dsrc/mat4/mat4.c | 324-------------------------------------------------------------------------------
Asrc/noise.c | 0
Msrc/terrain.c | 16++++++++++------
Msrc/terrain.h | 4++++
Msrc/update.c | 12++++++++++--
Msrc/util.c | 49+++++++------------------------------------------
Msrc/util.h | 1+
Asrc/vec3.c | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/vec3.h | 16++++++++++++++++
Dsrc/vec3/vec3.c | 204-------------------------------------------------------------------------------
Dsrc/vec3/vec3.h | 11-----------
Msrc/window.c | 2+-
19 files changed, 603 insertions(+), 596 deletions(-)

diff --git a/Makefile b/Makefile @@ -36,13 +36,13 @@ OBJS += $(SRC)/util.o SRCS=$(OBJS:.o=.c) -# include $(OBJS:.o=.d) +include $(OBJS:.o=.d) all: $(BIN) -# src/%.d: src/%.c -# @rm -f $@; \ -# $(CC) -MM $(CFLAGS) $< > $@ +src/%.d: src/%.c + @rm -f $@; \ + $(CC) -MM $(CFLAGS) $< > $@ %.o: %.c %.h $(CC) $(CFLAGS) -fPIC $(DEFS) -c $< -o $@ diff --git a/src/camera.c b/src/camera.c @@ -6,3 +6,9 @@ struct camera *camera_init(struct camera *cam) { return NULL; } + + +void +camera_follow(mat4 *cam, mat4 *target_prev, mat4 *target) { + cam +} diff --git a/src/common.h b/src/common.h @@ -5,6 +5,9 @@ #include <stdbool.h> #define MAT3_ELEMS 9 +#define M_X 12 +#define M_Y 13 +#define M_Z 14 #define MAT4_ELEMS 16 #define SLAB(f) "etc/slab/" f diff --git a/src/game.c b/src/game.c @@ -7,7 +7,7 @@ mat4 *cam_init = (float[16]){ 0.955761, 0.228018, -0.185425, 0.000000, -0.293528, 0.779583, -0.552437, 0.000000, 0.018780, 0.580299, 0.802257, 0.000000, - -58.746227, -62.404854, -34.097778, 1.000000 + -71.766136, -47.881512, -44.216671, 1.000000 }; void game_init(struct game *game) { @@ -16,11 +16,13 @@ void game_init(struct game *game) { float *camera = game->test_resources.camera; float *terrain = game->test_resources.terrain_node; float *player = game->test_resources.player; + float *player_cam = game->test_resources.player_cam; float *light_dir = game->test_resources.light_dir; mat4_id(mvp); mat4_id(normal); mat4_id(camera); + mat4_id(player_cam); light_dir[0] = 0.5; light_dir[1] = 1; @@ -35,7 +37,7 @@ void game_init(struct game *game) { terrain[14] = 20.0; - mat4_scale(player, V3(0.36,0.36,1.7), player); + mat4_scale(player, V3(0.36,0.36,PLAYER_HEIGHT), player); input_init(&game->input); } diff --git a/src/game.h b/src/game.h @@ -5,6 +5,8 @@ #include "buffer.h" #include "input.h" +#define PLAYER_HEIGHT 1.7 + /* * Global data used by our render callback: * NOTE: just for testing right now @@ -33,6 +35,7 @@ struct resources { float light_dir[3]; float camera[MAT4_ELEMS]; float player[MAT4_ELEMS]; + float player_cam[MAT4_ELEMS]; float camera_persp[MAT4_ELEMS]; GLfloat fade_factor; }; diff --git a/src/mat4.c b/src/mat4.c @@ -0,0 +1,325 @@ + +#include "mat4.h" +#include <math.h> +#include <stdio.h> +#include <string.h> +#include "../vec3/vec3.h" + +#define PI 3.14159265f + +mat4 *mat4_copy(const mat4 *src, mat4 *dst) { + memcpy(dst, src, sizeof(float) * 16); + return dst; +} + + +mat4 *mat4_id(mat4 *dst) { + dst[0] = 1.; dst[1] = 0.; dst[2] = 0.; dst[3] = 0.; + dst[4] = 0.; dst[5] = 1.; dst[6] = 0.; dst[7] = 0.; + dst[8] = 0.; dst[9] = 0.; dst[10] = 1.; dst[11] = 0.; + dst[12] = 0.; dst[13] = 0.; dst[14] = 0.; dst[15] = 1.; + + return dst; +} + +mat4 *mat4_transpose(mat4 *src, mat4 *dest) { + // If we are transposing ourselves we can skip a few steps but have to cache some values + if(dest == NULL || src == dest) { + float a01 = src[1], a02 = src[2], a03 = src[3]; + float a12 = src[6], a13 = src[7]; + float a23 = src[11]; + + src[1] = src[4]; + src[2] = src[8]; + src[3] = src[12]; + src[4] = a01; + src[6] = src[9]; + src[7] = src[13]; + src[8] = a02; + src[9] = a12; + src[11] = src[14]; + src[12] = a03; + src[13] = a13; + src[14] = a23; + return src; + } + + dest[0] = src[0]; + dest[1] = src[4]; + dest[2] = src[8]; + dest[3] = src[12]; + dest[4] = src[1]; + dest[5] = src[5]; + dest[6] = src[9]; + dest[7] = src[13]; + dest[8] = src[2]; + dest[9] = src[6]; + dest[10] = src[10]; + dest[11] = src[14]; + dest[12] = src[3]; + dest[13] = src[7]; + dest[14] = src[11]; + dest[15] = src[15]; + return dest; + +} + +/* + * mat4.frustum + * Generates a frustum matrix with the given bounds + * + * Params: + * left, right - scalar, left and right bounds of the frustum + * bottom, top - scalar, bottom and top bounds of the frustum + * near, far - scalar, near and far bounds of the frustum + * dest - Optional, mat4 frustum matrix will be written into + * + * Returns: + * dest if specified, a new mat4 otherwise + */ +mat4 *mat4_frustum (float left, float right, float bottom, + float top, float near, float far, mat4 *dest) { + float rl = (right - left); + float tb = (top - bottom); + float fn = (far - near); + dest[0] = (near*2) / rl; + dest[1] = 0; + dest[2] = 0; + dest[3] = 0; + dest[4] = 0; + dest[5] = (near*2) / tb; + dest[6] = 0; + dest[7] = 0; + dest[8] = (right + left) / rl; + dest[9] = (top + bottom) / tb; + dest[10] = -(far + near) / fn; + dest[11] = -1; + dest[12] = 0; + dest[13] = 0; + dest[14] = -(far*near*2) / fn; + dest[15] = 0; + return dest; +} + +/* + * mat4.translate + * Translates a matrix by the given vector + * + * Params: + * mat - mat4 to translate + * vec - vec3 specifying the translation + * dest - Optional, mat4 receiving operation result. If not specified result is written to mat + * + * Returns: + * dest if specified, mat otherwise + */ +mat4 *mat4_translate (mat4 *mat, float x, float y, float z, mat4 *dest) { + if(!dest || mat == dest) { + mat[12] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12]; + mat[13] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13]; + mat[14] = mat[2]*x + mat[6]*y + mat[10]*z + mat[14]; + mat[15] = mat[3]*x + mat[7]*y + mat[11]*z + mat[15]; + return mat; + } + + float a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; + float a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; + float a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; + + dest[0] = a00; + dest[1] = a01; + dest[2] = a02; + dest[3] = a03; + dest[4] = a10; + dest[5] = a11; + dest[6] = a12; + dest[7] = a13; + dest[8] = a20; + dest[9] = a21; + dest[10] = a22; + dest[11] = a23; + + dest[12] = a00*x + a10*y + a20*z + mat[12]; + dest[13] = a01*x + a11*y + a21*z + mat[13]; + dest[14] = a02*x + a12*y + a22*z + mat[14]; + dest[15] = a03*x + a13*y + a23*z + mat[15]; + return dest; +} + +mat4 *mat4_perspective(float fov, float aspect, float near, + float far, mat4 *dest) { + float top = near * tanf(fov*PI / 360.0f); + float right = top * aspect; + return mat4_frustum(-right, right, -top, top, near, far, dest); +} + +mat4 *mat4_inverse(mat4 *src, mat4 *dest) { + if(dest == NULL) { dest = src; } + + // Cache the srcrix values (makes for huge speed increases!) + float a00 = src[0], a01 = src[1], a02 = src[2], a03 = src[3]; + float a10 = src[4], a11 = src[5], a12 = src[6], a13 = src[7]; + float a20 = src[8], a21 = src[9], a22 = src[10], a23 = src[11]; + float a30 = src[12], a31 = src[13], a32 = src[14], a33 = src[15]; + + float b00 = a00*a11 - a01*a10; + float b01 = a00*a12 - a02*a10; + float b02 = a00*a13 - a03*a10; + float b03 = a01*a12 - a02*a11; + float b04 = a01*a13 - a03*a11; + float b05 = a02*a13 - a03*a12; + float b06 = a20*a31 - a21*a30; + float b07 = a20*a32 - a22*a30; + float b08 = a20*a33 - a23*a30; + float b09 = a21*a32 - a22*a31; + float b10 = a21*a33 - a23*a31; + float b11 = a22*a33 - a23*a32; + + // Calculate the determinant (inlined to avoid double-caching) + float invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); + + dest[0] = (a11*b11 - a12*b10 + a13*b09)*invDet; + dest[1] = (-a01*b11 + a02*b10 - a03*b09)*invDet; + dest[2] = (a31*b05 - a32*b04 + a33*b03)*invDet; + dest[3] = (-a21*b05 + a22*b04 - a23*b03)*invDet; + dest[4] = (-a10*b11 + a12*b08 - a13*b07)*invDet; + dest[5] = (a00*b11 - a02*b08 + a03*b07)*invDet; + dest[6] = (-a30*b05 + a32*b02 - a33*b01)*invDet; + dest[7] = (a20*b05 - a22*b02 + a23*b01)*invDet; + dest[8] = (a10*b10 - a11*b08 + a13*b06)*invDet; + dest[9] = (-a00*b10 + a01*b08 - a03*b06)*invDet; + dest[10] = (a30*b04 - a31*b02 + a33*b00)*invDet; + dest[11] = (-a20*b04 + a21*b02 - a23*b00)*invDet; + dest[12] = (-a10*b09 + a11*b07 - a12*b06)*invDet; + dest[13] = (a00*b09 - a01*b07 + a02*b06)*invDet; + dest[14] = (-a30*b03 + a31*b01 - a32*b00)*invDet; + dest[15] = (a20*b03 - a21*b01 + a22*b00)*invDet; + + return dest; +} + + +mat4 *mat4_multiply(const mat4 *a, const mat4 *b, mat4 *dst) { + float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; + float a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; + float a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; + float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; + + float b00 = b[0], b01 = b[1], b02 = b[2], b03 = b[3]; + float b10 = b[4], b11 = b[5], b12 = b[6], b13 = b[7]; + float b20 = b[8], b21 = b[9], b22 = b[10], b23 = b[11]; + float b30 = b[12], b31 = b[13], b32 = b[14], b33 = b[15]; + + dst[0] = b00*a00 + b01*a10 + b02*a20 + b03*a30; + dst[1] = b00*a01 + b01*a11 + b02*a21 + b03*a31; + dst[2] = b00*a02 + b01*a12 + b02*a22 + b03*a32; + dst[3] = b00*a03 + b01*a13 + b02*a23 + b03*a33; + dst[4] = b10*a00 + b11*a10 + b12*a20 + b13*a30; + dst[5] = b10*a01 + b11*a11 + b12*a21 + b13*a31; + dst[6] = b10*a02 + b11*a12 + b12*a22 + b13*a32; + dst[7] = b10*a03 + b11*a13 + b12*a23 + b13*a33; + dst[8] = b20*a00 + b21*a10 + b22*a20 + b23*a30; + dst[9] = b20*a01 + b21*a11 + b22*a21 + b23*a31; + dst[10] = b20*a02 + b21*a12 + b22*a22 + b23*a32; + dst[11] = b20*a03 + b21*a13 + b22*a23 + b23*a33; + dst[12] = b30*a00 + b31*a10 + b32*a20 + b33*a30; + dst[13] = b30*a01 + b31*a11 + b32*a21 + b33*a31; + dst[14] = b30*a02 + b31*a12 + b32*a22 + b33*a32; + dst[15] = b30*a03 + b31*a13 + b32*a23 + b33*a33; + + return dst; +} + +// TODO: util me +int float_eq(float a, float b); +int float_eq(float a, float b) { + return fabsf(a - b) < 0.0001; +} + + +mat4 *mat4_rotate(const mat4 *mat, const float angle, + const float *axis, mat4 *dest) { + float x = axis[0], y = axis[1], z = axis[2]; + float len = (float)sqrt(x*x + y*y + z*z); + + if (float_eq(len, 0.)) { return NULL; } + // TODO: float comparison tool + if (!float_eq(len, 1.)) { + len = 1 / len; + x *= len; + y *= len; + z *= len; + } + + float s = (float)sin(angle); + float c = (float)cos(angle); + float t = 1-c; + + // Cache the matrix values (makes for huge speed increases!) + float a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; + float a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; + float a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; + + // Construct the elements of the rotation matrix + float b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s; + float b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s; + float b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c; + + // If the source and destination differ, copy the unchanged last row + if(mat != dest) { + dest[12] = mat[12]; + dest[13] = mat[13]; + dest[14] = mat[14]; + dest[15] = mat[15]; + } + + // Perform rotation-specific matrix multiplication + dest[0] = a00*b00 + a10*b01 + a20*b02; + dest[1] = a01*b00 + a11*b01 + a21*b02; + dest[2] = a02*b00 + a12*b01 + a22*b02; + dest[3] = a03*b00 + a13*b01 + a23*b02; + + dest[4] = a00*b10 + a10*b11 + a20*b12; + dest[5] = a01*b10 + a11*b11 + a21*b12; + dest[6] = a02*b10 + a12*b11 + a22*b12; + dest[7] = a03*b10 + a13*b11 + a23*b12; + + dest[8] = a00*b20 + a10*b21 + a20*b22; + dest[9] = a01*b20 + a11*b21 + a21*b22; + dest[10] = a02*b20 + a12*b21 + a22*b22; + dest[11] = a03*b20 + a13*b21 + a23*b22; + + return dest; +} + +mat4 *mat4_scale(mat4 *a, float v[3], mat4 *out) { + float x = v[0], y = v[1], z = v[2]; + + out[0] = a[0] * x; + out[1] = a[1] * x; + out[2] = a[2] * x; + out[3] = a[3] * x; + out[4] = a[4] * y; + out[5] = a[5] * y; + out[6] = a[6] * y; + out[7] = a[7] * y; + out[8] = a[8] * z; + out[9] = a[9] * z; + out[10] = a[10] * z; + out[11] = a[11] * z; + out[12] = a[12]; + out[13] = a[13]; + out[14] = a[14]; + out[15] = a[15]; + return out; +}; + + +void mat4_print(const mat4 *m) { + for (int i = 0; i < 16; ++i) { + if (i % 4 == 0) + printf("\n"); + printf("%f, ", m[i]); + } + printf("\n"); +} diff --git a/src/mat4/mat4.h b/src/mat4.h diff --git a/src/mat4/mat4.c b/src/mat4/mat4.c @@ -1,324 +0,0 @@ - -#include "mat4.h" -#include <math.h> -#include <stdio.h> -#include <string.h> - -#define PI 3.14159265f - -mat4 *mat4_copy(const mat4 *src, mat4 *dst) { - memcpy(dst, src, sizeof(float) * 16); - return dst; -} - - -mat4 *mat4_id(mat4 *dst) { - dst[0] = 1.; dst[1] = 0.; dst[2] = 0.; dst[3] = 0.; - dst[4] = 0.; dst[5] = 1.; dst[6] = 0.; dst[7] = 0.; - dst[8] = 0.; dst[9] = 0.; dst[10] = 1.; dst[11] = 0.; - dst[12] = 0.; dst[13] = 0.; dst[14] = 0.; dst[15] = 1.; - - return dst; -} - -mat4 *mat4_transpose(mat4 *src, mat4 *dest) { - // If we are transposing ourselves we can skip a few steps but have to cache some values - if(dest == NULL || src == dest) { - float a01 = src[1], a02 = src[2], a03 = src[3]; - float a12 = src[6], a13 = src[7]; - float a23 = src[11]; - - src[1] = src[4]; - src[2] = src[8]; - src[3] = src[12]; - src[4] = a01; - src[6] = src[9]; - src[7] = src[13]; - src[8] = a02; - src[9] = a12; - src[11] = src[14]; - src[12] = a03; - src[13] = a13; - src[14] = a23; - return src; - } - - dest[0] = src[0]; - dest[1] = src[4]; - dest[2] = src[8]; - dest[3] = src[12]; - dest[4] = src[1]; - dest[5] = src[5]; - dest[6] = src[9]; - dest[7] = src[13]; - dest[8] = src[2]; - dest[9] = src[6]; - dest[10] = src[10]; - dest[11] = src[14]; - dest[12] = src[3]; - dest[13] = src[7]; - dest[14] = src[11]; - dest[15] = src[15]; - return dest; - -} - -/* - * mat4.frustum - * Generates a frustum matrix with the given bounds - * - * Params: - * left, right - scalar, left and right bounds of the frustum - * bottom, top - scalar, bottom and top bounds of the frustum - * near, far - scalar, near and far bounds of the frustum - * dest - Optional, mat4 frustum matrix will be written into - * - * Returns: - * dest if specified, a new mat4 otherwise - */ -mat4 *mat4_frustum (float left, float right, float bottom, - float top, float near, float far, mat4 *dest) { - float rl = (right - left); - float tb = (top - bottom); - float fn = (far - near); - dest[0] = (near*2) / rl; - dest[1] = 0; - dest[2] = 0; - dest[3] = 0; - dest[4] = 0; - dest[5] = (near*2) / tb; - dest[6] = 0; - dest[7] = 0; - dest[8] = (right + left) / rl; - dest[9] = (top + bottom) / tb; - dest[10] = -(far + near) / fn; - dest[11] = -1; - dest[12] = 0; - dest[13] = 0; - dest[14] = -(far*near*2) / fn; - dest[15] = 0; - return dest; -} - -/* - * mat4.translate - * Translates a matrix by the given vector - * - * Params: - * mat - mat4 to translate - * vec - vec3 specifying the translation - * dest - Optional, mat4 receiving operation result. If not specified result is written to mat - * - * Returns: - * dest if specified, mat otherwise - */ -mat4 *mat4_translate (mat4 *mat, float x, float y, float z, mat4 *dest) { - if(!dest || mat == dest) { - mat[12] = mat[0]*x + mat[4]*y + mat[8]*z + mat[12]; - mat[13] = mat[1]*x + mat[5]*y + mat[9]*z + mat[13]; - mat[14] = mat[2]*x + mat[6]*y + mat[10]*z + mat[14]; - mat[15] = mat[3]*x + mat[7]*y + mat[11]*z + mat[15]; - return mat; - } - - float a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; - float a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; - float a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; - - dest[0] = a00; - dest[1] = a01; - dest[2] = a02; - dest[3] = a03; - dest[4] = a10; - dest[5] = a11; - dest[6] = a12; - dest[7] = a13; - dest[8] = a20; - dest[9] = a21; - dest[10] = a22; - dest[11] = a23; - - dest[12] = a00*x + a10*y + a20*z + mat[12]; - dest[13] = a01*x + a11*y + a21*z + mat[13]; - dest[14] = a02*x + a12*y + a22*z + mat[14]; - dest[15] = a03*x + a13*y + a23*z + mat[15]; - return dest; -} - -mat4 *mat4_perspective(float fov, float aspect, float near, - float far, mat4 *dest) { - float top = near * tanf(fov*PI / 360.0f); - float right = top * aspect; - return mat4_frustum(-right, right, -top, top, near, far, dest); -} - -mat4 *mat4_inverse(mat4 *src, mat4 *dest) { - if(dest == NULL) { dest = src; } - - // Cache the srcrix values (makes for huge speed increases!) - float a00 = src[0], a01 = src[1], a02 = src[2], a03 = src[3]; - float a10 = src[4], a11 = src[5], a12 = src[6], a13 = src[7]; - float a20 = src[8], a21 = src[9], a22 = src[10], a23 = src[11]; - float a30 = src[12], a31 = src[13], a32 = src[14], a33 = src[15]; - - float b00 = a00*a11 - a01*a10; - float b01 = a00*a12 - a02*a10; - float b02 = a00*a13 - a03*a10; - float b03 = a01*a12 - a02*a11; - float b04 = a01*a13 - a03*a11; - float b05 = a02*a13 - a03*a12; - float b06 = a20*a31 - a21*a30; - float b07 = a20*a32 - a22*a30; - float b08 = a20*a33 - a23*a30; - float b09 = a21*a32 - a22*a31; - float b10 = a21*a33 - a23*a31; - float b11 = a22*a33 - a23*a32; - - // Calculate the determinant (inlined to avoid double-caching) - float invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06); - - dest[0] = (a11*b11 - a12*b10 + a13*b09)*invDet; - dest[1] = (-a01*b11 + a02*b10 - a03*b09)*invDet; - dest[2] = (a31*b05 - a32*b04 + a33*b03)*invDet; - dest[3] = (-a21*b05 + a22*b04 - a23*b03)*invDet; - dest[4] = (-a10*b11 + a12*b08 - a13*b07)*invDet; - dest[5] = (a00*b11 - a02*b08 + a03*b07)*invDet; - dest[6] = (-a30*b05 + a32*b02 - a33*b01)*invDet; - dest[7] = (a20*b05 - a22*b02 + a23*b01)*invDet; - dest[8] = (a10*b10 - a11*b08 + a13*b06)*invDet; - dest[9] = (-a00*b10 + a01*b08 - a03*b06)*invDet; - dest[10] = (a30*b04 - a31*b02 + a33*b00)*invDet; - dest[11] = (-a20*b04 + a21*b02 - a23*b00)*invDet; - dest[12] = (-a10*b09 + a11*b07 - a12*b06)*invDet; - dest[13] = (a00*b09 - a01*b07 + a02*b06)*invDet; - dest[14] = (-a30*b03 + a31*b01 - a32*b00)*invDet; - dest[15] = (a20*b03 - a21*b01 + a22*b00)*invDet; - - return dest; -} - - -mat4 *mat4_multiply(const mat4 *a, const mat4 *b, mat4 *dst) { - float a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3]; - float a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7]; - float a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11]; - float a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15]; - - float b00 = b[0], b01 = b[1], b02 = b[2], b03 = b[3]; - float b10 = b[4], b11 = b[5], b12 = b[6], b13 = b[7]; - float b20 = b[8], b21 = b[9], b22 = b[10], b23 = b[11]; - float b30 = b[12], b31 = b[13], b32 = b[14], b33 = b[15]; - - dst[0] = b00*a00 + b01*a10 + b02*a20 + b03*a30; - dst[1] = b00*a01 + b01*a11 + b02*a21 + b03*a31; - dst[2] = b00*a02 + b01*a12 + b02*a22 + b03*a32; - dst[3] = b00*a03 + b01*a13 + b02*a23 + b03*a33; - dst[4] = b10*a00 + b11*a10 + b12*a20 + b13*a30; - dst[5] = b10*a01 + b11*a11 + b12*a21 + b13*a31; - dst[6] = b10*a02 + b11*a12 + b12*a22 + b13*a32; - dst[7] = b10*a03 + b11*a13 + b12*a23 + b13*a33; - dst[8] = b20*a00 + b21*a10 + b22*a20 + b23*a30; - dst[9] = b20*a01 + b21*a11 + b22*a21 + b23*a31; - dst[10] = b20*a02 + b21*a12 + b22*a22 + b23*a32; - dst[11] = b20*a03 + b21*a13 + b22*a23 + b23*a33; - dst[12] = b30*a00 + b31*a10 + b32*a20 + b33*a30; - dst[13] = b30*a01 + b31*a11 + b32*a21 + b33*a31; - dst[14] = b30*a02 + b31*a12 + b32*a22 + b33*a32; - dst[15] = b30*a03 + b31*a13 + b32*a23 + b33*a33; - - return dst; -} - -// TODO: util me -int float_eq(float a, float b); -int float_eq(float a, float b) { - return fabsf(a - b) < 0.0001; -} - - -mat4 *mat4_rotate(const mat4 *mat, const float angle, - const float *axis, mat4 *dest) { - float x = axis[0], y = axis[1], z = axis[2]; - float len = (float)sqrt(x*x + y*y + z*z); - - if (float_eq(len, 0.)) { return NULL; } - // TODO: float comparison tool - if (!float_eq(len, 1.)) { - len = 1 / len; - x *= len; - y *= len; - z *= len; - } - - float s = (float)sin(angle); - float c = (float)cos(angle); - float t = 1-c; - - // Cache the matrix values (makes for huge speed increases!) - float a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3]; - float a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7]; - float a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11]; - - // Construct the elements of the rotation matrix - float b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s; - float b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s; - float b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c; - - // If the source and destination differ, copy the unchanged last row - if(mat != dest) { - dest[12] = mat[12]; - dest[13] = mat[13]; - dest[14] = mat[14]; - dest[15] = mat[15]; - } - - // Perform rotation-specific matrix multiplication - dest[0] = a00*b00 + a10*b01 + a20*b02; - dest[1] = a01*b00 + a11*b01 + a21*b02; - dest[2] = a02*b00 + a12*b01 + a22*b02; - dest[3] = a03*b00 + a13*b01 + a23*b02; - - dest[4] = a00*b10 + a10*b11 + a20*b12; - dest[5] = a01*b10 + a11*b11 + a21*b12; - dest[6] = a02*b10 + a12*b11 + a22*b12; - dest[7] = a03*b10 + a13*b11 + a23*b12; - - dest[8] = a00*b20 + a10*b21 + a20*b22; - dest[9] = a01*b20 + a11*b21 + a21*b22; - dest[10] = a02*b20 + a12*b21 + a22*b22; - dest[11] = a03*b20 + a13*b21 + a23*b22; - - return dest; -} - -mat4 *mat4_scale(mat4 *a, float v[3], mat4 *out) { - float x = v[0], y = v[1], z = v[2]; - - out[0] = a[0] * x; - out[1] = a[1] * x; - out[2] = a[2] * x; - out[3] = a[3] * x; - out[4] = a[4] * y; - out[5] = a[5] * y; - out[6] = a[6] * y; - out[7] = a[7] * y; - out[8] = a[8] * z; - out[9] = a[9] * z; - out[10] = a[10] * z; - out[11] = a[11] * z; - out[12] = a[12]; - out[13] = a[13]; - out[14] = a[14]; - out[15] = a[15]; - return out; -}; - - -void mat4_print(const mat4 *m) { - for (int i = 0; i < 16; ++i) { - if (i % 4 == 0) - printf("\n"); - printf("%f, ", m[i]); - } - printf("\n"); -} diff --git a/src/noise.c b/src/noise.c diff --git a/src/terrain.c b/src/terrain.c @@ -19,9 +19,8 @@ static const u32 plane_indices[] = { }; -double old_noisy_boi(void *data, double x, double y) { +double old_noisy_boi(struct terrain *t, double x, double y) { /* return cos(x/10.0) * sin(y/10.0) * 20.0; */ - struct terrain *t = (struct terrain*)data; struct perlin_settings *s = &t->settings; x *= s->scale; y *= s->scale; @@ -45,6 +44,13 @@ void terrain_init(struct terrain *terrain) { } +double offset_fn(struct terrain* terrain, double x, double y) { + struct perlin_settings *perlin = &terrain->settings; + double ox = perlin->ox * (1/perlin->scale); + double oy = perlin->oy * (1/perlin->scale); + return old_noisy_boi(terrain, ox+x, oy+y); +} + void terrain_create(struct terrain *terrain) { u32 i; @@ -53,12 +59,10 @@ terrain_create(struct terrain *terrain) { float tmp1[3], tmp2[3]; assert(terrain->n_samples > 0); del_point2d_t *points = calloc(terrain->n_samples, sizeof(*points)); - struct perlin_settings *perlin = &terrain->settings; float *verts = calloc(terrain->n_samples * 3, sizeof(*verts)); - double ox = perlin->ox * (1/perlin->scale); - double oy = perlin->oy * (1/perlin->scale); + terrain->fn = offset_fn; // 100 random samples from our noise function for (i = 0; i < (u32)terrain->n_samples; i++) { @@ -68,7 +72,7 @@ terrain_create(struct terrain *terrain) { x = terrain->samples[i].x; y = terrain->samples[i].y; - double z = old_noisy_boi((void*)terrain, ox+x, oy+y); + double z = terrain->fn(terrain, x, y); points[i].x = x; points[i].y = y; diff --git a/src/terrain.h b/src/terrain.h @@ -18,14 +18,18 @@ struct perlin_settings { double exp; }; + struct terrain { struct geometry geom; struct perlin_settings settings; struct point *samples; + double (*fn)(struct terrain *, double, double); int n_samples; double size; }; +double old_noisy_boi(struct terrain *, double x, double y); + void terrain_init(struct terrain *terrain); void terrain_create(struct terrain *terrain); void terrain_destroy(struct terrain *terrain); diff --git a/src/update.c b/src/update.c @@ -70,10 +70,18 @@ void update (struct game *game, u32 dt) { if (game->input.modifiers & KMOD_LALT) { movement(game, res->camera); - mat4_loo + /* mat4_multiply(res->player, res->ca era, res->player); */ } - else { + if (game->input.modifiers & KMOD_LCTRL) { movement(game, res->terrain_node); + /* mat4_multiply(res->player, res->ca era, res->player); */ + } + else { + movement(game, res->player); + res->player[14] = + game->terrain->fn(game->terrain, res->player[M_X], res->player[M_Y]) + + PLAYER_HEIGHT; + camera_follow(camera, player); /* movement(game, res->camera); */ } diff --git a/src/util.c b/src/util.c @@ -1,6 +1,6 @@ #include "util.h" -#include "vec3.h" +#include "vec3/vec3.h" #include <stdlib.h> int clampi(int a, int mina, int maxa) { @@ -44,45 +44,10 @@ double rand_0to1() { return (double) rand() / RAND_MAX; } -void glhLookAtf2( float *matrix, float *eyePosition3D, - float *center3D, float *upVector3D ) -{ - float forward[3], side[3], up[3]; - float matrix2[16], resultMatrix[16]; - // -------------------- - forward[0] = center3D[0] - eyePosition3D[0]; - forward[1] = center3D[1] - eyePosition3D[1]; - forward[2] = center3D[2] - eyePosition3D[2]; - vec3_normalize(forward, forward); - // -------------------- - // Side = forward x up - ComputeNormalOfPlane(side, forward, upVector3D); - NormalizeVector(side); - -------------------- - // Recompute up as: up = side x forward - ComputeNormalOfPlane(up, side, forward); - // -------------------- - matrix2[0] = side[0]; - matrix2[4] = side[1]; - matrix2[8] = side[2]; - matrix2[12] = 0.0; - // -------------------- - matrix2[1] = up[0]; - matrix2[5] = up[1]; - matrix2[9] = up[2]; - matrix2[13] = 0.0; - // -------------------- - matrix2[2] = -forward[0]; - matrix2[6] = -forward[1]; - matrix2[10] = -forward[2]; - matrix2[14] = 0.0; - // -------------------- - matrix2[3] = matrix2[7] = matrix2[11] = 0.0; - matrix2[15] = 1.0; - // -------------------- - MultiplyMatrices4by4OpenGL_FLOAT(resultMatrix, matrix, matrix2); - glhTranslatef2(resultMatrix, - -eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]); - // -------------------- - memcpy(matrix, resultMatrix, 16*sizeof(float)); +mat4 *look_at(vec3 *eye, vec3 *target, vec3 *up) { + float[3] z; + vec3_subtract(eye, target, z); + if (vec3_lengthsq(z) == 0) + z[V_Z] = 0; } + diff --git a/src/util.h b/src/util.h @@ -12,6 +12,7 @@ int clampi(int a, int mina, int maxa); double clamp(double a, double mina, double maxa); double max(double a, double b); double min(double a, double b); +mat4 *look_at(vec3 *eye, vec3 *target, vec3 *up); double rand_0to1(); diff --git a/src/vec3.c b/src/vec3.c @@ -0,0 +1,209 @@ + +#include <stdlib.h> +#include <math.h> + +#include "mat4/mat4.h" +#include "vec3.h" + +vec3 *vec3_create(vec3 *vec) { + vec3 *dest = calloc(sizeof(float_t), 3); + + if (vec) { + dest[0] = vec[0]; + dest[1] = vec[1]; + dest[2] = vec[2]; + } else { + dest[0] = dest[1] = dest[2] = 0; + } + + return dest; +} + +vec3 *vec3_set(vec3 *vec, vec3 *dest) { + dest[0] = vec[0]; + dest[1] = vec[1]; + dest[2] = vec[2]; + + return dest; +} + +vec3 *vec3_add(vec3 *vec, vec3 *vec2, vec3 *dest) { + if (!dest || vec == dest) { + vec[0] += vec2[0]; + vec[1] += vec2[1]; + vec[2] += vec2[2]; + return vec; + } + + dest[0] = vec[0] + vec2[0]; + dest[1] = vec[1] + vec2[1]; + dest[2] = vec[2] + vec2[2]; + + return dest; +} + +vec3 *vec3_subtract(vec3 *vec, vec3 *vec2, vec3 *dest) { + if (!dest || vec == dest) { + vec[0] -= vec2[0]; + vec[1] -= vec2[1]; + vec[2] -= vec2[2]; + return vec; + } + + dest[0] = vec[0] - vec2[0]; + dest[1] = vec[1] - vec2[1]; + dest[2] = vec[2] - vec2[2]; + return dest; +} + +vec3 *vec3_multiply(vec3 *vec, vec3 *vec2, vec3 *dest) { + if (!dest || vec == dest) { + vec[0] *= vec2[0]; + vec[1] *= vec2[1]; + vec[2] *= vec2[2]; + return vec; + } + + dest[0] = vec[0] * vec2[0]; + dest[1] = vec[1] * vec2[1]; + dest[2] = vec[2] * vec2[2]; + return dest; +} + +vec3 *vec3_negate(vec3 *vec, vec3 *dest) { + if (!dest) { dest = vec; } + + dest[0] = -vec[0]; + dest[1] = -vec[1]; + dest[2] = -vec[2]; + return dest; +} + +vec3 *vec3_scale(vec3 *vec, float val, vec3 *dest) { + if (!dest || vec == dest) { + vec[0] *= val; + vec[1] *= val; + vec[2] *= val; + return vec; + } + + dest[0] = vec[0] * val; + dest[1] = vec[1] * val; + dest[2] = vec[2] * val; + return dest; +} + +vec3 *vec3_normalize(vec3 *vec, vec3 *dest) { + if (!dest) { dest = vec; } + + float x = vec[0], y = vec[1], z = vec[2], + len = sqrt(x * x + y * y + z * z); + + if (!len) { + dest[0] = 0; + dest[1] = 0; + dest[2] = 0; + return dest; + } else if (len == 1) { + dest[0] = x; + dest[1] = y; + dest[2] = z; + return dest; + } + + len = 1 / len; + dest[0] = x * len; + dest[1] = y * len; + dest[2] = z * len; + return dest; +} + +vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest) { + if (!dest) { dest = vec; } + + float x = vec[0], y = vec[1], z = vec[2], + x2 = vec2[0], y2 = vec2[1], z2 = vec2[2]; + + dest[0] = y * z2 - z * y2; + dest[1] = z * x2 - x * z2; + dest[2] = x * y2 - y * x2; + return dest; +} + +float vec3_length(vec3 *vec) { + float x = vec[0], y = vec[1], z = vec[2]; + return sqrt(x * x + y * y + z * z); +} + +float vec3_dot(vec3 *vec, vec3 *vec2) { + return vec[0] * vec2[0] + vec[1] * vec2[1] + vec[2] * vec2[2]; +} + +vec3 *vec3_direction (vec3 *vec, vec3 *vec2, vec3 *dest) { + if (!dest) { dest = vec; } + + float x = vec[0] - vec2[0], + y = vec[1] - vec2[1], + z = vec[2] - vec2[2], + len = sqrt(x * x + y * y + z * z); + + if (!len) { + dest[0] = 0; + dest[1] = 0; + dest[2] = 0; + return dest; + } + + len = 1 / len; + dest[0] = x * len; + dest[1] = y * len; + dest[2] = z * len; + return dest; +} + +vec3 *vec3_lerp(vec3 *vec, vec3 *vec2, float lerp, vec3 *dest) { + if (!dest) { dest = vec; } + + dest[0] = vec[0] + lerp * (vec2[0] - vec[0]); + dest[1] = vec[1] + lerp * (vec2[1] - vec[1]); + dest[2] = vec[2] + lerp * (vec2[2] - vec[2]); + + return dest; +} + +float vec3_lengthsq(vec3 *vec, vec3 *vec) { + float x = vec2[0] - vec[0], + y = vec2[1] - vec[1], + z = vec2[2] - vec[2]; + + return x*x + y*y + z*z; +} + + +float vec3_length(vec3 *vec, vec3 *vec2) { + return sqrt(vec3_lengthsq(vec, vec2)); +} + +/* vec3 *vec3_unproject(vec3 *vec, mat4 view, mat4 proj, vec4_t viewport, vec3 *dest) { */ +/* if (!dest) { dest = vec; } */ + +/* mat4 m = mat4_create(NULL); */ +/* float *v = malloc(sizeof(float) * 4); */ + +/* v[0] = (vec[0] - viewport[0]) * 2.0 / viewport[2] - 1.0; */ +/* v[1] = (vec[1] - viewport[1]) * 2.0 / viewport[3] - 1.0; */ +/* v[2] = 2.0 * vec[2] - 1.0; */ +/* v[3] = 1.0; */ + +/* mat4_multiply(proj, view, m); */ +/* if(!mat4_inverse(m, NULL)) { return NULL; } */ + +/* mat4_multiplyVec4(m, v, NULL); */ +/* if(v[3] == 0.0) { return NULL; } */ + +/* dest[0] = v[0] / v[3]; */ +/* dest[1] = v[1] / v[3]; */ +/* dest[2] = v[2] / v[3]; */ + +/* return dest; */ +/* } */ diff --git a/src/vec3.h b/src/vec3.h @@ -0,0 +1,16 @@ +typedef float vec3; + +#define V3(x,y,z) ((vec3[3]){x,y,z}) +#define V_X 0 +#define V_Y 1 +#define V_Z 2 + +vec3 *vec3_scale(vec3 *vec, float val, vec3 *dest); +vec3 *vec3_subtract(vec3 *vec, vec3 *vec2, vec3 *dest); +vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest); +vec3 *vec3_multiply(vec3 *vec, vec3 *vec2, vec3 *dest); +vec3 *vec3_scale(vec3 *vec, float val, vec3 *dest); +vec3 *vec3_normalize(vec3 *vec, vec3 *dest); +vec3 *vec3_length(vec3 *vec, vec3 *dest); +vec3 *vec3_lengthsq(vec3 *vec, vec3 *dest); + diff --git a/src/vec3/vec3.c b/src/vec3/vec3.c @@ -1,204 +0,0 @@ - -#include <stdlib.h> -#include <math.h> - -#include "mat4/mat4.h" -#include "vec3.h" - -vec3 *vec3_create(vec3 *vec) { - vec3 *dest = calloc(sizeof(double_t), 3); - - if (vec) { - dest[0] = vec[0]; - dest[1] = vec[1]; - dest[2] = vec[2]; - } else { - dest[0] = dest[1] = dest[2] = 0; - } - - return dest; -} - -vec3 *vec3_set(vec3 *vec, vec3 *dest) { - dest[0] = vec[0]; - dest[1] = vec[1]; - dest[2] = vec[2]; - - return dest; -} - -vec3 *vec3_add(vec3 *vec, vec3 *vec2, vec3 *dest) { - if (!dest || vec == dest) { - vec[0] += vec2[0]; - vec[1] += vec2[1]; - vec[2] += vec2[2]; - return vec; - } - - dest[0] = vec[0] + vec2[0]; - dest[1] = vec[1] + vec2[1]; - dest[2] = vec[2] + vec2[2]; - - return dest; -} - -vec3 *vec3_subtract(vec3 *vec, vec3 *vec2, vec3 *dest) { - if (!dest || vec == dest) { - vec[0] -= vec2[0]; - vec[1] -= vec2[1]; - vec[2] -= vec2[2]; - return vec; - } - - dest[0] = vec[0] - vec2[0]; - dest[1] = vec[1] - vec2[1]; - dest[2] = vec[2] - vec2[2]; - return dest; -} - -vec3 *vec3_multiply(vec3 *vec, vec3 *vec2, vec3 *dest) { - if (!dest || vec == dest) { - vec[0] *= vec2[0]; - vec[1] *= vec2[1]; - vec[2] *= vec2[2]; - return vec; - } - - dest[0] = vec[0] * vec2[0]; - dest[1] = vec[1] * vec2[1]; - dest[2] = vec[2] * vec2[2]; - return dest; -} - -vec3 *vec3_negate(vec3 *vec, vec3 *dest) { - if (!dest) { dest = vec; } - - dest[0] = -vec[0]; - dest[1] = -vec[1]; - dest[2] = -vec[2]; - return dest; -} - -vec3 *vec3_scale(vec3 *vec, double val, vec3 *dest) { - if (!dest || vec == dest) { - vec[0] *= val; - vec[1] *= val; - vec[2] *= val; - return vec; - } - - dest[0] = vec[0] * val; - dest[1] = vec[1] * val; - dest[2] = vec[2] * val; - return dest; -} - -vec3 *vec3_normalize(vec3 *vec, vec3 *dest) { - if (!dest) { dest = vec; } - - double x = vec[0], y = vec[1], z = vec[2], - len = sqrt(x * x + y * y + z * z); - - if (!len) { - dest[0] = 0; - dest[1] = 0; - dest[2] = 0; - return dest; - } else if (len == 1) { - dest[0] = x; - dest[1] = y; - dest[2] = z; - return dest; - } - - len = 1 / len; - dest[0] = x * len; - dest[1] = y * len; - dest[2] = z * len; - return dest; -} - -vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest) { - if (!dest) { dest = vec; } - - double x = vec[0], y = vec[1], z = vec[2], - x2 = vec2[0], y2 = vec2[1], z2 = vec2[2]; - - dest[0] = y * z2 - z * y2; - dest[1] = z * x2 - x * z2; - dest[2] = x * y2 - y * x2; - return dest; -} - -double vec3_length(vec3 *vec) { - double x = vec[0], y = vec[1], z = vec[2]; - return sqrt(x * x + y * y + z * z); -} - -double vec3_dot(vec3 *vec, vec3 *vec2) { - return vec[0] * vec2[0] + vec[1] * vec2[1] + vec[2] * vec2[2]; -} - -vec3 *vec3_direction (vec3 *vec, vec3 *vec2, vec3 *dest) { - if (!dest) { dest = vec; } - - double x = vec[0] - vec2[0], - y = vec[1] - vec2[1], - z = vec[2] - vec2[2], - len = sqrt(x * x + y * y + z * z); - - if (!len) { - dest[0] = 0; - dest[1] = 0; - dest[2] = 0; - return dest; - } - - len = 1 / len; - dest[0] = x * len; - dest[1] = y * len; - dest[2] = z * len; - return dest; -} - -vec3 *vec3_lerp(vec3 *vec, vec3 *vec2, double lerp, vec3 *dest) { - if (!dest) { dest = vec; } - - dest[0] = vec[0] + lerp * (vec2[0] - vec[0]); - dest[1] = vec[1] + lerp * (vec2[1] - vec[1]); - dest[2] = vec[2] + lerp * (vec2[2] - vec[2]); - - return dest; -} - -double vec3_dist(vec3 *vec, vec3 *vec2) { - double x = vec2[0] - vec[0], - y = vec2[1] - vec[1], - z = vec2[2] - vec[2]; - - return sqrt(x*x + y*y + z*z); -} - -/* vec3 *vec3_unproject(vec3 *vec, mat4 view, mat4 proj, vec4_t viewport, vec3 *dest) { */ -/* if (!dest) { dest = vec; } */ - -/* mat4 m = mat4_create(NULL); */ -/* double *v = malloc(sizeof(double) * 4); */ - -/* v[0] = (vec[0] - viewport[0]) * 2.0 / viewport[2] - 1.0; */ -/* v[1] = (vec[1] - viewport[1]) * 2.0 / viewport[3] - 1.0; */ -/* v[2] = 2.0 * vec[2] - 1.0; */ -/* v[3] = 1.0; */ - -/* mat4_multiply(proj, view, m); */ -/* if(!mat4_inverse(m, NULL)) { return NULL; } */ - -/* mat4_multiplyVec4(m, v, NULL); */ -/* if(v[3] == 0.0) { return NULL; } */ - -/* dest[0] = v[0] / v[3]; */ -/* dest[1] = v[1] / v[3]; */ -/* dest[2] = v[2] / v[3]; */ - -/* return dest; */ -/* } */ diff --git a/src/vec3/vec3.h b/src/vec3/vec3.h @@ -1,11 +0,0 @@ -typedef float vec3; - -#define V3(x,y,z) ((float[3]){x,y,z}) - -vec3 *vec3_scale(vec3 *vec, double val, vec3 *dest); -vec3 *vec3_subtract(vec3 *vec, vec3 *vec2, vec3 *dest); -vec3 *vec3_cross (vec3 *vec, vec3 *vec2, vec3 *dest); -vec3 *vec3_multiply(vec3 *vec, vec3 *vec2, vec3 *dest); -vec3 *vec3_scale(vec3 *vec, double val, vec3 *dest); -vec3 *vec3_normalize(vec3 *vec, vec3 *dest); - diff --git a/src/window.c b/src/window.c @@ -9,7 +9,7 @@ void handle_resize(float *camera, int width, int height) { printf("resizing %d %d\n", width, height); glViewport( 0, 0, width, height ); - mat4_perspective(90 /* fov */, (float)width / height, 1, 1000, camera); + mat4_perspective(100 /* fov */, (float)width / height, 1, 1000, camera); /* glMatrixMode( GL_PROJECTION ); //Switch to setting the camera perspective */ /* Set the camera perspective */