diff options
| author | 3gg <3gg@shellblade.net> | 2025-09-06 13:24:02 -0700 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-09-06 13:24:02 -0700 |
| commit | 41ee3fe4ae76d9bba450f58a09c4edde1493672d (patch) | |
| tree | 6551c2d40f6f80f1816ade0c88bafc95e661bd19 | |
| parent | a7a2884c30a92654b676be05338947f7555bba58 (diff) | |
Draw only tiles visible in the screen in ortho maps. The same logic for iso maps is still missing.
| -rw-r--r-- | src/gfx2d.c | 28 |
1 files changed, 19 insertions, 9 deletions
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) { | |||
| 79 | return (ivec2){.x = a.x + b.x, .y = a.y + b.y}; | 79 | return (ivec2){.x = a.x + b.x, .y = a.y + b.y}; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | static inline ivec2 ivec2_mul(ivec2 a, ivec2 b) { | ||
| 83 | return (ivec2){.x = a.x * b.x, .y = a.y * b.y}; | ||
| 84 | } | ||
| 85 | |||
| 82 | static inline ivec2 ivec2_scale(ivec2 a, int s) { | 86 | static inline ivec2 ivec2_scale(ivec2 a, int s) { |
| 83 | return (ivec2){.x = a.x * s, .y = a.y * s}; | 87 | return (ivec2){.x = a.x * s, .y = a.y * s}; |
| 84 | } | 88 | } |
| @@ -91,12 +95,14 @@ static inline vec2 vec2_add(vec2 a, vec2 b) { | |||
| 91 | 95 | ||
| 92 | static inline vec2 ivec2_to_vec2(ivec2 a) { return (vec2){a.x, a.y}; } | 96 | static inline vec2 ivec2_to_vec2(ivec2 a) { return (vec2){a.x, a.y}; } |
| 93 | 97 | ||
| 94 | /// Map map coordinates to screen coordinates, both Cartesian. | 98 | /// Map ortho coordinates to screen coordinates. |
| 95 | static ivec2 map2screen( | 99 | /// |
| 100 | /// Camera coordinates are in pixels. Map coordinates are in tiles. | ||
| 101 | static ivec2 ortho2screen( | ||
| 96 | ivec2 camera, int tile_width, int tile_height, int map_x, int map_y) { | 102 | ivec2 camera, int tile_width, int tile_height, int map_x, int map_y) { |
| 97 | return ivec2_add( | 103 | return ivec2_add( |
| 98 | ivec2_neg(camera), | 104 | ivec2_neg(camera), |
| 99 | (ivec2){.x = map_x * tile_width, .y = map_y * tile_height}); | 105 | ivec2_mul((ivec2){map_x, map_y}, (ivec2){tile_width, tile_height})); |
| 100 | } | 106 | } |
| 101 | 107 | ||
| 102 | // Not actually used because we pre-compute the two axis vectors instead. | 108 | // 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) { | |||
| 603 | const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile); | 609 | const Ts_Tile* pTile = ts_tileset_get_tile(gfx->tileset, tile); |
| 604 | const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile); | 610 | const Pixel* pixels = ts_tileset_get_tile_pixels(gfx->tileset, tile); |
| 605 | 611 | ||
| 606 | const ivec2 screen_origin = map2screen( | 612 | const ivec2 screen_origin = ortho2screen( |
| 607 | gfx->camera, gfx->map->base_tile_width, gfx->map->base_tile_height, x, y); | 613 | gfx->camera, gfx->map->base_tile_width, gfx->map->base_tile_height, x, y); |
| 608 | 614 | ||
| 609 | draw_rect( | 615 | draw_rect( |
| @@ -645,12 +651,16 @@ static void draw_map_ortho(Gfx2d* gfx) { | |||
| 645 | assert(gfx); | 651 | assert(gfx); |
| 646 | assert(gfx->map); | 652 | assert(gfx->map); |
| 647 | 653 | ||
| 648 | // TODO: Same TODOs as in draw_map_iso(). | 654 | // TODO: Handle multiple layers. |
| 649 | |||
| 650 | const Tm_Layer* layer = tm_map_get_layer(gfx->map, 0); | 655 | const Tm_Layer* layer = tm_map_get_layer(gfx->map, 0); |
| 651 | 656 | ||
| 652 | for (int wy = 0; wy < gfx->map->world_height; ++wy) { | 657 | // TODO: This currently renders with tile granularity. Do so instead in terms |
| 653 | for (int wx = 0; wx < gfx->map->world_width; ++wx) { | 658 | // of pixels for more accurate camera panning. The camera coordinates are |
| 659 | // already given in pixels. | ||
| 660 | for (int wy = gfx->camera.y / gfx->map->base_tile_height; | ||
| 661 | wy < gfx->map->world_height; ++wy) { | ||
| 662 | for (int wx = gfx->camera.x / gfx->map->base_tile_width; | ||
| 663 | wx < gfx->map->world_width; ++wx) { | ||
| 654 | const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy); | 664 | const Tile tile = tm_layer_get_tile(gfx->map, layer, wx, wy); |
| 655 | draw_tile_ortho(gfx, tile, wx, wy); | 665 | draw_tile_ortho(gfx, tile, wx, wy); |
| 656 | } | 666 | } |
| @@ -711,7 +721,7 @@ static void draw_sprite_ortho( | |||
| 711 | // Apply an offset similarly to how we offset tiles. The sprite is offset by | 721 | // Apply an offset similarly to how we offset tiles. The sprite is offset by |
| 712 | // -base_tile_width/2 along the x-axis to align the sprite with the leftmost | 722 | // -base_tile_width/2 along the x-axis to align the sprite with the leftmost |
| 713 | // edge of the tile it is on. | 723 | // edge of the tile it is on. |
| 714 | const ivec2 screen_origin = map2screen( | 724 | const ivec2 screen_origin = ortho2screen( |
| 715 | gfx->camera, gfx->map->base_tile_width, gfx->map->base_tile_height, | 725 | gfx->camera, gfx->map->base_tile_width, gfx->map->base_tile_height, |
| 716 | sprite->position.x, sprite->position.y); | 726 | sprite->position.x, sprite->position.y); |
| 717 | 727 | ||
