add scenes, but they don't draw yet

Fri, 25 Apr 2025 18:38:08 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 25 Apr 2025 18:38:08 +0200
changeset 96
9e25f080a33e
parent 95
622887f7e954
child 97
f9a55457b26f

add scenes, but they don't draw yet

src/ascension/scene.h file | annotate | diff | comparison | revisions
src/ascension/window.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	Thu Apr 24 19:53:40 2025 +0200
+++ b/src/ascension/scene.h	Fri Apr 25 18:38:08 2025 +0200
@@ -51,6 +51,8 @@
 /**
  * Destroys a scene graph.
  *
+ * Does nothing when the scene was not initialized.
+ *
  * @param scene the scene graph
  */
 __attribute__((__nonnull__))
@@ -59,6 +61,8 @@
 /**
  * Draws the scene with the specified root node.
  *
+ * If @p scene is not initialized, drawing is skipped.
+ *
  * @param scene the scene graph
  * @param viewport the window viewport the scene shall be drawn to
  */
--- a/src/ascension/window.h	Thu Apr 24 19:53:40 2025 +0200
+++ b/src/ascension/window.h	Fri Apr 25 18:38:08 2025 +0200
@@ -39,6 +39,11 @@
 #define ASC_MAX_WINDOWS 4u
 #endif // ASC_MAX_WINDOWS
 
+#ifndef ASC_MAX_SCENES
+/** The maximum number of non-UI scenes per window. */
+#define ASC_MAX_SCENES 8u
+#endif // ASC_MAX_SCENES
+
 typedef struct AscWindowSettings {
     AscGLContextSettings glsettings;
     asc_vec2i dimensions;
@@ -54,6 +59,7 @@
     asc_vec2i dimensions;
     AscGLContext glctx;
     AscScene ui;
+    AscScene scenes[ASC_MAX_SCENES];
 } AscWindow;
 
 /**
@@ -122,6 +128,18 @@
  */
 unsigned int asc_window_index(Uint32 id);
 
+/**
+ * Returns a pointer to the scene within the currently active window with the specified index.
+ *
+ * If you want to use a scene, you need to initialize it first.
+ * You can destroy the scene any time you want, but used scenes are also
+ * destroyed automatically when the window gets destroyed.
+ *
+ * @param index an index less than #ASC_MAX_SCENES
+ * @return a pointer to the scene
+ */
+AscScene *asc_window_scene(unsigned int index);
+
 
 __attribute__((__nonnull__))
 void asc_add_ui_node(AscSceneNode *node);
