2 (asdf:oos
'asdf
:load-op
'#:cl-glfw-opengl-version_1_1
)
4 (defparameter *use-vbo
* t
)
6 (defconstant +pi
+ (coerce pi
'single-float
))
7 (defconstant +2pi
+ (* +pi
+ 2))
8 (defconstant +pi
/2+ (/ +pi
+ 2))
9 (defconstant +pi
/4+ (/ +pi
+ 4))
10 (defconstant +pi
/8+ (/ +pi
+ 8))
11 (defconstant +pi
/16+ (/ +pi
+ 16))
12 (defconstant +pi
/32+ (/ +pi
+ 32))
13 (defconstant +pi
/64+ (/ +pi
+ 64))
14 (defconstant +pi
/128+ (/ +pi
+ 128))
16 (defparameter *vertices-vbo
* nil
)
17 (defparameter *colours-vbo
* nil
)
18 (defparameter *normals-vbo
* nil
)
19 (defparameter *triangle-indices-vbo
* nil
)
21 (defparameter *triangle-indices
* nil
)
22 (defparameter *colours-array
* nil
)
23 (defparameter *normals-array
* nil
)
24 (defparameter *vertices-array
* nil
)
29 (step +pi
/64+)) ;; change this to change the detail of the sphere
30 (loop for phi from
(- step
+pi
/2+) upto
(- +pi
/2+ step
) by step
33 (loop for theta from
0.0 to
+2pi
+ by step
36 (let* ((theta (+ theta
(if (oddp y
) (/ step
2) 0.0)))
37 (v (list (* (cos phi
) (cos theta
))
38 (* (cos phi
) (sin theta
))
40 (norm (sqrt (reduce #'+ (mapcar #'* v v
))))
41 (normal (mapcar #'(lambda (e) (/ e norm
))
43 (setf *colours-array
* (nconc *colours-array
* (list (+ 0.5 (/ phi
+pi
+))
46 (setf *normals-array
* (nconc *normals-array
* normal
))
47 (setf *vertices-array
* (nconc *vertices-array
* v
)))))
48 (format t
"~a slices~%~a segments~%" slices segments
)
49 (nconc *normals-array
* (list 0.0 0.0 -
1.0 0.0 0.0 1.0))
50 (nconc *vertices-array
* (list 0.0 0.0 -
1.0 0.0 0.0 1.0))
51 (nconc *colours-array
* (list 0.0 0.5 1.0 1.0) (list 1.0 0.5 1.0 1.0))
52 (setf *triangle-indices
*
54 (loop for x upto segments nconcing
56 (- (/ (length *vertices-array
*) 3) 2)
57 (mod (1+ x
) segments
)))
59 (loop for y below
(1- slices
) nconcing
60 (loop for x below segments nconcing
61 (let ((v00 (+ x
(* y
(1+ segments
))))
62 (v01 (+ (mod (1+ x
) segments
) (* y
(1+ segments
))))
63 (v10 (+ x
(* (1+ y
) (1+ segments
))))
64 (v11 (+ (mod (1+ x
) segments
) (* (1+ y
) (1+ segments
)))))
66 (list v00 v01 v10 v10 v01 v11
)
67 (list v10 v00 v11 v00 v01 v11
)))))
68 (loop for x upto segments nconcing
69 (list (- (/ (length *vertices-array
*) 3) 1)
71 (* (1- slices
) (1+ segments
)))
72 (+ (mod (1+ x
) segments
)
73 (* (1- slices
) (1+ segments
))))))))
75 (defparameter *triangle-indices-length
* (length *triangle-indices
*))
76 (defparameter *vertices-array-length
* (length *vertices-array
*))
78 (defparameter *t0
* 0.0)
79 (defparameter *frames
* 0)
81 (cffi:defcallback key-press
:void
((key :int
) (action :int
))
82 (when (and (= action glfw
:+press
+) (= key
(char-code #\V
)))
83 (setf *use-vbo
* (and (not *use-vbo
*)
84 (gl-ext:extension-available-p
"ARB_vertex_buffer_object"))
87 (glfw:set-window-title
(format nil
"VBO: ~a~%" (if *use-vbo
* "on" "off")))))
90 (setf *triangle-indices
* (cffi:foreign-alloc
'gl
:uint
:initial-contents
*triangle-indices
*)
91 *colours-array
* (cffi:foreign-alloc
'gl
:float
:initial-contents
*colours-array
*)
92 *normals-array
* (cffi:foreign-alloc
'gl
:float
:initial-contents
*normals-array
*)
93 *vertices-array
* (cffi:foreign-alloc
'gl
:float
:initial-contents
*vertices-array
*))
95 (glfw:do-window
("A VBO Example" 0 0 0 0 0 0 16)
96 ((gl:enable gl
:+depth-test
+)
97 (gl:depth-func gl
:+less
+)
98 (gl:enable gl
:+light0
+)
99 (gl:enable gl
:+lighting
+)
101 (gl:light-fv gl
:+light0
+ gl
:+position
+ #(1.0
1.0 1.0 0.0))
102 (gl:color-material gl
:+front
+ gl
:+ambient-and-diffuse
+)
103 (gl:enable gl
:+color-material
+)
105 (glfw:set-key-callback
(cffi:callback key-press
))
107 (gl:with-setup-projection
108 (glu:perspective
45 4/3 0.125 8))
110 (when (setf *use-vbo
* (and t
(gl-ext:load-extension
"ARB_vertex_buffer_object")))
111 (let ((buffers (make-array 4)))
112 (gl:gen-buffers-arb
4 buffers
)
113 (setf *vertices-vbo
* (elt buffers
0)
114 *normals-vbo
* (elt buffers
1)
115 *colours-vbo
* (elt buffers
2)
116 *triangle-indices-vbo
* (elt buffers
3)))
117 (format t
"Loading in ~d bytes of indices~%" (* *triangle-indices-length
* (cffi:foreign-type-size
'gl
:uint
)) )
118 (gl:with-bind-buffer-arb
(gl:+element-array-buffer-arb
+ *triangle-indices-vbo
*)
119 (gl:buffer-data-arb gl
:+element-array-buffer-arb
+
120 (* *triangle-indices-length
* (cffi:foreign-type-size
'gl
:uint
))
122 gl
:+static-draw-arb
+))
124 (format t
"Loading in ~d bytes of vertices~%" (* *vertices-array-length
* (cffi:foreign-type-size
'gl
:float
)) )
125 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *vertices-vbo
*)
126 (gl:buffer-data-arb gl
:+array-buffer-arb
+
127 (* *vertices-array-length
* (cffi:foreign-type-size
'gl
:float
))
129 gl
:+static-draw-arb
+))
131 (format t
"Loading in ~d bytes of normals~%" (* *vertices-array-length
* (cffi:foreign-type-size
'gl
:float
)) )
132 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *normals-vbo
*)
133 (gl:buffer-data-arb gl
:+array-buffer-arb
+
134 (* *vertices-array-length
* (cffi:foreign-type-size
'gl
:float
))
136 gl
:+static-draw-arb
+))
138 (format t
"Loading in ~d bytes of colours~%" (* *vertices-array-length
* 4/3 (cffi:foreign-type-size
'gl
:float
)) )
139 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *colours-vbo
*)
140 (gl:buffer-data-arb gl
:+array-buffer-arb
+
141 (* *vertices-array-length
* 4/3 (cffi:foreign-type-size
'gl
:float
))
143 gl
:+static-draw-arb
+)))
144 (setf *t0
* (glfw:get-time
)))
146 (let ((t1 (glfw:get-time
)))
147 (when (> (- t1
*t0
*) 1)
148 (glfw:set-window-title
(format nil
"~4f FPS, VBO: ~a~%" (/ *frames
* (- t1
*t0
*)) (if *use-vbo
* "on" "off")))
151 (gl:clear
(logior gl
:+color-buffer-bit
+ gl
:+depth-buffer-bit
+))
153 (gl:translate-f
0 0 -
5)
154 (gl:rotate-d
(* 10 (glfw:get-time
)) 1 1 0)
155 (gl:rotate-d
(* 90 (glfw:get-time
)) 0 0 1)
156 (gl:with-push-client-attrib
(gl:+client-vertex-array-bit
+)
157 (gl:enable-client-state gl
:+color-array
+)
158 (gl:enable-client-state gl
:+vertex-array
+)
159 (gl:enable-client-state gl
:+normal-array
+)
162 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *colours-vbo
*)
163 (gl:color-pointer
4 gl
:+float
+ 0 (cffi:make-pointer
0)))
165 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *normals-vbo
*)
166 (gl:normal-pointer gl
:+float
+ 0 (cffi:make-pointer
0)))
168 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *vertices-vbo
*)
169 (gl:vertex-pointer
3 gl
:+float
+ 0 (cffi:make-pointer
0)))
171 (gl:with-bind-buffer-arb
(gl:+element-array-buffer-arb
+ *triangle-indices-vbo
*)
172 (gl:draw-elements gl
:+triangles
+ *triangle-indices-length
* gl
:+unsigned-int
+ (cffi:make-pointer
0))))
174 (gl:color-pointer
4 gl
:+float
+ 0 *colours-array
*)
175 (gl:normal-pointer gl
:+float
+ 0 *normals-array
*)
176 (gl:vertex-pointer
3 gl
:+float
+ 0 *vertices-array
*)
177 (gl:draw-elements gl
:+triangles
+ *triangle-indices-length
* gl
:+unsigned-int
+ *triangle-indices
*))))