# HG changeset patch # User Mike Becker # Date 1747246458 -7200 # Node ID ede9a9e92ff9e7d459a9c4474d170cfd3abbfc39 # Parent 54e56cdddab2ddd9bc2dd8db2a66e50e05430e58 add viewport_clear flag to camera settings diff -r 54e56cdddab2 -r ede9a9e92ff9 src/Makefile --- 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 $< diff -r 54e56cdddab2 -r ede9a9e92ff9 src/ascension/camera.h --- 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); diff -r 54e56cdddab2 -r ede9a9e92ff9 src/ascension/datatypes.h --- 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}; } diff -r 54e56cdddab2 -r ede9a9e92ff9 src/ascension/scene.h --- 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. diff -r 54e56cdddab2 -r ede9a9e92ff9 src/camera.c --- 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) { diff -r 54e56cdddab2 -r ede9a9e92ff9 src/scene.c --- 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 -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 diff -r 54e56cdddab2 -r ede9a9e92ff9 src/window.c --- 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 { diff -r 54e56cdddab2 -r ede9a9e92ff9 test/snake/snake.c --- 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();