summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2023-04-30 10:21:08 -0400
committerDavid Thompson <dthompson2@worcester.edu>2023-04-30 10:28:17 -0400
commitd17a18a52d6c1fafef5e0751e69a2fa0728977f3 (patch)
tree455cec8a67956a04f32e0f432dbb65a150187180
parent429d764c9fa4eb7df57c52e25a97f13e0e8c5c1e (diff)
Allow regions to be "frozen" so they don't render/update.
-rw-r--r--catbird/region.scm49
1 files changed, 42 insertions, 7 deletions
diff --git a/catbird/region.scm b/catbird/region.scm
index af6f206..c7620ad 100644
--- a/catbird/region.scm
+++ b/catbird/region.scm
@@ -29,7 +29,10 @@
#:use-module (chickadee)
#:use-module (chickadee data array-list)
#:use-module (chickadee graphics engine)
+ #:use-module (chickadee graphics framebuffer)
#:use-module (chickadee graphics viewport)
+ #:use-module (chickadee graphics sprite)
+ #:use-module (chickadee math matrix)
#:use-module (chickadee math rect)
#:use-module (ice-9 exceptions)
#:use-module (oop goops)
@@ -41,10 +44,13 @@
area-width
area-height
camera
+ freeze
+ frozen?
scene
replace-scene
push-scene
- pop-scene)
+ pop-scene
+ unfreeze)
#:re-export (name
rank
render
@@ -54,7 +60,12 @@
(area #:accessor area #:init-keyword #:area)
(camera #:accessor camera #:init-keyword #:camera #:init-value #f)
(scene-state #:accessor scene-state #:init-thunk make-pushdown-state)
- (viewport #:accessor viewport))
+ (viewport #:accessor viewport)
+ (framebuffer #:accessor framebuffer)
+ (framebuffer-rect #:accessor framebuffer-rect)
+ ;; Regions can be frozen for debugging purposes, so that the scene
+ ;; they contain isn't updated or rendered.
+ (frozen? #:accessor frozen? #:init-value #f))
(define-method (area-x (region <region>))
(rect-x (area region)))
@@ -84,7 +95,14 @@
(make-viewport (float->int (rect-x r))
(float->int (rect-y r))
(float->int (rect-width r))
- (float->int (rect-height r))))))
+ (float->int (rect-height r))))
+ (set! (framebuffer region)
+ (make-framebuffer (float->int (rect-width r))
+ (float->int (rect-height r))))
+ (set! (framebuffer-rect region)
+ (make-rect 0.0 0.0
+ (float->int (rect-width r))
+ (float->int (rect-height r))))))
(define (make-region area name rank)
(let* ((window (current-window))
@@ -98,6 +116,12 @@
(make-exception-with-message "region area exceeds window area")))
(make <region> #:area area #:name name #:rank rank)))
+(define-method (freeze (region <region>))
+ (set! (frozen? region) #t))
+
+(define-method (unfreeze (region <region>))
+ (set! (frozen? region) #f))
+
(define-method (scene (region <region>))
(state-current (scene-state region)))
@@ -127,12 +151,23 @@
(define-method (update (region <region>) dt)
(let ((s (scene region)))
- (when s (update/around s dt))))
+ (when (and s (not (frozen? region)))
+ (update/around s dt))))
+(define %identity-matrix (make-identity-matrix4))
(define-method (render (region <region>) alpha)
(let ((s (scene region))
- (c (camera region)))
+ (c (camera region))
+ (fb (framebuffer region)))
(when (and s c)
(parameterize ((current-camera c))
- (with-projection (projection-matrix (camera region))
- (render/around s alpha))))))
+ ;; Don't render to the framebuffer if region is frozen. Just
+ ;; draw the frozen frame instead.
+ (unless (frozen? region)
+ (with-framebuffer fb
+ (with-projection (projection-matrix (camera region))
+ (render/around s alpha))))
+ (with-graphics-state ((g:viewport (viewport region)))
+ (draw-sprite* (framebuffer-texture fb)
+ (framebuffer-rect region)
+ %identity-matrix))))))