More npc improvements
[lambdamundo.git] / mesh-compiler.lisp
blobf915cde2c36c16149e32753fc2fd5e9ecdbb046a
4 (in-package :mixamesh)
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"
25 (iterate
26 (with face-index = 0)
27 (for (values a b c) in-triangles (faces-of self))
28 (setf (cffi:mem-aref triangle-data :uint32 face-index) a)
29 (incf face-index)
30 (setf (cffi:mem-aref triangle-data :uint32 face-index) b)
31 (incf face-index)
32 (setf (cffi:mem-aref triangle-data :uint32 face-index) c)
33 (incf face-index))
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))
37 triangle-data
38 gl:+static-draw-arb+))
39 (copy-vertex-buffer ()
40 "Copy mesh vertex data into vertex buffer"
41 (iterate
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)
45 (incf vertex-index)
46 (setf (cffi:mem-aref vertex-data :float vertex-index) y)
47 (incf vertex-index)
48 (setf (cffi:mem-aref vertex-data :float vertex-index) z)
49 (incf vertex-index))
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))
53 vertex-data
54 gl:+static-draw-arb+)))
55 (copy-vertex-buffer)
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+))