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
*)))
55 (cffi:defcallback lambdamundo-mouse-wheel-callback
:void
((pos :int
))
56 (setf *mouse-wheel-delta
* (- pos
*mouse-wheel-pos
*))
57 (setf *mouse-wheel-pos
* pos
)
58 (setf *mouse-wheel-changed
* t
))
60 (defun callback-set ()
61 (glfw:set-key-callback
(cffi:callback lambdamundo-key-callback
))
62 (glfw:set-char-callback
(cffi:callback lambdamundo-char-callback
))
63 (glfw:set-mouse-wheel-callback
(cffi:callback lambdamundo-mouse-wheel-callback
))
64 ;; (glfw:set-window-size-callback (cffi:callback lambdamundo-resize-callback))
68 (defun callback-clear ()
69 (glfw:set-key-callback
(cffi:null-pointer
))
70 (glfw:set-char-callback
(cffi:null-pointer
))
71 (glfw:set-window-size-callback
(cffi:null-pointer
))
72 (glfw:set-mouse-wheel-callback
(cffi:null-pointer
)))
74 ;; gl init and de-init --------------------
77 (gl:enable gl
:+texture-2d
+)
78 (gl:enable gl
:+blend
+)
79 (gl:enable gl
:+depth-test
+)
80 (gl:disable gl
:+cull-face
+)
81 (gl:disable gl
:+lighting
+))
85 ;; drawing --------------------
86 ;; each cell will have to know how to cull itself
88 (eval-when ( :load-toplevel
:compile-toplevel
:execute
)
89 (defparameter *draw-fns
* (make-hash-table :test
'equalp
)
90 "An table of functions called in order to render the scene")
92 (defparameter *draw-array
* (make-array 0 :adjustable t
:fill-pointer
0)
93 "An array that indexes *draw-fns* to establish draw order" )
95 (defun extend-draw-array (name priority
)
96 "If the name is in the array, adjust priority, else add it to the array"
97 (assert (not (null (gethash name
*draw-fns
*))) (name) "~S is not a drawable")
100 (position-if #'(lambda (x) (equal (car x
) name
)) *draw-array
*)))
101 (if draw-priority-pos
102 (setf (aref *draw-array
* draw-priority-pos
) (cons name priority
))
103 (vector-push-extend (cons name priority
) *draw-array
*)))))
105 (defmacro make-draw-function
(name priority
&body forms
)
107 (setf (gethash ,name
*draw-fns
*)
108 (compile nil
'(lambda () ,@forms
)))
109 (extend-draw-array ,name
,priority
)
110 (sort *draw-array
* #'(lambda (a b
)
111 (< (car a
) (car b
))))))
112 (defun render-world ()
113 (gl:disable gl
:+texture-2d
+)
114 (gl:disable gl
:+blend
+)
115 (with-camera *camera
*
117 (for entry in-vector
*draw-array
*)
118 (funcall (gethash (car entry
) *draw-fns
*)))))
140 (gl:with-begin gl
:+quads
+
141 (gl:color-3f
0.0 1.0 0.0)
146 (apply #'gl
:vertex-3f
(nth (1- vertex
) vertices
)))))))
149 ;; animation --------------------
151 (defparameter *frames
* 0)
153 (defun update-world (dt)
155 (when *mouse-wheel-changed
*
156 (move *camera
* 0.0 (* *mouse-wheel-delta
* dt
))
157 (setf *mouse-wheel-changed
* nil
)))
159 ;; main routine -------------------
161 (let ((t0 (coerce (glfw:get-time
) 'single-float
))
163 (setf *mouse-wheel-pos
* (glfw:get-mouse-wheel
))
164 (setf *mouse-wheel-delta
* 0)
165 (setf glrepl
:*console-render-debug-fn
* #'render-debug
)
166 (glrepl::update-image test-image
)
168 (gl:clear-color
0.0 0.0 0.0 1.0)
170 (while (= (glfw::get-window-param glfw
:+opened
+) glfw
:+true
+))
171 (gl:clear
(logior gl
:+color-buffer-bit
+ gl
:+depth-buffer-bit
+))
172 (setf dt
(- (coerce (glfw:get-time
) 'single-float
) t0
))
173 (setf t0
(coerce (glfw:get-time
) 'single-float
))
175 (gl:viewport
0 0 (win-width-of glrepl
:*glwindow
*) (win-height-of glrepl
:*glwindow
*))
176 (gl:matrix-mode gl
:+projection
+)
178 (glu:perspective
45.0 (/ (win-height-of glrepl
:*glwindow
*) (win-width-of glrepl
:*glwindow
*)) 0.1 50.0)
179 (gl:matrix-mode gl
:+modelview
+)
181 (when glrepl
:*console
*
182 (glrepl:render-console
))
184 ;; check for time available if time is avaliable render
185 ;; surrender any cpu time..
186 (glfw:swap-buffers
))))
188 (defun begin-swank ()
190 (setf *swank-port
* (swank::start-session
4112))
191 (format t
"Please fire up your emacs and connect!~%")
193 (while (zerop (length swank
::*connections
*)))
197 (when (not (zerop (length swank
::*connections
*)))
198 (swank::end-session
*swank-port
*))
199 (setf *swank-port
* nil
))
202 "Cleanup when something went wrong."
207 (defun lambdamundo ()
210 (setf glrepl
:*glwindow
* (make-instance 'glrepl-window
))
211 (add-line glrepl
:*glwindow
*)
212 (add-line glrepl
:*glwindow
*)
213 (add-string glrepl
:*glwindow
* "(format nil \"Hello World\")")
214 (if (glfw:open-window
(win-width-of *glwindow
*) (win-height-of *glwindow
*) 16 16 16 16 32)
216 (glfw:set-window-title
"Lambdmundo")
220 (format t
"Making font..")
221 (setf (font-of glrepl
:*glwindow
*) (make-font (merge-pathnames #P
"VeraMono.ttf")));; prbly shld be mber of window
223 (glfw:swap-interval
1)
224 (glfw:enable glfw
:+key-repeat
+)
226 ;; (glrepl::dump (aref *font-images* 65))
231 (if (= (glfw::get-window-param glfw
:+opened
+) glfw
:+true
+)
236 (error "Failed to open window"))))
237 (error "Failed to init glfw")))
240 ;; (lambdamundo-window ("Lambdamundo"
241 ;; :dimensions (640 480)
242 ;; :colourbits (0 0 0 0)
245 ;; :mode glfw:+window+)
247 ;; (:void ((key :int) (action :int)) )
249 ;; (:void ((width :int) (height :int))
252 ;; ((glfw:enable glfw:+key-repeat+)
253 ;; (glfw:swap-interval 0)
255 ;; (glfw:set-window-size-callback (cffi:callback window-size-callback))
256 ;; (glfw:set-key-callback (cffi:callback key-callback)))
258 ;; ;; to do -- we need to drop in and out of body forms