2 (asdf:oos
'asdf
:load-op
'#:cl-glfw
)
3 (asdf:oos
'asdf
:load-op
'#:cl-glfw-opengl
)
5 (defparameter *autoexit
* 0)
6 (defparameter *view-rotx
* 20)
7 (defparameter *view-roty
* 30)
8 (defparameter *view-rotz
* 0)
9 (defparameter *gear1
* nil
)
10 (defparameter *gear2
* nil
)
11 (defparameter *gear3
* nil
)
13 (defun gear (inner-radius outer-radius width teeth tooth-depth
)
14 (let ((r0 inner-radius
)
15 (r1 (- outer-radius
(/ tooth-depth
2)))
16 (r2 (+ outer-radius
(/ tooth-depth
2)))
18 (da (/ (/ (* 2 pi
) teeth
) 4)))
19 (gl:shade-model gl
:+flat
+)
23 (gl:with-begin gl
:+quad-strip
+
24 (dotimes (i (1+ teeth
))
25 (setf angle
(/ (* i
2 pi
) teeth
))
26 (gl:vertex-3f
(* r0
(cos angle
)) (* r0
(sin angle
)) (* width
0.5))
27 (gl:vertex-3f
(* r1
(cos angle
)) (* r1
(sin angle
)) (* width
0.5))
29 (gl:vertex-3f
(* r0
(cos angle
)) (* r0
(sin angle
)) (* width
0.5))
30 (gl:vertex-3f
(* r1
(cos (+ angle
(* 3 da
))))
31 (* r1
(sin (+ angle
(* 3 da
))))
34 ;; draw front sides of teeth
35 (gl:with-begin gl
:+quads
+
37 (setf angle
(/ (* i
2 pi
) teeth
))
38 (gl:vertex-3f
(* r1
(cos angle
)) (* r1
(sin angle
)) (* width
0.5))
39 (gl:vertex-3f
(* r2
(cos (+ angle da
))) (* r2
(sin (+ angle da
))) (* width
0.5))
40 (gl:vertex-3f
(* r2
(cos (+ angle
(* 2 da
)))) (* r2
(sin (+ angle
(* 2 da
)))) (* width
0.5))
41 (gl:vertex-3f
(* r1
(cos (+ angle
(* 3 da
)))) (* r1
(sin (+ angle
(* 3 da
)))) (* width
0.5))))
46 (gl:with-begin gl
:+quad-strip
+
47 (dotimes (i (1+ teeth
))
48 (setf angle
(/ (* i
2 pi
) teeth
))
49 (gl:vertex-3f
(* r1
(cos angle
)) (* r1
(sin angle
)) (* (- width
) 0.5))
50 (gl:vertex-3f
(* r0
(cos angle
)) (* r0
(sin angle
)) (* (- width
) 0.5))
52 (gl:vertex-3f
(* r1
(cos (+ angle
(* 3 da
)))) (* r1
(sin (+ angle
(* 3 da
)))) (* (- width
) 0.5))
53 (gl:vertex-3f
(* r0
(cos angle
)) (* r0
(sin angle
)) (* (- width
) 0.5)))))
55 ;; draw back sides of teeth
56 (gl:with-begin gl
:+quads
+
58 (setf angle
(/ (* i
2 pi
) teeth
))
59 (gl:vertex-3f
(* r1
(cos (+ angle
(* 3 da
)))) (* r1
(sin (+ angle
(* 3 da
)))) (* (- width
) 0.5))
60 (gl:vertex-3f
(* r2
(cos (+ angle
(* 2 da
)))) (* r2
(sin (+ angle
(* 2 da
)))) (* (- width
) 0.5))
61 (gl:vertex-3f
(* r2
(cos (+ angle da
))) (* r2
(sin (+ angle da
))) (* (- width
) 0.5))
62 (gl:vertex-3f
(* r1
(cos angle
)) (* r1
(sin angle
)) (* (- width
) 0.5))))
64 ;; draw outward faces of teeth
65 (gl:with-begin gl
:+quad-strip
+
67 (setf angle
(/ (* i
2 pi
) teeth
))
68 (gl:vertex-3f
(* r1
(cos angle
)) (* r1
(sin angle
)) (* width
0.5))
69 (gl:vertex-3f
(* r1
(cos angle
)) (* r1
(sin angle
)) (* (- width
) 0.5))
70 (let* ((u (- (* r2
(cos (+ angle da
))) (* r1
(cos angle
))))
71 (v (- (* r2
(sin (+ angle da
))) (* r1
(sin angle
))))
72 (len (sqrt (+ (* u u
) (* v v
)))))
76 (gl:normal-3f v
(- u
) 0)
77 (gl:vertex-3f
(* r2
(cos (+ angle da
))) (* r2
(sin (+ angle da
))) (* width
0.5))
78 (gl:vertex-3f
(* r2
(cos (+ angle da
))) (* r2
(sin (+ angle da
))) (* (- width
) 0.5))
79 (gl:normal-3f
(cos angle
) (sin angle
) 0)
80 (gl:vertex-3f
(* r2
(cos (+ angle
(* 2 da
)))) (* r2
(sin (+ angle
(* 2 da
)))) (* width
0.5))
81 (gl:vertex-3f
(* r2
(cos (+ angle
(* 2 da
)))) (* r2
(sin (+ angle
(* 2 da
)))) (* (- width
) 0.5))
82 (setf u
(- (* r1
(cos (+ angle
(* 3 da
)))) (* r2
(cos (+ angle
(* 2 da
))))))
83 (setf v
(- (* r1
(sin (+ angle
(* 3 da
)))) (* r2
(sin (+ angle
(* 2 da
))))))
84 (gl:normal-3f v
(- u
) 0)
85 (gl:vertex-3f
(* r1
(cos (+ angle
(* 3 da
)))) (* r1
(sin (+ angle
(* 3 da
)))) (* width
0.5))
86 (gl:vertex-3f
(* r1
(cos (+ angle
(* 3 da
)))) (* r1
(sin (+ angle
(* 3 da
)))) (* (- width
) 0.5))
87 (gl:normal-3f
(cos angle
) (sin angle
) 0)))
89 (gl:vertex-3f
(* r1
(cos 0)) (* r1
(sin 0)) (* width
0.5))
90 (gl:vertex-3f
(* r1
(cos 0)) (* r1
(sin 0)) (* (- width
) 0.5)))
92 (gl:shade-model gl
:+smooth
+)
94 ;; draw inside radius cylinder */
95 (gl:with-begin gl
:+quad-strip
+
96 (dotimes (i (1+ teeth
))
97 (setf angle
(/ (* i
2 pi
) teeth
))
98 (gl:normal-3f
(- (cos angle
)) (- (sin angle
)) 0)
99 (gl:vertex-3f
(* r0
(cos angle
)) (* r0
(sin angle
)) (* (- width
) 0.5))
100 (gl:vertex-3f
(* r0
(cos angle
)) (* r0
(sin angle
)) (* width
0.5))))))
112 (when (>= (- t1 t-last-report
) 5)
113 (let* ((seconds (- t1 t-last-report
))
114 (fps (/ frames seconds
)))
115 (format t
"~d frames in ~3$ seconds = ~3$ FPS~%" frames seconds fps
))
116 (setf t-last-report t1
118 (when (and (not (zerop *autoexit
*))
119 (>= t1
(* 0.999 *autoexit
*)))
120 (glfw:close-window
)))
123 (gl:clear
(logior gl
:+color-buffer-bit
+ gl
:+depth-buffer-bit
+))
125 (gl:rotate-f
*view-rotx
* 1 0 0)
126 (gl:rotate-f
*view-roty
* 0 1 0)
127 (gl:rotate-f
*view-rotz
* 0 0 1)
130 (gl:translate-f -
3 -
2 0)
131 (gl:rotate-f angle
0 0 1)
132 (gl:call-list
*gear1
*))
135 (gl:translate-f
3.1 -
2 0)
136 (gl:rotate-f
(- (* -
2 angle
) 9) 0 0 1)
137 (gl:call-list
*gear2
*))
140 (gl:translate-f -
3.1 4.2 0)
141 (gl:rotate-f
(- (* -
2 angle
) 25) 0 0 1)
142 (gl:call-list
*gear3
*)))
147 (setf angle
(coerce (+ angle
(* 100 (- t1 t0
))) 'single-float
))))
150 (gl:enable gl
:+cull-face
+)
151 (gl:enable gl
:+lighting
+)
152 (gl:enable gl
:+light0
+)
153 (gl:enable gl
:+depth-test
+)
155 (gl:light-fv gl
:+light0
+ gl
:+position
+ #(5.0
5.0 10.0 0.0))
158 (gl:with-new-list
(setf *gear1
* (gl:gen-lists
1)) gl
:+compile
+
159 (gl:material-fv gl
:+front
+ gl
:+ambient-and-diffuse
+ #(0.8
0.1 0.0 1.0))
162 (gl:with-new-list
(setf *gear2
* (gl:gen-lists
1)) gl
:+compile
+
163 (gl:material-fv gl
:+front
+ gl
:+ambient-and-diffuse
+ #(0.0
0.8 0.2 1.0))
164 (gear 0.5 2 2 10 0.7))
166 (gl:with-new-list
(setf *gear3
* (gl:gen-lists
1)) gl
:+compile
+
167 (gl:material-fv gl
:+front
+ gl
:+ambient-and-diffuse
+ #(0.2
0.2 1.0 1.0))
168 (gear 1.3 2 0.5 10 0.7))
170 (gl:enable gl
:+normalize
+)
172 ;; did we get -info or -exit?
173 (dolist (arg (or #+sbcl sb-ext
:*posix-argv
*
174 #+lispworks system
:*line-arguments-list
*
175 #+cmu extensions
:*command-line-words
*
177 (cond ((string= arg
"-info")
178 (format t
"GL_RENDERER = ~s~%GL_VERSION = ~s~%GL_VENDOR = ~s~%GL_EXTENSIONS = ~s~%"
179 (gl:get-string gl
:+renderer
+)
180 (gl:get-string gl
:+version
+)
181 (gl:get-string gl
:+vendor
+)
182 (gl:get-string gl
:+extensions
+)))
183 ((string= arg
"-exit")
185 (format t
"Auto Exit after ~d seconds.~%" *autoexit
*)))))
187 (cffi:defcallback key-callback
:void
((key :int
) (action :int
))
188 (when (eql action glfw
:+press
+)
189 (cond ((eql key
(char-code #\Z
))
190 (if (eql (glfw:get-key glfw
:+key-lshift
+) glfw
:+press
+)
192 (incf *view-rotz
* 5)))
193 ((eql key glfw
:+key-esc
+) (glfw:close-window
))
194 ((eql key glfw
:+key-up
+) (incf *view-rotx
* 5))
195 ((eql key glfw
:+key-down
+) (decf *view-rotx
* 5))
196 ((eql key glfw
:+key-left
+) (incf *view-roty
* 5))
197 ((eql key glfw
:+key-right
+) (decf *view-roty
* 5)))))
199 (cffi:defcallback window-size-callback
:void
((width :int
) (height :int
))
200 (let* ((h (/ height width
))
203 (xmax (* znear
0.5)))
205 (gl:viewport
0 0 width height
)
206 (gl:with-setup-projection
207 (gl:frustum
(- xmax
) xmax
(* (- xmax
) h
) (* xmax h
) znear zfar
))
210 (gl:translate-f
0 0 -
20)))
213 (glfw:do-window
("Gears" 300 300 0 0 0 0 16 0 glfw
:+window
+)
214 ((glfw:enable glfw
:+key-repeat
+)
215 (glfw:swap-interval
0)
217 (glfw:set-window-size-callback
(cffi:callback window-size-callback
))
218 (glfw:set-key-callback
(cffi:callback key-callback
)))