From 665bf5f8ad788dc75ae011fd4038af44589ae2e0 Mon Sep 17 00:00:00 2001 From: John Connors Date: Thu, 28 Aug 2008 15:20:20 +0100 Subject: [PATCH] Ready for performance testing --- actor.lisp | 26 ++- camera.lisp | 15 +- lambdamundo-test.lisp | 20 +- main.lisp | 61 ++++-- mesh-compiler.lisp | 547 +++++++++++++++++++++++++++----------------------- npc.lisp | 19 +- turtle.lisp | 9 +- 7 files changed, 398 insertions(+), 299 deletions(-) rewrite mesh-compiler.lisp (66%) diff --git a/actor.lisp b/actor.lisp index 44ae953..2c134e6 100644 --- a/actor.lisp +++ b/actor.lisp @@ -2,7 +2,7 @@ (in-package :lambdamundo) -(defparameter *actors* (make-array 0 :adjustable t :fill-pointer 0)) +(defparameter *actors* (make-hash-table :test 'eql)) (def-tuple-class actor (:tuples @@ -11,15 +11,23 @@ (orientation :type quaternion) (w-velocity :type vector3d)) :slots - ((dv :type single-float :initform 0.0 :accessor dv-of) + ((id :allocation :class :reader id-of :initform (get-universal-time)) + (dv :type single-float :initform 0.0 :accessor dv-of) (dw :type single-float :initform 0.0 :accessor dw-of)))) (defmethod initialize-instance :after ((self actor) &rest args) (declare (ignore args)) - (setf (aref (orientation-of% self) 3) 1.0) - (vector-push-extend self *actors*)) + (setf (gethash (id-of self) *actors*) self)) +(defun make-actor (actor-type &rest args) + (let* ((actor + (apply #'make-instance actor-type args)) + (result (id-of actor))) + (incf (slot-value actor 'id)) + result)) + + (def-tuple-op angular-velocity ((vector vector3d (vx vy vz)) (quat quaternion (qx qy qz qw))) @@ -86,3 +94,13 @@ (quaternion-transform-vector3d (vector3d* 1.0 0.0 0.0) (orientation-of a))) + +(defun destroy-actor (actor) + (format *debug-io* "Goodbye ~A@%" actor) + (let ((destructee (gethash actor *actors*))) + (destroy destructee) + (values)) + (values)) + +(defmethod destroy ((a actor)) + (values)) \ No newline at end of file diff --git a/camera.lisp b/camera.lisp index 2965937..9e0054d 100644 --- a/camera.lisp +++ b/camera.lisp @@ -136,18 +136,18 @@ (camera-modelview-matrix ,camera) ,@forms)) -(defun make-camera () (make-instance 'camera - :location (make-vertex3d* 0.0 0.0 -5.0 1.0) - :orientation (make-quaternion* 0.0 0.0 0.0 1.0))) +(defun make-camera () (make-actor 'camera + :location (make-vertex3d* 0.0 0.0 -5.0 1.0) + :orientation (make-quaternion* 0.0 0.0 0.0 1.0))) (defparameter *camera* nil) -(defun set-current-camera (cam) (setf *camera* cam)) +(defun set-current-camera (cam) (setf *camera* (gethash cam *actors*))) (defun reset-camera () - (setf *camera* (make-instance 'camera - :position (make-vertex3d* 0.0 0.0 -5.0 1.0) - :orientation (make-quaternion* 0.0 0.0 0.0 1.0)))) + (setf *camera* (make-actor 'camera + :position (make-vertex3d* 0.0 0.0 -5.0 1.0) + :orientation (make-quaternion* 0.0 0.0 0.0 1.0)))) @@ -161,3 +161,4 @@ (defmethod render ((c camera)) (camera-modelview-matrix c) (gl:get-floatv gl:+modelview-matrix+ *modelview-debug*)) + diff --git a/lambdamundo-test.lisp b/lambdamundo-test.lisp index ec67229..e52ca0e 100644 --- a/lambdamundo-test.lisp +++ b/lambdamundo-test.lisp @@ -3,7 +3,12 @@ (in-package :lambdamundo) -(make-turtle 1.5 1.5 0.0) +(defparameter + *turtle* + (make-actor 'turtle + :location (make-vertex3d* 1.5 1.5 0.0 1.0) + :orientation (make-quaternion* 0.0 0.0 0.0 1.0))) + (defparameter *dalek-mesh* (mixamesh:make-mesh 'lodematron:md2-mesh)) @@ -28,4 +33,15 @@ (one-shot (mixamesh::make-compiled-mesh *dalek-mesh* :skin (lodematron::skin-of (gethash *dalek-mesh* *meshes*)))) -(defparameter *dalek-actor* (make-npc *dalek-mesh*)) \ No newline at end of file +(defparameter *dalek-actor* + (make-actor 'npc + :mesh *dalek-mesh* + :location (make-vertex3d (location-of (gethash *turtle* *actors*))) + :orientation (make-quaternion (orientation-of (gethash *turtle* *actors*))))) + +(defparameter *dalek-actor* (make-npc *dalek-mesh*)) + +(destroy-actor *dalek-actor*) + + +(up *turtle* 0.5) \ No newline at end of file diff --git a/main.lisp b/main.lisp index 716a61a..e3a4ba1 100644 --- a/main.lisp +++ b/main.lisp @@ -117,16 +117,17 @@ (< (car a) (car b)))))) (defun render-world () - (gl:disable gl:+texture-2d+) (gl:disable gl:+blend+) (with-camera *camera* +#| (iterate (for entry in-vector *draw-array*) (funcall (gethash (car entry) *draw-fns*))) +|# (iterate - (for actor in-vector *actors*) + (for (key actor) in-hashtable *actors*) (render actor)))) - +#| (make-draw-function "testcube" 1 (let ((vertices @@ -154,14 +155,11 @@ (iterate (for vertex in poly) (apply #'gl:vertex-3f (nth (1- vertex) vertices))))))) - +|# ;; animation -------------------- -(defparameter *frames* 0) - (defun update-world (dt) - (incf *frames*) (when *mouse-wheel-changed* (pan *camera* 0.0 (* *mouse-wheel-delta* dt)) (setf *mouse-wheel-changed* nil))) @@ -180,6 +178,21 @@ (defparameter *one-shot-fn* nil) +(defparameter *in-main-loop* nil) + +(defparameter *fps* 0.0) +(defparameter *sample-interval* 100) +(defparameter *time-last-sample* 0) +(defparameter *frame* 0) + +(defun sample-function (t0) + (unless (zerop *frame*) + (format *debug-io* "Frame ~D " *frame*) + (format *debug-io* "Elapsed time ~D " (- t0 *time-last-sample*)) + (format *debug-io* "Fps ~D " (/ (- t0 *time-last-sample*) *sample-interval*)) + (format *debug-io* "Actors ~D~%" (1- (hash-table-size *actors*)))) + (setf *time-last-sample* t0)) + ;; main routine ------------------- (defun main-loop () (let ((t0 (coerce (glfw:get-time) 'single-float)) @@ -189,11 +202,16 @@ (setf glrepl:*console-render-debug-fn* #'render-debug) (glfw:sleep 0.05d0) (gl:clear-color 0.0 0.0 0.0 1.0) - (iterate + (setf *in-main-loop* t) + (setf *frame* 0) + (setf glrepl:*console* nil) + (iterate (while (= (glfw::get-window-param glfw:+opened+) glfw:+true+)) (gl:clear (logior gl:+color-buffer-bit+ gl:+depth-buffer-bit+)) (setf dt (- (coerce (glfw:get-time) 'single-float) t0)) (setf t0 (coerce (glfw:get-time) 'single-float)) + (when (zerop (mod *frame* *sample-interval*)) + (sample-function t0)) (update-world dt) (gl:viewport 0 0 (win-width-of glrepl:*glwindow*) (win-height-of glrepl:*glwindow*)) (gl:matrix-mode gl:+projection+) @@ -209,7 +227,9 @@ ;; update ;; check for time available if time is avaliable render ;; surrender any cpu time.. - (glfw:swap-buffers)))) + (incf *frame*) + (glfw:swap-buffers)) + (setf *in-main-loop* nil))) (defun begin-swank () (unless *swank-port* @@ -231,13 +251,14 @@ (defun oh-bum () "Cleanup when something went wrong." ;; (end-swank) - (glfw:close-window) - (glfw:terminate) - (clrhash *bounding-boxes*) - (clrhash *meshes*) - (clrhash *compiled-meshes*) - (clrhash *textures*) - (setf *actors* (make-array 0 :adjustable t :fill-pointer 0))) + (when (not *in-main-loop*) + (clrhash *textures*) + (destroy-font (font-of glrepl:*glwindow*)) + (iterate + (for (key actor) in *actors*) + (destroy actor)) + (glfw:close-window) + (glfw:terminate))) ;; to do -- wipe out previous state ;; (setf *actors* ) @@ -246,11 +267,11 @@ ;; (setf *textures* ) ;; (setf *meshes* ) -;; - +;; wipe out ogl resources (defun glfw-cleanup () - (glfw:close-window) - (glfw:terminate)) + (when (not *in-main-loop*) + (glfw:close-window) + (glfw:terminate))) diff --git a/mesh-compiler.lisp b/mesh-compiler.lisp dissimilarity index 66% index 4811a5e..55e4a8b 100644 --- a/mesh-compiler.lisp +++ b/mesh-compiler.lisp @@ -1,253 +1,294 @@ - - - -(in-package :mixamesh) - -;; this is an extension to mixamesh, but as it involves using ogl extensions, we have to compile -;; when OGL is active in order to successfuly aquire extension function vectors and avoid massive -;; warnings and even crashes with some video drivers (ATI, *cough*, *cough*...) - -;; as this uses extensions it has to be compiled and loaded with an active gl context -(defgeneric compile-mesh (mesh &rest args)) - -(defmethod compile-mesh ((mesh base-mesh) &rest args) - (declare (ignorable args)) - ;; this has only faces! - (format t "Stub called ~%") - (values)) - -;; being able to map across tuple arrays would make this a lot easier. - -(defmethod compile-mesh ((self simple-mesh) &rest args) - "Given a mesh return a compiled mesh, which is a non-modifiable mesh optimised for rendering in foreign memory." - (declare (ignorable args)) - (format t "Compiling simple mesh ~%") - (flet ((make-buffer () - "Create a buffer-name for an OpenGL vertex buffer object" - (let ((buffer-name (make-array 1 :element-type '(unsigned-byte 32)))) - (gl:gen-buffers-arb 1 buffer-name) - (aref buffer-name 0)))) - (let ((result (make-instance 'compiled-mesh)) - (triangle-data (cffi::foreign-alloc :uint32 :count (* 3 (triangle-array-dimensions (faces-of self))))) - (vertex-data (cffi:foreign-alloc :float :count (* 3 (vertex3d-array-dimensions (vertices-of self))))) - (vertex-buffer (make-buffer)) - (triangle-buffer (make-buffer))) - (flet ((copy-triangle-buffer () - "Copy mesh triangle data into vertex buffer" - (iterate - (with face-index = 0) - (for (values a b c) in-triangles (faces-of self)) - (setf (cffi:mem-aref triangle-data :uint32 face-index) a) - (incf face-index) - (setf (cffi:mem-aref triangle-data :uint32 face-index) b) - (incf face-index) - (setf (cffi:mem-aref triangle-data :uint32 face-index) c) - (incf face-index)) - (gl:bind-buffer-arb gl:+element-array-buffer-arb+ triangle-buffer) - (gl:buffer-data-arb gl:+element-array-buffer-arb+ - (* 3 (triangle-array-dimensions (faces-of self)) (cffi:foreign-type-size :uint32)) - triangle-data - gl:+static-draw-arb+)) - (copy-vertex-buffer () - "Copy mesh vertex data into vertex buffer" - (iterate - (with vertex-index = 0) - (for (values x y z w) in-vertices (vertices-of self)) - (setf (cffi:mem-aref vertex-data :float vertex-index) x) - (incf vertex-index) - (setf (cffi:mem-aref vertex-data :float vertex-index) y) - (incf vertex-index) - (setf (cffi:mem-aref vertex-data :float vertex-index) z) - (incf vertex-index)) - (gl:bind-buffer-arb gl:+array-buffer-arb+ vertex-buffer) - (gl:buffer-data-arb gl:+array-buffer-arb+ - (* 3 (vertex3d-array-dimensions (vertices-of self)) (cffi:foreign-type-size :float)) - vertex-data - gl:+static-draw-arb+))) - (copy-vertex-buffer) - (setf (slot-value result 'vertex-buffer) vertex-buffer) - (copy-triangle-buffer) - (setf (slot-value result 'triangle-buffer) triangle-buffer) - (setf (slot-value result 'element-count) (* 3 (triangle-array-dimensions (faces-of self)))) - (cffi:foreign-free vertex-data) - (cffi:foreign-free triangle-data)) - result))) - -(defun make-texture-from-skin (skin) - (let* ((texture (gethash skin *textures*)) - (result (make-instance 'glrepl:rgba-image :width (width-of texture) :height (height-of texture)))) - (iterate - (for index from 0 to (* (width-of texture) (height-of texture))) - (cl-tuples:with-colour-aref - ((map-of texture) - index - (r g b a)) - (setf (glrepl:pixel result index) (glrepl:pixval (coerce (floor (* 255 r)) '(unsigned-byte 8)) - (coerce (floor (* 255 g)) '(unsigned-byte 8)) - (coerce (floor (* 255 b)) '(unsigned-byte 8)) - (coerce (floor (* 255 a)) '(unsigned-byte 8)))))) - (glrepl:update-image result) - result)) - -(defmethod compile-mesh ((self lodematron:md2-mesh) &rest args) - (destructuring-bind - (&key skin) - args - (format t "Compiling md2 mesh with ~D tris and ~D uv tris ~%" (length (faces-of self)) (length (lodematron:uvs-tris-of self))) - (flet ((make-buffer () - "Create a buffer-name for an OpenGL vertex buffer object" - (let ((buffer-name (make-array 1 :element-type '(unsigned-byte 32)))) - (gl:gen-buffers-arb 1 buffer-name) - (aref buffer-name 0)))) - (let ((result (make-instance 'mixamesh:textured-compiled-mesh)) - (uv-data (cffi::foreign-alloc :float :count (* 2 3 (triangle-array-dimensions (lodematron:uvs-tris-of self))))) - (vertex-data (cffi:foreign-alloc :float :count (* 3 3 (triangle-array-dimensions (faces-of self))))) - (vertex-buffer (make-buffer)) - (uv-buffer (make-buffer))) - - (flet ((copy-uv-buffer () - "Copy uv triangle data into vertex buffer" - (iterate - (with uv-index = 0) - (for (values a b c) in-triangles (lodematron:uvs-tris-of self)) - - (with-vector2d-aref - ((uvs-of self) - a - (u v)) - (setf (cffi:mem-aref uv-data :float uv-index) u) - (incf uv-index) - (setf (cffi:mem-aref uv-data :float uv-index) v) - (incf uv-index)) - - (with-vector2d-aref - ((uvs-of self) - b - (u v)) - (setf (cffi:mem-aref uv-data :float uv-index) u) - (incf uv-index) - (setf (cffi:mem-aref uv-data :float uv-index) v) - (incf uv-index)) - - (with-vector2d-aref - ((uvs-of self) - c - (u v)) - (setf (cffi:mem-aref uv-data :float uv-index) u) - (incf uv-index) - (setf (cffi:mem-aref uv-data :float uv-index) v) - (incf uv-index))) - - (gl:bind-buffer-arb gl:+array-buffer-arb+ uv-buffer) - (gl:buffer-data-arb gl:+array-buffer-arb+ - (* 2 3 (triangle-array-dimensions (lodematron:uvs-tris-of self)) (cffi:foreign-type-size :float)) - uv-data - gl:+static-draw-arb+)) - - (copy-vertex-buffer () - "Copy mesh vertex data into vertex buffer" - (iterate - (with vertex-index = 0) - (for (values a b c) in-triangles (faces-of self)) - - (with-vertex3d-aref - ((vertices-of self) - a - (x y z w)) - (format t "Index ~D Vertex ~A ~A ~A ~%" a x y z) - - (setf (cffi:mem-aref vertex-data :float vertex-index) x) - (incf vertex-index) - (setf (cffi:mem-aref vertex-data :float vertex-index) y) - (incf vertex-index) - (setf (cffi:mem-aref vertex-data :float vertex-index) z) - (incf vertex-index)) - - (with-vertex3d-aref - ((vertices-of self) - b - (x y z w)) - (format t "Index ~D Vertex ~A ~A ~A ~%" b x y z) - (setf (cffi:mem-aref vertex-data :float vertex-index) x) - (incf vertex-index) - (setf (cffi:mem-aref vertex-data :float vertex-index) y) - (incf vertex-index) - (setf (cffi:mem-aref vertex-data :float vertex-index) z) - (incf vertex-index)) - - (with-vertex3d-aref - ((vertices-of self) - c - (x y z w)) - (format t "Index ~D Vertex ~A ~A ~A ~%" c x y z) - (setf (cffi:mem-aref vertex-data :float vertex-index) x) - (incf vertex-index) - (setf (cffi:mem-aref vertex-data :float vertex-index) y) - (incf vertex-index) - (setf (cffi:mem-aref vertex-data :float vertex-index) z) - (incf vertex-index))) - - (gl:bind-buffer-arb gl:+array-buffer-arb+ vertex-buffer) - (gl:buffer-data-arb gl:+array-buffer-arb+ - (* 3 3 (triangle-array-dimensions (faces-of self)) (cffi:foreign-type-size :float)) - vertex-data - gl:+static-draw-arb+))) - (copy-vertex-buffer) - (setf (slot-value result 'vertex-buffer) vertex-buffer) - (copy-uv-buffer) - (setf (slot-value result 'uv-buffer) uv-buffer) - (setf (slot-value result 'element-count) (* 3 (triangle-array-dimensions (faces-of self)))) - (cffi:foreign-free vertex-data) - (cffi:foreign-free uv-data) - (setf (texture-of result) (make-texture-from-skin skin))) - result)))) - - -(defun make-compiled-mesh (mesh &key skin) - (setf (gethash mesh *compiled-meshes*) (compile-mesh (gethash mesh *meshes*) :skin skin))) - - -(in-package :lambdamundo) - -(defmethod render ((self compiled-mesh)) - (gl:enable-client-state gl:+vertex-array+) - (gl:enable-client-state gl:+index-array+) - (gl:bind-buffer-arb gl:+array-buffer-arb+ (vertex-buffer-of self)) - (gl:bind-buffer-arb gl:+element-array-buffer-arb+ (triangle-buffer-of self)) - (gl:vertex-pointer 3 gl:+float+ 0 (cffi::null-pointer)) - (gl:draw-elements gl:+lines+ (element-count-of self) gl:+unsigned-int+ 0) - (gl:disable-client-state gl:+vertex-array+) - (gl:disable-client-state gl:+index-array+)) - -(defmethod render ((self textured-compiled-mesh)) - (gl:bind-texture gl:+texture-2d+ (cffi::mem-ref (name-of (mixamesh:texture-of self)) :uint32)) - (gl:tex-env-f gl:+texture-env+ gl:+texture-env-mode+ gl:+decal+) - (gl:enable-client-state gl:+vertex-array+) - (gl:enable-client-state gl:+texture-coord-array+) - (gl:bind-buffer-arb gl:+array-buffer-arb+ (vertex-buffer-of self)) - (gl:bind-buffer-arb gl:+array-buffer-arb+ (uv-buffer-of self)) - (gl:vertex-pointer 3 gl:+float+ 0 (cffi::null-pointer)) - (gl:tex-coord-pointer 2 gl:+float+ 0 0) - (gl:draw-arrays gl:+triangles+ (element-count-of self) 0) - (gl:disable-client-state gl:+vertex-array+) - (gl:disable-client-state gl:+texture-coord-array+)) - -(defmethod destroy ((self compiled-mesh)) - (flet ((delete-buffer (buf) - (let ((buf-array (make-array 1))) - (setf (aref buf-array 0) buf) - - (gl:delete-buffers-arb 1 buf-array)))) - (delete-buffer (vertex-buffer-of self)) - (delete-buffer (triangle-buffer-of self)))) - - -(defmethod destroy ((self textured-compiled-mesh)) - (flet ((delete-buffer (buf) - (let ((buf-array (make-array 1))) - (setf (aref buf-array 0) buf) - - (gl:delete-buffers-arb 1 buf-array)))) - (delete-buffer (vertex-buffer-of self) -;; (delete-buffer (uv-buffer-of self) - ))) + + + +(in-package :mixamesh) + +;; this is an extension to mixamesh, but as it involves using ogl extensions, we have to compile +;; when OGL is active in order to successfuly aquire extension function vectors and avoid massive +;; warnings and even crashes with some video drivers (ATI, *cough*, *cough*...) + +;; as this uses extensions it has to be compiled and loaded with an active gl context +(defgeneric compile-mesh (mesh &rest args)) + +(defmethod compile-mesh ((mesh base-mesh) &rest args) + (declare (ignorable args)) + ;; this has only faces! + (format t "Stub called ~%") + (values)) + +;; being able to map across tuple arrays would make this a lot easier. + +(defmethod compile-mesh ((self simple-mesh) &rest args) + "Given a mesh return a compiled mesh, which is a non-modifiable mesh optimised for rendering in foreign memory." + (declare (ignorable args)) + (format t "Compiling simple mesh ~%") + (flet ((make-buffer () + "Create a buffer-name for an OpenGL vertex buffer object" + (let ((buffer-name (make-array 1 :element-type '(unsigned-byte 32)))) + (gl:gen-buffers-arb 1 buffer-name) + (aref buffer-name 0)))) + (let ((result (make-instance 'compiled-mesh)) + (triangle-data (cffi::foreign-alloc :uint32 :count (* 3 (triangle-array-dimensions (faces-of self))))) + (vertex-data (cffi:foreign-alloc :float :count (* 3 (vertex3d-array-dimensions (vertices-of self))))) + (vertex-buffer (make-buffer)) + (triangle-buffer (make-buffer))) + (flet ((copy-triangle-buffer () + "Copy mesh triangle data into vertex buffer" + (iterate + (with face-index = 0) + (for (values a b c) in-triangles (faces-of self)) + (setf (cffi:mem-aref triangle-data :uint32 face-index) a) + (incf face-index) + (setf (cffi:mem-aref triangle-data :uint32 face-index) b) + (incf face-index) + (setf (cffi:mem-aref triangle-data :uint32 face-index) c) + (incf face-index)) + (gl:bind-buffer-arb gl:+element-array-buffer-arb+ triangle-buffer) + (gl:buffer-data-arb gl:+element-array-buffer-arb+ + (* 3 (triangle-array-dimensions (faces-of self)) (cffi:foreign-type-size :uint32)) + triangle-data + gl:+static-draw-arb+)) + (copy-vertex-buffer () + "Copy mesh vertex data into vertex buffer" + (iterate + (with vertex-index = 0) + (for (values x y z w) in-vertices (vertices-of self)) + (setf (cffi:mem-aref vertex-data :float vertex-index) x) + (incf vertex-index) + (setf (cffi:mem-aref vertex-data :float vertex-index) y) + (incf vertex-index) + (setf (cffi:mem-aref vertex-data :float vertex-index) z) + (incf vertex-index)) + (gl:bind-buffer-arb gl:+array-buffer-arb+ vertex-buffer) + (gl:buffer-data-arb gl:+array-buffer-arb+ + (* 3 (vertex3d-array-dimensions (vertices-of self)) (cffi:foreign-type-size :float)) + vertex-data + gl:+static-draw-arb+))) + (copy-vertex-buffer) + (setf (slot-value result 'vertex-buffer) vertex-buffer) + (copy-triangle-buffer) + (setf (slot-value result 'triangle-buffer) triangle-buffer) + (setf (slot-value result 'element-count) (* 3 (triangle-array-dimensions (faces-of self)))) + (cffi:foreign-free vertex-data) + (cffi:foreign-free triangle-data)) + result))) + +(defun make-texture-from-skin (skin) + (let* ((texture (gethash skin *textures*)) + (result (make-instance 'glrepl:rgba-image :width (width-of texture) :height (height-of texture)))) + (format *debug-io* "Map size ~A~%" (colour-array-dimensions (map-of texture))) + (format *debug-io* "texture size ~A~%" (* (width-of texture) (height-of texture))) + (iterate + (for index from 0 below (* (width-of texture) (height-of texture))) + (cl-tuples:with-colour-aref + ((map-of texture) + index + (r g b a)) + (setf (glrepl:pixel result index) + (glrepl:pixval (coerce (floor (* 255 r)) '(unsigned-byte 8)) + (coerce (floor (* 255 g)) '(unsigned-byte 8)) + (coerce (floor (* 255 b)) '(unsigned-byte 8)) + 255)))) + (glrepl:update-image result) + result)) + + +(defmethod compile-mesh ((self lodematron:md2-mesh) &rest args) + (destructuring-bind + (&key skin) + args + (format t "Compiling md2 mesh with ~D tris and ~D uv tris ~%" (length (faces-of self)) (length (lodematron:uvs-tris-of self))) + (flet ((make-buffer () + "Create a buffer-name for an OpenGL vertex buffer object" + (let ((buffer-name (make-array 1 :element-type '(unsigned-byte 32)))) + (gl:gen-buffers-arb 1 buffer-name) + (aref buffer-name 0)))) + (let* ((result (make-instance 'mixamesh:textured-compiled-mesh)) + (uv-data (cffi::foreign-alloc :float :count (* 2 3 (triangle-array-dimensions (lodematron:uvs-tris-of self))))) + (vertex-data (cffi:foreign-alloc :float :count (* 3 3 (triangle-array-dimensions (faces-of self))))) + (vertex-buffer (make-buffer)) + (uv-buffer (make-buffer))) + + (flet ((copy-uv-buffer () + "Copy uv triangle data into vertex buffer" + (iterate + (with uv-index = 0) + (for (values a b c) in-triangles (lodematron:uvs-tris-of self)) + + (with-vector2d-aref + ((uvs-of self) + a + (u v)) + + (setf (cffi:mem-aref uv-data :float uv-index) u) + (incf uv-index) + (setf (cffi:mem-aref uv-data :float uv-index) v) + (incf uv-index)) + + (with-vector2d-aref + ((uvs-of self) + b + (u v)) + + (setf (cffi:mem-aref uv-data :float uv-index) u) + (incf uv-index) + (setf (cffi:mem-aref uv-data :float uv-index) v) + (incf uv-index)) + + (with-vector2d-aref + ((uvs-of self) + c + (u v)) + + (setf (cffi:mem-aref uv-data :float uv-index) u) + (incf uv-index) + (setf (cffi:mem-aref uv-data :float uv-index) v) + (incf uv-index))) + + (gl:bind-buffer-arb gl:+array-buffer-arb+ uv-buffer) + (gl:buffer-data-arb gl:+array-buffer-arb+ + (* 2 3 (triangle-array-dimensions (lodematron:uvs-tris-of self)) (cffi:foreign-type-size :float)) + uv-data + gl:+static-draw-arb+)) + + (copy-vertex-buffer () + "Copy mesh vertex data into vertex buffer" + (iterate + (with vertex-index = 0) + (for (values a b c) in-triangles (faces-of self)) + + (with-vertex3d-aref + ((vertices-of self) + a + (x y z w)) + + + (setf (cffi:mem-aref vertex-data :float vertex-index) x) + (incf vertex-index) + (setf (cffi:mem-aref vertex-data :float vertex-index) y) + (incf vertex-index) + (setf (cffi:mem-aref vertex-data :float vertex-index) z) + (incf vertex-index)) + + (with-vertex3d-aref + ((vertices-of self) + b + (x y z w)) + + (setf (cffi:mem-aref vertex-data :float vertex-index) x) + (incf vertex-index) + (setf (cffi:mem-aref vertex-data :float vertex-index) y) + (incf vertex-index) + (setf (cffi:mem-aref vertex-data :float vertex-index) z) + (incf vertex-index)) + + (with-vertex3d-aref + ((vertices-of self) + c + (x y z w)) + + (setf (cffi:mem-aref vertex-data :float vertex-index) x) + (incf vertex-index) + (setf (cffi:mem-aref vertex-data :float vertex-index) y) + (incf vertex-index) + (setf (cffi:mem-aref vertex-data :float vertex-index) z) + (incf vertex-index))) + + (gl:bind-buffer-arb gl:+array-buffer-arb+ vertex-buffer) + (gl:buffer-data-arb gl:+array-buffer-arb+ + (* 3 3 (triangle-array-dimensions (faces-of self)) (cffi:foreign-type-size :float)) + vertex-data + gl:+static-draw-arb+))) + (copy-vertex-buffer) + (setf (slot-value result 'vertex-buffer) vertex-buffer) + (copy-uv-buffer) + (setf (slot-value result 'uv-buffer) uv-buffer) + (setf (slot-value result 'element-count) (* 3 (triangle-array-dimensions (faces-of self)))) + (cffi:foreign-free vertex-data) + (cffi:foreign-free uv-data) + (setf (texture-of result) (make-texture-from-skin skin))) + result)))) + + +(defun make-compiled-mesh (mesh &key skin) + (setf (gethash mesh *compiled-meshes*) (compile-mesh (gethash mesh *meshes*) :skin skin))) + + +(in-package :lambdamundo) + +;;(declaim (optimize (compilation-speed 0) (debug 0) (safety 0) (space 0) (speed 3))) + +(defmethod render ((self compiled-mesh)) + + (gl:enable-client-state gl:+vertex-array+) + (gl:enable-client-state gl:+index-array+) + (gl:bind-buffer-arb gl:+array-buffer-arb+ (vertex-buffer-of self)) + (gl:bind-buffer-arb gl:+element-array-buffer-arb+ (triangle-buffer-of self)) + (gl:vertex-pointer 3 gl:+float+ 0 (cffi::null-pointer)) + (gl:draw-elements gl:+triangles+ (element-count-of self) gl:+unsigned-int+ (cffi:null-pointer)) + (gl:disable-client-state gl:+vertex-array+) + (gl:disable-client-state gl:+index-array+)) + +(defmethod render ((self textured-compiled-mesh)) + ;; (format *debug-io* "Redering ..~%") + (gl:disable gl:+blend+) + (bind (mixamesh:texture-of self) gl:+replace+) + (gl:color-3f 1.0 1.0 1.0) + (gl:enable-client-state gl:+vertex-array+) + (gl:enable-client-state gl:+texture-coord-array+) + (gl:bind-buffer-arb gl:+array-buffer-arb+ (vertex-buffer-of self)) + (gl:bind-buffer-arb gl:+array-buffer-arb+ (uv-buffer-of self)) + (gl:vertex-pointer 3 gl:+float+ 0 (cffi::null-pointer)) + (gl:tex-coord-pointer 2 gl:+float+ 0 (cffi:null-pointer)) + (gl:draw-arrays gl:+triangles+ 0 (element-count-of self)) + (gl:disable-client-state gl:+texture-coord-array+) + (gl:disable-client-state gl:+vertex-array+) + (gl:disable gl:+blend+)) + +;; (format *debug-io* "Redering ..~%") +;; (glrepl::with-opengl +;; (gl:disable gl:+blend+) +;; (gl:enable gl:+texture-2d+) +;; (gl:bind-texture gl:+texture-2d+ (cffi::mem-ref (name-of (mixamesh:texture-of self)) :uint32)) +;; (gl:tex-env-f gl:+texture-env+ gl:+texture-env-mode+ gl:+decal+) +;; (gl:color-3f 1.0 1.0 1.0) +;; (gl:enable-client-state gl:+vertex-array+) + +;; (gl:bind-buffer-arb gl:+array-buffer-arb+ (vertex-buffer-of self)) +;; (gl:bind-buffer-arb gl:+array-buffer-arb+ (uv-buffer-of self)) +;; (gl:vertex-pointer 3 gl:+float+ 0 (cffi::null-pointer)) + +;; (gl:draw-arrays gl:+triangles+ (element-count-of self) 0) +;; (gl:disable-client-state gl:+vertex-array+) +;; (gl:disable-client-state gl:+texture-coord-array+) +;; (gl:enable gl:+blend+)) +;; )) + +(defmethod destroy ((self compiled-mesh)) + (flet ((delete-buffer (buf) + (let ((buf-array (make-array 1))) + (setf (aref buf-array 0) buf) + (gl:delete-buffers-arb 1 buf-array)))) + (when (vertex-buffer-of self) + (delete-buffer (vertex-buffer-of self)) + (setf (slot-value 'vertex-buffer self) nil)) + (setf (slot-value 'vertex-buffer self) nil) + (when (triangle-buffer-of self) + (delete-buffer (triangle-buffer-of self)) + (setf (slot-value 'triangle-buffer self) nil)))) + + +(defmethod destroy ((self textured-compiled-mesh)) + (flet ((delete-buffer (buf) + (let ((buf-array (make-array 1))) + (setf (aref buf-array 0) buf) + (gl:delete-buffers-arb 1 buf-array)))) + (when (texture-of self) + (destroy-image (texture-of self)) + (setf (texture-of self) nil)) + (when (vertex-buffer-of self) + (delete-buffer (vertex-buffer-of self)) + (setf (slot-value 'vertex-buffer self) nil)))) + +;; (delete-buffer (uv-buffer-of self) +;; ))) diff --git a/npc.lisp b/npc.lisp index ae07922..4a9c4f8 100644 --- a/npc.lisp +++ b/npc.lisp @@ -143,7 +143,7 @@ (with-vertex3d (location-of n) (x y z w) (gl:translate-f x y z)) (gl:scale-f 0.01 0.01 0.01) - (render-npc n) +;; (render-npc n) (render (or (gethash (mesh-of n) mixamesh:*compiled-meshes*) (gethash (mesh-of n) mixamesh:*meshes*))) (let ((aabb (gethash (mesh-of n) mixamesh:*bounding-boxes*))) @@ -153,8 +153,17 @@ (defmethod make-npc (mesh) (let ((result - (make-instance 'npc :location - (make-vertex3d (location-of *turtle*)) - :mesh mesh))) + (make-actor 'npc + :mesh mesh))) result)) - \ No newline at end of file + +(defmethod destroy ((n npc)) + (remhash (mesh-of n) *bounding-boxes*) + (let ((mesh (gethash (mesh-of n) *meshes*)) + (compiled-mesh (gethash (mesh-of n) *compiled-meshes*))) + (when mesh + (destroy mesh) + (remhash (mesh-of n) *meshes*)) + (when compiled-mesh + (remhash (mesh-of n) *compiled-meshes*) + (destroy compiled-mesh)))) \ No newline at end of file diff --git a/turtle.lisp b/turtle.lisp index 450e680..b5d2896 100644 --- a/turtle.lisp +++ b/turtle.lisp @@ -50,6 +50,7 @@ ;; x= red, y =green, z = blue (defmethod render ((a turtle)) +;; (break) (flet ((render-x-axis () ;; x @@ -108,14 +109,6 @@ (render-z-axis)))) -(defun make-turtle (x y z) - (if *turtle* - *turtle* - (let ((result - (make-instance 'turtle))) - (setf (location-of result) (vertex3d* x y z 1.0)) - (setf *turtle* result) - result))) -- 2.11.4.GIT