commit f1d93cae98cedbfea5f5f788fa63327f5f233f28
parent 4515542024925cd35387f4106fb509b19840a1db
Author: amin <dev@aminmesbah.com>
Date: Mon, 28 May 2018 21:33:27 +0000
Split platform and game layer
Also split header files to .c and .h files.
FossilOrigin-Name: bc2f85ee4be1a0d08e88cd231f8508c482e45eabcc03b0b922a52f7341e21240
Diffstat:
M | Makefile | | | 2 | +- |
A | src/game.c | | | 14 | ++++++++++++++ |
A | src/game.h | | | 8 | ++++++++ |
A | src/glmth.c | | | 411 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | src/glmth.h | | | 439 | ++++++------------------------------------------------------------------------- |
D | src/main.c | | | 122 | ------------------------------------------------------------------------------- |
A | src/platform_linux.c | | | 116 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/shader.c | | | 187 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | src/shader.h | | | 196 | ++++--------------------------------------------------------------------------- |
9 files changed, 779 insertions(+), 716 deletions(-)
diff --git a/Makefile b/Makefile
@@ -2,7 +2,7 @@ CC = clang
CFLAGS = -std=c99 -Ilib -Wall -Wextra -Wshadow -Wswitch-enum -Wno-unused-parameter -Wno-missing-braces
LDFLAGS = -ldl -lglfw -lGL -lGLEW -lGLU -lm -lpthread -lX11 -lXi -lXrandr
-SRC_FILES = glad.c main.c
+SRC_FILES = game.c glad.c glmth.c platform_linux.c shader.c
SRC = $(addprefix src/, $(SRC_FILES))
EXE_FILE = a_game
diff --git a/src/game.c b/src/game.c
@@ -0,0 +1,14 @@
+#include "game.h"
+#include <glad/glad.h>
+
+void game_update_and_render(GLuint vao_id, struct Shader *triangle_shader)
+{
+ glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glUseProgram(triangle_shader->program);
+
+ glBindVertexArray(vao_id);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ glBindVertexArray(0);
+}
diff --git a/src/game.h b/src/game.h
@@ -0,0 +1,8 @@
+#ifndef GAME_H
+#define GAME_H
+
+#include "shader.h"
+
+void game_update_and_render(GLuint vao_id, struct Shader *triangle_shader);
+
+#endif
diff --git a/src/glmth.c b/src/glmth.c
@@ -0,0 +1,411 @@
+#include "glmth.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+m4 glmth_m4_init_id()
+{
+ m4 m = { 0 };
+ m.E[0][0] = 1.0f;
+ m.E[1][1] = 1.0f;
+ m.E[2][2] = 1.0f;
+ m.E[3][3] = 1.0f;
+ return m;
+}
+
+
+void glmth_m4_print(m4 m)
+{
+ printf("[\n");
+ printf(" %f, %f, %f, %f\n", m.E[0][0], m.E[0][1], m.E[0][2], m.E[0][3]);
+ printf(" %f, %f, %f, %f\n", m.E[1][0], m.E[1][1], m.E[1][2], m.E[1][3]);
+ printf(" %f, %f, %f, %f\n", m.E[2][0], m.E[2][1], m.E[2][2], m.E[2][3]);
+ printf(" %f, %f, %f, %f\n", m.E[3][0], m.E[3][1], m.E[3][2], m.E[3][3]);
+ printf("]\n");
+}
+
+
+f32 *glmth_m4_valueptr(m4 m)
+{
+ f32 *values = malloc(sizeof(m4));
+ for (u8 v = 0; v < 16; ++v)
+ {
+ u8 row = v / 4;
+ u8 col = v % 4;
+ values[v] = m.E[row][col];
+ }
+ return values;
+}
+
+
+bool glmth_m4m4_eq(m4 mat1, m4 mat2)
+{
+ for (u8 i = 0; i < 4; ++i)
+ {
+ for (u8 j = 0; j < 4; ++j)
+ {
+ if (mat1.E[i][j] != mat2.E[i][j])
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+
+m4 glmth_m4m4_m(m4 mat1, m4 mat2)
+{
+ m4 r = {
+ .E[0][0] = (mat1.E[0][0] * mat2.E[0][0]) + (mat1.E[0][1] * mat2.E[1][0]) + (mat1.E[0][2] * mat2.E[2][0]) + (mat1.E[0][3] * mat2.E[3][0]),
+ .E[0][1] = (mat1.E[0][0] * mat2.E[0][1]) + (mat1.E[0][1] * mat2.E[1][1]) + (mat1.E[0][2] * mat2.E[2][1]) + (mat1.E[0][3] * mat2.E[3][1]),
+ .E[0][2] = (mat1.E[0][0] * mat2.E[0][2]) + (mat1.E[0][1] * mat2.E[1][2]) + (mat1.E[0][2] * mat2.E[2][2]) + (mat1.E[0][3] * mat2.E[3][2]),
+ .E[0][3] = (mat1.E[0][0] * mat2.E[0][3]) + (mat1.E[0][1] * mat2.E[1][3]) + (mat1.E[0][2] * mat2.E[2][3]) + (mat1.E[0][3] * mat2.E[3][3]),
+
+ .E[1][0] = (mat1.E[1][0] * mat2.E[0][0]) + (mat1.E[1][1] * mat2.E[1][0]) + (mat1.E[1][2] * mat2.E[2][0]) + (mat1.E[1][3] * mat2.E[3][0]),
+ .E[1][1] = (mat1.E[1][0] * mat2.E[0][1]) + (mat1.E[1][1] * mat2.E[1][1]) + (mat1.E[1][2] * mat2.E[2][1]) + (mat1.E[1][3] * mat2.E[3][1]),
+ .E[1][2] = (mat1.E[1][0] * mat2.E[0][2]) + (mat1.E[1][1] * mat2.E[1][2]) + (mat1.E[1][2] * mat2.E[2][2]) + (mat1.E[1][3] * mat2.E[3][2]),
+ .E[1][3] = (mat1.E[1][0] * mat2.E[0][3]) + (mat1.E[1][1] * mat2.E[1][3]) + (mat1.E[1][2] * mat2.E[2][3]) + (mat1.E[1][3] * mat2.E[3][3]),
+
+ .E[2][0] = (mat1.E[2][0] * mat2.E[0][0]) + (mat1.E[2][1] * mat2.E[1][0]) + (mat1.E[2][2] * mat2.E[2][0]) + (mat1.E[2][3] * mat2.E[3][0]),
+ .E[2][1] = (mat1.E[2][0] * mat2.E[0][1]) + (mat1.E[2][1] * mat2.E[1][1]) + (mat1.E[2][2] * mat2.E[2][1]) + (mat1.E[2][3] * mat2.E[3][1]),
+ .E[2][2] = (mat1.E[2][0] * mat2.E[0][2]) + (mat1.E[2][1] * mat2.E[1][2]) + (mat1.E[2][2] * mat2.E[2][2]) + (mat1.E[2][3] * mat2.E[3][2]),
+ .E[2][3] = (mat1.E[2][0] * mat2.E[0][3]) + (mat1.E[2][1] * mat2.E[1][3]) + (mat1.E[2][2] * mat2.E[2][3]) + (mat1.E[2][3] * mat2.E[3][3]),
+
+ .E[3][0] = (mat1.E[3][0] * mat2.E[0][0]) + (mat1.E[3][1] * mat2.E[1][0]) + (mat1.E[3][2] * mat2.E[2][0]) + (mat1.E[3][3] * mat2.E[3][0]),
+ .E[3][1] = (mat1.E[3][0] * mat2.E[0][1]) + (mat1.E[3][1] * mat2.E[1][1]) + (mat1.E[3][2] * mat2.E[2][1]) + (mat1.E[3][3] * mat2.E[3][1]),
+ .E[3][2] = (mat1.E[3][0] * mat2.E[0][2]) + (mat1.E[3][1] * mat2.E[1][2]) + (mat1.E[3][2] * mat2.E[2][2]) + (mat1.E[3][3] * mat2.E[3][2]),
+ .E[3][3] = (mat1.E[3][0] * mat2.E[0][3]) + (mat1.E[3][1] * mat2.E[1][3]) + (mat1.E[3][2] * mat2.E[2][3]) + (mat1.E[3][3] * mat2.E[3][3]),
+ };
+ return r;
+}
+
+
+v4 glmth_m4v4_m(m4 m, v4 v)
+{
+ v4 r = {
+ .x = (m.E[0][0] * v.x) + (m.E[0][1] * v.y) + (m.E[0][2] * v.z) + (m.E[0][3] * v.w),
+ .y = (m.E[1][0] * v.x) + (m.E[1][1] * v.y) + (m.E[1][2] * v.z) + (m.E[1][3] * v.w),
+ .z = (m.E[2][0] * v.x) + (m.E[2][1] * v.y) + (m.E[2][2] * v.z) + (m.E[2][3] * v.w),
+ .w = (m.E[3][0] * v.x) + (m.E[3][1] * v.y) + (m.E[3][2] * v.z) + (m.E[3][3] * v.w),
+ };
+ return r;
+}
+
+
+v3 glmth_v3_cross(v3 vec1, v3 vec2)
+{
+ v3 r = {
+ .x = (vec1.y * vec2.z) - (vec1.z * vec2.y),
+ .y = (vec1.z * vec2.x) - (vec1.x * vec2.z),
+ .z = (vec1.x * vec2.y) - (vec1.y * vec2.x),
+ };
+ return r;
+}
+
+
+v3 glmth_v3_init(f32 x, f32 y, f32 z)
+{
+ v3 v = { .x = x, .y = y, .z = z };
+ return v;
+}
+
+v3 glmth_v3_init_f(f32 f)
+{
+ return glmth_v3_init(f, f, f);
+}
+
+f32 glmth_v3_length(v3 v)
+{
+ return sqrtf((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
+}
+
+v3 glmth_v3f_m(v3 v, f32 s)
+{
+ v3 r = { .x = v.x * s, .y = v.y * s, .z = v.z * s };
+ return r;
+}
+
+v3 glmth_v3_negate(v3 v)
+{
+ v3 r = { .x = -v.x, .y = -v.y, .z = -v.z };
+ return r;
+}
+
+
+v3 glmth_v3_normalize(v3 v)
+{
+ f32 l = glmth_v3_length(v);
+ v3 r = glmth_v3_init(v.x / l, v.y / l, v.z / l);
+ return r;
+}
+
+
+void glmth_v3_print(v3 v)
+{
+ printf("( %f, %f, %f )\n", v.x, v.y, v.z);
+}
+
+
+v3 glmth_v3_a(v3 vec1, v3 vec2)
+{
+ v3 r = {
+ .x = vec1.x + vec2.x,
+ .y = vec1.y + vec2.y,
+ .z = vec1.z + vec2.z
+ };
+ return r;
+}
+
+
+v3 glmth_v3_s(v3 vec1, v3 vec2)
+{
+ return glmth_v3_a(vec1, glmth_v3_negate(vec2));
+}
+
+
+void glmth_v4_print(v4 v)
+{
+ printf("( %f, %f, %f, %f )\n", v.x, v.y, v.z, v.w);
+}
+
+
+bool glmth_v4v4_eq(v4 vec1, v4 vec2)
+{
+ for (u8 i = 0; i < 4; ++i)
+ {
+ if (vec1.E[i] != vec2.E[i])
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+void glmth_clampf(float *f, float min, float max)
+{
+ if (*f < min)
+ {
+ *f = min;
+ }
+ else if (*f > max)
+ {
+ *f = max;
+ }
+}
+
+
+f32 glmth_deg(f32 rad)
+{
+ return rad * (180.0f / M_PI);
+}
+
+
+float glmth_lerpf(float f, float min, float max)
+{
+ assert(f >= 0.0f && f <= 1.0f);
+ return (1.0f - f) * min + f * max;
+}
+
+
+f32 glmth_rad(f32 deg)
+{
+ return deg * (M_PI / 180.0f);
+}
+
+
+m4 glmth_rotate_x(m4 m, f32 rad)
+{
+ f32 c = cosf(rad);
+ f32 s = sinf(rad);
+
+ m4 r = glmth_m4_init_id();
+
+ r.E[1][1] = c;
+ r.E[1][2] = -s;
+
+ r.E[2][1] = s;
+ r.E[2][2] = c;
+
+ return glmth_m4m4_m(m, r);
+}
+
+
+m4 glmth_rotate_y(m4 m, f32 rad)
+{
+ f32 c = cosf(rad);
+ f32 s = sinf(rad);
+
+ m4 r = glmth_m4_init_id();
+
+ r.E[0][0] = c;
+ r.E[0][2] = s;
+
+ r.E[2][0] = -s;
+ r.E[2][2] = c;
+
+ return glmth_m4m4_m(m, r);
+}
+
+
+m4 glmth_rotate_z(m4 m, f32 rad)
+{
+ f32 c = cosf(rad);
+ f32 s = sinf(rad);
+
+ m4 r = glmth_m4_init_id();
+
+ r.E[0][0] = c;
+ r.E[0][1] = -s;
+
+ r.E[1][0] = s;
+ r.E[1][1] = c;
+
+ return glmth_m4m4_m(m, r);
+}
+
+
+m4 glmth_rotate(m4 m, f32 rad, v3 axis)
+{
+ axis = glmth_v3_normalize(axis);
+
+ f32 c = cosf(rad);
+ f32 s = sinf(rad);
+
+ m4 r = glmth_m4_init_id();
+
+ r.E[0][0] = c + (powf(axis.x, 2.0f) * (1 - c));
+ r.E[0][1] = (axis.x * axis.y * (1 - c)) - (axis.z * s);
+ r.E[0][2] = (axis.x * axis.z * (1 - c)) + (axis.y * s);
+
+ r.E[1][0] = (axis.y * axis.x * (1 - c)) + (axis.z * s);
+ r.E[1][1] = c + (powf(axis.y, 2.0f) * (1 - c));
+ r.E[1][2] = (axis.y * axis.z * (1 - c)) - (axis.x * s);
+
+ r.E[2][0] = (axis.z * axis.x * (1 - c)) - (axis.y * s);
+ r.E[2][1] = (axis.z * axis.y * (1 - c)) + (axis.x * s);
+ r.E[2][2] = c + (powf(axis.z, 2.0f) * (1 - c));
+
+ return glmth_m4m4_m(m, r);
+}
+
+
+m4 glmth_scale(m4 m, v3 v)
+{
+ m4 r = glmth_m4_init_id();
+ r.E[0][0] = v.x;
+ r.E[1][1] = v.y;
+ r.E[2][2] = v.z;
+ return glmth_m4m4_m(m, r);
+}
+
+
+m4 glmth_translate(m4 m, v3 v)
+{
+ m4 r = glmth_m4_init_id();
+ r.E[0][3] = v.x;
+ r.E[1][3] = v.y;
+ r.E[2][3] = v.z;
+ return glmth_m4m4_m(m, r);
+}
+
+
+m4 glmth_projection_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far)
+{
+ assert(left != right);
+ assert(bottom != top);
+ assert(near != far);
+
+ m4 r = glmth_m4_init_id();
+
+ r.E[0][0] = 2.0f / (right - left);
+ r.E[0][1] = 0.0f;
+ r.E[0][2] = 0.0f;
+ r.E[0][3] = -(right + left) / (right - left);
+
+ r.E[1][0] = 0.0f;
+ r.E[1][1] = 2.0f / (top - bottom);
+ r.E[1][2] = 0.0f;
+ r.E[1][3] = -(top + bottom) / (top - bottom);
+
+ r.E[2][0] = 0.0f;
+ r.E[2][1] = 0.0f;
+ r.E[2][2] = -2.0f / (far - near);
+ r.E[2][3] = -(far + near) / (far - near);
+
+ r.E[3][0] = 0.0f;
+ r.E[3][1] = 0.0f;
+ r.E[3][2] = 0.0f;
+ r.E[3][3] = 1.0f;
+
+ return r;
+}
+
+
+m4 glmth_projection_perspective(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far)
+{
+ assert(left != right);
+ assert(bottom != top);
+ assert(near != far);
+
+ m4 r = glmth_m4_init_id();
+
+ r.E[0][0] = (2.0f * near) / (right - left);
+ r.E[0][1] = 0.0f;
+ r.E[0][2] = (right + left) / (right - left);
+ r.E[0][3] = 0.0f;
+
+ r.E[1][0] = 0.0f;
+ r.E[1][1] = (2.0f * near) / (top - bottom);
+ r.E[1][2] = (top + bottom) / (top - bottom);
+ r.E[1][3] = 0.0f;
+
+ r.E[2][0] = 0.0f;
+ r.E[2][1] = 0.0f;
+ r.E[2][2] = -(far + near) / (far - near);
+ r.E[2][3] = (-2.0f * far * near) / (far - near);
+
+ r.E[3][0] = 0.0f;
+ r.E[3][1] = 0.0f;
+ r.E[3][2] = -1.0f;
+ r.E[3][3] = 0.0f;
+
+ return r;
+}
+
+
+m4 glmth_projection_perspective_fov(f32 fovy, f32 aspect, f32 near, f32 far)
+{
+ f32 half_height = tanf(fovy / 2.0f) * near;
+ f32 half_width = half_height * aspect;
+ f32 left = -half_width;
+ f32 right = half_width;
+ f32 bottom = -half_height;
+ f32 top = half_height;
+
+ return glmth_projection_perspective(left, right, bottom, top, near, far);
+}
+
+
+m4 glmth_camera_look_at(v3 camera_pos, v3 camera_target, v3 up)
+{
+ v3 camera_direction = glmth_v3_normalize(glmth_v3_s(camera_pos, camera_target));
+ v3 camera_right = glmth_v3_normalize(glmth_v3_cross(up, camera_direction));
+ v3 camera_up = glmth_v3_cross(camera_direction, camera_right);
+
+ m4 look = glmth_m4_init_id();
+ look.E[0][0] = camera_right.x;
+ look.E[0][1] = camera_right.y;
+ look.E[0][2] = camera_right.z;
+
+ look.E[1][0] = camera_up.x;
+ look.E[1][1] = camera_up.y;
+ look.E[1][2] = camera_up.z;
+
+ look.E[2][0] = camera_direction.x;
+ look.E[2][1] = camera_direction.y;
+ look.E[2][2] = camera_direction.z;
+
+ return glmth_m4m4_m(look, glmth_translate(glmth_m4_init_id(), glmth_v3_negate(camera_pos)));
+}
diff --git a/src/glmth.h b/src/glmth.h
@@ -92,412 +92,37 @@ typedef struct
} m4;
-m4 glmth_m4_init_id()
-{
- m4 m = { 0 };
- m.E[0][0] = 1.0f;
- m.E[1][1] = 1.0f;
- m.E[2][2] = 1.0f;
- m.E[3][3] = 1.0f;
- return m;
-}
-
-
-void glmth_m4_print(m4 m)
-{
- printf("[\n");
- printf(" %f, %f, %f, %f\n", m.E[0][0], m.E[0][1], m.E[0][2], m.E[0][3]);
- printf(" %f, %f, %f, %f\n", m.E[1][0], m.E[1][1], m.E[1][2], m.E[1][3]);
- printf(" %f, %f, %f, %f\n", m.E[2][0], m.E[2][1], m.E[2][2], m.E[2][3]);
- printf(" %f, %f, %f, %f\n", m.E[3][0], m.E[3][1], m.E[3][2], m.E[3][3]);
- printf("]\n");
-}
-
-
-f32 *glmth_m4_valueptr(m4 m)
-{
- f32 *values = malloc(sizeof(m4));
- for (u8 v = 0; v < 16; ++v)
- {
- u8 row = v / 4;
- u8 col = v % 4;
- values[v] = m.E[row][col];
- }
- return values;
-}
-
-
-bool glmth_m4m4_eq(m4 mat1, m4 mat2)
-{
- for (u8 i = 0; i < 4; ++i)
- {
- for (u8 j = 0; j < 4; ++j)
- {
- if (mat1.E[i][j] != mat2.E[i][j])
- {
- return false;
- }
- }
- }
- return true;
-}
-
-
-m4 glmth_m4m4_m(m4 mat1, m4 mat2)
-{
- m4 r = {
- .E[0][0] = (mat1.E[0][0] * mat2.E[0][0]) + (mat1.E[0][1] * mat2.E[1][0]) + (mat1.E[0][2] * mat2.E[2][0]) + (mat1.E[0][3] * mat2.E[3][0]),
- .E[0][1] = (mat1.E[0][0] * mat2.E[0][1]) + (mat1.E[0][1] * mat2.E[1][1]) + (mat1.E[0][2] * mat2.E[2][1]) + (mat1.E[0][3] * mat2.E[3][1]),
- .E[0][2] = (mat1.E[0][0] * mat2.E[0][2]) + (mat1.E[0][1] * mat2.E[1][2]) + (mat1.E[0][2] * mat2.E[2][2]) + (mat1.E[0][3] * mat2.E[3][2]),
- .E[0][3] = (mat1.E[0][0] * mat2.E[0][3]) + (mat1.E[0][1] * mat2.E[1][3]) + (mat1.E[0][2] * mat2.E[2][3]) + (mat1.E[0][3] * mat2.E[3][3]),
-
- .E[1][0] = (mat1.E[1][0] * mat2.E[0][0]) + (mat1.E[1][1] * mat2.E[1][0]) + (mat1.E[1][2] * mat2.E[2][0]) + (mat1.E[1][3] * mat2.E[3][0]),
- .E[1][1] = (mat1.E[1][0] * mat2.E[0][1]) + (mat1.E[1][1] * mat2.E[1][1]) + (mat1.E[1][2] * mat2.E[2][1]) + (mat1.E[1][3] * mat2.E[3][1]),
- .E[1][2] = (mat1.E[1][0] * mat2.E[0][2]) + (mat1.E[1][1] * mat2.E[1][2]) + (mat1.E[1][2] * mat2.E[2][2]) + (mat1.E[1][3] * mat2.E[3][2]),
- .E[1][3] = (mat1.E[1][0] * mat2.E[0][3]) + (mat1.E[1][1] * mat2.E[1][3]) + (mat1.E[1][2] * mat2.E[2][3]) + (mat1.E[1][3] * mat2.E[3][3]),
-
- .E[2][0] = (mat1.E[2][0] * mat2.E[0][0]) + (mat1.E[2][1] * mat2.E[1][0]) + (mat1.E[2][2] * mat2.E[2][0]) + (mat1.E[2][3] * mat2.E[3][0]),
- .E[2][1] = (mat1.E[2][0] * mat2.E[0][1]) + (mat1.E[2][1] * mat2.E[1][1]) + (mat1.E[2][2] * mat2.E[2][1]) + (mat1.E[2][3] * mat2.E[3][1]),
- .E[2][2] = (mat1.E[2][0] * mat2.E[0][2]) + (mat1.E[2][1] * mat2.E[1][2]) + (mat1.E[2][2] * mat2.E[2][2]) + (mat1.E[2][3] * mat2.E[3][2]),
- .E[2][3] = (mat1.E[2][0] * mat2.E[0][3]) + (mat1.E[2][1] * mat2.E[1][3]) + (mat1.E[2][2] * mat2.E[2][3]) + (mat1.E[2][3] * mat2.E[3][3]),
-
- .E[3][0] = (mat1.E[3][0] * mat2.E[0][0]) + (mat1.E[3][1] * mat2.E[1][0]) + (mat1.E[3][2] * mat2.E[2][0]) + (mat1.E[3][3] * mat2.E[3][0]),
- .E[3][1] = (mat1.E[3][0] * mat2.E[0][1]) + (mat1.E[3][1] * mat2.E[1][1]) + (mat1.E[3][2] * mat2.E[2][1]) + (mat1.E[3][3] * mat2.E[3][1]),
- .E[3][2] = (mat1.E[3][0] * mat2.E[0][2]) + (mat1.E[3][1] * mat2.E[1][2]) + (mat1.E[3][2] * mat2.E[2][2]) + (mat1.E[3][3] * mat2.E[3][2]),
- .E[3][3] = (mat1.E[3][0] * mat2.E[0][3]) + (mat1.E[3][1] * mat2.E[1][3]) + (mat1.E[3][2] * mat2.E[2][3]) + (mat1.E[3][3] * mat2.E[3][3]),
- };
- return r;
-}
-
-
-v4 glmth_m4v4_m(m4 m, v4 v)
-{
- v4 r = {
- .x = (m.E[0][0] * v.x) + (m.E[0][1] * v.y) + (m.E[0][2] * v.z) + (m.E[0][3] * v.w),
- .y = (m.E[1][0] * v.x) + (m.E[1][1] * v.y) + (m.E[1][2] * v.z) + (m.E[1][3] * v.w),
- .z = (m.E[2][0] * v.x) + (m.E[2][1] * v.y) + (m.E[2][2] * v.z) + (m.E[2][3] * v.w),
- .w = (m.E[3][0] * v.x) + (m.E[3][1] * v.y) + (m.E[3][2] * v.z) + (m.E[3][3] * v.w),
- };
- return r;
-}
-
-
-v3 glmth_v3_cross(v3 vec1, v3 vec2)
-{
- v3 r = {
- .x = (vec1.y * vec2.z) - (vec1.z * vec2.y),
- .y = (vec1.z * vec2.x) - (vec1.x * vec2.z),
- .z = (vec1.x * vec2.y) - (vec1.y * vec2.x),
- };
- return r;
-}
-
-
-v3 glmth_v3_init(f32 x, f32 y, f32 z)
-{
- v3 v = { .x = x, .y = y, .z = z };
- return v;
-}
-
-v3 glmth_v3_init_f(f32 f)
-{
- return glmth_v3_init(f, f, f);
-}
-
-f32 glmth_v3_length(v3 v)
-{
- return sqrtf((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
-}
-
-v3 glmth_v3f_m(v3 v, f32 s)
-{
- v3 r = { .x = v.x * s, .y = v.y * s, .z = v.z * s };
- return r;
-}
-
-v3 glmth_v3_negate(v3 v)
-{
- v3 r = { .x = -v.x, .y = -v.y, .z = -v.z };
- return r;
-}
-
-
-v3 glmth_v3_normalize(v3 v)
-{
- f32 l = glmth_v3_length(v);
- v3 r = glmth_v3_init(v.x / l, v.y / l, v.z / l);
- return r;
-}
-
-
-void glmth_v3_print(v3 v)
-{
- printf("( %f, %f, %f )\n", v.x, v.y, v.z);
-}
-
-
-v3 glmth_v3_a(v3 vec1, v3 vec2)
-{
- v3 r = {
- .x = vec1.x + vec2.x,
- .y = vec1.y + vec2.y,
- .z = vec1.z + vec2.z
- };
- return r;
-}
-
-
-v3 glmth_v3_s(v3 vec1, v3 vec2)
-{
- return glmth_v3_a(vec1, glmth_v3_negate(vec2));
-}
-
-
-void glmth_v4_print(v4 v)
-{
- printf("( %f, %f, %f, %f )\n", v.x, v.y, v.z, v.w);
-}
-
-
-bool glmth_v4v4_eq(v4 vec1, v4 vec2)
-{
- for (u8 i = 0; i < 4; ++i)
- {
- if (vec1.E[i] != vec2.E[i])
- {
- return false;
- }
- }
- return true;
-}
-
-
-void glmth_clampf(float *f, float min, float max)
-{
- if (*f < min)
- {
- *f = min;
- }
- else if (*f > max)
- {
- *f = max;
- }
-}
-
-
-f32 glmth_deg(f32 rad)
-{
- return rad * (180.0f / M_PI);
-}
-
-
-float glmth_lerpf(float f, float min, float max)
-{
- assert(f >= 0.0f && f <= 1.0f);
- return (1.0f - f) * min + f * max;
-}
-
-
-f32 glmth_rad(f32 deg)
-{
- return deg * (M_PI / 180.0f);
-}
-
-
-m4 glmth_rotate_x(m4 m, f32 rad)
-{
- f32 c = cosf(rad);
- f32 s = sinf(rad);
-
- m4 r = glmth_m4_init_id();
-
- r.E[1][1] = c;
- r.E[1][2] = -s;
-
- r.E[2][1] = s;
- r.E[2][2] = c;
-
- return glmth_m4m4_m(m, r);
-}
-
-
-m4 glmth_rotate_y(m4 m, f32 rad)
-{
- f32 c = cosf(rad);
- f32 s = sinf(rad);
-
- m4 r = glmth_m4_init_id();
-
- r.E[0][0] = c;
- r.E[0][2] = s;
-
- r.E[2][0] = -s;
- r.E[2][2] = c;
-
- return glmth_m4m4_m(m, r);
-}
-
-
-m4 glmth_rotate_z(m4 m, f32 rad)
-{
- f32 c = cosf(rad);
- f32 s = sinf(rad);
-
- m4 r = glmth_m4_init_id();
-
- r.E[0][0] = c;
- r.E[0][1] = -s;
-
- r.E[1][0] = s;
- r.E[1][1] = c;
-
- return glmth_m4m4_m(m, r);
-}
-
-
-m4 glmth_rotate(m4 m, f32 rad, v3 axis)
-{
- axis = glmth_v3_normalize(axis);
-
- f32 c = cosf(rad);
- f32 s = sinf(rad);
-
- m4 r = glmth_m4_init_id();
-
- r.E[0][0] = c + (powf(axis.x, 2.0f) * (1 - c));
- r.E[0][1] = (axis.x * axis.y * (1 - c)) - (axis.z * s);
- r.E[0][2] = (axis.x * axis.z * (1 - c)) + (axis.y * s);
-
- r.E[1][0] = (axis.y * axis.x * (1 - c)) + (axis.z * s);
- r.E[1][1] = c + (powf(axis.y, 2.0f) * (1 - c));
- r.E[1][2] = (axis.y * axis.z * (1 - c)) - (axis.x * s);
-
- r.E[2][0] = (axis.z * axis.x * (1 - c)) - (axis.y * s);
- r.E[2][1] = (axis.z * axis.y * (1 - c)) + (axis.x * s);
- r.E[2][2] = c + (powf(axis.z, 2.0f) * (1 - c));
-
- return glmth_m4m4_m(m, r);
-}
-
-
-m4 glmth_scale(m4 m, v3 v)
-{
- m4 r = glmth_m4_init_id();
- r.E[0][0] = v.x;
- r.E[1][1] = v.y;
- r.E[2][2] = v.z;
- return glmth_m4m4_m(m, r);
-}
-
-
-m4 glmth_translate(m4 m, v3 v)
-{
- m4 r = glmth_m4_init_id();
- r.E[0][3] = v.x;
- r.E[1][3] = v.y;
- r.E[2][3] = v.z;
- return glmth_m4m4_m(m, r);
-}
-
-
-m4 glmth_projection_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far)
-{
- assert(left != right);
- assert(bottom != top);
- assert(near != far);
-
- m4 r = glmth_m4_init_id();
-
- r.E[0][0] = 2.0f / (right - left);
- r.E[0][1] = 0.0f;
- r.E[0][2] = 0.0f;
- r.E[0][3] = -(right + left) / (right - left);
-
- r.E[1][0] = 0.0f;
- r.E[1][1] = 2.0f / (top - bottom);
- r.E[1][2] = 0.0f;
- r.E[1][3] = -(top + bottom) / (top - bottom);
-
- r.E[2][0] = 0.0f;
- r.E[2][1] = 0.0f;
- r.E[2][2] = -2.0f / (far - near);
- r.E[2][3] = -(far + near) / (far - near);
-
- r.E[3][0] = 0.0f;
- r.E[3][1] = 0.0f;
- r.E[3][2] = 0.0f;
- r.E[3][3] = 1.0f;
-
- return r;
-}
-
-
-m4 glmth_projection_perspective(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far)
-{
- assert(left != right);
- assert(bottom != top);
- assert(near != far);
-
- m4 r = glmth_m4_init_id();
-
- r.E[0][0] = (2.0f * near) / (right - left);
- r.E[0][1] = 0.0f;
- r.E[0][2] = (right + left) / (right - left);
- r.E[0][3] = 0.0f;
-
- r.E[1][0] = 0.0f;
- r.E[1][1] = (2.0f * near) / (top - bottom);
- r.E[1][2] = (top + bottom) / (top - bottom);
- r.E[1][3] = 0.0f;
-
- r.E[2][0] = 0.0f;
- r.E[2][1] = 0.0f;
- r.E[2][2] = -(far + near) / (far - near);
- r.E[2][3] = (-2.0f * far * near) / (far - near);
-
- r.E[3][0] = 0.0f;
- r.E[3][1] = 0.0f;
- r.E[3][2] = -1.0f;
- r.E[3][3] = 0.0f;
-
- return r;
-}
-
-
-m4 glmth_projection_perspective_fov(f32 fovy, f32 aspect, f32 near, f32 far)
-{
- f32 half_height = tanf(fovy / 2.0f) * near;
- f32 half_width = half_height * aspect;
- f32 left = -half_width;
- f32 right = half_width;
- f32 bottom = -half_height;
- f32 top = half_height;
-
- return glmth_projection_perspective(left, right, bottom, top, near, far);
-}
-
-
-m4 glmth_camera_look_at(v3 camera_pos, v3 camera_target, v3 up)
-{
- v3 camera_direction = glmth_v3_normalize(glmth_v3_s(camera_pos, camera_target));
- v3 camera_right = glmth_v3_normalize(glmth_v3_cross(up, camera_direction));
- v3 camera_up = glmth_v3_cross(camera_direction, camera_right);
-
- m4 look = glmth_m4_init_id();
- look.E[0][0] = camera_right.x;
- look.E[0][1] = camera_right.y;
- look.E[0][2] = camera_right.z;
-
- look.E[1][0] = camera_up.x;
- look.E[1][1] = camera_up.y;
- look.E[1][2] = camera_up.z;
-
- look.E[2][0] = camera_direction.x;
- look.E[2][1] = camera_direction.y;
- look.E[2][2] = camera_direction.z;
-
- return glmth_m4m4_m(look, glmth_translate(glmth_m4_init_id(), glmth_v3_negate(camera_pos)));
-}
-
+m4 glmth_m4_init_id();
+void glmth_m4_print(m4 m);
+f32 *glmth_m4_valueptr(m4 m);
+bool glmth_m4m4_eq(m4 mat1, m4 mat2);
+m4 glmth_m4m4_m(m4 mat1, m4 mat2);
+v4 glmth_m4v4_m(m4 m, v4 v);
+v3 glmth_v3_cross(v3 vec1, v3 vec2);
+v3 glmth_v3_init(f32 x, f32 y, f32 z);
+v3 glmth_v3_init_f(f32 f);
+f32 glmth_v3_length(v3 v);
+v3 glmth_v3f_m(v3 v, f32 s);
+v3 glmth_v3_negate(v3 v);
+v3 glmth_v3_normalize(v3 v);
+void glmth_v3_print(v3 v);
+v3 glmth_v3_a(v3 vec1, v3 vec2);
+v3 glmth_v3_s(v3 vec1, v3 vec2);
+void glmth_v4_print(v4 v);
+bool glmth_v4v4_eq(v4 vec1, v4 vec2);
+void glmth_clampf(float *f, float min, float max);
+f32 glmth_deg(f32 rad);
+float glmth_lerpf(float f, float min, float max);
+f32 glmth_rad(f32 deg);
+m4 glmth_rotate_x(m4 m, f32 rad);
+m4 glmth_rotate_y(m4 m, f32 rad);
+m4 glmth_rotate_z(m4 m, f32 rad);
+m4 glmth_rotate(m4 m, f32 rad, v3 axis);
+m4 glmth_scale(m4 m, v3 v);
+m4 glmth_translate(m4 m, v3 v);
+m4 glmth_projection_ortho(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far);
+m4 glmth_projection_perspective(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far);
+m4 glmth_projection_perspective_fov(f32 fovy, f32 aspect, f32 near, f32 far);
+m4 glmth_camera_look_at(v3 camera_pos, v3 camera_target, v3 up);
#endif
diff --git a/src/main.c b/src/main.c
@@ -1,122 +0,0 @@
-#include <stdio.h>
-
-#include <glad/glad.h>
-#include <GLFW/glfw3.h>
-
-#include "shader.h"
-#include "glmth.h"
-
-
-#define SCR_WIDTH 800
-#define SCR_HEIGHT 600
-
-void error_callback(int error, const char* description);
-void framebuffer_size_callback(GLFWwindow* window, int width, int height);
-
-#ifdef GLAD_DEBUG
-void pre_gl_callback(const char *func_name, void *func_ptr, int len_args, ...);
-#endif
-
-
-int main(void)
-{
- glfwSetErrorCallback(error_callback);
-
- if (!glfwInit())
- {
- fprintf(stderr, "GLFW initialization failed\n");
- return -1;
- }
-
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
-
- GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "A Game", NULL, NULL);
- if (!window)
- {
- fprintf(stderr, "GLFW window creation failed\n");
- glfwTerminate();
- return -1;
- }
- glfwMakeContextCurrent(window);
- glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
-
- if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
- {
- fprintf(stderr, "glad initialization failed\n");
- glfwDestroyWindow(window);
- glfwTerminate();
- return -1;
- }
-
- struct Shader triangle_shader = shader_compile("shader/triangle_v.glsl", "shader/triangle_f.glsl");
-
- GLfloat triangle_vertices[] = {
- // positions // colors
- -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
- 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.5f, 0.0f, 0.0f, 1.0f,
- };
-
- GLuint VBO;
- GLuint VAO;
- glGenVertexArrays(1, &VAO);
- glGenBuffers(1, &VBO);
-
- glBindVertexArray(VAO);
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_vertices), triangle_vertices, GL_STATIC_DRAW);
-
- // positions
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
- glEnableVertexAttribArray(0);
-
- // colors
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat)));
- glEnableVertexAttribArray(1);
- glBindVertexArray(0);
-
- while (!glfwWindowShouldClose(window))
- {
- glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- glUseProgram(triangle_shader.program);
-
- glBindVertexArray(VAO);
- glDrawArrays(GL_TRIANGLES, 0, 3);
- glBindVertexArray(0);
-
- glfwSwapBuffers(window);
- glfwPollEvents();
- }
-
- glDeleteVertexArrays(1, &VAO);
- glDeleteBuffers(1, &VBO);
-
- glfwDestroyWindow(window);
- glfwTerminate();
- return 0;
-}
-
-
-void error_callback(int error, const char* description)
-{
- fprintf(stderr, "Error: %s\n", description);
-}
-
-
-void framebuffer_size_callback(GLFWwindow* window, int width, int height)
-{
- glViewport(0, 0, width, height);
-}
-
-
-#ifdef GLAD_DEBUG
-void pre_gl_callback(const char *func_name, void *func_ptr, int len_args, ...)
-{
- printf("Calling: %s (%d arguments)\n", func_name, len_args);
-}
-#endif
diff --git a/src/platform_linux.c b/src/platform_linux.c
@@ -0,0 +1,116 @@
+#include <stdio.h>
+
+#include <glad/glad.h>
+#include <GLFW/glfw3.h>
+
+#include "shader.h"
+#include "glmth.h"
+#include "game.h"
+
+
+#define SCR_WIDTH 800
+#define SCR_HEIGHT 600
+
+void error_callback(int error, const char* description);
+void framebuffer_size_callback(GLFWwindow* window, int width, int height);
+
+#ifdef GLAD_DEBUG
+void pre_gl_callback(const char *func_name, void *func_ptr, int len_args, ...);
+#endif
+
+
+int main(void)
+{
+ glfwSetErrorCallback(error_callback);
+
+ if (!glfwInit())
+ {
+ fprintf(stderr, "GLFW initialization failed\n");
+ return -1;
+ }
+
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+ glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
+
+ GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "A Game", NULL, NULL);
+ if (!window)
+ {
+ fprintf(stderr, "GLFW window creation failed\n");
+ glfwTerminate();
+ return -1;
+ }
+ glfwMakeContextCurrent(window);
+ glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
+
+ if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress))
+ {
+ fprintf(stderr, "glad initialization failed\n");
+ glfwDestroyWindow(window);
+ glfwTerminate();
+ return -1;
+ }
+
+ struct Shader triangle_shader = shader_compile("shader/triangle_v.glsl", "shader/triangle_f.glsl");
+
+ GLfloat triangle_vertices[] = {
+ // positions // colors
+ -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
+ 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.5f, 0.0f, 0.0f, 1.0f,
+ };
+
+ GLuint vbo_id;
+ GLuint vao_id;
+ glGenVertexArrays(1, &vao_id);
+ glGenBuffers(1, &vbo_id);
+
+ glBindVertexArray(vao_id);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(triangle_vertices), triangle_vertices, GL_STATIC_DRAW);
+
+ // positions
+ // TODO: make sizeof dereference pointer
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
+ glEnableVertexAttribArray(0);
+
+ // colors
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat)));
+ glEnableVertexAttribArray(1);
+ glBindVertexArray(0);
+
+ while (!glfwWindowShouldClose(window))
+ {
+ game_update_and_render(vao_id, &triangle_shader);
+ glfwSwapBuffers(window);
+ glfwPollEvents();
+ }
+
+ glDeleteVertexArrays(1, &vao_id);
+ glDeleteBuffers(1, &vbo_id);
+
+ glfwDestroyWindow(window);
+ glfwTerminate();
+ return 0;
+}
+
+
+void error_callback(int error, const char* description)
+{
+ fprintf(stderr, "Error: %s\n", description);
+}
+
+
+void framebuffer_size_callback(GLFWwindow* window, int width, int height)
+{
+ glViewport(0, 0, width, height);
+}
+
+
+#ifdef GLAD_DEBUG
+void pre_gl_callback(const char *func_name, void *func_ptr, int len_args, ...)
+{
+ printf("Calling: %s (%d arguments)\n", func_name, len_args);
+}
+#endif
diff --git a/src/shader.c b/src/shader.c
@@ -0,0 +1,187 @@
+#include "shader.h"
+
+
+char *read_file(char *file_path)
+{
+ FILE *handle = fopen(file_path, "r");
+ char *buffer = NULL;
+
+ if (handle)
+ {
+ // get file size
+ fseek(handle, 0, SEEK_END);
+ uint32_t num_bytes_in_file = ftell(handle);
+ rewind(handle);
+
+ buffer = (char*) malloc(sizeof(char) * (num_bytes_in_file + 1) );
+
+ uint32_t bytes_read = fread(buffer, sizeof(char), num_bytes_in_file, handle);
+ // IMPORTANT! fread() doesn't add the '\0'
+ buffer[num_bytes_in_file] = '\0';
+
+ if (num_bytes_in_file != bytes_read)
+ {
+ free(buffer);
+ buffer = NULL;
+ }
+
+ fclose(handle);
+ }
+ else
+ {
+ printf("Error: Couldn't open file at path: %s", file_path);
+ }
+
+ return buffer;
+}
+
+
+struct Shader shader_compile(GLchar *vertex_path, GLchar *fragment_path)
+{
+ const GLchar *vertex_shader_source = read_file(vertex_path);
+ const GLchar *fragment_shader_source = read_file(fragment_path);
+
+ GLint success;
+ GLchar info_log[512];
+
+ GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
+ glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
+ glCompileShader(vertex_shader);
+ glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
+ if (!success)
+ {
+ glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
+ printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n", info_log);
+ }
+
+ GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
+ glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
+ glCompileShader(fragment_shader);
+ glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
+ if (!success)
+ {
+ glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
+ printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s\n", info_log);
+ }
+
+ struct Shader s;
+ s.program = glCreateProgram();
+ glAttachShader(s.program, vertex_shader);
+ glAttachShader(s.program, fragment_shader);
+ glLinkProgram(s.program);
+ glGetProgramiv(s.program, GL_LINK_STATUS, &success);
+ if (!success)
+ {
+ glGetShaderInfoLog(s.program, 512, NULL, info_log);
+ printf("ERROR::SHADER::LINKING_FAILED\n %s\n", info_log);
+ }
+
+ glDeleteShader(fragment_shader);
+ glDeleteShader(vertex_shader);
+
+ return s;
+}
+
+
+void shader_use(struct Shader *s)
+{
+ if (s)
+ {
+ glUseProgram(s->program);
+ }
+ else
+ {
+ printf("Error: invalid Shader pointer\n");
+ }
+}
+
+
+void shader_setb(struct Shader *s, char *name, bool value)
+{
+ if (s)
+ {
+ glUniform1i(glGetUniformLocation(s->program, name), (int)value);
+ }
+ else
+ {
+ printf("Error: invalid Shader pointer\n");
+ }
+}
+
+
+void shader_seti(struct Shader *s, char *name, int value)
+{
+ if (s)
+ {
+ glUniform1i(glGetUniformLocation(s->program, name), value);
+ }
+ else
+ {
+ printf("Error: invalid Shader pointer\n");
+ }
+}
+
+
+void shader_setf(struct Shader *s, char *name, f32 value)
+{
+ if (s)
+ {
+ glUniform1f(glGetUniformLocation(s->program, name), value);
+ }
+ else
+ {
+ printf("Error: invalid Shader pointer\n");
+ }
+}
+
+
+void shader_setm4(struct Shader *s, char *name, m4 *mat)
+{
+ if (s)
+ {
+ glUniformMatrix4fv(glGetUniformLocation(s->program, name), 1, GL_TRUE, glmth_m4_valueptr(*mat));
+ }
+ else
+ {
+ printf("Error: invalid Shader pointer\n");
+ }
+}
+
+
+void shader_setf3(struct Shader *s, char *name, f32 x, f32 y, f32 z)
+{
+ if (s)
+ {
+ glUniform3f(glGetUniformLocation(s->program, name), x, y, z);
+ }
+ else
+ {
+ printf("Error: invalid Shader pointer\n");
+ }
+}
+
+
+void shader_setf3_1(struct Shader *s, char *name, f32 f)
+{
+ if (s)
+ {
+ shader_setf3(s, name, f, f, f);
+ }
+ else
+ {
+ printf("Error: invalid Shader pointer\n");
+ }
+}
+
+
+void shader_setv3(struct Shader *s, char *name, v3 *v)
+{
+ if (s)
+ {
+ shader_setf3(s, name, v->x, v->y, v->z);
+ }
+ else
+ {
+ printf("Error: invalid Shader pointer\n");
+ }
+}
diff --git a/src/shader.h b/src/shader.h
@@ -13,191 +13,15 @@ struct Shader
uint32_t program;
};
-
-char *read_file(char *file_path)
-{
- FILE *handle = fopen(file_path, "r");
- char *buffer = NULL;
-
- if (handle)
- {
- // get file size
- fseek(handle, 0, SEEK_END);
- uint32_t num_bytes_in_file = ftell(handle);
- rewind(handle);
-
- buffer = (char*) malloc(sizeof(char) * (num_bytes_in_file + 1) );
-
- uint32_t bytes_read = fread(buffer, sizeof(char), num_bytes_in_file, handle);
- // IMPORTANT! fread() doesn't add the '\0'
- buffer[num_bytes_in_file] = '\0';
-
- if (num_bytes_in_file != bytes_read)
- {
- free(buffer);
- buffer = NULL;
- }
-
- fclose(handle);
- }
- else
- {
- printf("Error: Couldn't open file at path: %s", file_path);
- }
-
- return buffer;
-}
-
-
-struct Shader shader_compile(GLchar *vertex_path, GLchar *fragment_path)
-{
- const GLchar *vertex_shader_source = read_file(vertex_path);
- const GLchar *fragment_shader_source = read_file(fragment_path);
-
- GLint success;
- GLchar info_log[512];
-
- GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
- glCompileShader(vertex_shader);
- glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &success);
- if (!success)
- {
- glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
- printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n", info_log);
- }
-
- GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
- glCompileShader(fragment_shader);
- glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &success);
- if (!success)
- {
- glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
- printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s\n", info_log);
- }
-
- struct Shader s;
- s.program = glCreateProgram();
- glAttachShader(s.program, vertex_shader);
- glAttachShader(s.program, fragment_shader);
- glLinkProgram(s.program);
- glGetProgramiv(s.program, GL_LINK_STATUS, &success);
- if (!success)
- {
- glGetShaderInfoLog(s.program, 512, NULL, info_log);
- printf("ERROR::SHADER::LINKING_FAILED\n %s\n", info_log);
- }
-
- glDeleteShader(fragment_shader);
- glDeleteShader(vertex_shader);
-
- return s;
-}
-
-
-void shader_use(struct Shader *s)
-{
- if (s)
- {
- glUseProgram(s->program);
- }
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
-}
-
-
-void shader_setb(struct Shader *s, char *name, bool value)
-{
- if (s)
- {
- glUniform1i(glGetUniformLocation(s->program, name), (int)value);
- }
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
-}
-
-
-void shader_seti(struct Shader *s, char *name, int value)
-{
- if (s)
- {
- glUniform1i(glGetUniformLocation(s->program, name), value);
- }
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
-}
-
-
-void shader_setf(struct Shader *s, char *name, f32 value)
-{
- if (s)
- {
- glUniform1f(glGetUniformLocation(s->program, name), value);
- }
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
-}
-
-
-void shader_setm4(struct Shader *s, char *name, m4 *mat)
-{
- if (s)
- {
- glUniformMatrix4fv(glGetUniformLocation(s->program, name), 1, GL_TRUE, glmth_m4_valueptr(*mat));
- }
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
-}
-
-
-void shader_setf3(struct Shader *s, char *name, f32 x, f32 y, f32 z)
-{
- if (s)
- {
- glUniform3f(glGetUniformLocation(s->program, name), x, y, z);
- }
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
-}
-
-
-void shader_setf3_1(struct Shader *s, char *name, f32 f)
-{
- if (s)
- {
- shader_setf3(s, name, f, f, f);
- }
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
-}
-
-
-void shader_setv3(struct Shader *s, char *name, v3 *v)
-{
- if (s)
- {
- shader_setf3(s, name, v->x, v->y, v->z);
- }
- else
- {
- printf("Error: invalid Shader pointer\n");
- }
-}
-
+char *read_file(char *file_path);
+struct Shader shader_compile(GLchar *vertex_path, GLchar *fragment_path);
+void shader_use(struct Shader *s);
+void shader_setb(struct Shader *s, char *name, bool value);
+void shader_seti(struct Shader *s, char *name, int value);
+void shader_setf(struct Shader *s, char *name, f32 value);
+void shader_setm4(struct Shader *s, char *name, m4 *mat);
+void shader_setf3(struct Shader *s, char *name, f32 x, f32 y, f32 z);
+void shader_setf3_1(struct Shader *s, char *name, f32 f);
+void shader_setv3(struct Shader *s, char *name, v3 *v);
#endif