8 ;; as this uses extensions it has to be compiled and loaded with an active gl context
9 (defun compile-mesh (mesh &rest args
)
10 "Given a mesh return a compiled mesh, which is a non-modifiable mesh optimised for rendering in foreign memory."
11 (declare (ignorable args
))
12 (let ((self (gethash mesh
*meshes
*)))
13 (flet ((make-buffer ()
14 "Create a buffer-name for an OpenGL vertex buffer object"
15 (let ((buffer-name (make-array 1 :element-type
'(unsigned-byte 32))))
16 (gl:gen-buffers-arb
1 buffer-name
)
17 (aref buffer-name
0))))
18 (let ((result (make-instance 'compiled-mesh
))
19 (triangle-data (cffi::foreign-alloc
:uint32
:count
(* 3 (triangle-array-dimensions (faces-of self
)))))
20 (vertex-data (cffi:foreign-alloc
:float
:count
(* 3 (vertex3d-array-dimensions (vertices-of self
)))))
21 (vertex-buffer (make-buffer))
22 (triangle-buffer (make-buffer)))
23 (flet ((copy-triangle-buffer ()
24 "Copy mesh triangle data into vertex buffer"
27 (for (values a b c
) in-triangles
(faces-of self
))
28 (setf (cffi:mem-aref triangle-data
:uint32 face-index
) a
)
30 (setf (cffi:mem-aref triangle-data
:uint32 face-index
) b
)
32 (setf (cffi:mem-aref triangle-data
:uint32 face-index
) c
)
34 (gl:bind-buffer-arb gl
:+element-array-buffer-arb
+ triangle-buffer
)
35 (gl:buffer-data-arb gl
:+element-array-buffer-arb
+
36 (* 3 (triangle-array-dimensions (faces-of self
)) (cffi:foreign-type-size
:uint32
))
38 gl
:+static-draw-arb
+))
39 (copy-vertex-buffer ()
40 "Copy mesh vertex data into vertex buffer"
42 (with vertex-index
= 0)
43 (for (values x y z w
) in-vertices
(vertices-of self
))
44 (setf (cffi:mem-aref vertex-data
:float vertex-index
) x
)
46 (setf (cffi:mem-aref vertex-data
:float vertex-index
) y
)
48 (setf (cffi:mem-aref vertex-data
:float vertex-index
) z
)
50 (gl:bind-buffer-arb gl
:+array-buffer-arb
+ vertex-buffer
)
51 (gl:buffer-data-arb gl
:+array-buffer-arb
+
52 (* 3 (vertex3d-array-dimensions (vertices-of self
)) (cffi:foreign-type-size
:float
))
54 gl
:+static-draw-arb
+)))
56 (setf (slot-value result
'vertex-buffer
) vertex-buffer
)
57 (copy-triangle-buffer)
58 (setf (slot-value result
'triangle-buffer
) triangle-buffer
)
59 (setf (slot-value result
'element-count
) (* 3 (triangle-array-dimensions (faces-of self
))))
60 (cffi:foreign-free vertex-data
)
61 (cffi:foreign-free triangle-data
)
62 (setf (gethash mesh
*compiled-meshes
*) self
))))))
64 (in-package :lambdamundo
)
66 (defmethod render ((self compiled-mesh
))
67 (gl:enable-client-state gl
:+vertex-array
+)
68 (gl:enable-client-state gl
:+index-array
+)
69 (gl:bind-buffer-arb gl
:+array-buffer-arb
+ (vertex-buffer-of self
))
70 (gl:bind-buffer-arb gl
:+element-array-buffer-arb
+ (triangle-buffer-of self
))
71 (gl:vertex-pointer
3 gl
:+float
+ 0 0)
72 (gl:draw-elements gl
:+lines
+ (element-count-of self
) gl
:+unsigned-int
+ 0)
73 (gl:disable-client-state gl
:+vertex-array
+)
74 (gl:disable-client-state gl
:+index-array
+))