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
"Mouse wheel pos ~A ~A " *mouse-wheel-pos
* *mouse-wheel-delta
*)
50 (glrepl::render-string
51 (format nil
"Camera pos ~A " (multiple-value-list (position-of *camera
*))) 0 21)
52 (glrepl::render-string
53 (format nil
"Swank connections ~A" swank
::*connections
*) 0 22)
54 (glrepl::render-string
55 (format nil
"Vendor ~A " (gl:get-string gl
:+vendor
+)) 0 19))
58 (cffi:defcallback lambdamundo-mouse-wheel-callback
:void
((pos :int
))
59 (setf *mouse-wheel-delta
* (- pos
*mouse-wheel-pos
*))
60 (setf *mouse-wheel-pos
* pos
)
61 (setf *mouse-wheel-changed
* t
))
63 (defun callback-set ()
64 (glfw:set-key-callback
(cffi:callback lambdamundo-key-callback
))
65 (glfw:set-char-callback
(cffi:callback lambdamundo-char-callback
))
66 (glfw:set-mouse-wheel-callback
(cffi:callback lambdamundo-mouse-wheel-callback
))
67 ;; (glfw:set-window-size-callback (cffi:callback lambdamundo-resize-callback))
71 (defun callback-clear ()
72 (glfw:set-key-callback
(cffi:null-pointer
))
73 (glfw:set-char-callback
(cffi:null-pointer
))
74 (glfw:set-window-size-callback
(cffi:null-pointer
))
75 (glfw:set-mouse-wheel-callback
(cffi:null-pointer
)))
77 ;; gl init and de-init --------------------
80 (gl:enable gl
:+texture-2d
+)
81 (gl:enable gl
:+blend
+)
82 (gl:enable gl
:+depth-test
+)
83 (gl:disable gl
:+cull-face
+)
84 (gl:disable gl
:+lighting
+))
88 ;; drawing --------------------
89 ;; each cell will have to know how to cull itself
91 (eval-when ( :load-toplevel
:compile-toplevel
:execute
)
92 (defparameter *draw-fns
* (make-hash-table :test
'equalp
)
93 "An table of functions called in order to render the scene")
95 (defparameter *draw-array
* (make-array 0 :adjustable t
:fill-pointer
0)
96 "An array that indexes *draw-fns* to establish draw order" )
98 (defun extend-draw-array (name priority
)
99 "If the name is in the array, adjust priority, else add it to the array"
100 (assert (not (null (gethash name
*draw-fns
*))) (name) "~S is not a drawable")
103 (position-if #'(lambda (x) (equal (car x
) name
)) *draw-array
*)))
104 (if draw-priority-pos
105 (setf (aref *draw-array
* draw-priority-pos
) (cons name priority
))
106 (vector-push-extend (cons name priority
) *draw-array
*)))))
108 (defmacro make-draw-function
(name priority
&body forms
)
110 (setf (gethash ,name
*draw-fns
*)
111 (compile nil
'(lambda () ,@forms
)))
112 (extend-draw-array ,name
,priority
)
113 (sort *draw-array
* #'(lambda (a b
)
114 (< (car a
) (car b
))))))
116 (defun render-world ()
117 (gl:disable gl
:+texture-2d
+)
118 (gl:disable gl
:+blend
+)
119 (with-camera *camera
*
121 (for entry in-vector
*draw-array
*)
122 (funcall (gethash (car entry
) *draw-fns
*)))
124 (for actor in-vector
*actors
*)
147 (gl:with-begin gl
:+quads
+
148 (gl:color-3f
0.0 1.0 0.0)
153 (apply #'gl
:vertex-3f
(nth (1- vertex
) vertices
)))))))
156 ;; animation --------------------
158 (defparameter *frames
* 0)
160 (defun update-world (dt)
162 (when *mouse-wheel-changed
*
163 (move *camera
* 0.0 (* *mouse-wheel-delta
* dt
))
164 (setf *mouse-wheel-changed
* nil
)))
166 (defmacro one-shot
(&rest forms
)
167 `(setf *one-shot-fn
* #'(lambda () ,@forms
)))
169 (defmacro one-shot-compile
(pathname)
170 `(setf *one-shot-fn
* #'(lambda ()
172 (output-file warnings-p failure-p
)
173 (compile-file (merge-pathnames ,pathname
) :verbose t
:print t
)
174 (declare (ignore warnings-p
))
175 (when (not failure-p
)
176 (load output-file
:print t
))))))
178 (defparameter *one-shot-fn
* nil
)
180 ;; main routine -------------------
182 (let ((t0 (coerce (glfw:get-time
) 'single-float
))
184 (setf *mouse-wheel-pos
* (glfw:get-mouse-wheel
))
185 (setf *mouse-wheel-delta
* 0)
186 (setf glrepl
:*console-render-debug-fn
* #'render-debug
)
188 (gl:clear-color
0.0 0.0 0.0 1.0)
190 (while (= (glfw::get-window-param glfw
:+opened
+) glfw
:+true
+))
191 (gl:clear
(logior gl
:+color-buffer-bit
+ gl
:+depth-buffer-bit
+))
192 (setf dt
(- (coerce (glfw:get-time
) 'single-float
) t0
))
193 (setf t0
(coerce (glfw:get-time
) 'single-float
))
195 (gl:viewport
0 0 (win-width-of glrepl
:*glwindow
*) (win-height-of glrepl
:*glwindow
*))
196 (gl:matrix-mode gl
:+projection
+)
198 (glu:perspective
45.0 (/ (win-height-of glrepl
:*glwindow
*) (win-width-of glrepl
:*glwindow
*)) 0.1 50.0)
199 (gl:matrix-mode gl
:+modelview
+)
201 (when glrepl
:*console
*
202 (glrepl:render-console
))
204 (funcall *one-shot-fn
*)
205 (setf *one-shot-fn
* nil
))
207 ;; check for time available if time is avaliable render
208 ;; surrender any cpu time..
209 (glfw:swap-buffers
))))
211 (defun begin-swank ()
213 (setf *swank-port
* (swank::start-session
4112))
214 (format t
"Please fire up your emacs and connect.~%")
216 (while (zerop (length swank
::*connections
*)))
219 (format t
"~%Connected.~%")))
222 (when (not (zerop (length swank
::*connections
*)))
223 (swank::end-session
*swank-port
*))
224 (setf *swank-port
* nil
))
227 "Cleanup when something went wrong."
237 (defun lambdamundo ()
240 (setf glrepl
:*glwindow
* (make-instance 'glrepl-window
))
241 (add-line glrepl
:*glwindow
*)
242 (add-line glrepl
:*glwindow
*)
243 (add-string glrepl
:*glwindow
* "(one-shot-compile #P\"mesh-compiler.lisp\"")
244 (if (glfw:open-window
245 (win-width-of *glwindow
*)
246 (win-height-of *glwindow
*)
249 (glfw:set-window-title
"Lambdmundo")
253 (format t
"Making font..")
254 (setf (font-of glrepl
:*glwindow
*) (make-font (merge-pathnames #P
"VeraMono.ttf")));; prbly shld be mber of window
256 (gl-ext:load-extension
"ARB_vertex_program")
257 (gl-ext:load-extension
"ARB_vertex_buffer_object")
258 (one-shot-compile #P
"mesh-compiler.lisp")
259 (glfw:swap-interval
1)
260 (glfw:enable glfw
:+key-repeat
+)
262 ;; (glrepl::dump (aref *font-images* 65))
267 (if (= (glfw::get-window-param glfw
:+opened
+) glfw
:+true
+)
272 (error "Failed to open window"))))
273 (error "Failed to init glfw")))
276 ;; (lambdamundo-window ("Lambdamundo"
277 ;; :dimensions (640 480)
278 ;; :colourbits (0 0 0 0)
281 ;; :mode glfw:+window+)
283 ;; (:void ((key :int) (action :int)) )
285 ;; (:void ((width :int) (height :int))
288 ;; ((glfw:enable glfw:+key-repeat+)
289 ;; (glfw:swap-interval 0)
291 ;; (glfw:set-window-size-callback (cffi:callback window-size-callback))
292 ;; (glfw:set-key-callback (cffi:callback key-callback)))
294 ;; ;; to do -- we need to drop in and out of body forms