add player colors

Sat, 02 Aug 2025 15:19:06 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 02 Aug 2025 15:19:06 +0200
changeset 242
6eeb987f1681
parent 241
b53bd6ab2a47
child 243
b06168253818

add player colors

Makefile file | annotate | diff | comparison | revisions
src/Makefile file | annotate | diff | comparison | revisions
test/snake/Makefile file | annotate | diff | comparison | revisions
test/snake/shader/player.glsl file | annotate | diff | comparison | revisions
test/snake/snake.c file | annotate | diff | comparison | revisions
test/snake/textures/player-color-map.png file | annotate | diff | comparison | revisions
--- 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;
 }
Binary file test/snake/textures/player-color-map.png has changed

mercurial