From d8ea348867e4634d00a4f5678b39d15d98ce91fa Mon Sep 17 00:00:00 2001 From: Emil Kosz Date: Wed, 4 Jun 2025 20:26:25 +0200 Subject: [PATCH] Cloud shader, nice funny glitch --- game/res/shaders/clouds.frag | 17 +++++++++++++++++ game/res/shaders/clouds.vert | 17 +++++++++++++++++ game/src/camera.c | 2 +- game/src/chunk/chunkman.h | 2 +- game/src/entity/entity.h | 2 ++ game/src/entity/entman.c | 18 ++++++++++++++++-- game/src/entity/templates.c | 6 ++++-- game/src/graphics.c | 3 +++ game/src/program.c | 6 ++++++ game/src/program.h | 1 + game/src/resources.c | 19 +++++++++++++++---- game/src/state.c | 2 +- 12 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 game/res/shaders/clouds.frag create mode 100644 game/res/shaders/clouds.vert diff --git a/game/res/shaders/clouds.frag b/game/res/shaders/clouds.frag new file mode 100644 index 0000000..18447de --- /dev/null +++ b/game/res/shaders/clouds.frag @@ -0,0 +1,17 @@ +#version 100 + +precision mediump float; + +uniform sampler2D texture; + +varying vec2 f_uv; + +void main () +{ + if(texture2D (texture, f_uv).a < 0.1) + { + discard; + } + + gl_FragColor = texture2D (texture, f_uv); +} diff --git a/game/res/shaders/clouds.vert b/game/res/shaders/clouds.vert new file mode 100644 index 0000000..de17b21 --- /dev/null +++ b/game/res/shaders/clouds.vert @@ -0,0 +1,17 @@ +#version 100 + +attribute vec4 position; +attribute vec2 uv; + +uniform mat4 view; +uniform mat4 projection; +uniform mat4 model; +uniform float time; + +varying vec2 f_uv; + +void main () +{ + f_uv = (uv * 20.0) + (time * 20.0); + gl_Position = projection * view * model * position; +} diff --git a/game/src/camera.c b/game/src/camera.c index 5321479..bc2f371 100644 --- a/game/src/camera.c +++ b/game/src/camera.c @@ -33,5 +33,5 @@ camera_get_view (mat4 dest) void camera_get_projection (float aspect, mat4 dest) { - glm_perspective (glm_rad (70), aspect, 0.01, 5000.0, dest); + glm_perspective (glm_rad (70), aspect, 0.01, 7000.0, dest); } diff --git a/game/src/chunk/chunkman.h b/game/src/chunk/chunkman.h index 9ef9708..316b413 100644 --- a/game/src/chunk/chunkman.h +++ b/game/src/chunk/chunkman.h @@ -9,7 +9,7 @@ #include "../entity/entman.h" #include "../entity/templates.h" -#define RENDER_DISTANCE 3 +#define RENDER_DISTANCE 6 void chunkman_init (); void chunkman_update (vec3 camera_position); diff --git a/game/src/entity/entity.h b/game/src/entity/entity.h index 527acd3..dbfe4cd 100644 --- a/game/src/entity/entity.h +++ b/game/src/entity/entity.h @@ -20,6 +20,8 @@ typedef struct Entity vec3 position; vec3 rotation; vec3 scale; + /* Use RESPRG to get the int. */ + unsigned int program; /* Use RESTEX to get the int. */ unsigned int texture; } Entity; diff --git a/game/src/entity/entman.c b/game/src/entity/entman.c index 62486d9..bbc03e8 100644 --- a/game/src/entity/entman.c +++ b/game/src/entity/entman.c @@ -1,11 +1,17 @@ #include "entman.h" +/* TODO: Put uniforms into vertex attributes for pseudoinstancing. */ +/* TODO: Instead of having a huge far plane, render the clouds + seperately somehow. */ + extern vec3 camera_position; +extern int last_time; Entity *player_entity; static GSequence *entities; static EntityMesh mesh_quad1, mesh_quad2, mesh_quad_x; +static unsigned int last_program = -1; static unsigned int last_type = -1; static unsigned int last_texture = -1; @@ -43,7 +49,8 @@ entman_init () .position = { 0.0, 200.0, 0.0 }, .scale = { 5000.0, 5000.0, 5000.0 }, .rotation = { 90.0 }, - .texture = RESTEX ("clouds") + .texture = RESTEX ("clouds"), + .program = RESPRG ("clouds") }; ENTADD (sky); @@ -169,7 +176,13 @@ entman_render_internal (gpointer data, gpointer userdata) glm_scale (model, entity->scale); - program_set_mat4 (RESPRG ("default"), "model", model); + if (entity->program != last_program) + { + program_use (entity->program); + } + + program_set_mat4 (entity->program, "model", model); + program_set_float (entity->program, "time", last_time); if (entity->texture != last_texture) { @@ -182,6 +195,7 @@ entman_render_internal (gpointer data, gpointer userdata) EntityMesh_bind (&to_render); } + last_program = entity->program; last_type = entity->mesh_type; last_texture = entity->texture; EntityMesh_render (&to_render); diff --git a/game/src/entity/templates.c b/game/src/entity/templates.c index 0e67b66..afa7f6b 100644 --- a/game/src/entity/templates.c +++ b/game/src/entity/templates.c @@ -27,7 +27,8 @@ ent_templates_init () .position = { 0.0 }, .scale = { 3.0, 8.0, 3.0 }, .rotation = { 0.0 }, - .texture = RESTEX ("tree0") + .texture = RESTEX ("tree0"), + .program = RESPRG ("default") }; ent_templates_add ("tree", tree); @@ -41,7 +42,8 @@ ent_templates_init () .position = { 0.0 }, .scale = { 1.0, 0.5, 1.0 }, .rotation = { 0.0 }, - .texture = RESTEX ("grass0") + .texture = RESTEX ("grass0"), + .program = RESPRG ("default") }; ent_templates_add ("grass", grass); diff --git a/game/src/graphics.c b/game/src/graphics.c index 1b207f5..4cee223 100644 --- a/game/src/graphics.c +++ b/game/src/graphics.c @@ -74,6 +74,9 @@ graphics_render () chunkman_render (camera_position, RESPRG ("chunk")); + program_use (RESPRG ("clouds")); + program_set_mat4 (RESPRG ("clouds"), "projection", projection); + program_set_mat4 (RESPRG ("clouds"), "view", view); program_use (RESPRG ("default")); program_set_mat4 (RESPRG ("default"), "projection", projection); program_set_mat4 (RESPRG ("default"), "view", view); diff --git a/game/src/program.c b/game/src/program.c index 7c2eb1c..9121cb8 100644 --- a/game/src/program.c +++ b/game/src/program.c @@ -78,6 +78,12 @@ program_set_vec3 (int program, const char *name, float x, float y, float z) glUniform3f (glGetUniformLocation (program, name), x, y, z); } +void +program_set_float (int program, const char *name, float value) +{ + glUniform1f (glGetUniformLocation (program, name), value); +} + void program_set_int_array (int program, const char *name, size_t count, int *value) { diff --git a/game/src/program.h b/game/src/program.h index a610a0a..c6a5456 100644 --- a/game/src/program.h +++ b/game/src/program.h @@ -11,6 +11,7 @@ void shader_fail (int shader); void program_fail (int program); int program_create (const char *v_src, const char *f_src); +void program_set_float (int program, const char *name, float value); void program_set_int_array (int program, const char *name, size_t count, int *value); void program_set_vec3 (int program, const char *name, float x, float y, float z); void program_set_mat4 (int program, const char *name, mat4 value); diff --git a/game/src/resources.c b/game/src/resources.c index c3095fa..9d4842d 100644 --- a/game/src/resources.c +++ b/game/src/resources.c @@ -10,7 +10,8 @@ resources_load_program (const char *v_path, const char *f_path) if (v_file == NULL) { - WARN ("File `%s' does not exist.", v_path); + WARN ("File `%s' does not exist.", v_path); + return 0; } fseek (v_file, 0L, SEEK_END); @@ -23,7 +24,8 @@ resources_load_program (const char *v_path, const char *f_path) if (f_file == NULL) { - WARN ("File `%s' does not exist.", f_path); + WARN ("File `%s' does not exist.", f_path); + return 0; } fseek (f_file, 0L, SEEK_END); @@ -46,6 +48,7 @@ resources_load_texture (const char *path) if (surface == NULL) { WARN ("Failed to load texture from path %s: %s", path, SDL_GetError ()); + return 0; } unsigned int texture = texture_create (surface->w, surface->h, surface->pixels); @@ -55,13 +58,19 @@ resources_load_texture (const char *path) static inline void resources_add_program (char *key, unsigned int program) { - g_hash_table_insert (programs, key, GINT_TO_POINTER (program)); + if (program) + { + g_hash_table_insert (programs, key, GINT_TO_POINTER (program)); + } } static inline void resources_add_texture (char *key, unsigned int texture) { - g_hash_table_insert (textures, key, GINT_TO_POINTER (texture)); + if (texture) + { + g_hash_table_insert (textures, key, GINT_TO_POINTER (texture)); + } } unsigned int @@ -89,6 +98,8 @@ resources_init () RAP ("default", RLP ("res/shaders/default.vert", "res/shaders/default.frag")); RAP ("chunk", RLP ("res/shaders/chunk.vert", "res/shaders/chunk.frag")); + RAP ("clouds", RLP ("res/shaders/clouds.vert", "res/shaders/clouds.frag")); + RAT ("terrain0", RLT ("res/textures/dirt.png")); RAT ("terrain1", RLT ("res/textures/drygrass.png")); RAT ("terrain2", RLT ("res/textures/grass.png")); diff --git a/game/src/state.c b/game/src/state.c index b9f0f1f..5b8b491 100644 --- a/game/src/state.c +++ b/game/src/state.c @@ -4,7 +4,7 @@ extern vec3 camera_position; extern Entity *player_entity; float delta_time; -static int last_time; +int last_time; void game_state_init (int ticks)