map: WIP camera viewport rendering
authorLukas Krickl <lukas@krickl.dev>
Tue, 3 Mar 2026 11:46:20 +0000 (12:46 +0100)
committerLukas Krickl <lukas@krickl.dev>
Tue, 3 Mar 2026 11:46:20 +0000 (12:46 +0100)
src/r_assets.c
src/t_camera.c
src/t_camera.h
src/t_map.c
src/u_math.c
src/u_math.h

index b68499e54b6d105b452dad93ce7e5cea8f671b09..05588a27ddddea19ed924a8c7f6bb908ab9ccf63 100644 (file)
@@ -53,6 +53,12 @@ void r_draw_solid_isometric_tile(i32 x, i32 y, r_color color) {
        r_color final_color;
        struct u_vec2 t = u_tile_to_screen(x, y);
        t = u_screen_to_camera(&t_main_camera, t);
+       
+       /* do not draw if tile is not visible at all */
+       if (!t_camera_is_visible_world(&t_main_camera, t.x, t.y)
+                       && !t_camera_is_visible_world(&t_main_camera, t.x + R_TILE_W, t.y + R_TILE_H)) {
+               return;
+       }
 
        /* converted origin point in isometric space */
        
index bb60a64b8c05af03c5e5bb395eef0593e08408bc..896dd7984f01fbc9f91ba34a8a81300603a47a4a 100644 (file)
@@ -1,4 +1,5 @@
 #include "t_camera.h"
+#include "u_math.h"
 
 struct t_camera t_main_camera;
 
@@ -13,12 +14,21 @@ struct t_camera t_camera_init(i32 viewport_x, i32 viewport_y) {
 }
 
 void t_camera_scroll(struct t_camera *c, i32 by_x, i32 by_y) {
+       /* TODO: calculate min/max viewport based on map in a better way */
        c->x += by_x;
        c->y += by_y;
+}
+
+lrts_bool t_camera_is_visible_screen(struct t_camera *c, i32 x, i32 y) {
+       return u_point_in_rect(x, y, c->x, c->y, c->x + c->viewport_x, c->y + c->viewport_y);
+}
 
-       /* TODO: calculate max viewport based on map */
-       U_CLAMP(c->x, -4096, 4096);
-       U_CLAMP(c->y, -4096, 4096);
+lrts_bool t_camera_is_visible_world(struct t_camera *c, i32 x, i32 y) {
+       struct u_vec2 t;
+       t.x = c->x;
+       t.y = c->y;
+       
+       return u_point_in_rect(x, y, t.x, t.y, t.x + c->viewport_x, t.y + c->viewport_y);
 }
 
 
index 347d34994340ac50f01286ef9ced183fed32b6b8..3a9d57c960f2acc5903bdbcf25ec1cceb5f0b22f 100644 (file)
@@ -20,4 +20,10 @@ void t_camera_scroll(struct t_camera *c, i32 by_x, i32 by_y);
 /* adjusts a screen coodrinate by the camera offset */
 struct u_vec2 u_screen_to_camera(struct t_camera *c, struct u_vec2 v);
 
+/* tests if a point is visible in screen sapce */
+lrts_bool t_camera_is_visible_screen(struct t_camera *c, i32 x, i32 y);
+
+/* tests if a point is visible in world space */
+lrts_bool t_camera_is_visible_world(struct t_camera *c, i32 x, i32 y);
+
 #endif
index 4f3995c909372f5dfe4b10f3d0895325c4176c0a..55608a1eb0d6da0a8d13814d29bb9c85b76b5ab6 100644 (file)
@@ -26,19 +26,12 @@ void t_map_draw(struct t_map *m) {
        struct u_vec2 start;
        struct u_vec2 end;
        
-       /* estimate the viewport based on the orthogonal map 
-        * This is not perfect, but it is good enough to avoid drawing a
-        * full size map.
-        */
-       start.x = t_main_camera.x / R_TILE_W;
-       start.y = t_main_camera.y / R_TILE_H;
-
-       end.x = ((t_main_camera.x + t_main_camera.viewport_x) / R_TILE_W) * 2;
-       end.y = ((t_main_camera.y + t_main_camera.viewport_y) / R_TILE_H) * 2;
-
        start.x = 0;
        start.y = 0;
 
+       end.x = t_map.width;
+       end.y = t_map.height;
+
        for (i = start.x; i < end.x; i++) {
                for (j = start.y; j < end.y; j++) {
                        r_draw_tile(&m->tiles[j * m->width + i], i, j);
index 52908e5fc3b0172e362b0a5933ae95ab0448ddaa..e4c40a6b0c46a48cc6b640180cacb2985ecab91e 100644 (file)
@@ -19,6 +19,15 @@ struct u_vec2 u_tile_to_screen(i32 x, i32 y) {
        return r;
 }
 
+struct u_vec2 u_point_to_screen(i32 x, i32 y) {
+       struct u_vec2 r;
+
+       r.x = (x) + (y);
+       r.y = (y) - (x);
+
+       return r;
+}
+
 lrts_bool u_point_in_rect(i32 x, i32 y, i32 rx, i32 ry, i32 rw, i32 rh) {
        return x >= rx && x <= rx + rw
                        && y >= ry && y <= ry + rh;
index c299f559cee555db0057c7831840324062ca0083..af63f6c7e38cf53f5e910fbe3094764c6ab64d9a 100644 (file)
@@ -50,6 +50,9 @@ struct u_vec2 u_vec2_mul(i32 n, struct u_vec2 v);
  */
 struct u_vec2 u_tile_to_screen(i32 x, i32 y);
 
+/* convers a point to screen space */
+struct u_vec2 u_point_to_screen(i32 x, i32 y);
+
 /* tests if a point is contained inside a rectangle */
 lrts_bool u_point_in_rect(i32 x, i32 y, i32 rx, i32 ry, i32 rw, i32 rh);