add viewport_clear flag to camera settings default tip

Wed, 14 May 2025 20:14:18 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 14 May 2025 20:14:18 +0200
changeset 121
ede9a9e92ff9
parent 120
54e56cdddab2

add viewport_clear flag to camera settings

src/Makefile file | annotate | diff | comparison | revisions
src/ascension/camera.h file | annotate | diff | comparison | revisions
src/ascension/datatypes.h file | annotate | diff | comparison | revisions
src/ascension/scene.h file | annotate | diff | comparison | revisions
src/camera.c 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/Makefile	Tue May 13 20:27:43 2025 +0200
+++ b/src/Makefile	Wed May 14 20:14:18 2025 +0200
@@ -50,8 +50,11 @@
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -c $<
 
-$(BUILD_DIR)/camera.o: camera.c ascension/error.h ascension/camera.h \
- ascension/datatypes.h
+$(BUILD_DIR)/camera.o: camera.c ascension/error.h ascension/context.h \
+ ascension/datatypes.h ascension/window.h ascension/glcontext.h \
+ ascension/shader.h ascension/texture.h ascension/scene.h \
+ ascension/scene_node.h ascension/transform.h ascension/camera.h \
+ ascension/input.h ascension/ui/font.h ascension/camera.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -c $<
 
@@ -85,7 +88,8 @@
 	$(CC) -o $@ $(CFLAGS) -c $<
 
 $(BUILD_DIR)/glcontext.o: glcontext.c ascension/glcontext.h \
- ascension/shader.h ascension/texture.h ascension/error.h
+ ascension/shader.h ascension/texture.h ascension/datatypes.h \
+ ascension/error.h
 	@echo "Compiling $<"
 	$(CC) -o $@ $(CFLAGS) -c $<
 
--- a/src/ascension/camera.h	Tue May 13 20:27:43 2025 +0200
+++ b/src/ascension/camera.h	Wed May 14 20:14:18 2025 +0200
@@ -46,6 +46,8 @@
      */
     asc_camera_viewport_update_func viewport_update_func;
     asc_camera_projection_update_func projection_update_func;
+    asc_col4f clear_color;
+    bool viewport_clear;
 };
 
 enum AscCameraType {
@@ -54,7 +56,7 @@
     ASC_CAMERA_PERSPECTIVE,
 };
 
-typedef struct {
+struct asc_camera_init_args {
     enum AscCameraType type;
     union {
         struct {
@@ -66,10 +68,17 @@
     };
     asc_camera_viewport_update_func viewport_update_func;
     asc_camera_projection_update_func projection_update_func;
-} AscCameraParams;
+    /**
+     * Indicates whether the viewport for this camera shall be cleared before rendering.
+     * The active drawing color will be used as the clear color (can be changed in the camera struct, afterward).
+     */
+    bool viewport_clear;
+};
 
 __attribute__((__nonnull__))
-void asc_camera_init(AscCamera *camera, AscCameraParams params);
+void asc_camera_init_(AscCamera *camera, struct asc_camera_init_args args);
+
+#define asc_camera_init(camera,...) asc_camera_init_(camera, (struct asc_camera_init_args){__VA_ARGS__})
 
 __attribute__((__nonnull__))
 void asc_camera_ortho(AscCamera *camera, asc_recti rect);
--- a/src/ascension/datatypes.h	Tue May 13 20:27:43 2025 +0200
+++ b/src/ascension/datatypes.h	Wed May 14 20:14:18 2025 +0200
@@ -150,6 +150,16 @@
     return r;
 }
 
+static inline asc_col4f asc_col_itof(asc_col4i c) {
+    // dividing by 256 is much more performant
+    return (asc_col4f) {
+        (c.red+1.f) / 256.f,
+        (c.green+1.f) / 256.f,
+        (c.blue+1.f) / 256.f,
+        (c.alpha+1.f) / 256.f,
+    };
+}
+
 static inline SDL_Color asc_col_sdl(asc_col4i col) {
     return (SDL_Color) {.r = col.red, .g = col.green, .b = col.blue, .a = col.alpha};
 }
--- a/src/ascension/scene.h	Tue May 13 20:27:43 2025 +0200
+++ b/src/ascension/scene.h	Wed May 14 20:14:18 2025 +0200
@@ -43,7 +43,15 @@
  * @param camera_params initial camera parameters
  */
 __attribute__((__nonnull__))
-void asc_scene_init(AscScene *scene, AscCameraParams camera_params);
+void asc_scene_init_(AscScene *scene, struct asc_camera_init_args camera_params);
+
+/**
+ * Initializes a scene graph.
+ *
+ * @param scene the scene graph
+ * @param ... initial camera parameters
+ */
+#define asc_scene_init(scene, ...) asc_scene_init_(scene, (struct asc_camera_init_args){__VA_ARGS__})
 
 /**
  * Destroys a scene graph.
--- a/src/camera.c	Tue May 13 20:27:43 2025 +0200
+++ b/src/camera.c	Wed May 14 20:14:18 2025 +0200
@@ -26,25 +26,28 @@
  */
 
 #include "ascension/error.h"
