6 (defvar *esc-pressed
* nil
)
8 (defparameter *glwindow
* nil
)
10 (defparameter *console
* t
)
12 ;; evaluate a form, echo result to console: somewhat stolen
13 ;; from perfectstorm..
14 (defun console-eval (s)
15 "Evauluate s and return the output as a string"
18 (handler-case (multiple-value-list
19 (eval (read (make-string-input-stream s
))))
21 (format nil
"~a" e
))))))
24 ;; -- callbacks --------------
26 (cffi:defcallback console-char-callback
:void
((key :int
) (action :int
))
27 ;; (format t "Char ~A " key)
28 (when (and *console
* (= action glfw
:+press
+))
29 (let ((c (code-char key
)))
31 (add-char *glwindow
* (code-char key
))))))
34 (cffi:defcallback console-key-callback
:void
((key :int
) (action :int
))
35 ;; (format t "Keypress ~A " key)
36 (when (= action glfw
:+press
+)
37 ;; f10 toggles console
38 (when (= key glfw
:+key-f10
+)
39 (setf *console
* (not *console
*)))
42 (= key glfw
:+key-esc
+) (setf *esc-pressed
* t
))
45 ;; ;; backspace removes previous char
46 ((= key glfw
:+key-backspace
+) (del-char-left *glwindow
*))
47 ;; ;; del removes next char
48 ((= key glfw
:+key-del
+) (del-char-right *glwindow
*))
49 ((= key glfw
:+key-f5
+) (progn
50 (setf (current-result-line *glwindow
*)
51 (console-eval (current-line-as-string *glwindow
*)))
52 (add-to-history *glwindow
* (current-line-as-string *glwindow
*))))
54 ((= key glfw
:+key-left
+) (cursor-left *glwindow
*))
55 ((= key glfw
:+key-right
+) (cursor-right *glwindow
*))
57 ;; up down through history
58 ((= key glfw
:+key-up
+) (setf (current-line *glwindow
*) (previous-history *glwindow
*)))
59 ((= key glfw
:+key-down
+) (setf (current-line *glwindow
*) (next-history *glwindow
*)))
61 ((= key glfw
:+key-f6
+) (setf (current-result-line *glwindow
*) "Repl Result"))
67 ;; ;; page up, page down, skip sexps
70 ;; ;; return inserts newline
71 ;; ;; f5 evaluates -- TO DO -- sort this out
74 (cffi:defcallback window-size-callback
:void
((width :int
) (height :int
))
75 (setf (win-width-of *glwindow
*) width
)
76 (setf (win-height-of *glwindow
*) height
)
77 (viewport *glwindow
*))
81 (gl:enable gl
:+texture-2d
+)
82 (gl:enable gl
:+blend
+)
83 (gl:matrix-mode gl
:+projection
+)
86 (gl:matrix-mode gl
:+modelview
+)
89 (viewport *glwindow
*))
94 (defun callback-set ()
95 (setf *esc-pressed
* nil
)
96 (glfw:set-key-callback
(cffi:callback console-key-callback
))
97 (glfw:set-char-callback
(cffi:callback console-char-callback
)))
99 (defun callback-clear ()
100 (glfw:set-key-callback
(cffi:null-pointer
))
101 (glfw:set-char-callback
(cffi:null-pointer
)))
103 (defun render-char (font c x y
)
104 (when (graphic-char-p c
)
105 (let ((image (aref (glrepl::images-of font
) (char-code c
))))
106 (when (typep image
'rgba-image
) ;; couldn't this simply be when?
108 (gl:bind-texture gl
:+texture-2d
+
109 (cffi::mem-ref
(name-of image
) :uint32
))
110 (gl:tex-env-f gl
:+texture-env
+ gl
:+texture-env-mode
+ gl
:+replace
+) ;; maybe +decal+?
111 (gl:color-4f
0.0 0.0 0.0 1.0)
112 (gl:blend-func gl
:+src-alpha
+ gl
:+one-minus-src-alpha
+)
113 (let ((texture-height (texture-height-of *glwindow
*))
114 (texture-width (texture-width-of *glwindow
*)))
115 (gl:with-begin gl
:+quads
+
116 (gl:tex-coord-2i
0 1)
117 (gl:vertex-2f x y
) ;; top lhs
118 (gl:tex-coord-2i
1 1)
119 (gl:vertex-2f
(+ x texture-width
) y
) ;; top rhs
120 (gl:tex-coord-2f
1 0)
121 (gl:vertex-2f
(+ x texture-width
) (+ y texture-height
)) ;; bot rhs
122 (gl:tex-coord-2i
0 0)
123 (gl:vertex-2f x
(+ y texture-height
))))))))) ;; bot lhs
125 (defun render-cursor (font x y
)
126 (let ((image (aref (glrepl::images-of font
) (char-code #\_
))))
127 (when (typep image
'rgba-image
)
129 (gl:bind-texture gl
:+texture-2d
+
130 (cffi::mem-ref
(name-of image
) :uint32
))
131 (gl:tex-env-f gl
:+texture-env
+ gl
:+texture-env-mode
+ gl
:+replace
+) ;; maybe +decal+?
132 (gl:color-4f
1.0 0.0 0.0 1.0)
133 (gl:blend-func gl
:+src-alpha
+ gl
:+one-minus-src-alpha
+)
134 (let ((texture-height (texture-height-of *glwindow
*))
135 (texture-width (texture-width-of *glwindow
*)))
136 (gl:with-begin gl
:+quads
+
137 (gl:tex-coord-2i
0 1)
138 (gl:vertex-2f x y
) ;; top lhs
139 (gl:tex-coord-2i
1 1)
140 (gl:vertex-2f
(+ x texture-width
) y
) ;; top rhs
141 (gl:tex-coord-2f
1 0)
142 (gl:vertex-2f
(+ x texture-width
) (+ y texture-height
)) ;; bot rhs
143 (gl:tex-coord-2i
0 0)
144 (gl:vertex-2f x
(+ y texture-height
)))))))) ;; bot lhs
146 ;; (defun render-world ()
147 ;; (multiple-value-bind
149 ;; (window-pixel-atxy *glwindow* 0 0)
150 ;; (render-char (font-of *glwindow*) #\A px py)))
152 (defun render-string (str x y
)
156 ;; while there is still a line to render
157 (for char-to-render in-string str
)
158 (multiple-value-bind (pixel-x pixel-y
)
159 (window-pixel-atxy *glwindow
* sx sy
)
161 (when (graphic-char-p char-to-render
)
162 ;; actually draw our char
163 (render-char (font-of *glwindow
*) char-to-render pixel-x pixel-y
)
164 ;; advance cursor to next screen colum
168 (defparameter *console-render-debug-fn
* #'(lambda ()))
171 (defun render-console ()
173 ;; set up textures, clobber projection, give us raster-style viewport
174 (gl:enable gl
:+texture-2d
+)
175 (gl:enable gl
:+blend
+)
176 (gl:matrix-mode gl
:+projection
+)
178 (gl:matrix-mode gl
:+modelview
+)
180 (viewport *glwindow
*)
181 (funcall *console-render-debug-fn
*)
182 (let* ((rendered-chain (current-line *glwindow
*))
185 (current-chain-offset 0)
186 (char-to-render #\Nul
)
187 (cursor (make-instance 'flexichain
:left-sticky-flexicursor
:position
0 :chain rendered-chain
)))
188 (declare (type fixnum screen-line screen-column current-chain-offset
))
190 ;; while there is still a line to render
191 (while (and (not (null cursor
)) (< screen-line
(text-height-of *glwindow
*))))
193 (while (not (flexichain:at-end-p cursor
)))
194 (setf char-to-render
(flexichain:element
> cursor
))
195 (multiple-value-bind (pixel-x pixel-y
)
196 (window-pixel-atxy *glwindow
* screen-column screen-line
)
199 (when (graphic-char-p char-to-render
)
200 ;; actually draw our char
201 (render-char (font-of *glwindow
*) char-to-render pixel-x pixel-y
)
202 (when (and (zerop current-chain-offset
)
203 (= (flexichain:cursor-pos cursor
) (flexichain:cursor-pos
(current-cursor *glwindow
*))))
204 (render-cursor (font-of *glwindow
*) pixel-x pixel-y
))
205 ;; advance cursor to next screen colum
207 ;; word wrap if off ed
208 (when (>= screen-column
(text-width-of *glwindow
*))
209 (setf screen-column
0)
213 (when (char= #\Newline char-to-render
)
214 ;; first render the cursor if its at eol
216 (setf screen-column
0)
219 (incf (flexichain:cursor-pos cursor
))
221 (multiple-value-bind (pixel-x pixel-y
)
222 (window-pixel-atxy *glwindow
* screen-column screen-line
)
224 (when (and (zerop current-chain-offset
)
225 (= (flexichain:cursor-pos cursor
) (flexichain:cursor-pos
(current-cursor *glwindow
*))))
226 (render-cursor (font-of *glwindow
*) pixel-x pixel-y
)))))
228 ;; ran out of this line, bump onto next
230 (setf screen-column
0)
231 (incf current-chain-offset
)
233 (setf rendered-chain nil
)
234 (let ((current-chain-index (+ (cursor-line-of *glwindow
*) current-chain-offset
)))
235 (when (< current-chain-index
(length (lines-of *glwindow
*)))
236 (setf rendered-chain
(chain-of (aref (lines-of *glwindow
*) current-chain-index
)))
237 (setf cursor
(make-instance 'flexichain
:left-sticky-flexicursor
:position
0 :chain rendered-chain
))))))))
241 (let ((t0 (glfw:get-time
))
243 (test-image (make-instance 'glrepl
::rgba-image
:width
64 :height
64)))
245 (for i from
0 below
(* 64 64))
246 (setf (glrepl::pixel test-image i
) #X000000FF
))
247 (glrepl::update-image test-image
)
249 (gl:clear-color
0.0 0.0 0.0 1.0)
251 (while (= (glfw::get-window-param glfw
:+opened
+) glfw
:+true
+))
252 (gl:clear gl
:+color-buffer-bit
+)
253 (setf dt
(- (glfw:get-time
) t0
))
254 (setf t0
(glfw:get-time
))
256 ;;(glrepl::render test-image)
258 ;; check for time available if time is avaliable render
259 ;; surrender any cpu time..
262 (glfw:close-window
)))))
267 (setf *glwindow
* (make-instance 'glrepl-window
))
268 (add-line *glwindow
*)
269 (add-line *glwindow
*)
270 (add-string *glwindow
* "(format nil \"Hello World\")")
271 (if (glfw:open-window
(win-width-of *glwindow
*) (win-height-of *glwindow
*) 16 16 16 16 16)
273 (glfw:set-window-title
"OpenGL Repl")
276 (format t
"Making font..")
277 (setf (font-of *glwindow
*) (make-font (merge-pathnames #P
"VeraMono.ttf"))) ;; prbly shld be mber of window
279 (glfw:swap-interval
1)
280 (glfw:enable glfw
:+key-repeat
+)
282 ;; (glrepl::dump (aref *font-images* 65))
290 (error "Failed to open window"))))
291 (error "Failed to init glfw")))
293 ;; (defun test-glrepl ()
294 ;; (glfw:with-init-window ("Glrepl" *win-width* *win-height*)
295 ;; (glfw:set-window-size-callback (cffi:callback window-size-callback))
296 ;; (glfw:set-key-callback (cffi:callback key-callback))
297 ;; (glfw:swap-interval 1)
300 ;; (while (and (not *esc-pressed*)
301 ;; (eql (glfw:get-window-param glfw:+opened+) gl:+true+)))
302 ;; (gl:clear gl:+color-buffer-bit+)
304 ;; (glfw:swap-buffers)
306 ;; (if (eql (glfw:get-window-param glfw:+opened+) gl:+true+)
307 ;; (glfw:close-window))
308 ;; (glfw:terminate))))
310 ;; (setf *glwindow* (make-instance 'glrepl-window))
311 ;; (make-instance 'glrepl-window-line)
313 ;; (add-line *glwindow*)
314 ;; (add-string *glwindow* "Hello World")