commit a029a83bff3d9e9782b1788efc1c77204b6e3546
parent c0f7412b3f672b0de814096613e92ea089792b5c
Author: William Casarin <bill@casarin.me>
Date: Tue, 23 Jun 2015 01:57:59 -0700
working perspective camera
Diffstat:
7 files changed, 127 insertions(+), 11 deletions(-)
diff --git a/etc/shaders/test.v.glsl b/etc/shaders/test.v.glsl
@@ -2,13 +2,16 @@
attribute vec3 position;
attribute vec3 normal;
+
uniform mat4 mvp;
+uniform mat4 normal_matrix;
+
varying float v_dot;
uniform vec3 light_dir;
void main()
{
- vec4 trans_normal = vec4(normal, 1);
- gl_Position = mvp * vec4(position.xyz * 0.2, 1.0);
+ vec4 trans_normal = normal_matrix * vec4(normal, 1);
+ gl_Position = mvp * vec4(position.xyz, 1.0);
v_dot = max(dot(trans_normal.xyz, light_dir), 0.4);
}
diff --git a/src/common.h b/src/common.h
@@ -5,6 +5,8 @@
#define MAT3_ELEMS 9
#define MAT4_ELEMS 16
+#define PI 3.14159265f;
+
typedef unsigned short u16;
typedef signed short s16;
diff --git a/src/game.c b/src/game.c
@@ -7,4 +7,7 @@ void init_game(struct game_state *game) {
float *normal = &game->test_resources.normal_matrix[0];
mat4_id(mvp);
mat4_id(normal);
+
+ // move the camera a bit
+ mat4_translate(mvp, 0.0f, 0.0f, -10.0f, mvp);
}
diff --git a/src/game.h b/src/game.h
@@ -25,6 +25,7 @@ struct test_resources {
float normal_matrix[MAT4_ELEMS];
float test_mvp[MAT4_ELEMS];
+ float camera[MAT4_ELEMS];
GLfloat fade_factor;
};
diff --git a/src/mat4/mat4.c b/src/mat4/mat4.c
@@ -3,6 +3,8 @@
#include <math.h>
#include <string.h>
+#define PI 3.14159265f
+
mat4 *mat4_copy(const mat4 *src, mat4 *dst) {
memcpy(dst, src, sizeof(float) * 16);
return dst;
@@ -60,6 +62,95 @@ mat4 *mat4_transpose(mat4 *src, mat4 *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; }
diff --git a/src/mat4/mat4.h b/src/mat4/mat4.h
@@ -1,6 +1,13 @@
typedef float mat4;
+mat4 *mat4_frustum (float left, float right, float bottom,
+ float top, float near, float far, mat4 *dest);
+
+mat4 *mat4_perspective(float fov, float aspect, float near,
+ float far, mat4 *dest);
+
+mat4 *mat4_translate (mat4 *mat, float x, float y, float z, mat4 *dest);
mat4 *mat4_transpose(mat4 *src, mat4 *dest);
mat4 *mat4_inverse(mat4 *src, mat4 *dest);
mat4 *mat4_copy(const mat4 *src, mat4 *dst);
diff --git a/src/render.c b/src/render.c
@@ -97,6 +97,9 @@ init_gl(struct test_resources * resources) {
);
assert(resources->fragment_shader != 0);
+ // camera
+ mat4_perspective(45 /* fov */, 1080 / 720, 1, 100, resources->camera);
+
// Shader program
resources->program = make_program(resources->vertex_shader,
resources->fragment_shader);
@@ -138,26 +141,32 @@ recalc_normals(GLint norm_uniform, mat4 *mvp, mat4 *normal) {
glUniformMatrix4fv(norm_uniform, 1, 0, calc);
}
+static float tmp_matrix[MAT4_ELEMS] = { 0 };
+
void render (struct test_resources * resources) {
- float *mvp = &resources->test_mvp[0];
+ static float id[MAT4_ELEMS] = { 0 };
+ mat4_id(id);
+
+ float *mvp = resources->test_mvp;
+ float *normal = resources->normal_matrix;
+ float *camera = resources->camera;
float fade_factor = resources->fade_factor;
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); //clear background screen to black
glClear( GL_COLOR_BUFFER_BIT );
static float v3[] = { 1, 1, 0 };
- //v3[1] = (float)(fade_factor * 0.4);
- mat4_rotate(mvp, (float)0.004, v3, mvp);
-
- recalc_normals(resources->uniforms.normal_matrix, mvp,
- &resources->normal_matrix[0]);
+ //v3[1] = fade_factor * 0.4f;
+ mat4_rotate(mvp, 0.004f, v3, mvp);
+ mat4_multiply(camera, mvp, tmp_matrix);
+ recalc_normals(resources->uniforms.normal_matrix, mvp, normal);
glUseProgram(resources->program);
- glUniform3f(resources->uniforms.light_dir, -1, 1, (float)-0.09);
- glUniform1f(resources->uniforms.fade_factor, fade_factor);
- glUniformMatrix4fv(resources->uniforms.mvp, 1, 0, resources->test_mvp);
+ glUniform3f(resources->uniforms.light_dir, -1, 1, -0.09f);
+ //glUniform1f(resources->uniforms.fade_factor, fade_factor);
+ glUniformMatrix4fv(resources->uniforms.mvp, 1, 0, tmp_matrix);
bind_vbo(&resources->vertex_buffer,
resources->attributes.position);