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)
|
||||
|
||||
(defstruct attrib
|
||||
name
|
||||
(name "")
|
||||
type
|
||||
size
|
||||
offset)
|
||||
|
||||
(defstruct (vertex-buffer (:constructor %make-vertex-buffer))
|
||||
data
|
||||
attribs)
|
||||
attribs
|
||||
buffer-object)
|
||||
|
||||
(defstruct (index-buffer (:constructor %make-index-buffer))
|
||||
type
|
||||
mode
|
||||
data)
|
||||
size
|
||||
data
|
||||
buffer-object)
|
||||
|
||||
(defstruct (mesh-stream (:constructor %make-mesh-stream))
|
||||
program
|
||||
|
|
@ -44,12 +47,12 @@
|
|||
(size (third attrib))
|
||||
(buffer (fourth attrib)))
|
||||
(prog1
|
||||
(make-attrib :name name :type type
|
||||
(make-attrib :name (symbol-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)))))))
|
||||
(incf end-offset (* len (gl-utils:size-of type)))))))
|
||||
data))
|
||||
(vertex-buffer (%make-vertex-buffer :data (make-array buffer-size) :attribs attribs))
|
||||
(buffer-index 0))
|
||||
|
|
@ -58,10 +61,27 @@
|
|||
do (dotimes (i (length buffer))
|
||||
(setf (aref (vertex-buffer-data vertex-buffer) buffer-index) (aref buffer i))
|
||||
(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)))
|
||||
|
||||
(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)
|
||||
(setf (mesh-stream-program stream) symbol))
|
||||
|
|
|
|||
|
|
@ -54,9 +54,10 @@ Destroy the opengl context and the related resources."
|
|||
"Update the render module.
|
||||
Render a frame and swap buffers."
|
||||
(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 :color-buffer-bit :depth-buffer-bit)
|
||||
(render-scene (game:get-world-origin))
|
||||
(glop:swap-buffers *window*))
|
||||
|
||||
(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)
|
||||
(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 "~%")
|
||||
(setf i 0))
|
||||
(format t ".")
|
||||
(compile-program program-symbol)))))
|
||||
(compile-program program-symbol)))
|
||||
(format t "~%")))
|
||||
|
||||
(defun destroy-all-shaders ()
|
||||
"Destroy the programs registered in opengl."
|
||||
(format t "Deleting shaders")
|
||||
(loop for program-symbol being the symbol in :%stoe.shaders
|
||||
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 "shader")))
|
||||
(:file "mesh")
|
||||
(:file "render"))
|
||||
(:file "render")
|
||||
(:file "shaders"))
|
||||
:depends-on ("modules" "utils"))
|
||||
(:file "stoe"
|
||||
:depends-on ("utils" "modules")))))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue