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.0d0
)
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
+)
99 (glfw:set-key-callback
(cffi:callback key-press
))
101 (gl:with-setup-projection
102 (glu:perspective
45.0d0
(/ 4.0d0
3.0d0
) 0.125d0
8.0d0
))
104 (when (setf *use-vbo
* (and t
(gl-ext:load-extension
"ARB_vertex_buffer_object")))
105 (let ((buffers (make-array 4)))
106 (gl:gen-buffers-arb
4 buffers
)
107 (setf *vertices-vbo
* (elt buffers
0)
108 *normals-vbo
* (elt buffers
1)
109 *colours-vbo
* (elt buffers
2)
110 *triangle-indices-vbo
* (elt buffers
3)))
111 (gl:with-bind-buffer-arb
(gl:+element-array-buffer-arb
+ *triangle-indices-vbo
*)
112 (gl:buffer-data-arb gl
:+element-array-buffer-arb
+
113 (* *triangle-indices-length
* (cffi:foreign-type-size
'gl
:uint
))
115 gl
:+static-draw-arb
+))
117 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *vertices-vbo
*)
118 (gl:buffer-data-arb gl
:+array-buffer-arb
+
119 (* *vertices-array-length
* (cffi:foreign-type-size
'gl
:float
))
121 gl
:+static-draw-arb
+))
123 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *normals-vbo
*)
124 (gl:buffer-data-arb gl
:+array-buffer-arb
+
125 (* *vertices-array-length
* (cffi:foreign-type-size
'gl
:float
))
127 gl
:+static-draw-arb
+))
129 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *colours-vbo
*)
130 (gl:buffer-data-arb gl
:+array-buffer-arb
+
131 (* *vertices-array-length
* 4/3 (cffi:foreign-type-size
'gl
:float
))
133 gl
:+dynamic-draw-arb
+)))
134 (setf *t0
* (glfw:get-time
)))
136 (let ((t1 (glfw:get-time
)))
137 (when (> (- t1
*t0
*) 1.0)
138 (glfw:set-window-title
(format nil
"~4f FPS, VBO: ~a~%" (/ *frames
* (- t1
*t0
*)) (if *use-vbo
* "on" "off")))
141 (gl:clear
(logior gl
:+color-buffer-bit
+ gl
:+depth-buffer-bit
+))
143 (gl:translate-f
0.0 0.0 -
5.0)
144 (gl:rotate-d
(* 10.0d0
(glfw:get-time
)) 1d0
1d0
0d0
)
145 (gl:rotate-d
(* 90.0d0
(glfw:get-time
)) 0d0
0d0
1d0
)
146 (gl:with-push-client-attrib
(gl:+client-vertex-array-bit
+)
147 (gl:enable-client-state gl
:+color-array
+)
148 (gl:enable-client-state gl
:+vertex-array
+)
149 (gl:enable-client-state gl
:+normal-array
+)
152 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *colours-vbo
*)
153 (gl:color-pointer
4 gl
:+float
+ 0 (cffi:make-pointer
0)))
155 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *normals-vbo
*)
156 (gl:normal-pointer gl
:+float
+ 0 (cffi:make-pointer
0)))
158 (gl:with-bind-buffer-arb
(gl:+array-buffer-arb
+ *vertices-vbo
*)
159 (gl:vertex-pointer
3 gl
:+float
+ 0 (cffi:make-pointer
0)))
161 (gl:with-bind-buffer-arb
(gl:+element-array-buffer-arb
+ *triangle-indices-vbo
*)
162 (gl:draw-elements gl
:+triangles
+ *triangle-indices-length
* gl
:+unsigned-int
+ (cffi:make-pointer
0))))
164 (gl:color-pointer
4 gl
:+float
+ 0 *colours-array
*)
165 (gl:normal-pointer gl
:+float
+ 0 *normals-array
*)
166 (gl:vertex-pointer
3 gl
:+float
+ 0 *vertices-array
*)
167 (gl:draw-elements gl
:+triangles
+ *triangle-indices-length
* gl
:+unsigned-int
+ *triangle-indices
*))))