27 |
27 |
28 #include <ascension/core.h> |
28 #include <ascension/core.h> |
29 #include <ascension/ui.h> |
29 #include <ascension/ui.h> |
30 #include <ascension/sprite.h> |
30 #include <ascension/sprite.h> |
31 #include <ascension/2d.h> |
31 #include <ascension/2d.h> |
|
32 #include <ascension/shader.h> |
32 |
33 |
33 #include <cx/printf.h> |
34 #include <cx/printf.h> |
34 |
35 |
35 enum Textures2d { |
36 #define TEXTURE_2D_COUNT 3 |
36 TEX_PLAYER = 0, |
37 static AscTexture tex2d[TEXTURE_2D_COUNT]; |
37 TEX_BACKDROP, |
38 #define TEXTURE_PLAYER &tex2d[0] |
38 TEX2D_COUNT |
39 #define TEXTURE_PLAYER_COLOR_MAP &tex2d[1] |
39 }; |
40 #define TEXTURE_BACKDROP &tex2d[2] |
40 static AscTexture tex2d[TEX2D_COUNT]; |
41 |
41 #define TEXTURE_PLAYER &tex2d[TEX_PLAYER] |
42 #define SHADER_ID_PLAYER 1 |
42 #define TEXTURE_BACKDROP &tex2d[TEX_BACKDROP] |
|
43 |
43 |
44 #define BACKDROP_SCENE asc_window_scene(0) |
44 #define BACKDROP_SCENE asc_window_scene(0) |
45 #define MAIN_SCENE asc_window_scene(1) |
45 #define MAIN_SCENE asc_window_scene(1) |
46 |
46 |
47 #define HUD_WIDTH 400 |
47 #define HUD_WIDTH 400 |
80 directions[MOVE_DOWN] = ASC_VEC2I(0, 1); |
81 directions[MOVE_DOWN] = ASC_VEC2I(0, 1); |
81 directions[MOVE_RIGHT] = ASC_VEC2I(1, 0); |
82 directions[MOVE_RIGHT] = ASC_VEC2I(1, 0); |
82 } |
83 } |
83 |
84 |
84 static void textures_destroy(void) { |
85 static void textures_destroy(void) { |
85 asc_texture_destroy(tex2d, TEX2D_COUNT); |
86 asc_texture_destroy(tex2d, TEXTURE_2D_COUNT); |
86 } |
87 } |
87 |
88 |
88 static void textures_init(void) { |
89 static void textures_init(void) { |
89 asc_texture_init_2d(tex2d, TEX2D_COUNT); |
90 asc_texture_init_2d(tex2d, TEXTURE_2D_COUNT); |
90 asc_texture_from_file(TEXTURE_PLAYER, "player.png"); |
91 asc_texture_from_file(TEXTURE_PLAYER, "player.png"); |
|
92 asc_texture_from_file(TEXTURE_PLAYER_COLOR_MAP, "player-color-map.png"); |
91 asc_texture_from_file(TEXTURE_BACKDROP, "backdrop.png"); |
93 asc_texture_from_file(TEXTURE_BACKDROP, "backdrop.png"); |
92 asc_gl_context_add_cleanup_func(asc_active_glctx, textures_destroy); |
94 asc_gl_context_add_cleanup_func(asc_active_glctx, textures_destroy); |
93 } |
95 } |
94 |
96 |
95 static void backdrop_scale(AscBehavior *behavior) { |
97 static void backdrop_scale(AscBehavior *behavior) { |
138 .font = asc_font(ASC_FONT_REGULAR, 12), |
140 .font = asc_font(ASC_FONT_REGULAR, 12), |
139 ); |
141 ); |
140 asc_behavior_add(node, .func = fps_counter_update, .interval = asc_seconds(1)); |
142 asc_behavior_add(node, .func = fps_counter_update, .interval = asc_seconds(1)); |
141 asc_behavior_add(node, fps_counter_tie_to_corner); |
143 asc_behavior_add(node, fps_counter_tie_to_corner); |
142 asc_ui_add_node(node); |
144 asc_ui_add_node(node); |
|
145 } |
|
146 |
|
147 typedef struct { |
|
148 AscShaderProgram program; |
|
149 asc_uniform_loc map_albedo; |
|
150 asc_uniform_loc map_color; |
|
151 asc_uniform_loc color; |
|
152 } PlayerShader; |
|
153 |
|
154 static void player_shader_init(AscShaderProgram *p, cx_attr_unused int flags) { |
|
155 asc_shader_init_uniform_loc_nice(p, PlayerShader, map_albedo); |
|
156 asc_shader_init_uniform_loc_nice(p, PlayerShader, map_color); |
|
157 asc_shader_init_uniform_loc_nice(p, PlayerShader, color); |
|
158 } |
|
159 |
|
160 static AscShaderProgram *player_shader_create(cx_attr_unused int unused) { |
|
161 return asc_shader_create((AscShaderCodes) { |
|
162 .vtx = {.source_file = "sprite_vtx.glsl"}, |
|
163 .frag = {.source_file = "player.glsl",}, |
|
164 }, sizeof(PlayerShader), player_shader_init, 0); |
|
165 } |
|
166 |
|
167 static void player_draw(const AscCamera *camera, const AscSceneNode *node) { |
|
168 asc_cptr_cast(AscSprite, sprite, node); |
|
169 const Player *player = node->user_data; |
|
170 |
|
171 // TODO: we shall finally add the shader information to the node |
|
172 const AscShaderProgram *s = asc_shader_lookup( |
|
173 SHADER_ID_PLAYER, player_shader_create, 0 |
|
174 ); |
|
175 if (asc_shader_use(s, camera)) return; |
|
176 asc_cptr_cast(PlayerShader, shader, s); |
|
177 |
|
178 asc_shader_upload_model_matrix(s, node); |
|
179 |
|
180 // Bind texture |
|
181 asc_texture_bind(TEXTURE_PLAYER, shader->map_albedo, 0); |
|
182 asc_texture_bind(TEXTURE_PLAYER_COLOR_MAP, shader->map_color, 1); |
|
183 asc_shader_upload_col4f(shader->color, player->color); |
|
184 asc_mesh_draw_triangle_strip(&sprite->mesh); |
143 } |
185 } |
144 |
186 |
145 static void player_move(AscBehavior *behavior) { |
187 static void player_move(AscBehavior *behavior) { |
146 AscSceneNode *node = behavior->node; |
188 AscSceneNode *node = behavior->node; |
147 Player *player = node->user_data; |
189 Player *player = node->user_data; |
202 } |
244 } |
203 |
245 |
204 static Player *player_create(void) { |
246 static Player *player_create(void) { |
205 AscSceneNode *sprite = asc_sprite( |
247 AscSceneNode *sprite = asc_sprite( |
206 .name = "Player", |
248 .name = "Player", |
207 .texture = TEXTURE_PLAYER, |
|
208 .width = game_field_tile_size, |
249 .width = game_field_tile_size, |
209 .height = game_field_tile_size, |
250 .height = game_field_tile_size, |
210 .origin_x = game_field_tile_size / 2, |
251 .origin_x = game_field_tile_size / 2, |
211 .origin_y = game_field_tile_size / 2, |
252 .origin_y = game_field_tile_size / 2, |
212 ); |
253 ); |
213 asc_scene_add_node(MAIN_SCENE, sprite); |
254 asc_scene_add_node(MAIN_SCENE, sprite); |
214 Player *player = asc_scene_node_allocate_data(sprite, sizeof(Player)); |
255 Player *player = asc_scene_node_allocate_data(sprite, sizeof(Player)); |
215 player_position(player, 12, 8); |
256 player_position(player, 12, 8); |
216 player->speed = 3.f; // start with 3 tiles/sec |
257 player->speed = 3.f; // start with 3 tiles/sec |
|
258 player->color = ASC_RGB_F(1, 0, 0); |
|
259 sprite->draw_func = player_draw; |
217 asc_behavior_add(sprite, player_move); |
260 asc_behavior_add(sprite, player_move); |
218 return player; |
261 return player; |
219 } |
262 } |
220 |
263 |
221 static void gamefield_create() { |
264 static void gamefield_create() { |