6 ;; this is an extension to mixamesh, but as it involves using ogl extensions, we have to compile
7 ;; when OGL is active in order to successfuly aquire extension function vectors and avoid massive
8 ;; warnings and even crashes with some video drivers (ATI, *cough*, *cough*...)
10 ;; as this uses extensions it has to be compiled and loaded with an active gl context
11 (defgeneric compile-mesh
(mesh &rest args
))
13 (defmethod compile-mesh ((mesh base-mesh
) &rest args
)
14 (declare (ignorable args
))
15 ;; this has only faces!
16 (format t
"Stub called ~%")
19 ;; being able to map across tuple arrays would make this a lot easier.
21 (defmethod compile-mesh ((self simple-mesh
) &rest args
)
22 "Given a mesh return a compiled mesh, which is a non-modifiable mesh optimised for rendering in foreign memory."
23 (declare (ignorable args
))
24 (format t
"Compiling simple mesh ~%")
25 (flet ((make-buffer ()
26 "Create a buffer-name for an OpenGL vertex buffer object"
27 (let ((buffer-name (make-array 1 :element-type
'(unsigned-byte 32))))
28 (gl:gen-buffers-arb
1 buffer-name
)
29 (aref buffer-name
0))))
30 (let ((result (make-instance 'compiled-mesh
))
31 (triangle-data (cffi::foreign-alloc
:uint32
:count
(* 3 (triangle-array-dimensions (faces-of self
)))))
32 (vertex-data (cffi:foreign-alloc
:float
:count
(* 3 (vertex3d-array-dimensions (vertices-of self
)))))
33 (vertex-buffer (make-buffer))
34 (triangle-buffer (make-buffer)))
35 (flet ((copy-triangle-buffer ()
36 "Copy mesh triangle data into vertex buffer"
39 (for (values a b c
) in-triangles
(faces-of self
))
40 (setf (cffi:mem-aref triangle-data
:uint32 face-index
) a
)
42 (setf (cffi:mem-aref triangle-data
:uint32 face-index
) b
)
44 (setf (cffi:mem-aref triangle-data
:uint32 face-index
) c
)
46 (gl:bind-buffer-arb gl
:+element-array-buffer-arb
+ triangle-buffer
)
47 (gl:buffer-data-arb gl
:+element-array-buffer-arb
+
48 (* 3 (triangle-array-dimensions (faces-of self
)) (cffi:foreign-type-size
:uint32
))
50 gl
:+static-draw-arb
+))
51 (copy-vertex-buffer ()
52 "Copy mesh vertex data into vertex buffer"
54 (with vertex-index
= 0)
55 (for (values x y z w
) in-vertices
(vertices-of self
))
56 (setf (cffi:mem-aref vertex-data
:float vertex-index
) x
)
58 (setf (cffi:mem-aref vertex-data
:float vertex-index
) y
)
60 (setf (cffi:mem-aref vertex-data
:float vertex-index
) z
)
62 (gl:bind-buffer-arb gl
:+array-buffer-arb
+ vertex-buffer
)
63 (gl:buffer-data-arb gl
:+array-buffer-arb
+
64 (* 3 (vertex3d-array-dimensions (vertices-of self
)) (cffi:foreign-type-size
:float
))
66 gl
:+static-draw-arb
+)))
68 (setf (slot-value result
'vertex-buffer
) vertex-buffer
)
69 (copy-triangle-buffer)
70 (setf (slot-value result
'triangle-buffer
) triangle-buffer
)
71 (setf (slot-value result
'element-count
) (* 3 (triangle-array-dimensions (faces-of self
))))
72 (cffi:foreign-free vertex-data
)
73 (cffi:foreign-free triangle-data
))
76 (defun make-texture-from-skin (skin)
77 (let* ((texture (gethash skin
*textures
*))
78 (result (make-instance 'glrepl
:rgba-image
:width
(width-of texture
) :height
(height-of texture
))))
79 (format *debug-io
* "Map size ~A~%" (colour-array-dimensions (map-of texture
)))
80 (format *debug-io
* "texture size ~A~%" (* (width-of texture
) (height-of texture
)))
82 (for index from
0 below
(* (width-of texture
) (height-of texture
)))
83 (cl-tuples:with-colour-aref
87 (setf (glrepl:pixel result index
)
88 (glrepl:pixval
(coerce (floor (* 255 r
)) '(unsigned-byte 8))
89 (coerce (floor (* 255 g
)) '(unsigned-byte 8))
90 (coerce (floor (* 255 b
)) '(unsigned-byte 8))
92 (glrepl:update-image result
)
96 (defmethod compile-mesh ((self lodematron
:md2-mesh
) &rest args
)
100 (format t
"Compiling md2 mesh with ~D tris and ~D uv tris ~%" (length (faces-of self
)) (length (lodematron:uvs-tris-of self
)))
101 (flet ((make-buffer ()
102 "Create a buffer-name for an OpenGL vertex buffer object"
103 (let ((buffer-name (make-array 1 :element-type
'(unsigned-byte 32))))
104 (gl:gen-buffers-arb
1 buffer-name
)
105 (aref buffer-name
0))))
106 (let* ((result (make-instance 'mixamesh
:textured-compiled-mesh
))
107 (uv-data (cffi::foreign-alloc
:float
:count
(* 2 3 (triangle-array-dimensions (lodematron:uvs-tris-of self
)))))
108 (vertex-data (cffi:foreign-alloc
:float
:count
(* 3 3 (triangle-array-dimensions (faces-of self
)))))
109 (vertex-buffer (make-buffer))
110 (uv-buffer (make-buffer)))
112 (flet ((copy-uv-buffer ()
113 "Copy uv triangle data into vertex buffer"
116 (for (values a b c
) in-triangles
(lodematron:uvs-tris-of self
))
123 (setf (cffi:mem-aref uv-data
:float uv-index
) u
)
125 (setf (cffi:mem-aref uv-data
:float uv-index
) v
)
133 (setf (cffi:mem-aref uv-data
:float uv-index
) u
)
135 (setf (cffi:mem-aref uv-data
:float uv-index
) v
)
143 (setf (cffi:mem-aref uv-data
:float uv-index
) u
)
145 (setf (cffi:mem-aref uv-data
:float uv-index
) v
)
148 (gl:bind-buffer-arb gl
:+array-buffer-arb
+ uv-buffer
)
149 (gl:buffer-data-arb gl
:+array-buffer-arb
+
150 (* 2 3 (triangle-array-dimensions (lodematron:uvs-tris-of self
)) (cffi:foreign-type-size
:float
))
152 gl
:+static-draw-arb
+))
154 (copy-vertex-buffer ()
155 "Copy mesh vertex data into vertex buffer"
157 (with vertex-index
= 0)
158 (for (values a b c
) in-triangles
(faces-of self
))
166 (setf (cffi:mem-aref vertex-data
:float vertex-index
) x
)
168 (setf (cffi:mem-aref vertex-data
:float vertex-index
) y
)
170 (setf (cffi:mem-aref vertex-data
:float vertex-index
) z
)
178 (setf (cffi:mem-aref vertex-data
:float vertex-index
) x
)
180 (setf (cffi:mem-aref vertex-data
:float vertex-index
) y
)
182 (setf (cffi:mem-aref vertex-data
:float vertex-index
) z
)
190 (setf (cffi:mem-aref vertex-data
:float vertex-index
) x
)
192 (setf (cffi:mem-aref vertex-data
:float vertex-index
) y
)
194 (setf (cffi:mem-aref vertex-data
:float vertex-index
) z
)
195 (incf vertex-index
)))
197 (gl:bind-buffer-arb gl
:+array-buffer-arb
+ vertex-buffer
)
198 (gl:buffer-data-arb gl
:+array-buffer-arb
+
199 (* 3 3 (triangle-array-dimensions (faces-of self
)) (cffi:foreign-type-size
:float
))
201 gl
:+static-draw-arb
+)))
203 (setf (slot-value result
'vertex-buffer
) vertex-buffer
)
205 (setf (slot-value result
'uv-buffer
) uv-buffer
)
206 (setf (slot-value result
'element-count
) (* 3 (triangle-array-dimensions (faces-of self
))))
207 (cffi:foreign-free vertex-data
)
208 (cffi:foreign-free uv-data
)
209 (setf (texture-of result
) (make-texture-from-skin skin
)))
213 (defun make-compiled-mesh (mesh &key skin
)
214 (setf (gethash mesh
*compiled-meshes
*) (compile-mesh (gethash mesh
*meshes
*) :skin skin
)))
217 (in-package :lambdamundo
)
219 ;;(declaim (optimize (compilation-speed 0) (debug 0) (safety 0) (space 0) (speed 3)))
221 (defmethod render ((self compiled-mesh
))
223 (gl:enable-client-state gl
:+vertex-array
+)
224 (gl:enable-client-state gl
:+index-array
+)
225 (gl:bind-buffer-arb gl
:+array-buffer-arb
+ (vertex-buffer-of self
))
226 (gl:bind-buffer-arb gl
:+element-array-buffer-arb
+ (triangle-buffer-of self
))
227 (gl:vertex-pointer
3 gl
:+float
+ 0 (cffi::null-pointer
))
228 (gl:draw-elements gl
:+triangles
+ (element-count-of self
) gl
:+unsigned-int
+ (cffi:null-pointer
))
229 (gl:disable-client-state gl
:+vertex-array
+)
230 (gl:disable-client-state gl
:+index-array
+))
232 (defmethod render ((self textured-compiled-mesh
))
233 ;; (format *debug-io* "Redering ..~%")
234 (gl:disable gl
:+blend
+)
235 (bind (mixamesh:texture-of self
) gl
:+replace
+)
236 (gl:color-3f
1.0 1.0 1.0)
237 (gl:enable-client-state gl
:+vertex-array
+)
238 (gl:enable-client-state gl
:+texture-coord-array
+)
239 (gl:bind-buffer-arb gl
:+array-buffer-arb
+ (vertex-buffer-of self
))
240 (gl:bind-buffer-arb gl
:+array-buffer-arb
+ (uv-buffer-of self
))
241 (gl:vertex-pointer
3 gl
:+float
+ 0 (cffi::null-pointer
))
242 (gl:tex-coord-pointer
2 gl
:+float
+ 0 (cffi:null-pointer
))
243 (gl:draw-arrays gl
:+triangles
+ 0 (element-count-of self
))
244 (gl:disable-client-state gl
:+texture-coord-array
+)
245 (gl:disable-client-state gl
:+vertex-array
+)
246 (gl:disable gl
:+blend
+))
248 ;; (format *debug-io* "Redering ..~%")
249 ;; (glrepl::with-opengl
250 ;; (gl:disable gl:+blend+)
251 ;; (gl:enable gl:+texture-2d+)
252 ;; (gl:bind-texture gl:+texture-2d+ (cffi::mem-ref (name-of (mixamesh:texture-of self)) :uint32))
253 ;; (gl:tex-env-f gl:+texture-env+ gl:+texture-env-mode+ gl:+decal+)
254 ;; (gl:color-3f 1.0 1.0 1.0)
255 ;; (gl:enable-client-state gl:+vertex-array+)
257 ;; (gl:bind-buffer-arb gl:+array-buffer-arb+ (vertex-buffer-of self))
258 ;; (gl:bind-buffer-arb gl:+array-buffer-arb+ (uv-buffer-of self))
259 ;; (gl:vertex-pointer 3 gl:+float+ 0 (cffi::null-pointer))
261 ;; (gl:draw-arrays gl:+triangles+ (element-count-of self) 0)
262 ;; (gl:disable-client-state gl:+vertex-array+)
263 ;; (gl:disable-client-state gl:+texture-coord-array+)
264 ;; (gl:enable gl:+blend+))
267 (defmethod destroy ((self compiled-mesh
))
268 (flet ((delete-buffer (buf)
269 (let ((buf-array (make-array 1)))
270 (setf (aref buf-array
0) buf
)
271 (gl:delete-buffers-arb
1 buf-array
))))
272 (when (vertex-buffer-of self
)
273 (delete-buffer (vertex-buffer-of self
))
274 (setf (slot-value 'vertex-buffer self
) nil
))
275 (setf (slot-value 'vertex-buffer self
) nil
)
276 (when (triangle-buffer-of self
)
277 (delete-buffer (triangle-buffer-of self
))
278 (setf (slot-value 'triangle-buffer self
) nil
))))
281 (defmethod destroy ((self textured-compiled-mesh
))
282 (flet ((delete-buffer (buf)
283 (let ((buf-array (make-array 1)))
284 (setf (aref buf-array
0) buf
)
285 (gl:delete-buffers-arb
1 buf-array
))))
286 (when (texture-of self
)
287 (destroy-image (texture-of self
))
288 (setf (texture-of self
) nil
))
289 (when (vertex-buffer-of self
)
290 (delete-buffer (vertex-buffer-of self
))
291 (setf (slot-value 'vertex-buffer self
) nil
))))
293 ;; (delete-buffer (uv-buffer-of self)