1 (defpackage :gtk-glext-demo
2 (:use
:cl
:gtk
:gtkglext
:gobject
:glib
:iter
)
7 (in-package :gtk-glext-demo
)
11 (defun draw (widget event
)
12 (declare (ignore widget event
))
13 (gl:clear-color
0 0 0 0)
17 (gl:shade-model
:smooth
)
18 (gl:light-model
:light-model-local-viewer
1)
19 (gl:color-material
:front
:ambient-and-diffuse
)
20 (gl:enable
:light0
:lighting
:cull-face
:depth-test
)
23 (gl:rotate
*theta
* 1 1 0)
24 (gl:light
:light0
:position
'(0 1 1 0))
25 (gl:light
:light0
:diffuse
'(0.2
0.4 0.6 0))
26 (gl:clear
:color-buffer-bit
:depth-buffer-bit
)
29 (glut:solid-teapot
1.5)
36 (let ((window (make-instance 'gtk-window
38 :window-position
:center
42 (v-box (make-instance 'v-box
))
43 (label (make-instance 'label
:label
"Click me!"))
44 (drawing (make-instance 'gl-drawing-area
:on-expose
#'draw
)))
45 (box-pack-start v-box drawing
)
46 (box-pack-start v-box label
:expand nil
)
47 (container-add window v-box
)
48 (let ((source-id (gtk-main-add-timeout 100 (lambda ()
50 (mod (+ *theta
* 0.5) 360))
51 (widget-queue-draw drawing
)
52 (setf (label-label label
)
53 (format nil
"Theta = ~A" *theta
*))
55 (connect-signal window
"delete-event" (lambda (w e
)
56 (declare (ignore w e
))
57 (g-source-remove source-id
)
59 (widget-show window
:all t
))))
67 (let ((window (make-instance 'gtk-window
68 :window-position
:center
72 (area (make-instance 'gl-drawing-area
:on-expose
#'planet-draw
:on-resize
#'planet-resize
)))
73 (container-add window area
)
74 (connect-signal window
"realize"
76 (pushnew :key-press-mask
(gdk:gdk-window-events
(widget-window window
)))))
77 (connect-signal window
"key-press-event"
81 (let ((c (aref (gdk:event-key-string e
) 0)))
83 (#\d
(incf *d
* 10) (widget-queue-draw area
))
84 (#\D
(incf *d
* -
10) (widget-queue-draw area
))
85 (#\y
(incf *y
* 5) (widget-queue-draw area
))
86 (#\Y
(incf *y
* -
5) (widget-queue-draw area
)))))
88 (let ((timer-id (gtk-main-add-timeout 10 (lambda ()
89 (incf *d
* 1) (incf *y
* 0.5)
90 (widget-queue-draw area
)
92 (connect-signal window
"delete-event" (lambda (w e
)
93 (declare (ignore w e
))
94 (g-source-remove timer-id
)
96 (widget-show window
))))
98 (defun planet-draw (w e
)
99 (declare (ignore w e
))
100 (gl:clear-color
0 0 0 0)
101 (gl:shade-model
:flat
)
102 (gl:clear
:color-buffer
)
104 (gl:with-pushed-matrix
106 (gl:translate
0 0 -
2)
108 (glut:wire-sphere
1 20 16)
109 ;; draw smaller planet
110 (gl:rotate
*y
* 0 1 0)
112 (gl:rotate
*d
* 0 1 0)
113 (glut:wire-sphere
0.2 10 8))
116 (defun planet-resize (w width height
)
118 (gl:viewport
0 0 width height
)
119 (gl:matrix-mode
:projection
)
121 (glu:perspective
60 (/ width height
) 1 20)
122 (gl:matrix-mode
:modelview
)
124 (glu:look-at
0 0 5 0 0 0 0 1 0))
126 (defclass opengl-window
(gtk-window)
127 ((expose-fn-text-view :initform
(make-instance 'text-view
) :reader opengl-window-expose-fn-text-view
)
128 (resize-fn-text-view :initform
(make-instance 'text-view
) :reader opengl-window-resize-fn-text-view
)
129 (expose-fn :initform nil
:accessor opengl-window-expose-fn
)
130 (resize-fn :initform nil
:accessor opengl-window-resize-fn
)
131 (drawing-area :initform
(make-instance 'gl-drawing-area
:height-request
100) :reader opengl-window-drawing-area
))
132 (:metaclass gobject-class
)
134 :title
"Lisp interactive OpenGL"
137 :window-position
:center
))
139 (defmethod initialize-instance :after
((window opengl-window
) &key
&allow-other-keys
)
140 (setf (text-buffer-text (text-view-buffer (opengl-window-expose-fn-text-view window
)))
143 (text-buffer-text (text-view-buffer (opengl-window-resize-fn-text-view window
)))
144 ";; Resize-fn. Parameters: w h
146 (let-ui (v-paned :var v
147 (:expr
(opengl-window-drawing-area window
))
148 :resize t
:shrink nil
152 :hscrollbar-policy
:automatic
153 :vscrollbar-policy
:automatic
154 (:expr
(opengl-window-expose-fn-text-view window
)))
155 :resize t
:shrink nil
157 :hscrollbar-policy
:automatic
158 :vscrollbar-policy
:automatic
159 (:expr
(opengl-window-resize-fn-text-view window
)))
160 :resize t
:shrink nil
)
162 (button :label
"Update functions" :var update-fns-button
) :expand nil
163 (button :label
"Redraw" :var redraw-button
) :expand nil
)
165 :resize t
:shrink nil
)
166 (container-add window v
)
167 (connect-signal update-fns-button
"clicked"
170 (update-fns window
)))
171 (connect-signal redraw-button
"clicked"
174 (widget-queue-draw (opengl-window-drawing-area window
))))
175 (let ((area (opengl-window-drawing-area window
)))
176 (setf (gl-drawing-area-on-expose area
)
178 (declare (ignore w e
))
179 (opengl-interactive-on-expose window
))
180 (gl-drawing-area-on-resize area
)
182 (declare (ignore widget
))
183 (opengl-interactive-on-resize window w h
))))))
185 (defun opengl-interactive-on-expose (window)
186 (if (opengl-window-expose-fn window
)
188 (funcall (opengl-window-expose-fn window
))
191 (setf (opengl-window-expose-fn window
) nil
)
192 (progn (gl:clear-color
0 0 0 0)
194 (gl:depth-func
:less
)
196 (gl:shade-model
:smooth
)
197 (gl:light-model
:light-model-local-viewer
1)
198 (gl:color-material
:front
:ambient-and-diffuse
)
199 (gl:enable
:light0
:lighting
:cull-face
:depth-test
)
201 (gl:translate
0 0 -
5)
202 (gl:rotate
*theta
* 1 1 0)
203 (gl:light
:light0
:position
'(0 1 1 0))
204 (gl:light
:light0
:diffuse
'(0.2
0.4 0.6 0))
205 (gl:clear
:color-buffer-bit
:depth-buffer-bit
)
208 (glut:solid-teapot
1.5)
211 (progn (gl:clear-color
0 0 0 0)
213 (gl:depth-func
:less
)
215 (gl:shade-model
:smooth
)
216 (gl:light-model
:light-model-local-viewer
1)
217 (gl:color-material
:front
:ambient-and-diffuse
)
218 (gl:enable
:light0
:lighting
:cull-face
:depth-test
)
220 (gl:translate
0 0 -
5)
221 (gl:rotate
*theta
* 1 1 0)
222 (gl:light
:light0
:position
'(0 1 1 0))
223 (gl:light
:light0
:diffuse
'(0.2
0.4 0.6 0))
224 (gl:clear
:color-buffer-bit
:depth-buffer-bit
)
227 (glut:solid-teapot
1.5)
231 (defun opengl-interactive-on-resize (window w h
)
232 (if (opengl-window-resize-fn window
)
234 (funcall (opengl-window-resize-fn window
) w h
)
237 (setf (opengl-window-resize-fn window
) nil
)
238 (gl:viewport
0 0 w h
)
239 (gl:matrix-mode
:projection
)
241 (glu:perspective
60 (/ w h
) 1 20)
242 (gl:matrix-mode
:modelview
)
245 (gl:viewport
0 0 w h
)
246 (gl:matrix-mode
:projection
)
248 (glu:perspective
60 (/ w h
) 1 20)
249 (gl:matrix-mode
:modelview
)
251 #+nil
(glu:look-at
0 0 5 0 0 0 0 1 0)
254 (defpackage :cl-gtk2-gl-demo-read-package
255 (:use
:cl
:cl-opengl
))
257 (defun read-exprs (string)
258 (with-input-from-string
260 (let ((eof (gensym)))
261 (iter (for expr
= (read stream nil eof
))
262 (until (eq expr eof
))
265 (defun read-fn (string fn-args
)
266 (let ((*package
* (find-package :cl-gtk2-gl-demo-read-package
)))
267 (let ((exprs (read-exprs string
)))
269 (eval `(lambda (,@fn-args
)
272 (defparameter *resize-fn-args
* (list (intern "W" :cl-gtk2-gl-demo-read-package
)
273 (intern "H" :cl-gtk2-gl-demo-read-package
)))
275 (defun update-fns (window)
276 (with-gtk-message-error-handler
277 (let ((expose-fn (read-fn (text-buffer-text (text-view-buffer (opengl-window-expose-fn-text-view window
))) nil
))
278 (resize-fn (read-fn (text-buffer-text (text-view-buffer (opengl-window-resize-fn-text-view window
)))
280 (assert (or (null expose-fn
) (functionp expose-fn
)))
281 (assert (or (null resize-fn
) (functionp resize-fn
)))
282 (setf (opengl-window-expose-fn window
) expose-fn
283 (opengl-window-resize-fn window
) resize-fn
)
284 (widget-queue-draw (opengl-window-drawing-area window
)))))
286 (defun opengl-interactive ()
287 (let ((output *standard-output
*))
289 (setf *standard-output
* output
)
290 (let ((w (make-instance 'opengl-window
)))