Rework rendering to allow multi-layer render

Internal Changelog:
- A scene now has a maximum amount of render texture. It is to be
  rendered in order of the array by the engine.
- A scene now needs an explicit render system to draw onto the render
  textures. The scene will also init the number of render layers
  needed.
- The change is to allow more separate of concerns when it comes to
  rendering. A scene can also now compartmentalise the rendered items,
  which hopefully make understanding the code easier.
- Update all exisiting code to use the new render system.
scene_man
En Yi 2024-05-04 17:57:07 +08:00
parent 0d4089d9ce
commit 75d019aa34
9 changed files with 109 additions and 79 deletions

View File

@ -152,15 +152,32 @@ void init_scene(Scene_t* scene, render_func_t render_func, action_func_t action_
//scene->scene_type = scene_type; //scene->scene_type = scene_type;
scene->render_function = render_func; scene->render_function = render_func;
scene->layers.n_layers = 0;
scene->bg_colour = WHITE;
scene->action_function = action_func; scene->action_function = action_func;
scene->state = SCENE_ENDED; scene->state = SCENE_ENDED;
scene->time_scale = 1.0f; scene->time_scale = 1.0f;
} }
bool add_scene_layer(Scene_t* scene, int width, int height, Rectangle render_area)
{
if (scene->layers.n_layers >= MAX_RENDER_LAYERS) return false;
scene->layers.render_layers[scene->layers.n_layers].layer_tex = LoadRenderTexture(width, height);
scene->layers.render_layers[scene->layers.n_layers].render_area = render_area;
scene->layers.n_layers++;
return true;
}
void free_scene(Scene_t* scene) void free_scene(Scene_t* scene)
{ {
sc_map_term_64(&scene->action_map); sc_map_term_64(&scene->action_map);
sc_array_term(&scene->systems); sc_array_term(&scene->systems);
for (uint8_t i = 0; i < scene->layers.n_layers; ++i)
{
UnloadRenderTexture(scene->layers.render_layers[i].layer_tex);
}
free_entity_manager(&scene->ent_manager); free_entity_manager(&scene->ent_manager);
deinit_particle_system(&scene->part_sys); deinit_particle_system(&scene->part_sys);
} }
@ -178,10 +195,24 @@ inline void update_scene(Scene_t* scene, float delta_time)
inline void render_scene(Scene_t* scene) inline void render_scene(Scene_t* scene)
{ {
if (scene->render_function != NULL) BeginDrawing();
ClearBackground(scene->bg_colour);
for (uint8_t i = 0; i < scene->layers.n_layers; ++i)
{ {
scene->render_function(scene); RenderLayer_t* layer = scene->layers.render_layers + i;
Rectangle draw_rec = layer->render_area;
Vector2 draw_pos = {draw_rec.x, draw_rec.y};
draw_rec.x = 0;
draw_rec.y = 0;
draw_rec.height *= -1;
DrawTextureRec(
layer->layer_tex.texture,
draw_rec,
draw_pos,
WHITE
);
} }
EndDrawing();
} }
inline void do_action(Scene_t* scene, ActionType_t action, bool pressed) inline void do_action(Scene_t* scene, ActionType_t action, bool pressed)

View File

