2 (in-package :lambdamundo
)
4 ;; callbacks --------------------
6 ;; window size / projection
8 (cffi:defcallback lambdamundo-resize-callback
9 :void
((w :int
) (h :int
))
10 (setf (win-width-of glrepl
:*glwindow
*) w
)
11 (setf (win-height-of glrepl
:*glwindow
*) h
)
17 (gl:with-setup-projection
18 (glu:perspective
45.0 h
/w
0.1 50.0))))
20 ;; (gl:with-setup-projection
21 ;; (gl:frustum (- xmax) xmax (* (- xmax) h/w) (* xmax h/w) znear zfar))
24 ;; (gl:translate-f 0 0 -20)))
29 (cffi:defcallback lambdamundo-char-callback
:void
((key :int
) (action :int
))
30 ;; (format t "Char ~A " key)
31 (when (and glrepl
:*console
* (= action glfw
:+press
+))
32 (let ((c (code-char key
)))
34 (glrepl:add-char glrepl
:*glwindow
* (code-char key
))))))
36 (cffi:defcallback lambdamundo-key-callback
:void
((key :int
) (action :int
))
37 (unless glrepl
:*console
* (when-funcall (gethash key
*standard-key-fns
*) action
))
38 (when glrepl
:*console
* (when-funcall (gethash key
*console-key-fns
*) action
)))
42 (defparameter *mouse-wheel-pos
* 0)
43 (defparameter *mouse-wheel-delta
* 0)
44 (defparameter *mouse-wheel-changed
* nil
)
46 (defun render-debug ()
47 (glrepl::render-string
48 (format nil
"~6,2F ~6,2F ~6,2F ~6,3F " (aref *modelview-debug
* 0) (aref *modelview-debug
* 1) (aref *modelview-debug
* 2) (aref *modelview-debug
* 3))
50 (glrepl::render-string
51 (format nil
"~6,2F ~6,2F ~6,2F ~6,3F " (aref *modelview-debug
* 4) (aref *modelview-debug
* 5) (aref *modelview-debug
* 6) (aref *modelview-debug
* 7))
53 (glrepl::render-string
54 (format nil
"~6,2F ~6,2F ~6,2F ~6,3F " (aref *modelview-debug
* 8) (aref *modelview-debug
* 9) (aref *modelview-debug
* 10) (aref *modelview-debug
* 11))
56 (glrepl::render-string
57 (format nil
"~6,2F ~6,2F ~6,2F ~6,3F " (aref *modelview-debug
* 12) (aref *modelview-debug
* 13) (aref *modelview-debug
* 14) (aref *modelview-debug
* 14))
61 (cffi:defcallback lambdamundo-mouse-wheel-callback
:void
((pos :int
))
62 (setf *mouse-wheel-delta
* (- pos
*mouse-wheel-pos
*))
63 (setf *mouse-wheel-pos
* pos
)
64 (setf *mouse-wheel-changed
* t
))
66 (defun callback-set ()
67 (glfw:set-key-callback
(cffi:callback lambdamundo-key-callback
))
68 (glfw:set-char-callback
(cffi:callback lambdamundo-char-callback
))
69 (glfw:set-mouse-wheel-callback
(cffi:callback lambdamundo-mouse-wheel-callback
))
70 ;; (glfw:set-window-size-callback (cffi:callback lambdamundo-resize-callback))
74 (defun callback-clear ()
75 (glfw:set-key-callback
(cffi:null-pointer
))
76 (glfw:set-char-callback
(cffi:null-pointer
))
77 (glfw:set-window-size-callback
(cffi:null-pointer
))
78 (glfw:set-mouse-wheel-callback
(cffi:null-pointer
)))
80 ;; gl init and de-init --------------------
83 (gl:enable gl
:+texture-2d
+)
84 (gl:enable gl
:+blend
+)
85 (gl:enable gl
:+depth-test
+)
86 (gl:disable gl
:+cull-face
+)
87 (gl:disable gl
:+lighting
+))
91 ;; drawing --------------------
92 ;; each cell will have to know how to cull itself
94 (eval-when ( :load-toplevel
:compile-toplevel
:execute
)
95 (defparameter *draw-fns
* (make-hash-table :test
'equalp
)
96 "An table of functions called in order to render the scene")
98 (defparameter *draw-array
* (make-array 0 :adjustable t
:fill-pointer
0)
99 "An array that indexes *draw-fns* to establish draw order" )
101 (defun extend-draw-array (name priority
)
102 "If the name is in the array, adjust priority, else add it to the array"
103 (assert (not (null (gethash name
*draw-fns
*))) (name) "~S is not a drawable")
106 (position-if #'(lambda (x) (equal (car x
) name
)) *draw-array
*)))
107 (if draw-priority-pos
108 (setf (aref *draw-array
* draw-priority-pos
) (cons name priority
))
109 (vector-push-extend (cons name priority
) *draw-array
*)))))
111 (defmacro make-draw-function
(name priority
&body forms
)
113 (setf (gethash ,name
*draw-fns
*)
114 (compile nil
'(lambda () ,@forms
)))
115 (extend-draw-array ,name
,priority
)
116 (sort *draw-array
* #'(lambda (a b
)
117 (< (car a
) (car b
))))))
119 (defun render-world ()
120 (gl:disable gl
:+texture-2d
+)
121 (gl:disable gl
:+blend
+)
122 (with-camera *camera
*
124 (for entry in-vector
*draw-array
*)
125 (funcall (gethash (car entry
) *draw-fns
*)))
127 (for actor in-vector
*actors
*)
150 (gl:with-begin gl
:+quads
+
151 (gl:color-3f
0.0 1.0 0.0)
156 (apply #'gl
:vertex-3f
(nth (1- vertex
) vertices
)))))))
159 ;; animation --------------------
161 (defparameter *frames
* 0)
163 (defun update-world (dt)
165 (when *mouse-wheel-changed
*
166 (pan *camera
* 0.0 (* *mouse-wheel-delta
* dt
))
167 (setf *mouse-wheel-changed
* nil
)))
169 (defmacro one-shot
(&rest forms
)
170 `(setf *one-shot-fn
* #'(lambda () ,@forms
)))
172 (defmacro one-shot-compile
(pathname)
173 `(setf *one-shot-fn
* #'(lambda ()
175 (output-file warnings-p failure-p
)
176 (compile-file (merge-pathnames ,pathname
) :verbose t
:print t
)
177 (declare (ignore warnings-p
))
178 (when (not failure-p
)
179 (load output-file
:print t
))))))
181 (defparameter *one-shot-fn
* nil
)
183 ;; main routine -------------------
185 (let ((t0 (coerce (glfw:get-time
) 'single-float
))
187 (setf *mouse-wheel-pos
* (glfw:get-mouse-wheel
))
188 (setf *mouse-wheel-delta
* 0)
189 (setf glrepl
:*console-render-debug-fn
* #'render-debug
)
191 (gl:clear-color
0.0 0.0 0.0 1.0)
193 (while (= (glfw::get-window-param glfw
:+opened
+) glfw
:+true
+))
194 (gl:clear
(logior gl
:+color-buffer-bit
+ gl
:+depth-buffer-bit
+))
195 (setf dt
(- (coerce (glfw:get-time
) 'single-float
) t0
))
196 (setf t0
(coerce (glfw:get-time
) 'single-float
))
198 (gl:viewport
0 0 (win-width-of glrepl
:*glwindow
*) (win-height-of glrepl
:*glwindow
*))
199 (gl:matrix-mode gl
:+projection
+)
201 (glu:perspective
45.0 (/ (win-height-of glrepl
:*glwindow
*) (win-width-of glrepl
:*glwindow
*)) 0.1 50.0)
202 (gl:matrix-mode gl
:+modelview
+)
204 (when glrepl
:*console
*
205 (glrepl:render-console
))
207 (funcall *one-shot-fn
*)
208 (setf *one-shot-fn
* nil
))
210 ;; check for time available if time is avaliable render
211 ;; surrender any cpu time..
212 (glfw:swap-buffers
))))
214 (defun begin-swank ()
216 (setf *swank-port
* (swank::start-session
4112))
217 (format t
"Please fire up your emacs and connect.~%")
219 (while (zerop (length swank
::*connections
*)))
223 (format t
"~%Connected.~%")))
226 (when (not (zerop (length swank
::*connections
*)))
227 (swank::end-session
*swank-port
*))
228 (setf *swank-port
* nil
))
231 "Cleanup when something went wrong."
242 (defun lambdamundo ()
245 (setf glrepl
:*glwindow
* (make-instance 'glrepl-window
))
246 (add-line glrepl
:*glwindow
*)
247 (add-line glrepl
:*glwindow
*)
248 (add-string glrepl
:*glwindow
* "(one-shot-compile #P\"mesh-compiler.lisp)\"")
249 (if (glfw:open-window
250 (win-width-of *glwindow
*)
251 (win-height-of *glwindow
*)
254 (glfw:set-window-title
"Lambdmundo")
258 (format t
"Making font..~%")
259 (setf (font-of glrepl
:*glwindow
*) (make-font (merge-pathnames #P
"VeraMono.ttf")))
261 (format t
"Compiling mesh compiler..~%")
262 (gl-ext:load-extension
"ARB_vertex_program")
263 (gl-ext:load-extension
"ARB_vertex_buffer_object")
264 (one-shot-compile #P
"mesh-compiler.lisp")
265 (format t
"Done..~%")
266 (glfw:swap-interval
1)
267 (glfw:enable glfw
:+key-repeat
+)
269 (set-current-camera (make-camera))
274 (if (= (glfw::get-window-param glfw
:+opened
+) glfw
:+true
+)
279 (error "Failed to open window"))))
280 (error "Failed to init glfw")))
283 ;; (lambdamundo-window ("Lambdamundo"
284 ;; :dimensions (640 480)
285 ;; :colourbits (0 0 0 0)
288 ;; :mode glfw:+window+)
290 ;; (:void ((key :int) (action :int)) )
292 ;; (:void ((width :int) (height :int))
295 ;; ((glfw:enable glfw:+key-repeat+)
296 ;; (glfw:swap-interval 0)
298 ;; (glfw:set-window-size-callback (cffi:callback window-size-callback))
299 ;; (glfw:set-key-callback (cffi:callback key-callback)))
301 ;; ;; to do -- we need to drop in and out of body forms