transparent-cube

Minimal cross-platform native/wasm graphics example.
git clone git://git.amin.space/transparent-cube.git
Log | Files | Refs | README | LICENSE

commit 604c8c44f8d040b28e08dd9256000e3d007eae02
parent dcad58da5a6dd0e438ca6aadc2b9d20bd466aaec
Author: amin <dev@aminmesbah.com>
Date:   Sat, 15 Jun 2019 23:39:07 +0000

Hoist file io to platform layer

FossilOrigin-Name: 9f8eca96334459fd9032869c1b81df4ffd2a9d5cbec5c359862b12f6381de3ea
Diffstat:
Msrc/game.c | 11++++++++++-
Msrc/game.h | 20+-------------------
Msrc/glmth.h | 6++----
Msrc/platform_linux.c | 39+++++++++++++++++++++++++++++++++++++++
Msrc/platform_linux.h | 10++--------
Msrc/shader.c | 118++++++++++++++++++++++++++++++++-----------------------------------------------
Msrc/shader.h | 5+----
7 files changed, 102 insertions(+), 107 deletions(-)

diff --git a/src/game.c b/src/game.c @@ -59,7 +59,16 @@ void game_init(struct GameState *game_state, uint32_t screen_width, uint32_t scr game_state->cube_ebo = cube_ebo; } - game_state->cube_shader = shader_compile("shader/cube_v.glsl", "shader/cube_f.glsl"); + // game_shader_load + { + struct PlatformApi platform = game_state->platform; + char *v_source = platform.platform_read_entire_file("shader/cube_v.glsl"); + char *f_source = platform.platform_read_entire_file("shader/cube_f.glsl"); + struct Shader main_shader = shader_compile(v_source, f_source); + free(v_source); + free(f_source); + game_state->cube_shader = main_shader; + } glEnable(GL_DEPTH_TEST); diff --git a/src/game.h b/src/game.h @@ -15,25 +15,7 @@ #include "glmth.h" #include "shader.h" - -struct GameState -{ - u32 cube_vao; - u32 cube_vbo; - u32 cube_ebo; - struct Shader cube_shader; -}; - -typedef void (game_update_and_render_func)(struct GameState *game_state, float dt, u32 screen_width, u32 screen_height); -void game_update_and_render(struct GameState *game_state, float dt, u32 screen_width, u32 screen_height); +#include "platform.h" void game_init(struct GameState *game_state, u32 screen_width, u32 screen_height); void game_cleanup(struct GameState *game_state); - -#ifdef PLATFORM_HOTLOAD_GAME_CODE -// We need to call this from the platform layer in order for the game, when -// built as a shared object library to have access to the OpenGL symbols. -// https://github.com/Dav1dde/glad/issues/151 -typedef void (game_load_opengl_symbols_func)(void); -void game_load_opengl_symbols(void); -#endif // PLATFORM_HOTLOAD_GAME_CODE diff --git a/src/glmth.h b/src/glmth.h @@ -95,16 +95,14 @@ static inline m4 glmth_m4_init_id(void) return m; } -static inline f32 *glmth_m4_valueptr(m4 m) +static inline void glmth_m4_valueptr(m4 m, f32* out_valueptr) { - 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]; + out_valueptr[v] = m.E[row][col]; } - return values; } static inline m4 glmth_m4m4_m(m4 mat1, m4 mat2) diff --git a/src/platform_linux.c b/src/platform_linux.c @@ -10,6 +10,7 @@ #include <GLFW/glfw3.h> #include "game.c" +#include "platform.h" #include "platform_linux.h" void error_callback(int error, const char* description); @@ -71,6 +72,8 @@ int main(void) #endif // USE_TEST_SEED struct GameState game_state = {0}; + game_state.platform.platform_read_entire_file = &linux_read_entire_file; + game_init(&game_state, PLATFORM_SCR_WIDTH, PLATFORM_SCR_HEIGHT); #ifdef PLATFORM_HOTLOAD_GAME_CODE @@ -151,6 +154,42 @@ time_t file_get_modified_time(char *file_path) return mtime; } +PLATFORM_READ_ENTIRE_FILE(linux_read_entire_file) +{ + FILE *handle = fopen(file_path, "r"); + char *buffer = NULL; + + if (handle) + { + // get file size + fseek(handle, 0, SEEK_END); + u32 num_bytes_in_file = ftell(handle); + rewind(handle); + + // TODO: replace malloc with own allocator so I stop having nightmares + buffer = (char*) malloc(sizeof(char) * (num_bytes_in_file + 1) ); + + u32 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); + // TODO: handle errors here in a better way + exit(1); + } + + return buffer; +} #ifdef PLATFORM_HOTLOAD_GAME_CODE void unload_game_code(struct GameCode *game_code) diff --git a/src/platform_linux.h b/src/platform_linux.h @@ -13,16 +13,10 @@ #define PLATFORM_UPDATES_PER_SECOND 120 #define PLATFORM_MS_PER_UPDATE (PLATFORM_SECOND / PLATFORM_UPDATES_PER_SECOND) +PLATFORM_READ_ENTIRE_FILE(linux_read_entire_file); + #ifdef PLATFORM_HOTLOAD_GAME_CODE #define PLATFORM_GAME_LIB_PATH "./out/release/game.so" -struct GameCode -{ - bool is_valid; - void *game_code_library; - time_t last_write_time; - game_load_opengl_symbols_func *game_load_opengl_symbols; - game_update_and_render_func *game_update_and_render; -}; #endif // PLATFORM_HOTLOAD_GAME_CODE #endif // PLATFORM_LINUX_H diff --git a/src/shader.c b/src/shader.c @@ -1,84 +1,58 @@ -#include "shader.h" - -char *read_file(char *file_path) +struct Shader shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source) { - FILE *handle = fopen(file_path, "r"); - char *buffer = NULL; + GLint success; + GLchar info_log[512]; - if (handle) + if (!(vertex_shader_source && fragment_shader_source)) { - // get file size - fseek(handle, 0, SEEK_END); - u32 num_bytes_in_file = ftell(handle); - rewind(handle); - - buffer = (char*) malloc(sizeof(char) * (num_bytes_in_file + 1) ); - - u32 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); + printf("Error: One or more shader source files weren't loaded.\n"); + exit(1); } else { - printf("Error: Couldn't open file at path: %s", file_path); - } - - return buffer; -} - - -struct Shader shader_compile(char *vertex_path, char *fragment_path) -{ - const GLchar *vertex_shader_source = read_file(vertex_path); - const GLchar *fragment_shader_source = read_file(fragment_path); + 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); + // TODO: handle errors here in a better way + exit(1); + } - i32 success; - char info_log[512]; + 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); + // TODO: handle errors here in a better way + exit(1); + } - u32 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); - } + 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); + // TODO: handle errors here in a better way + exit(1); + } - u32 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); - } + glDeleteShader(fragment_shader); + glDeleteShader(vertex_shader); - 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); + return s; } - - glDeleteShader(fragment_shader); - glDeleteShader(vertex_shader); - - return s; } @@ -138,7 +112,9 @@ void shader_setm4(struct Shader *s, char *name, m4 *mat) { if (s) { - glUniformMatrix4fv(glGetUniformLocation(s->program, name), 1, GL_TRUE, glmth_m4_valueptr(*mat)); + f32 valueptr[sizeof(m4)]; + glmth_m4_valueptr(*mat, valueptr); + glUniformMatrix4fv(glGetUniformLocation(s->program, name), 1, GL_TRUE, valueptr); } else { diff --git a/src/shader.h b/src/shader.h @@ -1,12 +1,9 @@ -#pragma once - struct Shader { u32 program; }; -char *read_file(char *file_path); -struct Shader shader_compile(char *vertex_path, char *fragment_path); +struct Shader shader_compile(const GLchar *vertex_shader_source, const GLchar *fragment_shader_source); 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);