@ -42,9 +42,22 @@ typedef void(*system_func_t)(Scene_t*);
typedef void(*action_func_t)(Scene_t*, ActionType_t, bool); typedef void(*action_func_t)(Scene_t*, ActionType_t, bool);
sc_array_def(system_func_t, systems); sc_array_def(system_func_t, systems);
typedef struct RenderLayer {
RenderTexture2D layer_tex;
Rectangle render_area;
}RenderLayer_t;
typedef struct SceneRenderLayers {
RenderLayer_t render_layers[MAX_RENDER_LAYERS];
uint8_t n_layers;
} SceneRenderLayers_t;
struct Scene { struct Scene {
struct sc_map_64 action_map; // key -> actions struct sc_map_64 action_map; // key -> actions
struct sc_array_systems systems; struct sc_array_systems systems;
SceneRenderLayers_t layers;
Color bg_colour;
// TODO: Render function is obsolete and should be treated like a system
render_func_t render_function; render_func_t render_function;
action_func_t action_function; action_func_t action_function;
EntityManager_t ent_manager; EntityManager_t ent_manager;
@ -57,6 +70,7 @@ struct Scene {
GameEngine_t *engine; GameEngine_t *engine;
}; };
void init_engine(GameEngine_t* engine); void init_engine(GameEngine_t* engine);
void deinit_engine(GameEngine_t* engine); void deinit_engine(GameEngine_t* engine);
void process_inputs(GameEngine_t* engine, Scene_t* scene); void process_inputs(GameEngine_t* engine, Scene_t* scene);
@ -74,6 +88,7 @@ extern void do_action(Scene_t* scene, ActionType_t action, bool pressed);
//void init_scene(Scene_t* scene, SceneType_t scene_type, system_func_t render_func, action_func_t action_func); //void init_scene(Scene_t* scene, SceneType_t scene_type, system_func_t render_func, action_func_t action_func);
void init_scene(Scene_t* scene, render_func_t render_func, action_func_t action_func); void init_scene(Scene_t* scene, render_func_t render_func, action_func_t action_func);
bool add_scene_layer(Scene_t* scene, int width, int height, Rectangle render_area);
void free_scene(Scene_t* scene); void free_scene(Scene_t* scene);
#endif // __ENGINE_H #endif // __ENGINE_H

View File

@ -1,6 +1,7 @@
#ifndef _ENGINE_CONF_H #ifndef _ENGINE_CONF_H
#define _ENGINE_CONF_H #define _ENGINE_CONF_H
#define MAX_RENDER_LAYERS 4
#define MAX_ENTITIES 2048 #define MAX_ENTITIES 2048
#define MAX_TEXTURES 16 #define MAX_TEXTURES 16
#define MAX_SPRITES 64 #define MAX_SPRITES 64
@ -16,7 +17,6 @@
#define MAX_PARTICLES 64 #define MAX_PARTICLES 64
#define MAX_TILE_TYPES 16 #define MAX_TILE_TYPES 16
#define N_TAGS 10 #define N_TAGS 10
#define N_COMPONENTS 20 #define N_COMPONENTS 20
#define MAX_COMP_POOL_SIZE MAX_ENTITIES #define MAX_COMP_POOL_SIZE MAX_ENTITIES

View File

@ -40,6 +40,9 @@ static bool crate_activation = false;
#define SELECTION_REGION_WIDTH (SELECTION_TILE_SIZE * MAX_SPAWN_TYPE) #define SELECTION_REGION_WIDTH (SELECTION_TILE_SIZE * MAX_SPAWN_TYPE)
#define SELECTION_REGION_HEIGHT SELECTION_TILE_SIZE #define SELECTION_REGION_HEIGHT SELECTION_TILE_SIZE
#define GAME_LAYER 0
#define SELECTION_LAYER 1
#define CONTROL_LAYER 2
static char* get_spawn_selection_string(enum EntitySpawnSelection sel) static char* get_spawn_selection_string(enum EntitySpawnSelection sel)
{ {
switch(sel) switch(sel)
@ -80,41 +83,19 @@ static inline unsigned int get_tile_idx(int x, int y, const TileGrid_t* tilemap)
} }
// This means you might be able to have two editor scene without running into problems // This means you might be able to have two editor scene without running into problems
static RenderTexture2D selection_section;
#define SELECTION_RENDER_HEIGHT (SELECTION_REGION_HEIGHT * 3) #define SELECTION_RENDER_HEIGHT (SELECTION_REGION_HEIGHT * 3)
static void level_scene_render_func(Scene_t* scene) static void level_scene_render_func(Scene_t* scene)
{ {
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
Entity_t* p_ent; Entity_t* p_ent;
Rectangle draw_rec = data->game_rec;
draw_rec.x = 0;
draw_rec.y = 0;
draw_rec.height *= -1;
static char buffer[512]; static char buffer[512];
BeginDrawing();
ClearBackground(LIGHTGRAY);
DrawTextureRec(
data->game_viewport.texture,
draw_rec,
(Vector2){data->game_rec.x, data->game_rec.y},
WHITE
);
draw_rec.width = SELECTION_REGION_WIDTH;
draw_rec.height = -SELECTION_RENDER_HEIGHT;
Vector2 draw_pos = {data->game_rec.x, data->game_rec.y + data->game_rec.height + SELECTION_GAP}; Vector2 draw_pos = {data->game_rec.x, data->game_rec.y + data->game_rec.height + SELECTION_GAP};
DrawTextureRec( BeginTextureMode(scene->layers.render_layers[CONTROL_LAYER].layer_tex);
selection_section.texture, ClearBackground(BLANK);
draw_rec,
draw_pos,
WHITE
);
draw_pos.x = data->game_rec.x + current_spawn_selection * SELECTION_TILE_SIZE;
DrawRectangleLines( DrawRectangleLines(
draw_pos.x, draw_pos.y, data->game_rec.x + current_spawn_selection * SELECTION_TILE_SIZE, draw_pos.y,
SELECTION_TILE_SIZE, SELECTION_TILE_SIZE, GREEN SELECTION_TILE_SIZE, SELECTION_TILE_SIZE, GREEN
); );
@ -185,10 +166,10 @@ static void level_scene_render_func(Scene_t* scene)
print_mempool_stats(buffer); print_mempool_stats(buffer);
DrawText(buffer, gui_x, gui_y, 12, BLACK); DrawText(buffer, gui_x, gui_y, 12, BLACK);
gui_y += 300; gui_y += 330;
sprintf(buffer, "Chests: %u / %u", data->coins.current, data->coins.total); sprintf(buffer, "Chests: %u / %u", data->coins.current, data->coins.total);
DrawText(buffer, gui_x, gui_y, 24, BLACK); DrawText(buffer, gui_x, gui_y, 24, BLACK);
EndDrawing(); EndTextureMode();
} }
static void render_editor_game_scene(Scene_t* scene) static void render_editor_game_scene(Scene_t* scene)
@ -212,7 +193,7 @@ static void render_editor_game_scene(Scene_t* scene)
max.x = (int)fmin(tilemap.width, max.x + 1); max.x = (int)fmin(tilemap.width, max.x + 1);
max.y = (int)fmin(tilemap.height, max.y + 1); max.y = (int)fmin(tilemap.height, max.y + 1);
BeginTextureMode(data->game_viewport); BeginTextureMode(scene->layers.render_layers[GAME_LAYER].layer_tex);
ClearBackground(WHITE); ClearBackground(WHITE);
BeginMode2D(data->camera.cam); BeginMode2D(data->camera.cam);
for (int tile_y = min.y; tile_y < max.y; tile_y++) for (int tile_y = min.y; tile_y < max.y; tile_y++)
@ -837,7 +818,7 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
if (!pressed) metal_toggle = !metal_toggle; if (!pressed) metal_toggle = !metal_toggle;
const Color crate_colour = metal_toggle ? GRAY : BROWN; const Color crate_colour = metal_toggle ? GRAY : BROWN;
Vector2 draw_pos = {SPAWN_CRATE * SELECTION_TILE_SIZE , 0}; Vector2 draw_pos = {SPAWN_CRATE * SELECTION_TILE_SIZE , 0};
BeginTextureMode(selection_section); BeginTextureMode(scene->layers.render_layers[SELECTION_LAYER].layer_tex);
for (uint8_t i = SPAWN_CRATE; i <= SPAWN_CRATE_BOMB; ++i) for (uint8_t i = SPAWN_CRATE; i <= SPAWN_CRATE_BOMB; ++i)
{ {
DrawRectangle(draw_pos.x, draw_pos.y, SELECTION_TILE_SIZE, SELECTION_TILE_SIZE, crate_colour); DrawRectangle(draw_pos.x, draw_pos.y, SELECTION_TILE_SIZE, SELECTION_TILE_SIZE, crate_colour);
@ -1015,9 +996,22 @@ void init_sandbox_scene(LevelScene_t* scene)
unsigned int tile_idx = (scene->data.tilemap.height - 1) * scene->data.tilemap.width + i; unsigned int tile_idx = (scene->data.tilemap.height - 1) * scene->data.tilemap.width + i;
change_a_tile(&scene->data.tilemap, tile_idx, SOLID_TILE); change_a_tile(&scene->data.tilemap, tile_idx, SOLID_TILE);
} }
selection_section = LoadRenderTexture(SELECTION_REGION_WIDTH, SELECTION_RENDER_HEIGHT);
BeginTextureMode(selection_section); scene->scene.bg_colour = LIGHTGRAY;
add_scene_layer(
&scene->scene, scene->data.game_rec.width, scene->data.game_rec.height,
scene->data.game_rec
);
add_scene_layer(
&scene->scene, SELECTION_REGION_WIDTH, SELECTION_REGION_HEIGHT,
(Rectangle){
scene->data.game_rec.x, scene->data.game_rec.y + scene->data.game_rec.height + SELECTION_GAP,
SELECTION_REGION_WIDTH, SELECTION_REGION_HEIGHT
}
);
add_scene_layer(&scene->scene, 1280, 640, (Rectangle){0, 0, 1280, 640});
BeginTextureMode(scene->scene.layers.render_layers[SELECTION_LAYER].layer_tex);
ClearBackground(LIGHTGRAY); ClearBackground(LIGHTGRAY);
Vector2 draw_pos = {0, 0}; Vector2 draw_pos = {0, 0};
const Color crate_colour = metal_toggle ? GRAY : BROWN; const Color crate_colour = metal_toggle ? GRAY : BROWN;
@ -1228,6 +1222,7 @@ void init_sandbox_scene(LevelScene_t* scene)
sc_array_add(&scene->scene.systems, &player_respawn_system); sc_array_add(&scene->scene.systems, &player_respawn_system);
sc_array_add(&scene->scene.systems, &level_end_detection_system); sc_array_add(&scene->scene.systems, &level_end_detection_system);
sc_array_add(&scene->scene.systems, &render_editor_game_scene); sc_array_add(&scene->scene.systems, &render_editor_game_scene);
sc_array_add(&scene->scene.systems, &level_scene_render_func);
// This avoid graphical glitch, not essential // This avoid graphical glitch, not essential
//sc_array_add(&scene->scene.systems, &update_tilemap_system); //sc_array_add(&scene->scene.systems, &update_tilemap_system);
@ -1260,5 +1255,4 @@ void free_sandbox_scene(LevelScene_t* scene)
{ {
free_scene(&scene->scene); free_scene(&scene->scene);
term_level_scene_data(&scene->data); term_level_scene_data(&scene->data);
UnloadRenderTexture(selection_section); // Unload render texture
} }

View File

@ -10,24 +10,15 @@
static Tile_t all_tiles[MAX_N_TILES] = {0}; static Tile_t all_tiles[MAX_N_TILES] = {0};
#define GAME_LAYER 0
#define CONTROL_LAYER 1
static void level_scene_render_func(Scene_t* scene) static void level_scene_render_func(Scene_t* scene)
{ {
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
Rectangle draw_rec = data->game_rec;
draw_rec.x = 0;
draw_rec.y = 0;
draw_rec.height *= -1;
static char buffer[512]; static char buffer[512];
BeginDrawing(); BeginTextureMode(scene->layers.render_layers[CONTROL_LAYER].layer_tex);
ClearBackground(LIGHTGRAY); ClearBackground(BLANK);
DrawTextureRec(
data->game_viewport.texture,
draw_rec,
(Vector2){data->game_rec.x, data->game_rec.y},
WHITE
);
Entity_t* p_ent; Entity_t* p_ent;
sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_ent) sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_ent)
@ -45,13 +36,13 @@ static void level_scene_render_func(Scene_t* scene)
//sprintf(buffer, "Spawn Entity: %s", get_spawn_selection_string(current_spawn_selection)); //sprintf(buffer, "Spawn Entity: %s", get_spawn_selection_string(current_spawn_selection));
//DrawText(buffer, gui_x, 240, 12, BLACK); //DrawText(buffer, gui_x, 240, 12, BLACK);
sprintf(buffer, "Number of Entities: %u", sc_map_size_64v(&scene->ent_manager.entities)); sprintf(buffer, "Number of Entities: %u", sc_map_size_64v(&scene->ent_manager.entities));
DrawText(buffer, gui_x, 270, 12, BLACK); DrawText(buffer, gui_x, 70, 12, BLACK);
sprintf(buffer, "FPS: %u", GetFPS()); sprintf(buffer, "FPS: %u", GetFPS());
DrawText(buffer, gui_x, 320, 12, BLACK); DrawText(buffer, gui_x, 120, 12, BLACK);
print_mempool_stats(buffer); print_mempool_stats(buffer);
DrawText(buffer, gui_x, 350, 12, BLACK); DrawText(buffer, gui_x, 150, 12, BLACK);
EndDrawing(); EndTextureMode();
} }
static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed) static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
@ -130,7 +121,7 @@ static void render_regular_game_scene(Scene_t* scene)
max.x = (int)fmin(tilemap.width, max.x + 1); max.x = (int)fmin(tilemap.width, max.x + 1);
max.y = (int)fmin(tilemap.height, max.y + 1); max.y = (int)fmin(tilemap.height, max.y + 1);
BeginTextureMode(data->game_viewport); BeginTextureMode(scene->layers.render_layers[GAME_LAYER].layer_tex);
ClearBackground(WHITE); ClearBackground(WHITE);
BeginMode2D(data->camera.cam); BeginMode2D(data->camera.cam);
@ -369,6 +360,14 @@ void init_game_scene(LevelScene_t* scene)
(Rectangle){25, 25, 32*TILE_SIZE, 18*TILE_SIZE} (Rectangle){25, 25, 32*TILE_SIZE, 18*TILE_SIZE}
); );
// TODO: Remove the hardcoded window size
scene->scene.bg_colour = LIGHTGRAY;
add_scene_layer(
&scene->scene, scene->data.game_rec.width, scene->data.game_rec.height,
scene->data.game_rec
);
add_scene_layer(&scene->scene, 1280, 640, (Rectangle){0, 0, 1280, 640});
create_player(&scene->scene.ent_manager); create_player(&scene->scene.ent_manager);
update_entity_manager(&scene->scene.ent_manager); update_entity_manager(&scene->scene.ent_manager);
@ -401,6 +400,7 @@ void init_game_scene(LevelScene_t* scene)
sc_array_add(&scene->scene.systems, &player_respawn_system); sc_array_add(&scene->scene.systems, &player_respawn_system);
sc_array_add(&scene->scene.systems, &update_water_runner_system); sc_array_add(&scene->scene.systems, &update_water_runner_system);
sc_array_add(&scene->scene.systems, &render_regular_game_scene); sc_array_add(&scene->scene.systems, &render_regular_game_scene);
sc_array_add(&scene->scene.systems, &level_scene_render_func);
// This avoid graphical glitch, not essential // This avoid graphical glitch, not essential
//sc_array_add(&scene->scene.systems, &update_tilemap_system); //sc_array_add(&scene->scene.systems, &update_tilemap_system);

