fix the render module to use the scene graph defined in game module
Modify the mesh class to use a foreign array for the vertex and index streams to pass to opengl, but the memory is not yet properly managed. Add a function to render each node in the scene graph when it finds a mesh component.
This commit is contained in:
parent
d4fd7ecc55
commit
764baddb3c
5 changed files with 141 additions and 9 deletions
|
|
@ -11,19 +11,22 @@
|
||||||
(in-package :stoe.render.mesh)
|
(in-package :stoe.render.mesh)
|
||||||
|
|
||||||
(defstruct attrib
|
(defstruct attrib
|
||||||
name
|
(name "")
|
||||||
type
|
type
|
||||||
size
|
size
|
||||||
offset)
|
offset)
|
||||||
|
|
||||||
(defstruct (vertex-buffer (:constructor %make-vertex-buffer))
|
(defstruct (vertex-buffer (:constructor %make-vertex-buffer))
|
||||||
data
|
data
|
||||||
attribs)
|
attribs
|
||||||
|
buffer-object)
|
||||||
|
|
||||||
(defstruct (index-buffer (:constructor %make-index-buffer))
|
(defstruct (index-buffer (:constructor %make-index-buffer))
|
||||||
type
|
type
|
||||||
mode
|
mode
|
||||||
data)
|
size
|
||||||
|
data
|
||||||
|
buffer-object)
|
||||||
|
|
||||||
(defstruct (mesh-stream (:constructor %make-mesh-stream))
|
(defstruct (mesh-stream (:constructor %make-mesh-stream))
|
||||||
program
|
program
|
||||||
|
|
@ -44,12 +47,12 @@
|
||||||
(size (third attrib))
|
(size (third attrib))
|
||||||
(buffer (fourth attrib)))
|
(buffer (fourth attrib)))
|
||||||
(prog1
|
(prog1
|
||||||
(make-attrib :name name :type type
|
(make-attrib :name (symbol-name name) :type type
|
||||||
:size size :offset end-offset)
|
:size size :offset end-offset)
|
||||||
(setf buffer-data (cons buffer buffer-data))
|
(setf buffer-data (cons buffer buffer-data))
|
||||||
(let ((len (length buffer)))
|
(let ((len (length buffer)))
|
||||||
(incf buffer-size len)
|
(incf buffer-size len)
|
||||||
(incf end-offset (* len size (gl-utils:size-of type)))))))
|
(incf end-offset (* len (gl-utils:size-of type)))))))
|
||||||
data))
|
data))
|
||||||
(vertex-buffer (%make-vertex-buffer :data (make-array buffer-size) :attribs attribs))
|
(vertex-buffer (%make-vertex-buffer :data (make-array buffer-size) :attribs attribs))
|
||||||
(buffer-index 0))
|
(buffer-index 0))
|
||||||
|
|
@ -58,10 +61,27 @@
|
||||||
do (dotimes (i (length buffer))
|
do (dotimes (i (length buffer))
|
||||||
(setf (aref (vertex-buffer-data vertex-buffer) buffer-index) (aref buffer i))
|
(setf (aref (vertex-buffer-data vertex-buffer) buffer-index) (aref buffer i))
|
||||||
(incf buffer-index)))
|
(incf buffer-index)))
|
||||||
|
(setf (vertex-buffer-buffer-object vertex-buffer) (first (gl:gen-buffers 1)))
|
||||||
|
(let ((ptr (cffi:foreign-alloc :float :initial-contents (vertex-buffer-data vertex-buffer) :count end-offset)))
|
||||||
|
(gl:bind-buffer :array-buffer (vertex-buffer-buffer-object vertex-buffer))
|
||||||
|
(%gl:buffer-data :array-buffer end-offset ptr :static-draw)
|
||||||
|
(gl:bind-buffer :array-buffer 0)
|
||||||
|
(cffi:foreign-free ptr))
|
||||||
vertex-buffer)))
|
vertex-buffer)))
|
||||||
|
|
||||||
(defun make-index-buffer (data)
|
(defun make-index-buffer (data)
|
||||||
(%make-index-buffer :type (first data) :mode (second data) :data (third data)))
|
(let ((type (first data))
|
||||||
|
(mode (second data))
|
||||||
|
(size (length (third data)))
|
||||||
|
(data (third data)))
|
||||||
|
(let ((index-buffer (%make-index-buffer :type type :mode mode :size size :data data)))
|
||||||
|
(setf (index-buffer-buffer-object index-buffer) (first (gl:gen-buffers 1)))
|
||||||
|
(let ((ptr (cffi:foreign-alloc type :initial-contents data :count size)))
|
||||||
|
(gl:bind-buffer :element-array-buffer (index-buffer-buffer-object index-buffer))
|
||||||
|
(%gl:buffer-data :element-array-buffer (* size (gl-utils:size-of type)) ptr :static-draw)
|
||||||
|
(gl:bind-buffer :element-array-buffer 0)
|
||||||
|
(cffi:foreign-free ptr))
|
||||||
|
index-buffer)))
|
||||||
|
|
||||||
(defun %set-mesh-stream-program (stream symbol)
|
(defun %set-mesh-stream-program (stream symbol)
|
||||||
(setf (mesh-stream-program stream) symbol))
|
(setf (mesh-stream-program stream) symbol))
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,10 @@ Destroy the opengl context and the related resources."
|
||||||
"Update the render module.
|
"Update the render module.
|
||||||
Render a frame and swap buffers."
|
Render a frame and swap buffers."
|
||||||
(declare (ignore delta-time))
|
(declare (ignore delta-time))
|
||||||
(gl:clear-color 0.0 0 0 0)
|
(gl:clear-color 0 0 0 0)
|
||||||
(gl:clear-depth 1.0)
|
(gl:clear-depth 1.0)
|
||||||
(gl:clear :color-buffer-bit :depth-buffer-bit)
|
(gl:clear :color-buffer-bit :depth-buffer-bit)
|
||||||
|
(render-scene (game:get-world-origin))
|
||||||
(glop:swap-buffers *window*))
|
(glop:swap-buffers *window*))
|
||||||
|
|
||||||
(modules:register-initialize-fun #'initialize)
|
(modules:register-initialize-fun #'initialize)
|
||||||
|
|
@ -71,3 +72,46 @@ This needs to be called once per frame, at the beginning of the loop."
|
||||||
|
|
||||||
(defmethod glop:on-event (window event)
|
(defmethod glop:on-event (window event)
|
||||||
(declare (ignore window event)))
|
(declare (ignore window event)))
|
||||||
|
|
||||||
|
(defun render-mesh (node mesh)
|
||||||
|
"Render a single mesh."
|
||||||
|
(loop for stream in (mesh::mesh-streams mesh)
|
||||||
|
do (shader::using-program (program (mesh::mesh-stream-program stream))
|
||||||
|
(shader::with-uniforms (model-to-camera camera-to-clip) program
|
||||||
|
(gl:uniform-matrix model-to-camera 4 (vector (m:* (go::view (game:get-current-camera))
|
||||||
|
(go::trans-matrix node))))
|
||||||
|
(gl:uniform-matrix camera-to-clip 4 (vector (go::projection (game:get-current-camera)))))
|
||||||
|
(let* ((vertex-buffer (mesh::mesh-stream-vertex-buffer stream))
|
||||||
|
(index-buffer (mesh::mesh-stream-index-buffer stream))
|
||||||
|
(attribs (mesh::vertex-buffer-attribs vertex-buffer)))
|
||||||
|
(gl:bind-buffer :array-buffer (mesh::vertex-buffer-buffer-object vertex-buffer))
|
||||||
|
(loop for attrib in attribs
|
||||||
|
do (let* ((attrib-name (mesh::attrib-name attrib))
|
||||||
|
(attrib-loc (shader::get-attrib-location program attrib-name)))
|
||||||
|
(gl-utils:gl-assert (gl:enable-vertex-attrib-array attrib-loc))
|
||||||
|
(gl-utils:gl-assert (gl:vertex-attrib-pointer attrib-loc (mesh::attrib-size attrib)
|
||||||
|
(mesh::attrib-type attrib) :false 0
|
||||||
|
(mesh::attrib-offset attrib)))))
|
||||||
|
(gl:bind-buffer :element-array-buffer (mesh::index-buffer-buffer-object index-buffer))
|
||||||
|
(gl-utils:gl-assert (%gl:draw-elements (mesh::index-buffer-mode index-buffer)
|
||||||
|
(mesh::index-buffer-size index-buffer)
|
||||||
|
(mesh::index-buffer-type index-buffer) 0))
|
||||||
|
(gl:disable-vertex-attrib-array 0)
|
||||||
|
(gl:bind-buffer :element-array-buffer 0)
|
||||||
|
(gl:bind-buffer :array-buffer 0)))))
|
||||||
|
|
||||||
|
(defun render-node (node)
|
||||||
|
"Render a single node."
|
||||||
|
(with-slots ((components go::components)) node
|
||||||
|
(let ((mesh (car (member-if (lambda (c) (typep c 'mesh::mesh)) components))))
|
||||||
|
(when mesh
|
||||||
|
(render-mesh node mesh)))))
|
||||||
|
|
||||||
|
(defun render-scene (node)
|
||||||
|
"Walk the scene graph and render the graphical components."
|
||||||
|
(with-slots ((children go::children)) node
|
||||||
|
(loop for child in children
|
||||||
|
do (progn
|
||||||
|
(go:update-trans-matrix child)
|
||||||
|
(render-node child)
|
||||||
|
(render-scene child)))))
|
||||||
|
|
|
||||||
|
|
@ -136,10 +136,47 @@ Retrieve the attributes and uniform locations."
|
||||||
(format t "~%")
|
(format t "~%")
|
||||||
(setf i 0))
|
(setf i 0))
|
||||||
(format t ".")
|
(format t ".")
|
||||||
(compile-program program-symbol)))))
|
(compile-program program-symbol)))
|
||||||
|
(format t "~%")))
|
||||||
|
|
||||||
(defun destroy-all-shaders ()
|
(defun destroy-all-shaders ()
|
||||||
"Destroy the programs registered in opengl."
|
"Destroy the programs registered in opengl."
|
||||||
(format t "Deleting shaders")
|
(format t "Deleting shaders")
|
||||||
(loop for program-symbol being the symbol in :%stoe.shaders
|
(loop for program-symbol being the symbol in :%stoe.shaders
|
||||||
do (delete-program program-symbol)))
|
do (delete-program program-symbol)))
|
||||||
|
|
||||||
|
(defun get-attrib-location (program symbol)
|
||||||
|
(fourth (first (member symbol (program-attribs program) :key #'car :test #'equal))))
|
||||||
|
|
||||||
|
(defmacro using-program ((var program) &body body)
|
||||||
|
"Use the specified program and bind all its attributes and uniform for use in `body'."
|
||||||
|
`(let ((,var (symbol-value (find-symbol (symbol-name ,program) :%stoe.shaders))))
|
||||||
|
(gl-utils:gl-assert (gl:use-program (program-gl-program ,var)))
|
||||||
|
,@body
|
||||||
|
(gl-utils:gl-assert (gl:use-program 0))))
|
||||||
|
|
||||||
|
(defmacro with-uniforms (vars program &body body)
|
||||||
|
`(let ,(mapcar (lambda (var)
|
||||||
|
(cond
|
||||||
|
((listp var) (list (first var)
|
||||||
|
`(fourth (first (member (symbol-name ',(second var))
|
||||||
|
(program-uniforms ,program)
|
||||||
|
:key #'car :test #'equal)))))
|
||||||
|
((symbolp var) (list var `(fourth (first (member (symbol-name ',var)
|
||||||
|
(program-uniforms ,program)
|
||||||
|
:key #'car :test #'equal)))))))
|
||||||
|
vars)
|
||||||
|
,@body))
|
||||||
|
|
||||||
|
(defmacro with-attribs (vars program &body body)
|
||||||
|
`(let ,(mapcar (lambda (var)
|
||||||
|
(cond
|
||||||
|
((listp var) (list (first var)
|
||||||
|
`(fourth (first (member (symbol-name ',(second var))
|
||||||
|
(program-attribs ,program)
|
||||||
|
:key #'car :test #'equal)))))
|
||||||
|
((symbolp var) (list var `(fourth (first (member (symbol-name ',var)
|
||||||
|
(program-attribs ,program)
|
||||||
|
:key #'car :test #'equal)))))))
|
||||||
|
vars)
|
||||||
|
,@body))
|
||||||
|
|
|
||||||
30
src/render/shaders.lisp
Normal file
30
src/render/shaders.lisp
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#|
|
||||||
|
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.render.shaders
|
||||||
|
(:nicknames :shaders)
|
||||||
|
(:use :cl
|
||||||
|
:shader))
|
||||||
|
(in-package :stoe.render.shaders)
|
||||||
|
|
||||||
|
(defshader simple-vertex (:version 330
|
||||||
|
:in ((position :vec4 :location 0)
|
||||||
|
(color :vec4 :location 1))
|
||||||
|
:out ((out-color :vec4 :interp :smooth))
|
||||||
|
:uniform ((camera-to-clip :mat4)
|
||||||
|
(model-to-camera :mat4))
|
||||||
|
)
|
||||||
|
"gl_Position = camera_to_clip * model_to_camera * position;
|
||||||
|
out_color = color;")
|
||||||
|
|
||||||
|
(defshader simple-fragment (:version 330
|
||||||
|
:in ((out-color :vec4))
|
||||||
|
:out ((frag-color :vec4)))
|
||||||
|
"frag_color = out_color;")
|
||||||
|
|
||||||
|
(defprogram simple-shader ()
|
||||||
|
:vertex-shader simple-vertex
|
||||||
|
:fragment-shader simple-fragment)
|
||||||
3
stoe.asd
3
stoe.asd
|
|
@ -61,7 +61,8 @@
|
||||||
((:file "glsl-compiler")
|
((:file "glsl-compiler")
|
||||||
(:file "shader")))
|
(:file "shader")))
|
||||||
(:file "mesh")
|
(:file "mesh")
|
||||||
(:file "render"))
|
(:file "render")
|
||||||
|
(:file "shaders"))
|
||||||
:depends-on ("modules" "utils"))
|
:depends-on ("modules" "utils"))
|
||||||
(:file "stoe"
|
(:file "stoe"
|
||||||
:depends-on ("utils" "modules")))))
|
:depends-on ("utils" "modules")))))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue