-
-
Notifications
You must be signed in to change notification settings - Fork 44
/
pipelined-scene.lisp
59 lines (50 loc) · 2.45 KB
/
pipelined-scene.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
(in-package #:org.shirakumo.fraf.trial)
(defclass pipelined-scene (scene pipeline)
((to-preload :initarg :to-preload :initform () :accessor to-preload)))
(defmethod preload (object (scene pipelined-scene))
(pushnew object (to-preload scene)))
(defmethod preload ((name symbol) (scene scene))
(preload (make-instance name) scene))
(defmethod setup-scene :around (main (scene pipelined-scene))
(prog1 (call-next-method)
;; We only bother packing the pipeline if it's been set up in any way.
;; Doing it always will actually clear the pipeline even if it's already
;; been set up.
(when (nodes scene)
(let ((context (context main))
(scale (setting* 1.0 :display :frame-scale)))
(pack-pipeline scene
(max 1 (ceiling (* scale (width context))))
(max 1 (ceiling (* scale (height context)))))))
(loop for pass across (passes scene)
do (enter scene pass)
(dolist (thing (to-preload scene))
(when (typep thing '(or class entity))
(enter thing pass))))
;; KLUDGE: this will trigger class changed events which we can ignore.
;; we have to do this both because it's a waste of time, but also
;; because not doing so leads to real ???? OpenGL driver state.
(discard-events scene 'class-changed)))
(defmethod stage :before ((scene pipelined-scene) (area staging-area))
(loop for texture across (textures scene)
do (stage texture area))
(loop for entity in (to-preload scene)
do (stage entity area))
(loop for pass across (passes scene)
do (stage pass area)))
(defmethod handle :after ((event resize) (scene pipelined-scene))
(resize scene
(max 1 (ceiling (* (setting* 1.0 :display :frame-scale) (width event))))
(max 1 (ceiling (* (setting* 1.0 :display :frame-scale) (height event))))))
(defmethod register :after ((entity renderable) (scene pipelined-scene))
(loop for pass across (passes scene)
do (when (object-renderable-p entity pass)
(enter entity pass))))
(defmethod deregister :after ((entity renderable) (scene pipelined-scene))
(loop for pass across (passes scene)
do (when (object-renderable-p entity pass)
(leave entity pass))))
(defmethod describe-object :after ((scene pipelined-scene) stream)
(format stream "~&~%Shader Passes:~%")
(loop for pass across (passes scene)
do (format stream " ~a~%" pass)))