View File

@ -6,14 +6,14 @@
static void menu_scene_render_func(Scene_t* scene) static void menu_scene_render_func(Scene_t* scene)
{ {
MenuSceneData_t* data = &(CONTAINER_OF(scene, MenuScene_t, scene)->data); MenuSceneData_t* data = &(CONTAINER_OF(scene, MenuScene_t, scene)->data);
BeginDrawing(); BeginTextureMode(scene->layers.render_layers[0].layer_tex);
ClearBackground(RAYWHITE); ClearBackground(RAYWHITE);
DrawText("This is a game", 25, 220, 12, BLACK); DrawText("This is a game", 25, 220, 12, BLACK);
UI_button(data->buttons, "Start"); UI_button(data->buttons, "Start");
UI_button(data->buttons + 1, "Sandbox"); UI_button(data->buttons + 1, "Sandbox");
UI_button(data->buttons + 2, "Continue"); UI_button(data->buttons + 2, "Continue");
UI_button(data->buttons + 3, "Exit"); UI_button(data->buttons + 3, "Exit");
EndDrawing(); EndTextureMode();
} }
static void exec_component_function(Scene_t* scene, int sel) static void exec_component_function(Scene_t* scene, int sel)
@ -132,10 +132,10 @@ static void gui_loop(Scene_t* scene)
void init_menu_scene(MenuScene_t* scene) void init_menu_scene(MenuScene_t* scene)
{ {
//init_scene(&scene->scene, MENU_SCENE, &menu_scene_render_func, &menu_do_action);
init_scene(&scene->scene, &menu_scene_render_func, &menu_do_action); init_scene(&scene->scene, &menu_scene_render_func, &menu_do_action);
sc_array_add(&scene->scene.systems, &gui_loop); sc_array_add(&scene->scene.systems, &gui_loop);
sc_array_add(&scene->scene.systems, &menu_scene_render_func);
scene->data.buttons[0] = (UIComp_t) { scene->data.buttons[0] = (UIComp_t) {
.bbox = {25,255,125,30}, .bbox = {25,255,125,30},
@ -160,6 +160,7 @@ void init_menu_scene(MenuScene_t* scene)
scene->data.max_comp = 4; scene->data.max_comp = 4;
scene->data.selected_comp = 0; scene->data.selected_comp = 0;
scene->data.mode = MOUSE_MODE; scene->data.mode = MOUSE_MODE;
add_scene_layer(&scene->scene, 1280, 640, (Rectangle){0, 0, 1280, 640});
sc_map_put_64(&scene->scene.action_map, KEY_UP, ACTION_UP); sc_map_put_64(&scene->scene.action_map, KEY_UP, ACTION_UP);
sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN); sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN);

View File

@ -40,7 +40,7 @@ typedef struct LevelCamera {
typedef struct LevelSceneData { typedef struct LevelSceneData {
TileGrid_t tilemap; TileGrid_t tilemap;
RenderTexture2D game_viewport; // TODO: game_rec is actually obsolete since this is in the scene game layer
Rectangle game_rec; Rectangle game_rec;
LevelCamera_t camera; LevelCamera_t camera;
Sprite_t* tile_sprites[MAX_TILE_SPRITES]; Sprite_t* tile_sprites[MAX_TILE_SPRITES];
@ -60,7 +60,6 @@ void free_game_scene(LevelScene_t* scene);
void init_sandbox_scene(LevelScene_t* scene); void init_sandbox_scene(LevelScene_t* scene);
void free_sandbox_scene(LevelScene_t* scene); void free_sandbox_scene(LevelScene_t* scene);
void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles, Rectangle view_zone); void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles, Rectangle view_zone);
//void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles);
void term_level_scene_data(LevelSceneData_t* data); void term_level_scene_data(LevelSceneData_t* data);
void reload_level_tilemap(LevelScene_t* scene); void reload_level_tilemap(LevelScene_t* scene);
void load_next_level_tilemap(LevelScene_t* scene); void load_next_level_tilemap(LevelScene_t* scene);

View File

@ -4,13 +4,8 @@
#include "constants.h" #include "constants.h"
void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles, Rectangle view_zone) void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles, Rectangle view_zone)
//void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles)
{ {
//data->game_viewport = LoadRenderTexture(VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE);
//data->game_rec = (Rectangle){25, 25, VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE};
data->game_viewport = LoadRenderTexture(view_zone.width, view_zone.height);
data->game_rec = view_zone; data->game_rec = view_zone;
//data->camera.cam = (Camera2D){0};
memset(&data->camera, 0, sizeof(LevelCamera_t)); memset(&data->camera, 0, sizeof(LevelCamera_t));
data->camera.cam.rotation = 0.0f; data->camera.cam.rotation = 0.0f;
data->camera.cam.zoom = 1.0f; data->camera.cam.zoom = 1.0f;
@ -53,7 +48,6 @@ void term_level_scene_data(LevelSceneData_t* data)
{ {
sc_map_term_64v(&data->tilemap.tiles[i].entities_set); sc_map_term_64v(&data->tilemap.tiles[i].entities_set);
} }
UnloadRenderTexture(data->game_viewport); // Unload render texture
} }
bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num) bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)

