From 8d6944a867d45717aeeea686dc9b525202cd5a9f Mon Sep 17 00:00:00 2001 From: John Connors Date: Sat, 23 Aug 2008 21:21:00 +0100 Subject: [PATCH] Compiled meshes work --- lambdamundo-test.lisp | 29 +++++++++++++ main.lisp | 31 ++++++++++++-- mesh-compiler.lisp | 75 ++++++++++++++++++++++++++++++++ npc.lisp | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 lambdamundo-test.lisp create mode 100644 mesh-compiler.lisp create mode 100644 npc.lisp diff --git a/lambdamundo-test.lisp b/lambdamundo-test.lisp new file mode 100644 index 0000000..ba1991e --- /dev/null +++ b/lambdamundo-test.lisp @@ -0,0 +1,29 @@ + + + +(in-package :lambdamundo) + +(make-turtle 1.5 1.5 0.0) + +(defparameter *dalek-mesh* (mixamesh:make-mesh 'mixamesh:simple-mesh)) + +(defparameter *compiled-dalek-mesh* nil) ;; (mixamesh:mesh-compile *dalek-mesh*)) + +;; (one-shot-compile #P"mesh-compiler.lisp") + +(defparameter *dalek* nil) + +(defparameter *dalek-md2* + (setf *dalek* + (with-open-file + (dalek-md2 + (merge-pathnames #P"dalekx/tris.md2") + :direction :input + :element-type '(unsigned-byte 8)) + (lodematron:parse-md2-file dalek-md2)))) + +(lodematron::pose *dalek-md2* (gethash *dalek-mesh* *meshes*) "stand16" "someskin") + +(one-shot (setf *compiled-dalek-mesh* (mixamesh::compile-mesh *dalek-mesh*))) + +(defparameter *dalek-actor* (make-npc *dalek-mesh*)) \ No newline at end of file diff --git a/main.lisp b/main.lisp index 963227c..816797a 100644 --- a/main.lisp +++ b/main.lisp @@ -50,7 +50,10 @@ (glrepl::render-string (format nil "Camera pos ~A " (multiple-value-list (position-of *camera*))) 0 21) (glrepl::render-string - (format nil "Swank connections ~A" swank::*connections*) 0 22)) + (format nil "Swank connections ~A" swank::*connections*) 0 22) + (glrepl::render-string + (format nil "Vendor ~A " (gl:get-string gl:+vendor+)) 0 19)) + (cffi:defcallback lambdamundo-mouse-wheel-callback :void ((pos :int)) (setf *mouse-wheel-delta* (- pos *mouse-wheel-pos*)) @@ -160,6 +163,20 @@ (move *camera* 0.0 (* *mouse-wheel-delta* dt)) (setf *mouse-wheel-changed* nil))) +(defmacro one-shot (&rest forms) + `(setf *one-shot-fn* #'(lambda () ,@forms))) + +(defmacro one-shot-compile (pathname) + `(setf *one-shot-fn* #'(lambda () + (multiple-value-bind + (output-file warnings-p failure-p) + (compile-file (merge-pathnames ,pathname) :verbose t :print t) + (declare (ignore warnings-p)) + (when (not failure-p) + (load output-file :print t)))))) + +(defparameter *one-shot-fn* nil) + ;; main routine ------------------- (defun main-loop () (let ((t0 (coerce (glfw:get-time) 'single-float)) @@ -183,6 +200,9 @@ (render-world) (when glrepl:*console* (glrepl:render-console)) + (when *one-shot-fn* + (funcall *one-shot-fn*) + (setf *one-shot-fn* nil)) ;; update ;; check for time available if time is avaliable render ;; surrender any cpu time.. @@ -194,7 +214,7 @@ (format t "Please fire up your emacs and connect!~%") (iterate (while (zerop (length swank::*connections*))) - (cl:sleep 1)))) + (cl:sleep 0.1)))) (defun end-swank () (when (not (zerop (length swank::*connections*))) @@ -209,7 +229,7 @@ ;; -(defparameter *dalek* nil) + ;; (defun lambdamundo () @@ -218,7 +238,7 @@ (setf glrepl:*glwindow* (make-instance 'glrepl-window)) (add-line glrepl:*glwindow*) (add-line glrepl:*glwindow*) - (add-string glrepl:*glwindow* "(format nil \"Hello World\")") + (add-string glrepl:*glwindow* "(one-shot-compile #P\"mesh-compiler.lisp\"") (if (glfw:open-window (win-width-of *glwindow*) (win-height-of *glwindow*) @@ -231,6 +251,9 @@ (format t "Making font..") (setf (font-of glrepl:*glwindow*) (make-font (merge-pathnames #P"VeraMono.ttf")));; prbly shld be mber of window (format t "Done..") + (gl-ext:load-extension "ARB_vertex_program") + (gl-ext:load-extension "ARB_vertex_buffer_object") + (one-shot-compile #P"mesh-compiler.lisp") (glfw:swap-interval 1) (glfw:enable glfw:+key-repeat+) (callback-set) diff --git a/mesh-compiler.lisp b/mesh-compiler.lisp new file mode 100644 index 0000000..f915cde --- /dev/null +++ b/mesh-compiler.lisp @@ -0,0 +1,75 @@ + + + +(in-package :mixamesh) + + + +;; as this uses extensions it has to be compiled and loaded with an active gl context +(defun compile-mesh (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)) + (let ((self (gethash mesh *meshes*))) + (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) + (setf (gethash mesh *compiled-meshes*) self)))))) + +(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 0) + (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+)) + diff --git a/npc.lisp b/npc.lisp new file mode 100644 index 0000000..5fdcc50 --- /dev/null +++ b/npc.lisp @@ -0,0 +1,115 @@ + + +(in-package :lambdamundo) + +(defclass npc (actor) + ((mesh :initarg :mesh :accessor mesh-of))) + + +;; simple rendering method for debugging +(defmethod render ((self mixamesh:simple-mesh)) +;; (break) + (iterate + (for (values a b c) in-triangles (faces-of self)) + (with-vertex3d-aref + ((vertices-of self) a + (ax ay az aw)) + (with-vertex3d-aref + ((vertices-of self) b + (bx by bz bw)) + (with-vertex3d-aref + ((vertices-of self) c + (cx cy cz cw)) + (gl:with-begin gl:+lines+ + (gl:vertex-3f ax ay az) + (gl:vertex-3f bx by bz) + (gl:vertex-3f bx by bz) + (gl:vertex-3f cx cy cz) + (gl:vertex-3f cx cy cz) + (gl:vertex-3f ax ay az))))))) + +(defun render-npc (a) + (flet + ((render-x-axis () + ;; x + (gl:color-3f 1.0 0.0 0.0) + (with-vertex3d + (location-of a) + (x y z w) + (gl:vertex-3f x y z)) + (with-vector3d + (vector3d-sum + (vertex3d-vector3d + (location-of a)) + (cross-of a)) + (x y z) + (gl:vertex-3f x y z))) + + (render-y-axis () + ;; y + (gl:color-3f 0.0 1.0 0.0) + (with-vertex3d + (location-of a) + (x y z w) + (gl:vertex-3f x y z)) + (with-vector3d + (vector3d-sum + (vertex3d-vector3d + (location-of a)) + (up-of a)) + (x y z) + (gl:vertex-3f x y z))) + + + (render-z-axis () + ;; z + (gl:color-3f 0.0 0.0 1.0) + (with-vertex3d + (location-of a) + (x y z w) + (gl:vertex-3f x y z)) + (with-vector3d + (vector3d-sum + (vertex3d-vector3d + (location-of a)) + (direction-of a)) + (x y z) + (gl:vertex-3f x y z)))) + + + (gl:with-begin gl:+lines+ + (render-x-axis) + (render-y-axis) + (render-z-axis)))) + + +(let ((modelview-matrix (new-matrix44))) + (defmethod render ((n npc)) + (flet ((npc-modelview-matrix () + (gl:matrix-mode gl:+modelview+) + (gl:load-matrix-f + (setf modelview-matrix + (make-matrix44 + (transpose-matrix44 + (with-vertex3d + (location-of n) + (x y z w) + (translation-matrix44 x y z)))))))) +;; (npc-modelview-matrix) + (gl:matrix-mode gl:+modelview+) + (gl:push-matrix) + (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 (or (gethash (mesh-of n) mixamesh:*compiled-meshes*) + (gethash (mesh-of n) mixamesh:*meshes*))) + (gl:pop-matrix)))) + +(defmethod make-npc (mesh) + (let ((result + (make-instance 'npc :location + (make-vertex3d (location-of *turtle*)) + :mesh mesh))) + result)) + \ No newline at end of file -- 2.11.4.GIT