From 41ee3fe4ae76d9bba450f58a09c4edde1493672d Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 6 Sep 2025 13:24:02 -0700 Subject: Draw only tiles visible in the screen in ortho maps. The same logic for iso maps is still missing. --- src/gfx2d.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'src/gfx2d.c') diff --git a/src/gfx2d.c b/src/gfx2d.c index 8d78c2b..e79dd3e 100644 --- a/src/gfx2d.c +++ b/src/gfx2d.c @@ -79,6 +79,10 @@ static inline ivec2 ivec2_add(ivec2 a, ivec2 b) { return (ivec2){.x = a.x + b.x, .y = a.y + b.y}; } +static inline ivec2 ivec2_mul(ivec2 a, ivec2 b) { + return (ivec2){.x = a.x * b.x, .y = a.y * b.y}; +} + static inline ivec2 ivec2_scale(ivec2 a, int s) { return (ivec2){.x = a.x * s, .y = a.y * s}; } @@ -91,12 +95,14 @@ static inline vec2 vec2_add(vec2 a, vec2 b) { static inline vec2 ivec2_to_vec2(ivec2 a) { return (vec2){a.x, a.y}; } -/// Map map coordinates to screen coordinates, both Cartesian. -static ivec2 map2screen( +/// Map ortho coordinates to screen coordinates. +/// +/// Camera coordinates are in pixels. Map coordinates are in tiles. +static ivec2 ortho2screen( ivec2 camera, int tile_width, int tile_height, int map_x, int map_y) { return ivec2_add( ivec2_neg(camera), - (ivec2){.x = map_x * tile_width, .y = map_y * tile_height}); + ivec2_mul((ivec2){map_x, map_y}, (ivec2){tile_width, tile_height})); } // Not actually used because we pre-compute the two axis vectors instead. @@ -603,7 +609,7 @@ static void draw_tile_ortho(Gfx2d* gfx, Tile tile, int x, int y) { const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile); const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile); - const ivec2 screen_origin = map2screen( + const ivec2 screen_origin = ortho2screen( gfx->camera, gfx->map->base_tile_width, gfx->map->base_tile_height, x, y); draw_rect( @@ -645,12 +651,16 @@ static void draw_map_ortho(Gfx2d* gfx) { assert(gfx); assert(gfx->map); - // TODO: Same TODOs as in draw_map_iso(). - + // TODO: Handle multiple layers. const Tm_Layer* layer = tm_map_get_layer(gfx->map, 0); - for (int wy = 0; wy < gfx->map->world_height; ++wy) { - for (int wx = 0; wx < gfx->map->world_width; ++wx) { + // TODO: This currently renders with tile granularity. Do so instead in terms + // of pixels for more accurate camera panning. The camera coordinates are + // already given in pixels. + for (int wy = gfx->camera.y / gfx->map->base_tile_height; + wy < gfx->map->world_height; ++wy) { + for (int wx = gfx->camera.x / gfx->map->base_tile_width; + wx < gfx->map->world_width; ++wx) { const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy); draw_tile_ortho(gfx, tile, wx, wy); } @@ -711,7 +721,7 @@ static void draw_sprite_ortho( // Apply an offset similarly to how we offset tiles. The sprite is offset by // -base_tile_width/2 along the x-axis to align the sprite with the leftmost // edge of the tile it is on. - const ivec2 screen_origin = map2screen( + const ivec2 screen_origin = ortho2screen( gfx->camera, gfx->map->base_tile_width, gfx->map->base_tile_height, sprite->position.x, sprite->position.y); -- cgit v1.2.3