View File

@ -23,6 +23,7 @@ static GameEngine_t engine =
}; };
static bool water_toggle = false; static bool water_toggle = false;
#define GAME_LAYER 0
static void level_scene_render_func(Scene_t* scene) static void level_scene_render_func(Scene_t* scene)
{ {
@ -31,7 +32,7 @@ static void level_scene_render_func(Scene_t* scene)
Entity_t* p_ent; Entity_t* p_ent;
BeginTextureMode(data->game_viewport); BeginTextureMode(scene->layers.render_layers[GAME_LAYER].layer_tex);
ClearBackground(WHITE); ClearBackground(WHITE);
BeginMode2D(data->camera.cam); BeginMode2D(data->camera.cam);
for (size_t i = 0; i < tilemap.n_tiles; ++i) for (size_t i = 0; i < tilemap.n_tiles; ++i)
@ -177,19 +178,7 @@ static void level_scene_render_func(Scene_t* scene)
EndMode2D(); EndMode2D();
EndTextureMode(); EndTextureMode();
Rectangle draw_rec = data->game_rec; scene->bg_colour = water_toggle ? ColorAlpha(BLUE, 0.2) : LIGHTGRAY;
draw_rec.x = 0;
draw_rec.y = 0;
draw_rec.height *= -1;
BeginDrawing();
ClearBackground( water_toggle? ColorAlpha(BLUE, 0.2) : LIGHTGRAY);
DrawTextureRec(
data->game_viewport.texture,
draw_rec,
(Vector2){data->game_rec.x, data->game_rec.y},
WHITE
);
EndDrawing();
} }
static inline unsigned int get_tile_idx(int x, int y, const TileGrid_t* tilemap) static inline unsigned int get_tile_idx(int x, int y, const TileGrid_t* tilemap)
@ -413,11 +402,17 @@ int main(void)
LevelScene_t scene; LevelScene_t scene;
scene.scene.engine = &engine; scene.scene.engine = &engine;
init_scene(&scene.scene, &level_scene_render_func, &level_do_action); init_scene(&scene.scene, &level_scene_render_func, &level_do_action);
init_entity_tag_map(&scene.scene.ent_manager, PLAYER_ENT_TAG, 4);
init_entity_tag_map(&scene.scene.ent_manager, DYNMEM_ENT_TAG, 16);
init_level_scene_data( init_level_scene_data(
&scene.data, MAX_N_TILES, all_tiles, &scene.data, MAX_N_TILES, all_tiles,
(Rectangle){25, 25, VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE} (Rectangle){25, 25, VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE}
); );
assert(scene.data.tilemap.n_tiles <= MAX_N_TILES); assert(scene.data.tilemap.n_tiles <= MAX_N_TILES);
add_scene_layer(
&scene.scene, scene.data.game_rec.width, scene.data.game_rec.height,
scene.data.game_rec
);
for (size_t i = 0; i < scene.data.tilemap.width; ++i) for (size_t i = 0; i < scene.data.tilemap.width; ++i)
{ {
@ -441,6 +436,7 @@ int main(void)
sc_array_add(&scene.scene.systems, &toggle_block_system); sc_array_add(&scene.scene.systems, &toggle_block_system);
sc_array_add(&scene.scene.systems, &camera_update_system); sc_array_add(&scene.scene.systems, &camera_update_system);
sc_array_add(&scene.scene.systems, &player_dir_reset_system); sc_array_add(&scene.scene.systems, &player_dir_reset_system);
sc_array_add(&scene.scene.systems, &level_scene_render_func);
sc_map_put_64(&scene.scene.action_map, KEY_R, ACTION_RESTART); sc_map_put_64(&scene.scene.action_map, KEY_R, ACTION_RESTART);