Tue, 12 Aug 2025 21:04:59 +0200
update viewports of cameras before executing behaviors, so that the new viewport information is available in the behavior functions
src/ascension/camera.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/ascension/camera.h Sat Aug 09 14:36:39 2025 +0200 +++ b/src/ascension/camera.h Tue Aug 12 21:04:59 2025 +0200 @@ -82,6 +82,18 @@ void asc_camera_ortho(AscCamera *camera, asc_rect rect); + +/** + * Updates the camera with the new window viewport. + * + * This is automatically called when a window resizes. + * It should not be necessary to call this function manually. + * + * @param camera the camera + * @param window_size the new window size + */ +void asc_camera_update_viewport(AscCamera *camera, asc_vec2u window_size); + /** * Shorter version of updating an orthographic camera which assumes the top right corner at (0,0). *
--- a/src/ascension/scene.h Sat Aug 09 14:36:39 2025 +0200 +++ b/src/ascension/scene.h Tue Aug 12 21:04:59 2025 +0200 @@ -62,6 +62,14 @@ #define asc_scene_init(scene, name, ...) asc_scene_init_(scene, name, (struct asc_camera_init_args){__VA_ARGS__}) /** + * Checks if a scene is active. + * + * @param scene the scene + * @return true if the scene is active for rendering, false if the scene is uninitialized or destroyed + */ +#define asc_scene_active(scene) ((scene)->root != NULL) + +/** * Destroys a scene graph. * * Does nothing when the scene was not initialized.
--- a/src/camera.c Sat Aug 09 14:36:39 2025 +0200 +++ b/src/camera.c Tue Aug 12 21:04:59 2025 +0200 @@ -62,3 +62,15 @@ void asc_camera_ortho_update_size(AscCamera *camera, asc_vec2u size) { asc_mat4f_ortho_update_size(camera->projection, (float)size.width, (float)size.height); } + +void asc_camera_update_viewport(AscCamera *camera, asc_vec2u window_size) { + if (camera->viewport_update_func == NULL) { + // this assumes the viewport was initialized with zeros! + camera->viewport.size = window_size; + } else { + camera->viewport = camera->viewport_update_func(window_size); + } + if (camera->projection_update_func != NULL) { + camera->projection_update_func(camera, window_size); + } +}
--- a/src/scene.c Sat Aug 09 14:36:39 2025 +0200 +++ b/src/scene.c Tue Aug 12 21:04:59 2025 +0200 @@ -120,20 +120,6 @@ void asc_scene_draw(AscScene *scene) { if (scene->root == NULL) return; - // if the window resized, we must update the viewport - if (asc_active_window->resized) { - asc_vec2u window_size = asc_active_window->dimensions; - if (scene->camera.viewport_update_func == NULL) { - // this assumes the viewport was initialized with zeros! - scene->camera.viewport.size = window_size; - } else { - scene->camera.viewport = scene->camera.viewport_update_func(window_size); - } - if (scene->camera.projection_update_func != NULL) { - scene->camera.projection_update_func(&scene->camera, window_size); - } - } - // when the viewport is zero, exit immediately if (scene->camera.viewport.size.width == 0 || scene->camera.viewport.size.height == 0) { return;
--- a/src/window.c Sat Aug 09 14:36:39 2025 +0200 +++ b/src/window.c Tue Aug 12 21:04:59 2025 +0200 @@ -143,6 +143,16 @@ glViewport(0, 0, window_width, window_height); glClear(GL_COLOR_BUFFER_BIT); + // Update the viewports when the window resized + if (window->resized) { + for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) { + if (asc_scene_active(&window->scenes[i])) { + asc_camera_update_viewport(&window->scenes[i].camera, window->dimensions); + } + } + asc_camera_update_viewport(&window->ui.camera, window->dimensions); + } + // Execute all behaviors // TODO: this can eventually be parallelized for (unsigned int i = 0; i < ASC_MAX_SCENES; i++) {
--- a/test/snake/snake.c Sat Aug 09 14:36:39 2025 +0200 +++ b/test/snake/snake.c Tue Aug 12 21:04:59 2025 +0200 @@ -121,11 +121,7 @@ } static void main_scene_frame_scale(AscBehavior *behavior) { - // TODO: we cannot skip this behavior when window is resized, - // because the viewport is updated after executing all behaviors - // and then the resized flag is cleared already. - // A possible solution is to add something like a post-rendering behavior. - // Another solution would be a viewport-changed-event (once we implement events) + if (!asc_active_window->resized) return; asc_ptr_cast(AscRectangle, frame, behavior->node); asc_rectangle_set_bounds(frame, MAIN_SCENE->camera.viewport); }