summaryrefslogtreecommitdiff
path: root/chickadee.scm
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2023-09-30 19:42:01 -0400
committerDavid Thompson <dthompson2@worcester.edu>2023-11-08 21:35:34 -0500
commitd2adfa5c5bae5d8ee20564ec9e50cae4b75f945d (patch)
treef119ba324c4da2b173e4fa05be6136e040a9a4d2 /chickadee.scm
parentac57fbe150e213389b4ef61b7a510a1fa8d5a093 (diff)
WIP: Switch to WebGPU-like API
Diffstat (limited to 'chickadee.scm')
-rw-r--r--chickadee.scm126
1 files changed, 67 insertions, 59 deletions
diff --git a/chickadee.scm b/chickadee.scm
index 656ce0b..8343a6b 100644
--- a/chickadee.scm
+++ b/chickadee.scm
@@ -16,7 +16,7 @@
;;; Commentary:
;;
-;; Simple SDL + OpenGL game loop implementation.
+;; Core event loop.
;;
;;; Code:
@@ -26,12 +26,12 @@
#:use-module (chickadee game-loop)
#:use-module (chickadee math matrix)
#:use-module (chickadee graphics color)
- #:use-module (chickadee graphics engine)
#:use-module (chickadee graphics gpu)
- #:use-module (chickadee graphics viewport)
+ ;; #:use-module (chickadee graphics viewport)
#:use-module (chickadee utils)
#:use-module (ice-9 atomic)
#:use-module (ice-9 match)
+ #:use-module (ice-9 threads)
#:use-module (sdl2)
#:use-module (sdl2 events)
#:use-module ((sdl2 input game-controller) #:prefix sdl2:)
@@ -76,6 +76,9 @@
#:re-export (abort-game
current-timestep))
+
+
+
(define %time-freq (exact->inexact internal-time-units-per-second))
(define (elapsed-time)
@@ -155,10 +158,8 @@ not being pushed at all."
(define* (make-window #:key (title "Chickadee") fullscreen? resizable?
(width 640) (height 480) (multisample? #t))
- ;; Hint that we want OpenGL 3.2 Core profile. Doesn't mean we'll
- ;; get it, though!
- (sdl2:set-gl-attribute! 'context-major-version 3)
- (sdl2:set-gl-attribute! 'context-major-version 2)
+ ;; Hint that we want the core profile with deprecated features
+ ;; disabled. Doesn't mean we'll get it, though!
(sdl2:set-gl-attribute! 'context-profile-mask 1) ; core profile
(sdl2:set-gl-attribute! 'stencil-size 8) ; 8-bit stencil buffer
(if multisample?
@@ -254,7 +255,8 @@ border is disabled, otherwise it is enabled.")
(window-height 480)
window-fullscreen?
window-resizable?
- (clear-color %default-clear-color)
+ (clear-color black;; %default-clear-color
+ )
(update-hz 60)
(load noop)
(update noop)
@@ -304,20 +306,19 @@ border is disabled, otherwise it is enabled.")
#:fullscreen? window-fullscreen?
#:resizable? window-resizable?
#:multisample? #f)))
- (default-viewport (vector
- (make-viewport 0 0 window-width window-height
- #:clear-color clear-color)))
+ ;; (default-viewport (vector
+ ;; (make-viewport 0 0 window-width window-height
+ ;; #:clear-color clear-color)))
(default-projection (vector
(orthographic-projection 0 window-width
window-height 0
0 1)))
- (gpu (make-gpu (window-gl-context window)))
- (gfx (make-graphics-engine gpu)))
+ (gpu (make-gpu (unwrap-window window) (window-gl-context window))))
(define (invert-y y)
;; SDL's origin is the top-left, but our origin is the bottom
;; left so we need to invert Y coordinates that SDL gives us.
(- window-height y))
- (define (input-sdl)
+ (define (flush-sdl-input)
(define (process-event event)
(cond
((quit-event? event)
@@ -398,9 +399,9 @@ border is disabled, otherwise it is enabled.")
((width height)
(set! window-width width)
(set! window-height height)
- (vector-set! default-viewport 0
- (make-viewport 0 0 width height
- #:clear-color clear-color))
+ ;; (vector-set! default-viewport 0
+ ;; (make-viewport 0 0 width height
+ ;; #:clear-color clear-color))
(vector-set! default-projection 0
(orthographic-projection 0 width height 0 0 1))
(window-resize width height))))))
@@ -409,51 +410,58 @@ border is disabled, otherwise it is enabled.")
(when event
(process-event event)
(loop (poll-event)))))
- (define (update-sdl dt)
- (input-sdl)
- (update dt)
- ;; Update audio after updating game state so that any sounds
- ;; that were queued to play this frame start playing immediately.
- (update-audio)
- ;; Free any GPU resources that have been GC'd.
- (graphics-engine-gc gfx))
- (define (render-sdl-opengl alpha)
- (graphics-engine-reset! gfx)
- ;; Enable seamless cube maps.
- ;; TODO: This should go somewhere else.
- (set-gpu-seamless-cube-maps! (current-gpu) #t)
- (with-viewport (vector-ref default-viewport 0)
- (clear-viewport)
- (with-graphics-state ((projection (vector-ref default-projection 0)))
- (draw alpha)))
- (sdl2:swap-gl-window (unwrap-window window)))
(define (on-error e stack)
(error e stack)
;; Flush all input events that have occurred while in the error
;; state.
(while (poll-event) #t))
- (dynamic-wind
- (const #t)
- (lambda ()
- (parameterize ((current-window window)
- (current-graphics-engine gfx))
- ;; Attempt to activate vsync, if possible. Some systems do
- ;; not support setting the OpenGL swap interval.
- (catch #t
- (lambda ()
- (sdl2:set-gl-swap-interval! 'vsync))
- (lambda args
- (display "warning: could not enable vsync\n"
- (current-error-port))))
- (sdl2:load-game-controller-mappings!
- (scope-datadir "gamecontrollerdb.txt"))
- (run-game* #:init load
- #:update update-sdl
- #:render render-sdl-opengl
- #:error (and error on-error)
- #:time elapsed-time
- #:update-hz update-hz)))
+ ;; The game loop will run in its own thread so that updating game
+ ;; state can happen while rendering and input are being processed
+ ;; in the main thread and thus improving overall performance.
+ ;; This is where all user code is executed.
+ (define (game-loop)
+ (parameterize ((current-window window)
+ (current-gpu gpu))
+ (run-game* #:init load
+ #:update update
+ #:render draw
+ #:error (and error on-error)
+ #:time elapsed-time
+ #:update-hz update-hz)))
+ ;; The main loop handles the input and rendering queues, as input
+ ;; polling and GPU calls have to be done from the main thread in
+ ;; SDL.
+ (define (main-loop)
+ (flush-sdl-input)
+ (update-audio)
+ ;; (graphics-engine-reset! gfx)
+ ;; Enable seamless cube maps.
+ ;; TODO: This should go somewhere else.
+ ;; (set-gpu-seamless-cube-maps! (current-gpu) #t)
+ ;; (with-viewport (vector-ref default-viewport 0)
+ ;; (clear-viewport)
+ ;; (with-graphics-state ((projection (vector-ref default-projection 0)))
+ ;; (draw alpha)))
+ (gpu-tick gpu)
+ (gpu-swap gpu)
+ ;; Free any GPU resources that have been GC'd.
+ (gpu-gc gpu)
+ (usleep 1) ; don't use 100% of the cpu pls
+ (main-loop))
+ ;; Attempt to activate vsync, if possible. Some systems do
+ ;; not support setting the OpenGL swap interval.
+ (catch #t
(lambda ()
- (quit-audio)
- (sdl2:delete-gl-context! (window-gl-context window))
- (sdl2:close-window! (unwrap-window window))))))
+ (sdl2:set-gl-swap-interval! 'vsync))
+ (lambda args
+ (display "warning: could not enable vsync\n"
+ (current-error-port))))
+ ;; Make lots of game controllers "just work."
+ (sdl2:load-game-controller-mappings!
+ (scope-datadir "gamecontrollerdb.txt"))
+ ;; Launch game loop in a separate thread and start the main loop.
+ (let ((game-thread (call-with-new-thread game-loop)))
+ (main-loop)
+ (quit-audio)
+ (sdl2:delete-gl-context! (window-gl-context window))
+ (sdl2:close-window! (unwrap-window window)))))