change asc_scene_init() to also request parameters for camera initialization default tip

Mon, 28 Apr 2025 21:13:01 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 28 Apr 2025 21:13:01 +0200
changeset 100
5231da78831e
parent 99
ac143db979dc

change asc_scene_init() to also request parameters for camera initialization

src/ascension/scene.h file | annotate | diff | comparison | revisions
src/scene.c file | annotate | diff | comparison | revisions
src/window.c file | annotate | diff | comparison | revisions
test/snake/snake.c file | annotate | diff | comparison | revisions
--- a/src/ascension/scene.h	Sun Apr 27 15:17:12 2025 +0200
+++ b/src/ascension/scene.h	Mon Apr 28 21:13:01 2025 +0200
@@ -33,20 +33,37 @@
 #include "camera.h"
 
 typedef struct {
-    // TODO: should a scene always have an own camera?
-    // yes: that would enable efficient frustum culling that does not need to be recalculated
-    // no: if the same scene needs to be drawn from different cameras, we must duplicate the scene graph
     AscCamera camera;
     AscSceneNode *root;
 } AscScene;
 
+enum AscCameraType {
+    ASC_CAMERA_CUSTOM,
+    ASC_CAMERA_ORTHO,
+    ASC_CAMERA_PERSPECTIVE,
+};
+
+typedef struct {
+    enum AscCameraType type;
+    union {
+        struct {
+            asc_recti rect;
+        } ortho;
+        struct {
+            // TODO: implement
+        } perspective;
+    };
+    asc_camera_viewport_update_func viewport_update_func;
+} AscCameraParams;
+
 /**
  * Initializes a scene graph.
  *
  * @param scene the scene graph
+ * @param camera_params initial camera parameters
  */
 __attribute__((__nonnull__))
-void asc_scene_init(AscScene *scene);
+void asc_scene_init(AscScene *scene, AscCameraParams camera_params);
 
 /**
  * Destroys a scene graph.
@@ -59,6 +76,16 @@
 void asc_scene_destroy(AscScene *scene);
 
 /**
+ * Returns a pointer to the scene's camera.
+ *
+ * @param scene the scene graph
+ */
+__attribute__((__nonnull__))
+static inline AscCamera *asc_scene_camera(AscScene *scene) {
+    return &scene->camera;
+}
+
+/**
  * Draws the scene with the specified root node.
  *
  * If @p scene is not initialized, drawing is skipped.
--- a/src/scene.c	Sun Apr 27 15:17:12 2025 +0200
+++ b/src/scene.c	Mon Apr 28 21:13:01 2025 +0200
@@ -40,14 +40,24 @@
 
 #include <assert.h>
 
-void asc_scene_init(AscScene *scene) {
+void asc_scene_init(AscScene *scene, AscCameraParams camera_params) {
     if (scene->root != NULL) {
         asc_wprintf("Scene %"PRIxPTR" is already initialized - initialization skipped.", (uintptr_t) scene);
         return;
     }
+    if (camera_params.type == ASC_CAMERA_ORTHO) {
+        asc_camera_ortho(&scene->camera, camera_params.ortho.rect);
+    } else if (camera_params.type == ASC_CAMERA_PERSPECTIVE) {
+        // TODO: implement
+        asc_wprintf("Camera type PERSPECTIVE is not yet implemented.");
+    } else {
+        // at least zero all the bytes (law of the least surprise)
+        memset(&scene->camera, 0, sizeof(AscCamera));
+    }
+    scene->camera.viewport_update_func = camera_params.viewport_update_func;
+    scene->root = asc_scene_node_empty();
+
     asc_dprintf("Initialized scene %"PRIxPTR, (uintptr_t) scene);
-    // TODO: how should we initialize the camera?
-    scene->root = asc_scene_node_empty();
 }
 
 void asc_scene_destroy(AscScene *scene) {
--- a/src/window.c	Sun Apr 27 15:17:12 2025 +0200
+++ b/src/window.c	Mon Apr 28 21:13:01 2025 +0200
@@ -76,9 +76,11 @@
     window->resized = true; // count initial sizing as resize
 
     if (asc_gl_context_initialize(&window->glctx, window->window, &settings->glsettings)) {
-        asc_scene_init(&window->ui);
-        asc_camera_ortho(&window->ui.camera, (asc_recti){
-            0, 0, window->dimensions.width, window->dimensions.height
+        asc_scene_init(&window->ui, (AscCameraParams){
+            .type = ASC_CAMERA_ORTHO,
+            .ortho.rect = (asc_recti){
+                0, 0, window->dimensions.width, window->dimensions.height
+            }
         });
         asc_dprintf("Window %u initialized at index %u", window->id, index);
         asc_context.active_window = index;
--- a/test/snake/snake.c	Sun Apr 27 15:17:12 2025 +0200
+++ b/test/snake/snake.c	Mon Apr 28 21:13:01 2025 +0200
@@ -150,9 +150,11 @@
     asc_window_initialize(0, &settings);
 
     // initialize the main scene (a 500x500 game field)
-    asc_scene_init(MAIN_SCENE);
-    asc_camera_ortho(&MAIN_SCENE->camera, (asc_recti){0, 0, 500, 500});
-    MAIN_SCENE->camera.viewport_update_func = update_viewport_for_window_resize;
+    asc_scene_init(MAIN_SCENE, (AscCameraParams) {
+        .type = ASC_CAMERA_ORTHO,
+        .ortho.rect = (asc_recti){0, 0, 500, 500},
+        .viewport_update_func = update_viewport_for_window_resize
+    });
 
     // load textures
     init_textures();

mercurial