+#include "ascension/context.h"
 #include "ascension/camera.h"
 
-void asc_camera_init(AscCamera *camera, AscCameraParams params) {
-    if (params.type == ASC_CAMERA_ORTHO) {
-        asc_recti rect = params.ortho.rect;
+void asc_camera_init_(AscCamera *camera, struct asc_camera_init_args args) {
+    if (args.type == ASC_CAMERA_ORTHO) {
+        asc_recti rect = args.ortho.rect;
         if (rect.size.width <= 0 || rect.size.height <= 0) {
             rect.size.width = 1;
             rect.size.height = 1;
         }
         asc_camera_ortho(camera, rect);
-    } else if (params.type == ASC_CAMERA_PERSPECTIVE) {
+    } else if (args.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(camera, 0, sizeof(AscCamera));
     }
-    camera->viewport_update_func = params.viewport_update_func;
-    camera->projection_update_func = params.projection_update_func;
+    camera->viewport_update_func = args.viewport_update_func;
+    camera->projection_update_func = args.projection_update_func;
+    camera->viewport_clear = args.viewport_clear;
+    camera->clear_color = asc_col_itof(asc_context.ink);
 }
 
 void asc_camera_ortho(AscCamera *camera, asc_recti rect) {
--- a/src/scene.c	Tue May 13 20:27:43 2025 +0200
+++ b/src/scene.c	Wed May 14 20:14:18 2025 +0200
@@ -41,12 +41,12 @@
 
 #include <assert.h>
 
-void asc_scene_init(AscScene *scene, AscCameraParams camera_params) {
+void asc_scene_init_(AscScene *scene, struct asc_camera_init_args args) {
     if (scene->root != NULL) {
         asc_wprintf("Scene %"PRIxPTR" is already initialized - initialization skipped.", (uintptr_t) scene);
         return;
     }
-    asc_camera_init(&scene->camera, camera_params);
+    asc_camera_init_(&scene->camera, args);
     scene->root = asc_scene_node_empty();
 
     asc_dprintf("Initialized scene %"PRIxPTR, (uintptr_t) scene);
@@ -149,6 +149,19 @@
             scene->camera.viewport.size.width,
             scene->camera.viewport.size.height
     );
+    if (scene->camera.viewport_clear) {
+        glScissor(
+            scene->camera.viewport.pos.x,
+            -scene->camera.viewport.pos.y,
+            scene->camera.viewport.size.width,
+            scene->camera.viewport.size.height
+        );
+        glEnable(GL_SCISSOR_TEST);
+        const asc_col4f col = scene->camera.clear_color;
+        glClearColor(col.red, col.green, col.blue, col.alpha);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glDisable(GL_SCISSOR_TEST);
+    }
 
     // -------------------------
     // process the render groups
--- a/src/window.c	Tue May 13 20:27:43 2025 +0200
+++ b/src/window.c	Wed May 14 20:14:18 2025 +0200
@@ -78,11 +78,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, (AscCameraParams){
+        asc_scene_init(&window->ui,
             .type = ASC_CAMERA_ORTHO,
             .ortho.rect = asc_recti_new(0, 0, window->dimensions.width, window->dimensions.height),
             .projection_update_func = asc_camera_ortho_update_size
-        });
+        );
         asc_dprintf("Window %u initialized at index %u", window->id, index);
         asc_context.active_window = index;
     } else {
--- a/test/snake/snake.c	Tue May 13 20:27:43 2025 +0200
+++ b/test/snake/snake.c	Wed May 14 20:14:18 2025 +0200
@@ -173,15 +173,17 @@
 
     // initialize the scenes
     const int game_field_size = 500;
-    asc_scene_init(BACKDROP_SCENE, (AscCameraParams) {
+    asc_scene_init(BACKDROP_SCENE,
         .type = ASC_CAMERA_ORTHO,
         .projection_update_func = asc_camera_ortho_update_size
-    });
-    asc_scene_init(MAIN_SCENE, (AscCameraParams) {
+    );
+    asc_ink_rgb(0, 128, 90);
+    asc_scene_init(MAIN_SCENE,
         .type = ASC_CAMERA_ORTHO,
         .ortho.rect = asc_recti_new(0, 0, game_field_size, game_field_size),
+        .viewport_clear = true,
         .viewport_update_func = update_viewport_for_window_resize
-    });
+    );
 
     // backdrop for letterbox/pillarbox
     create_backdrop();

mercurial