summaryrefslogtreecommitdiff
path: root/sly/render.scm
diff options
context:
space:
mode:
authorDavid Thompson <dthompson2@worcester.edu>2015-08-26 09:12:02 -0400
committerDavid Thompson <dthompson2@worcester.edu>2015-08-26 09:12:02 -0400
commitf8b48b550d5f167483a545f207ae053d8fa9d5dd (patch)
treec1577bdd721598dbe48d7b6ca3a21ad202a99471 /sly/render.scm
parenta0b33ff9274b0fb682e36a42e3aa70ce5581df7c (diff)
render: Reimplement OpenGL state machine manager.
The implementation is a bit cleaner, and it's a stepping stone towards render combinators. * sly/render/context.scm: Delete. * sly/render.scm: New file. * Makefile.am (SOURCES): Add it. Remove context.scm. * sly/game.scm (run-game-loop): Use new <graphics> type. * sly/render/model.scm (draw-model): Likewise. * sly/render/scene.scm (draw-scene): Likewise. * examples/2048/2048.scm: Remove (sly render context) import.
Diffstat (limited to 'sly/render.scm')
-rw-r--r--sly/render.scm206
1 files changed, 206 insertions, 0 deletions
diff --git a/sly/render.scm b/sly/render.scm
new file mode 100644
index 0000000..15103cd
--- /dev/null
+++ b/sly/render.scm
@@ -0,0 +1,206 @@
+;;; Sly
+;;; Copyright (C) 2014 David Thompson <davet@gnu.org>
+;;;
+;;; Sly is free software: you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation, either version 3 of the License, or
+;;; (at your option) any later version.
+;;;
+;;; Sly is distributed in the hope that it will be useful, but WITHOUT
+;;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+;;; License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program. If not, see
+;;; <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Manages the OpenGL state machine.
+;;
+;;; Code:
+
+(define-module (sly render)
+ #:use-module (rnrs bytevectors)
+ #:use-module (ice-9 match)
+ #:use-module (ice-9 q)
+ #:use-module (srfi srfi-9)
+ #:use-module (srfi srfi-42)
+ #:use-module (gl)
+ #:use-module (gl enums)
+ #:use-module (gl low-level)
+ #:use-module (sly wrappers gl)
+ #:use-module (sly math transform)
+ #:use-module (sly render shader)
+ #:use-module (sly render texture)
+ #:use-module (sly render utils)
+ #:use-module (sly render mesh)
+ #:use-module (sly render framebuffer)
+ #:use-module (sly render camera)
+ #:export (make-graphics
+ graphics?
+ graphics-blend-mode
+ set-graphics-blend-mode!
+ graphics-depth-test?
+ set-graphics-depth-test!
+ graphics-texture
+ set-graphics-texture!
+ graphics-shader
+ set-graphics-shader!
+ graphics-mesh
+ set-graphics-mesh!
+ graphics-framebuffer
+ set-graphics-framebuffer!
+ graphics-viewport
+ set-graphics-viewport!
+ graphics-transform
+ graphics-transform-mul!
+ graphics-transform-identity!
+ with-graphics
+ with-transform-excursion
+ with-graphics-excursion))
+
+;;;
+;;; Transformation matrix stack.
+;;;
+
+(define (make-null-transform)
+ (make-transform 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0))
+
+(define (make-transform-stack size)
+ (let ((stack (make-q)))
+ (do-ec (: i size) (q-push! stack (make-null-transform)))
+ stack))
+
+(define (copy-transform! src dest)
+ (bytevector-copy! (transform-matrix src) 0
+ (transform-matrix dest) 0
+ 64))
+
+(define (call-with-transform-excursion stack thunk)
+ (let ((t (q-pop! stack)))
+ (dynamic-wind
+ (lambda ()
+ (copy-transform! t (q-front stack)))
+ thunk
+ (lambda ()
+ (q-push! stack t)))))
+
+(define (stack-transform-mul! stack t)
+ (let ((dest (q-front stack)))
+ (call-with-transform-excursion stack
+ (lambda ()
+ (transform*! dest (q-front stack) t)))))
+
+(define (stack-transform-identity! stack)
+ (copy-transform! identity-transform (q-front stack)))
+
+;;;
+;;; Graphics context.
+;;;
+
+(define-record-type <graphics>
+ (%make-graphics blend-mode depth-test? texture shader
+ mesh framebuffer viewport projection model-view)
+ graphics?
+ (blend-mode graphics-blend-mode %set-graphics-blend-mode!)
+ (depth-test? graphics-depth-test? %set-graphics-depth-test!)
+ (texture graphics-texture %set-graphics-texture!)
+ (shader graphics-shader %set-graphics-shader!)
+ (mesh graphics-mesh %set-graphics-mesh!)
+ (framebuffer graphics-framebuffer %set-graphics-framebuffer!)
+ (viewport graphics-viewport %set-graphics-viewport!)
+ (projection graphics-projection)
+ (model-view graphics-model-view))
+
+(define (make-context-switcher getter setter switch)
+ (lambda* (gfx x #:optional force)
+ (when (or force (not (equal? (getter gfx) x)))
+ (setter gfx x)
+ (switch x))))
+
+(define set-graphics-blend-mode!
+ (make-context-switcher graphics-blend-mode
+ %set-graphics-blend-mode!
+ apply-blend-mode))
+
+(define set-graphics-depth-test!
+ (make-context-switcher graphics-depth-test?
+ %set-graphics-depth-test!
+ apply-depth-test))
+
+(define set-graphics-texture!
+ (make-context-switcher graphics-texture
+ %set-graphics-texture!
+ apply-texture))
+
+(define set-graphics-shader!
+ (make-context-switcher graphics-shader
+ %set-graphics-shader!
+ apply-shader-program))
+
+(define set-graphics-mesh!
+ (make-context-switcher graphics-mesh
+ %set-graphics-mesh!
+ apply-mesh))
+
+(define set-graphics-framebuffer!
+ (make-context-switcher graphics-framebuffer
+ %set-graphics-framebuffer!
+ apply-framebuffer))
+
+(define set-graphics-viewport!
+ (make-context-switcher graphics-viewport
+ %set-graphics-viewport!
+ apply-viewport))
+
+(define* (make-graphics #:optional (transform-stack-size 32))
+ (%make-graphics #f #f #f #f #f #f #f
+ (make-transform-stack transform-stack-size)
+ (make-transform-stack transform-stack-size)))
+
+(define (graphics-reset! gfx)
+ (set-graphics-blend-mode! gfx #f)
+ (set-graphics-depth-test! gfx #f)
+ (set-graphics-texture! gfx null-texture)
+ (set-graphics-shader! gfx null-shader-program)
+ (set-graphics-mesh! gfx null-mesh)
+ (set-graphics-framebuffer! gfx null-framebuffer)
+ (set-graphics-viewport! gfx null-viewport)
+ (stack-transform-identity! (graphics-projection gfx))
+ (stack-transform-identity! (graphics-model-view gfx)))
+
+(define-syntax-rule (with-graphics gfx body ...)
+ (begin (graphics-reset! gfx) body ...))
+
+(define (graphics-transform gfx)
+ (q-front (graphics-model-view gfx)))
+
+(define (graphics-transform-mul! gfx t)
+ (stack-transform-mul! (graphics-model-view gfx) t))
+
+(define (graphics-transform-identity! gfx)
+ (stack-transform-identity! (graphics-model-view gfx)))
+
+;; emacs: (put 'with-transform-excursion 'scheme-indent-function 1)
+(define-syntax-rule (with-transform-excursion gfx body ...)
+ (call-with-transform-excursion (graphics-model-view gfx)
+ (lambda ()
+ body ...)))
+
+(define-syntax-rule (with-graphics-excursion gfx body ...)
+ (match gfx
+ (($ <graphics> blend-mode depth-test? texture shader mesh
+ viewport framebuffer _ _)
+ body ...
+ (set-graphics-blend-mode! gfx blend-mode)
+ (set-graphics-depth-test! gfx depth-test?)
+ (set-graphics-texture! gfx texture)
+ (set-graphics-shader! gfx shader)
+ (set-graphics-mesh! gfx mesh)
+ (set-graphics-framebuffer! gfx framebuffer)
+ (set-graphics-viewport! gfx viewport))))