--- a/src/scene.c	Thu Apr 24 19:53:40 2025 +0200
+++ b/src/scene.c	Fri Apr 25 18:38:08 2025 +0200
@@ -41,17 +41,25 @@
 #include <assert.h>
 
 void asc_scene_init(AscScene *scene) {
+    if (scene->root != NULL) {
+        asc_wprintf("Scene %"PRIxPTR" is already initialized - initialization skipped.", (uintptr_t) scene);
+        return;
+    }
     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) {
+    if (scene->root == NULL) return;
+
     asc_dprintf("Destroyed scene %"PRIxPTR, (uintptr_t) scene);
     asc_scene_node_free(scene->root);
 }
 
 void asc_scene_draw(AscScene *scene, asc_recti viewport) {
+    if (scene->root == NULL) return;
+
     // create render groups
     CxList *render_group[ASC_RENDER_GROUP_COUNT];
     cx_for_n(i, ASC_RENDER_GROUP_COUNT) {
--- a/src/window.c	Thu Apr 24 19:53:40 2025 +0200
+++ b/src/window.c	Fri Apr 25 18:38:08 2025 +0200
@@ -77,10 +77,10 @@
 
     if (asc_gl_context_initialize(&window->glctx, window->window, &settings->glsettings)) {
         asc_scene_init(&window->ui);
-        asc_dprintf("Window %u initialized", window->id);
+        asc_dprintf("Window %u initialized at index %u", window->id, index);
         asc_context.active_window = index;
     } else {
-        asc_error("Creating GL context failed for window %u", window->id);
+        asc_error("Creating GL context failed for window %u at index %u", window->id, index);
         // cleanup on error
         SDL_DestroyWindow(window->window);
         window->window = NULL;
@@ -104,6 +104,9 @@
     asc_gl_context_activate(&window->glctx);
 
     // destroy all scenes
+    for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) {
+        asc_scene_destroy(&window->scenes[i]);
+    }
     asc_scene_destroy(&window->ui);
 
     // release context related data
@@ -125,8 +128,13 @@
 }
 
 void asc_window_sync(unsigned int index) {
+    if (index > ASC_MAX_WINDOWS) {
+        asc_error("Index for syncing window out of bounds (%u/%u).", index, ASC_MAX_WINDOWS);
+        return;
+    }
+    AscWindow *window = &asc_context.windows[index];
     // necessary safeguard
-    if (asc_context.windows[index].id == 0) return;
+    if (window->id == 0) return;
 
     // active the window that shall be synced temporarily
     unsigned int active_index = asc_context.active_window;
@@ -135,22 +143,24 @@
     }
 
     // Clear the color buffer for the window frame
-    int window_width = asc_active_window->dimensions.width;
-    int window_height = asc_active_window->dimensions.height;
+    int window_width = window->dimensions.width;
+    int window_height = window->dimensions.height;
     glViewport(0, 0, window_width, window_height);
     glClear(GL_COLOR_BUFFER_BIT);
 
-    // Draw the UI
-    AscScene *ui = &asc_active_window->ui;
+    // Draw all scenes
     asc_recti viewport = {0, 0, window_width, window_height};
-    asc_camera_ortho(&ui->camera, viewport);
-    asc_scene_draw(ui, viewport);
+    for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) {
+        asc_scene_draw(&window->scenes[i], viewport);
+    }
+    asc_camera_ortho(&window->ui.camera, viewport);
+    asc_scene_draw(&window->ui, viewport);
 
     // Swap Buffers
-    SDL_GL_SwapWindow(asc_active_window->window);
+    SDL_GL_SwapWindow(window->window);
 
     // Clear Flags
-    asc_active_window->resized = false;
+    window->resized = false;
 
     if (index != active_index) {
         asc_window_activate(active_index);
@@ -173,3 +183,7 @@
 void asc_add_ui_node(AscSceneNode *node) {
     asc_scene_add_node(&asc_active_window->ui, node);
 }
+
+AscScene *asc_window_scene(unsigned int index) {
+    return &asc_active_window->scenes[index];
+}
--- a/test/snake/snake.c	Thu Apr 24 19:53:40 2025 +0200
+++ b/test/snake/snake.c	Fri Apr 25 18:38:08 2025 +0200
@@ -37,6 +37,8 @@
 static AscTexture tex2d[TEX2D_COUNT];
 #define TEXTURE_SHIP &tex2d[TEX_SHIP]
 
+#define MAIN_SCENE asc_window_scene(0)
+
 static void destroy_textures(void *dummy) {
     asc_texture_destroy(tex2d, TEX2D_COUNT);
 }
@@ -101,8 +103,7 @@
         .height = 64
     );
 
-    // TODO: add to 2D scene instead of UI scene, once we have one
-    asc_add_ui_node(sprite);
+    asc_scene_add_node(MAIN_SCENE, sprite);
 
     // TODO: return something
 }
@@ -128,6 +129,11 @@
     settings.title = "Snake";
     asc_window_initialize(0, &settings);
 
+    // initialize the main scene (a 500x500 game field)
+    asc_scene_init(MAIN_SCENE);
+    // TODO: this is intentionally bullshit at the moment to force me to care about aspect ratio
+    asc_camera_ortho(&MAIN_SCENE->camera, (asc_recti){0, 0, 500, 500});
+
     // load textures
     init_textures();
 

mercurial