Sat, 02 Aug 2025 15:19:06 +0200
add player colors
--- a/Makefile Sat Aug 02 14:58:30 2025 +0200 +++ b/Makefile Sat Aug 02 15:19:06 2025 +0200 @@ -23,16 +23,10 @@ # POSSIBILITY OF SUCH DAMAGE. # -DEMO_GAMES_DIR=build/test - -all: $(DEMO_GAMES_DIR)/snake +all: snake -$(DEMO_GAMES_DIR)/snake: build/lib/libascension.a FORCE +snake: build/lib/libascension.a FORCE @cd test/snake && $(MAKE) - @cp -Rf shader $(DEMO_GAMES_DIR)/ - @cp -Rf fonts $(DEMO_GAMES_DIR)/ - @cp -Rf test/snake/textures $(DEMO_GAMES_DIR)/ - @echo "Assets for demo game 'snake' successfully copied." build/lib/libascension.a: config.mk FORCE @cd src && $(MAKE)
--- a/src/Makefile Sat Aug 02 14:58:30 2025 +0200 +++ b/src/Makefile Sat Aug 02 15:19:06 2025 +0200 @@ -134,8 +134,7 @@ ascension/texture.h ascension/camera.h ascension/context.h \ ascension/window.h ascension/glcontext.h ascension/scene.h \ ascension/input.h ascension/font.h ascension/glcontext.h \ - ascension/error.h ascension/mesh.h ascension/shader.h \ - ascension/constants.h + ascension/mesh.h ascension/shader.h ascension/constants.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $<
--- a/test/snake/Makefile Sat Aug 02 14:58:30 2025 +0200 +++ b/test/snake/Makefile Sat Aug 02 15:19:06 2025 +0200 @@ -25,12 +25,17 @@ include ../../config.mk -BUILD_DIR=$(srcdir)/build/test +BUILD_DIR=$(srcdir)/build/snake LIB_ASCENSION=$(srcdir)/build/lib/libascension.a CFLAGS += -I$(srcdir)/src $(CPPFLAGS) all: $(BUILD_DIR) $(BUILD_DIR)/snake FORCE @echo "Demo game 'snake' successfully built." + @cp -Ruf $(srcdir)/shader $(BUILD_DIR)/ + @cp -Ruf $(srcdir)/fonts $(BUILD_DIR)/ + @cp -Ruf textures $(BUILD_DIR)/ + @cp -Ruf shader $(BUILD_DIR)/ + @echo "Assets for demo game 'snake' successfully copied." $(BUILD_DIR): mkdir -p $@ @@ -53,7 +58,8 @@ ../../src/ascension/font.h ../../src/ascension/behavior.h \ ../../src/ascension/ui.h ../../src/ascension/text.h \ ../../src/ascension/mesh.h ../../src/ascension/texture.h \ - ../../src/ascension/sprite.h ../../src/ascension/2d.h + ../../src/ascension/sprite.h ../../src/ascension/2d.h \ + ../../src/ascension/shader.h @echo "Compiling $<" $(CC) -o $@ $(CFLAGS) -c $<
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/snake/shader/player.glsl Sat Aug 02 15:19:06 2025 +0200 @@ -0,0 +1,16 @@ +layout(location = 0) out vec4 diffuse; +in vec2 uvcoord; + +uniform sampler2D map_albedo; +uniform sampler2D map_color; +uniform vec4 color; + +void main(void) { + // TODO: use greyscale texture instead + vec4 color_map_pixel = texture(map_color, uvcoord); + if (color_map_pixel.a > 0) { + diffuse = color * color_map_pixel * texture(map_albedo, uvcoord); + } else { + diffuse = texture(map_albedo, uvcoord); + } +}
--- a/test/snake/snake.c Sat Aug 02 14:58:30 2025 +0200 +++ b/test/snake/snake.c Sat Aug 02 15:19:06 2025 +0200 @@ -29,17 +29,17 @@ #include <ascension/ui.h> #include <ascension/sprite.h> #include <ascension/2d.h> +#include <ascension/shader.h> #include <cx/printf.h> -enum Textures2d { - TEX_PLAYER = 0, - TEX_BACKDROP, - TEX2D_COUNT -}; -static AscTexture tex2d[TEX2D_COUNT]; -#define TEXTURE_PLAYER &tex2d[TEX_PLAYER] -#define TEXTURE_BACKDROP &tex2d[TEX_BACKDROP] +#define TEXTURE_2D_COUNT 3 +static AscTexture tex2d[TEXTURE_2D_COUNT]; +#define TEXTURE_PLAYER &tex2d[0] +#define TEXTURE_PLAYER_COLOR_MAP &tex2d[1] +#define TEXTURE_BACKDROP &tex2d[2] + +#define SHADER_ID_PLAYER 1 #define BACKDROP_SCENE asc_window_scene(0) #define MAIN_SCENE asc_window_scene(1) @@ -57,6 +57,7 @@ static asc_vec2i directions[4]; typedef struct { + asc_col4f color; enum MoveDirection direction; enum MoveDirection target_direction; /** @@ -82,12 +83,13 @@ } static void textures_destroy(void) { - asc_texture_destroy(tex2d, TEX2D_COUNT); + asc_texture_destroy(tex2d, TEXTURE_2D_COUNT); } static void textures_init(void) { - asc_texture_init_2d(tex2d, TEX2D_COUNT); + asc_texture_init_2d(tex2d, TEXTURE_2D_COUNT); asc_texture_from_file(TEXTURE_PLAYER, "player.png"); + asc_texture_from_file(TEXTURE_PLAYER_COLOR_MAP, "player-color-map.png"); asc_texture_from_file(TEXTURE_BACKDROP, "backdrop.png"); asc_gl_context_add_cleanup_func(asc_active_glctx, textures_destroy); } @@ -142,6 +144,46 @@ asc_ui_add_node(node); } +typedef struct { + AscShaderProgram program; + asc_uniform_loc map_albedo; + asc_uniform_loc map_color; + asc_uniform_loc color; +} PlayerShader; + +static void player_shader_init(AscShaderProgram *p, cx_attr_unused int flags) { + asc_shader_init_uniform_loc_nice(p, PlayerShader, map_albedo); + asc_shader_init_uniform_loc_nice(p, PlayerShader, map_color); + asc_shader_init_uniform_loc_nice(p, PlayerShader, color); +} + +static AscShaderProgram *player_shader_create(cx_attr_unused int unused) { + return asc_shader_create((AscShaderCodes) { + .vtx = {.source_file = "sprite_vtx.glsl"}, + .frag = {.source_file = "player.glsl",}, + }, sizeof(PlayerShader), player_shader_init, 0); +} + +static void player_draw(const AscCamera *camera, const AscSceneNode *node) { + asc_cptr_cast(AscSprite, sprite, node); + const Player *player = node->user_data; + + // TODO: we shall finally add the shader information to the node + const AscShaderProgram *s = asc_shader_lookup( + SHADER_ID_PLAYER, player_shader_create, 0 + ); + if (asc_shader_use(s, camera)) return; + asc_cptr_cast(PlayerShader, shader, s); + + asc_shader_upload_model_matrix(s, node); + + // Bind texture + asc_texture_bind(TEXTURE_PLAYER, shader->map_albedo, 0); + asc_texture_bind(TEXTURE_PLAYER_COLOR_MAP, shader->map_color, 1); + asc_shader_upload_col4f(shader->color, player->color); + asc_mesh_draw_triangle_strip(&sprite->mesh); +} + static void player_move(AscBehavior *behavior) { AscSceneNode *node = behavior->node; Player *player = node->user_data; @@ -204,7 +246,6 @@ static Player *player_create(void) { AscSceneNode *sprite = asc_sprite( .name = "Player", - .texture = TEXTURE_PLAYER, .width = game_field_tile_size, .height = game_field_tile_size, .origin_x = game_field_tile_size / 2, @@ -214,6 +255,8 @@ Player *player = asc_scene_node_allocate_data(sprite, sizeof(Player)); player_position(player, 12, 8); player->speed = 3.f; // start with 3 tiles/sec + player->color = ASC_RGB_F(1, 0, 0); + sprite->draw_func = player_draw; asc_behavior_add(sprite, player_move); return player; }