From 1eea9dbc73a8d3378bd452a28889ec08bf2772ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renaud=20Casenave-P=C3=A9r=C3=A9?= Date: Wed, 22 Oct 2014 10:28:23 +0900 Subject: [PATCH] rewrite mesh.lisp to better handle mesh data The data layout is now fixed and each keyword is associated to a function to construct the data structure with the code add the file to the project --- src/render/gl-utils.lisp | 9 ++- src/render/mesh.lisp | 142 ++++++++++++++++++++++++++++++--------- stoe.asd | 1 + 3 files changed, 118 insertions(+), 34 deletions(-) diff --git a/src/render/gl-utils.lisp b/src/render/gl-utils.lisp index 848cbcc..3cdb811 100644 --- a/src/render/gl-utils.lisp +++ b/src/render/gl-utils.lisp @@ -12,7 +12,8 @@ :initialize :version-supported-p :gl-assert - :gl-restart)) + :gl-restart + :size-of)) (in-package :stoe.render.gl-utils) (defvar *major-version* nil) @@ -44,3 +45,9 @@ Store values like the drivers version." `(restart-case (gl-assert ,form) (continue () :report "Continue"))) + +(defun size-of (type) + (ecase type + (:byte 1) + (:unsigned-short 2) + (:float 4))) diff --git a/src/render/mesh.lisp b/src/render/mesh.lisp index e349b8a..76dfaba 100644 --- a/src/render/mesh.lisp +++ b/src/render/mesh.lisp @@ -1,44 +1,120 @@ #| -This file is a part of stoe project. -Copyright (c) 2014 Renaud Casenave-Péré (renaud@casenave-pere.fr) + This file is a part of stoe project. + Copyright (c) 2014 Renaud Casenave-Péré (renaud@casenave-pere.fr) |# (in-package :cl-user) -(defpackage stoe.mesh +(defpackage stoe.render.mesh (:nicknames :mesh) - (:use :cl)) -(in-package :stoe.mesh) + (:use :cl :utils) + (:export :make-mesh)) +(in-package :stoe.render.mesh) -(defstruct vertex-stream - (name) - (data) - (type) - (size)) +(defstruct attrib + name + type + size + offset) -(defstruct index-stream - (data) - (type) - (mode)) +(defstruct (vertex-buffer (:constructor %make-vertex-buffer)) + data + attribs) + +(defstruct (index-buffer (:constructor %make-index-buffer)) + type + mode + data) + +(defstruct (mesh-stream (:constructor %make-mesh-stream)) + program + vertex-buffer + index-buffer) (defclass mesh () - ((name :initform "") - (index-stream :initform nil :type index-stream) - (vertex-streams :initform nil :type (single-array vertex-stream)))) + ((name :initform "" :reader mesh-name) + (streams :initform nil :reader mesh-streams))) -(defmacro defmesh (name &body body) - (let ((mesh-symbol (gensym))) - `(let ((,mesh-symbol (make-instance 'mesh :name ,(symbol-name name)))) - (with-slots (indices vertices) ,mesh-symbol - ,@(loop while body - collect (let* ((stream (pop body)) - (stream-name (pop stream))) - (if (eq stream-name :index) - `(setf indices (make-index-stream ,@stream)) - `(push (make-vertex-stream :name ,stream-name ,@stream) vertices))))) - ,mesh-symbol))) +(defun make-vertex-buffer (data) + (let ((buffer-data nil) + (buffer-size 0) + (end-offset 0)) + (let* ((attribs (mapcar (lambda (attrib) + (let ((name (first attrib)) + (type (second attrib)) + (size (third attrib)) + (buffer (fourth attrib))) + (prog1 + (make-attrib :name name :type type + :size size :offset end-offset) + (setf buffer-data (cons buffer buffer-data)) + (let ((len (length buffer))) + (incf buffer-size len) + (incf end-offset (* len size (gl-utils:size-of type))))))) + data)) + (vertex-buffer (%make-vertex-buffer :data (make-array buffer-size) :attribs attribs)) + (buffer-index 0)) + (setf buffer-data (nreverse buffer-data)) + (loop for buffer in buffer-data + do (dotimes (i (length buffer)) + (setf (aref (vertex-buffer-data vertex-buffer) buffer-index) (aref buffer i)) + (incf buffer-index))) + vertex-buffer))) -(defun load-mesh (data) - (let ((mesh (make-instance 'mesh :name (getf data :name)))) - (with-slots (index-stream vertex-streams) mesh - (setf index-stream (getf data :index-stream)) - (setf vertex-streams (getf data :vertex-streams))))) +(defun make-index-buffer (data) + (%make-index-buffer :type (first data) :mode (second data) :data (third data))) + +(defun %set-mesh-stream-program (stream symbol) + (setf (mesh-stream-program stream) symbol)) + +(defun %set-mesh-stream-vertex-buffer (stream data) + (setf (mesh-stream-vertex-buffer stream) (make-vertex-buffer data))) + +(defun %set-mesh-stream-index-buffer (stream data) + (setf (mesh-stream-index-buffer stream) (make-index-buffer data))) + +(defun make-mesh-stream (data) + (let ((stream (%make-mesh-stream)) + (alist (group data))) + (mapc (lambda (pair) (apply (intern (concatenate 'string "%SET-MESH-STREAM-" (symbol-name (first pair))) :mesh) + stream (list (second pair)))) + alist) + stream)) + +(defun %set-mesh-name (mesh name) + (setf (slot-value mesh 'name) name)) + +(defun %set-mesh-streams (mesh streams) + (setf (slot-value mesh 'streams) (mapcar 'make-mesh-stream streams))) + +(defun make-mesh (data) + (let ((mesh (make-instance 'mesh)) + (alist (group data))) + (mapc (lambda (pair) (apply (intern (concatenate 'string "%SET-MESH-" (symbol-name (first pair))) :mesh) + mesh (list (second pair)))) + alist) + mesh)) + +;; (defun load-mesh (data) +;; (let ((mesh (make-instance 'mesh :name (getf data :name)))) +;; (with-slots (index-stream vertex-streams material) mesh +;; (setf index-stream (getf (third data) :index-stream)) +;; (setf vertex-streams (getf (third data) :vertex-streams)) +;; (setf material (getf (third data) :material)) +;; ;; (let ((buffers (gl:gen-buffers 2))) +;; ;; (gl:bind-buffer :array-buffer (first buffers)) +;; ;; (gl:with-gl-array arr :float :count (length ))) +;; ) +;; mesh)) + + +;; (defmacro defmesh (name &body body) +;; (let ((mesh-symbol (gensym))) +;; `(let ((,mesh-symbol (make-instance 'mesh :name ,(symbol-name name)))) +;; (with-slots (indices vertices) ,mesh-symbol +;; ,@(loop while body +;; collect (let* ((stream (pop body)) +;; (stream-name (pop stream))) +;; (if (eq stream-name :index) +;; `(setf indices (make-index-stream ,@stream)) +;; `(push (make-vertex-stream :name ,stream-name ,@stream) vertices))))) +;; ,mesh-symbol))) diff --git a/stoe.asd b/stoe.asd index 9f4d81d..4d72c84 100644 --- a/stoe.asd +++ b/stoe.asd @@ -55,6 +55,7 @@ :components ((:file "glsl-compiler") (:file "shader"))) + (:file "mesh") (:file "render")) :depends-on ("modules" "utils")) (:file "stoe"