a-game

2D platformer written from scratch.
git clone git://git.amin.space/a-game.git
Log | Files | Refs | README | LICENSE

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:
MMakefile | 2+-
Asrc/game.c | 14++++++++++++++
Asrc/game.h | 8++++++++
Asrc/glmth.c | 411+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/glmth.h | 439++++++-------------------------------------------------------------------------
Dsrc/main.c | 122-------------------------------------------------------------------------------
Asrc/platform_linux.c | 116+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/shader.c | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/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