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
This commit is contained in:
Renaud Casenave-Péré 2014-10-22 10:28:23 +09:00
parent b5f5641d05
commit 1eea9dbc73
3 changed files with 118 additions and 34 deletions

View file

@ -12,7 +12,8 @@
:initialize :initialize
:version-supported-p :version-supported-p
:gl-assert :gl-assert
:gl-restart)) :gl-restart
:size-of))
(in-package :stoe.render.gl-utils) (in-package :stoe.render.gl-utils)
(defvar *major-version* nil) (defvar *major-version* nil)
@ -44,3 +45,9 @@ Store values like the drivers version."
`(restart-case `(restart-case
(gl-assert ,form) (gl-assert ,form)
(continue () :report "Continue"))) (continue () :report "Continue")))
(defun size-of (type)
(ecase type
(:byte 1)
(:unsigned-short 2)
(:float 4)))

View file

@ -1,44 +1,120 @@
#| #|
This file is a part of stoe project. This file is a part of stoe project.
Copyright (c) 2014 Renaud Casenave-Péré (renaud@casenave-pere.fr) Copyright (c) 2014 Renaud Casenave-Péré (renaud@casenave-pere.fr)
|# |#
(in-package :cl-user) (in-package :cl-user)
(defpackage stoe.mesh (defpackage stoe.render.mesh
(:nicknames :mesh) (:nicknames :mesh)
(:use :cl)) (:use :cl :utils)
(in-package :stoe.mesh) (:export :make-mesh))
(in-package :stoe.render.mesh)
(defstruct vertex-stream (defstruct attrib
(name) name
(data) type
(type) size
(size)) offset)
(defstruct index-stream (defstruct (vertex-buffer (:constructor %make-vertex-buffer))
(data) data
(type) attribs)
(mode))
(defstruct (index-buffer (:constructor %make-index-buffer))
type
mode
data)
(defstruct (mesh-stream (:constructor %make-mesh-stream))
program
vertex-buffer
index-buffer)
(defclass mesh () (defclass mesh ()
((name :initform "") ((name :initform "" :reader mesh-name)
(index-stream :initform nil :type index-stream) (streams :initform nil :reader mesh-streams)))
(vertex-streams :initform nil :type (single-array vertex-stream))))
(defmacro defmesh (name &body body) (defun make-vertex-buffer (data)
(let ((mesh-symbol (gensym))) (let ((buffer-data nil)
`(let ((,mesh-symbol (make-instance 'mesh :name ,(symbol-name name)))) (buffer-size 0)
(with-slots (indices vertices) ,mesh-symbol (end-offset 0))
,@(loop while body (let* ((attribs (mapcar (lambda (attrib)
collect (let* ((stream (pop body)) (let ((name (first attrib))
(stream-name (pop stream))) (type (second attrib))
(if (eq stream-name :index) (size (third attrib))
`(setf indices (make-index-stream ,@stream)) (buffer (fourth attrib)))
`(push (make-vertex-stream :name ,stream-name ,@stream) vertices))))) (prog1
,mesh-symbol))) (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) (defun make-index-buffer (data)
(let ((mesh (make-instance 'mesh :name (getf data :name)))) (%make-index-buffer :type (first data) :mode (second data) :data (third data)))
(with-slots (index-stream vertex-streams) mesh
(setf index-stream (getf data :index-stream)) (defun %set-mesh-stream-program (stream symbol)
(setf vertex-streams (getf data :vertex-streams))))) (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)))

View file

@ -55,6 +55,7 @@
:components :components
((:file "glsl-compiler") ((:file "glsl-compiler")
(:file "shader"))) (:file "shader")))
(:file "mesh")
(:file "render")) (:file "render"))
:depends-on ("modules" "utils")) :depends-on ("modules" "utils"))
(:file "stoe" (:file "stoe"