Use the renderer to show some meshes
Create some classes to store the mesh data streams and adapt the import file accordingly. Add object and camera classes to be manipulated by the game. Render the meshes in the graph scene using only position vertex stream and an unicolor shader. Also add some models and a startup package to ease testing.
This commit is contained in:
parent
ae6ce45c53
commit
0a5d24fe3e
13 changed files with 982 additions and 258 deletions
524
data/TieFighter.dae
Normal file
524
data/TieFighter.dae
Normal file
File diff suppressed because one or more lines are too long
199
data/cube.dae
Normal file
199
data/cube.dae
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
|
||||
<asset>
|
||||
<contributor>
|
||||
<author>Blender User</author>
|
||||
<authoring_tool>Blender 2.75.0 commit date:2015-07-07, commit time:14:56, hash:c27589e</authoring_tool>
|
||||
</contributor>
|
||||
<created>2015-08-19T17:43:33</created>
|
||||
<modified>2015-08-19T17:43:33</modified>
|
||||
<unit name="meter" meter="1"/>
|
||||
<up_axis>Z_UP</up_axis>
|
||||
</asset>
|
||||
<library_cameras>
|
||||
<camera id="Camera-camera" name="Camera">
|
||||
<optics>
|
||||
<technique_common>
|
||||
<perspective>
|
||||
<xfov sid="xfov">49.13434</xfov>
|
||||
<aspect_ratio>1.777778</aspect_ratio>
|
||||
<znear sid="znear">0.1</znear>
|
||||
<zfar sid="zfar">100</zfar>
|
||||
</perspective>
|
||||
</technique_common>
|
||||
</optics>
|
||||
<extra>
|
||||
<technique profile="blender">
|
||||
<YF_dofdist>0</YF_dofdist>
|
||||
<shiftx>0</shiftx>
|
||||
<shifty>0</shifty>
|
||||
</technique>
|
||||
</extra>
|
||||
</camera>
|
||||
</library_cameras>
|
||||
<library_lights>
|
||||
<light id="Lamp-light" name="Lamp">
|
||||
<technique_common>
|
||||
<point>
|
||||
<color sid="color">1 1 1</color>
|
||||
<constant_attenuation>1</constant_attenuation>
|
||||
<linear_attenuation>0</linear_attenuation>
|
||||
<quadratic_attenuation>0.00111109</quadratic_attenuation>
|
||||
</point>
|
||||
</technique_common>
|
||||
<extra>
|
||||
<technique profile="blender">
|
||||
<adapt_thresh>0.000999987</adapt_thresh>
|
||||
<area_shape>1</area_shape>
|
||||
<area_size>0.1</area_size>
|
||||
<area_sizey>0.1</area_sizey>
|
||||
<area_sizez>1</area_sizez>
|
||||
<atm_distance_factor>1</atm_distance_factor>
|
||||
<atm_extinction_factor>1</atm_extinction_factor>
|
||||
<atm_turbidity>2</atm_turbidity>
|
||||
<att1>0</att1>
|
||||
<att2>1</att2>
|
||||
<backscattered_light>1</backscattered_light>
|
||||
<bias>1</bias>
|
||||
<blue>1</blue>
|
||||
<buffers>1</buffers>
|
||||
<bufflag>0</bufflag>
|
||||
<bufsize>2880</bufsize>
|
||||
<buftype>2</buftype>
|
||||
<clipend>30.002</clipend>
|
||||
<clipsta>1.000799</clipsta>
|
||||
<compressthresh>0.04999995</compressthresh>
|
||||
<dist sid="blender_dist">29.99998</dist>
|
||||
<energy sid="blender_energy">1</energy>
|
||||
<falloff_type>2</falloff_type>
|
||||
<filtertype>0</filtertype>
|
||||
<flag>0</flag>
|
||||
<gamma sid="blender_gamma">1</gamma>
|
||||
<green>1</green>
|
||||
<halo_intensity sid="blnder_halo_intensity">1</halo_intensity>
|
||||
<horizon_brightness>1</horizon_brightness>
|
||||
<mode>8192</mode>
|
||||
<ray_samp>1</ray_samp>
|
||||
<ray_samp_method>1</ray_samp_method>
|
||||
<ray_samp_type>0</ray_samp_type>
|
||||
<ray_sampy>1</ray_sampy>
|
||||
<ray_sampz>1</ray_sampz>
|
||||
<red>1</red>
|
||||
<samp>3</samp>
|
||||
<shadhalostep>0</shadhalostep>
|
||||
<shadow_b sid="blender_shadow_b">0</shadow_b>
|
||||
<shadow_g sid="blender_shadow_g">0</shadow_g>
|
||||
<shadow_r sid="blender_shadow_r">0</shadow_r>
|
||||
<sky_colorspace>0</sky_colorspace>
|
||||
<sky_exposure>1</sky_exposure>
|
||||
<skyblendfac>1</skyblendfac>
|
||||
<skyblendtype>1</skyblendtype>
|
||||
<soft>3</soft>
|
||||
<spotblend>0.15</spotblend>
|
||||
<spotsize>75</spotsize>
|
||||
<spread>1</spread>
|
||||
<sun_brightness>1</sun_brightness>
|
||||
<sun_effect_type>0</sun_effect_type>
|
||||
<sun_intensity>1</sun_intensity>
|
||||
<sun_size>1</sun_size>
|
||||
<type>0</type>
|
||||
</technique>
|
||||
</extra>
|
||||
</light>
|
||||
</library_lights>
|
||||
<library_images/>
|
||||
<library_effects>
|
||||
<effect id="Material-effect">
|
||||
<profile_COMMON>
|
||||
<technique sid="common">
|
||||
<phong>
|
||||
<emission>
|
||||
<color sid="emission">0 0 0 1</color>
|
||||
</emission>
|
||||
<ambient>
|
||||
<color sid="ambient">0 0 0 1</color>
|
||||
</ambient>
|
||||
<diffuse>
|
||||
<color sid="diffuse">0.64 0.64 0.64 1</color>
|
||||
</diffuse>
|
||||
<specular>
|
||||
<color sid="specular">0.5 0.5 0.5 1</color>
|
||||
</specular>
|
||||
<shininess>
|
||||
<float sid="shininess">50</float>
|
||||
</shininess>
|
||||
<index_of_refraction>
|
||||
<float sid="index_of_refraction">1</float>
|
||||
</index_of_refraction>
|
||||
</phong>
|
||||
</technique>
|
||||
</profile_COMMON>
|
||||
</effect>
|
||||
</library_effects>
|
||||
<library_materials>
|
||||
<material id="Material-material" name="Material">
|
||||
<instance_effect url="#Material-effect"/>
|
||||
</material>
|
||||
</library_materials>
|
||||
<library_geometries>
|
||||
<geometry id="Cube-mesh" name="Cube">
|
||||
<mesh>
|
||||
<source id="Cube-mesh-positions">
|
||||
<float_array id="Cube-mesh-positions-array" count="24">1 1 -1 1 -1 -1 -1 -0.9999998 -1 -0.9999997 1 -1 1 0.9999995 1 0.9999994 -1.000001 1 -1 -0.9999997 1 -1 1 1</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Cube-mesh-positions-array" count="8" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<source id="Cube-mesh-normals">
|
||||
<float_array id="Cube-mesh-normals-array" count="36">0 0 -1 0 0 1 1 -5.96046e-7 3.27825e-7 -4.76837e-7 -1 0 -1 2.38419e-7 -1.19209e-7 2.08616e-7 1 0 0 0 -1 0 0 1 1 0 -2.38419e-7 0 -1 -4.76837e-7 -1 2.38419e-7 -1.49012e-7 2.68221e-7 1 2.38419e-7</float_array>
|
||||
<technique_common>
|
||||
<accessor source="#Cube-mesh-normals-array" count="12" stride="3">
|
||||
<param name="X" type="float"/>
|
||||
<param name="Y" type="float"/>
|
||||
<param name="Z" type="float"/>
|
||||
</accessor>
|
||||
</technique_common>
|
||||
</source>
|
||||
<vertices id="Cube-mesh-vertices">
|
||||
<input semantic="POSITION" source="#Cube-mesh-positions"/>
|
||||
</vertices>
|
||||
<polylist material="Material-material" count="12">
|
||||
<input semantic="VERTEX" source="#Cube-mesh-vertices" offset="0"/>
|
||||
<input semantic="NORMAL" source="#Cube-mesh-normals" offset="1"/>
|
||||
<vcount>3 3 3 3 3 3 3 3 3 3 3 3 </vcount>
|
||||
<p>0 0 1 0 2 0 7 1 6 1 5 1 4 2 5 2 1 2 5 3 6 3 2 3 2 4 6 4 7 4 0 5 3 5 7 5 3 6 0 6 2 6 4 7 7 7 5 7 0 8 4 8 1 8 1 9 5 9 2 9 3 10 2 10 7 10 4 11 0 11 7 11</p>
|
||||
</polylist>
|
||||
</mesh>
|
||||
</geometry>
|
||||
</library_geometries>
|
||||
<library_controllers/>
|
||||
<library_visual_scenes>
|
||||
<visual_scene id="Scene" name="Scene">
|
||||
<node id="Camera" name="Camera" type="NODE">
|
||||
<matrix sid="transform">0.6858805 -0.3173701 0.6548619 7.481132 0.7276338 0.3124686 -0.6106656 -6.50764 -0.01081678 0.8953432 0.4452454 5.343665 0 0 0 1</matrix>
|
||||
<instance_camera url="#Camera-camera"/>
|
||||
</node>
|
||||
<node id="Lamp" name="Lamp" type="NODE">
|
||||
<matrix sid="transform">-0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1</matrix>
|
||||
<instance_light url="#Lamp-light"/>
|
||||
</node>
|
||||
<node id="Cube" name="Cube" type="NODE">
|
||||
<matrix sid="transform">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
|
||||
<instance_geometry url="#Cube-mesh" name="Cube">
|
||||
<bind_material>
|
||||
<technique_common>
|
||||
<instance_material symbol="Material-material" target="#Material-material"/>
|
||||
</technique_common>
|
||||
</bind_material>
|
||||
</instance_geometry>
|
||||
</node>
|
||||
</visual_scene>
|
||||
</library_visual_scenes>
|
||||
<scene>
|
||||
<instance_visual_scene url="#Scene"/>
|
||||
</scene>
|
||||
</COLLADA>
|
||||
|
|
@ -7,10 +7,11 @@
|
|||
(:nicknames :engine)
|
||||
(:use-reexport
|
||||
:stoe/engine/gl-utils
|
||||
:stoe/engine/mesh
|
||||
:stoe/engine/scene
|
||||
#+stoe-foreign-assets
|
||||
:stoe/engine/import
|
||||
:stoe/engine/input
|
||||
:stoe/engine/viewport
|
||||
:stoe/engine/render
|
||||
:stoe/engine/shaders))
|
||||
:stoe/engine/shaders
|
||||
:stoe/engine/render))
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
#|
|
||||
This file is a part of stoe project.
|
||||
Copyright (c) 2015 Renaud Casenave-Péré (renaud@casenave-pere.fr)
|
||||
|#
|
||||
|
||||
(uiop:define-package :stoe/engine/camera
|
||||
(:use :cl :maths)
|
||||
(:export #:camera #:view #:proj
|
||||
#:make-camera
|
||||
#:update-view)
|
||||
(:import-from :stoe/engine/object
|
||||
#:object #:pos #:dir))
|
||||
(in-package :stoe/engine/camera)
|
||||
|
||||
(defclass camera (object)
|
||||
((fovy :initarg :fovy :accessor fovy)
|
||||
(aspect :initarg :aspect :accessor aspect)
|
||||
(near :initarg :near :accessor near)
|
||||
(far :initarg :far :accessor far)
|
||||
(projection :initarg :projection :accessor proj :type 'float44)
|
||||
(view :accessor view :type 'float44))
|
||||
(:documentation "Base class for a camera representing a view of the game world."))
|
||||
|
||||
(defun make-camera (fovy aspect near far)
|
||||
(let ((camera (make-instance 'camera :position (vec 0.0 0.0 2.0)
|
||||
:direction (quat (vec 0.0 0.0 1.0) 0.0)
|
||||
:fovy fovy
|
||||
:aspect aspect
|
||||
:near near
|
||||
:far far
|
||||
:projection (mperspective fovy aspect near far))))
|
||||
(update-view camera)
|
||||
camera))
|
||||
|
||||
(defun update-view (camera)
|
||||
"Compute the world to view matrix from the position and the direction of `camera'."
|
||||
(with-accessors ((pos pos) (dir dir) (view view)) camera
|
||||
(setf view (m* (transpose (quat-to-mat4 dir)) (mtranslate (v- pos))))))
|
||||
|
|
@ -7,7 +7,9 @@
|
|||
(:use :cl)
|
||||
(:export #:gl-assert
|
||||
#:gl-restart
|
||||
#:size-of))
|
||||
#:ctype-size
|
||||
#:ctype-to-gltype
|
||||
#:ltype-to-ctype))
|
||||
(in-package :stoe/engine/gl-utils)
|
||||
|
||||
(defmacro gl-assert (&body body)
|
||||
|
|
@ -25,8 +27,23 @@
|
|||
(gl-assert ,form)
|
||||
(continue () :report "Continue")))
|
||||
|
||||
(defun size-of (type)
|
||||
(defun ctype-size (type)
|
||||
(ecase type
|
||||
(:byte 1)
|
||||
(:unsigned-char 1)
|
||||
(:unsigned-short 2)
|
||||
(:float 4)))
|
||||
|
||||
(defun ctype-to-gltype (ctype)
|
||||
(ecase ctype
|
||||
(:unsigned-char :unsigned-byte)
|
||||
(t ctype)))
|
||||
|
||||
(defun ltype-to-ctype (ltype len)
|
||||
(ecase ltype
|
||||
(single-float :float)
|
||||
(double-float :double)
|
||||
(t (cond
|
||||
((< len 256) :unsigned-char)
|
||||
((< len 65536) :unsigned-short)
|
||||
((< len 4294967296) :unsigned-int)
|
||||
(t :uint64)))))
|
||||
|
|
|
|||
|
|
@ -5,31 +5,37 @@
|
|||
|
||||
(uiop:define-package :stoe/engine/import
|
||||
(:use :cl :maths
|
||||
:stoe/engine/gl-utils
|
||||
:stoe/engine/mesh
|
||||
:stoe/engine/scene)
|
||||
(:export #:import-graphic-assets))
|
||||
(in-package :stoe/engine/import)
|
||||
|
||||
(defun import-stream (stream)
|
||||
(let ((len (array-total-size stream)))
|
||||
(defun import-stream (stream attrib)
|
||||
(let* ((len (array-total-size stream)))
|
||||
(when (> len 0)
|
||||
(let* ((dim-x len)
|
||||
(dim-y (array-total-size (aref stream 0)))
|
||||
(array (make-array (list (* dim-x dim-y)) :element-type 'single-float)))
|
||||
(loop for i below dim-x
|
||||
(let* ((count len)
|
||||
(stride (array-total-size (aref stream 0)))
|
||||
(elt-type (array-element-type (aref stream 0)))
|
||||
(ctype (ltype-to-ctype elt-type (* count stride)))
|
||||
(array (make-array (list (* count stride)) :element-type elt-type)))
|
||||
(loop for i below count
|
||||
do (let ((row (aref stream i)))
|
||||
(loop for j below dim-y
|
||||
do (setf (aref array (+ j (* i dim-y))) (aref row j)))))
|
||||
(make-stream-array array dim-x dim-y)))))
|
||||
(loop for j below stride
|
||||
do (setf (aref array (+ j (* i stride))) (aref row j)))))
|
||||
(make-vertex-stream array ctype count attrib stride)))))
|
||||
|
||||
(defun import-faces (faces)
|
||||
(let* ((dim-x (array-total-size faces))
|
||||
(dim-y (array-total-size (aref faces 0)))
|
||||
(array (make-array (list (* dim-x dim-y)) :element-type 'fixnum)))
|
||||
(loop for i below dim-x
|
||||
(defun import-faces (faces mode)
|
||||
(let* ((count (array-total-size faces))
|
||||
(stride (array-total-size (aref faces 0)))
|
||||
(elt-type (array-element-type (aref faces 0)))
|
||||
(ctype (ltype-to-ctype elt-type (* count stride)))
|
||||
(array (make-array (list (* count stride)) :element-type 'fixnum)))
|
||||
(loop for i below count
|
||||
do (let ((row (aref faces i)))
|
||||
(loop for j below dim-y
|
||||
do (setf (aref array (+ j (* i dim-y))) (aref row j)))))
|
||||
array))
|
||||
(loop for j below stride
|
||||
do (setf (aref array (+ j (* i stride))) (aref row j)))))
|
||||
(make-index-stream array ctype count mode)))
|
||||
|
||||
(defun import-transform (trans)
|
||||
(let ((mat (mat-null 4 'single-float)))
|
||||
|
|
@ -53,15 +59,26 @@
|
|||
(rec node root-node)
|
||||
root-node))))
|
||||
|
||||
(defun import-modes (mesh)
|
||||
(when (classimp:mesh-has-multiple-primitive-types mesh)
|
||||
(error "Multiple primitive types are not yet supported"))
|
||||
(cond
|
||||
((classimp:mesh-has-points mesh) :points)
|
||||
((classimp:mesh-has-lines mesh) :lines)
|
||||
((classimp:mesh-has-triangles mesh) :triangles)
|
||||
((classimp:mesh-has-polygons mesh) (error "Polygons mode is not supported."))))
|
||||
|
||||
(defun import-graphic-assets (filename)
|
||||
(let ((ai-scene (classimp:import-into-lisp filename)))
|
||||
(make-instance 'scene
|
||||
:meshes
|
||||
(coerce (loop for i below (array-total-size (classimp:meshes ai-scene))
|
||||
for mesh = (aref (classimp:meshes ai-scene) i)
|
||||
collect (make-instance 'mesh
|
||||
:vertices (import-stream (classimp:vertices mesh))
|
||||
:colors (import-stream (classimp:colors mesh))
|
||||
:faces (import-faces (classimp:faces mesh))))
|
||||
collect (make-mesh
|
||||
(remove nil (list (import-stream (classimp:vertices mesh)
|
||||
:position)
|
||||
(import-stream (classimp:colors mesh)
|
||||
:color)))
|
||||
(import-faces (classimp:faces mesh) (import-modes mesh))))
|
||||
'vector)
|
||||
:root-node (import-nodes (classimp:root-node ai-scene)))))
|
||||
|
|
|
|||
200
engine/mesh.lisp
200
engine/mesh.lisp
|
|
@ -4,150 +4,82 @@
|
|||
|#
|
||||
|
||||
(uiop:define-package :stoe/engine/mesh
|
||||
(:use :cl :stoe/core/utils)
|
||||
(:export #:mesh
|
||||
#:make-mesh
|
||||
#:mesh-streams
|
||||
#:mesh-stream-program
|
||||
#:mesh-stream-vertex-buffer
|
||||
#:mesh-stream-index-buffer
|
||||
#:vertex-buffer-attribs
|
||||
#:vertex-buffer-buffer-object
|
||||
#:index-buffer-buffer-object
|
||||
#:index-buffer-mode
|
||||
#:index-buffer-size
|
||||
#:index-buffer-type
|
||||
#:attrib-symb
|
||||
#:attrib-size
|
||||
#:attrib-type
|
||||
#:attrib-offset))
|
||||
(:use :cl :cffi :maths :shader
|
||||
:stoe/core/utils
|
||||
:stoe/engine/gl-utils)
|
||||
(:export #:mesh #:vertex-streams #:faces #:make-mesh
|
||||
#:stream-array #:ctype
|
||||
#:vertex-stream #:attrib
|
||||
#:index-stream #:mode
|
||||
#:make-stream-array #:make-vertex-stream #:make-index-stream #:bsize
|
||||
#:render-mesh))
|
||||
(in-package :stoe/engine/mesh)
|
||||
|
||||
(defstruct attrib
|
||||
(symb nil)
|
||||
type
|
||||
size
|
||||
offset)
|
||||
|
||||
(defstruct (vertex-buffer (:constructor %make-vertex-buffer))
|
||||
data
|
||||
attribs
|
||||
buffer-object)
|
||||
|
||||
(defstruct (index-buffer (:constructor %make-index-buffer))
|
||||
type
|
||||
mode
|
||||
size
|
||||
data
|
||||
buffer-object)
|
||||
|
||||
(defstruct (mesh-stream (:constructor %make-mesh-stream))
|
||||
program
|
||||
vertex-buffer
|
||||
index-buffer)
|
||||
|
||||
(defclass mesh ()
|
||||
((name :initform "" :reader mesh-name)
|
||||
(streams :initform nil :reader mesh-streams)))
|
||||
((streams :initarg :streams :accessor vertex-streams)
|
||||
(faces :initarg :faces :accessor faces))
|
||||
(:documentation "Class for a single mesh."))
|
||||
|
||||
(defun make-vertex-buffer (data)
|
||||
(let ((buffer-data nil)
|
||||
(buffer-size 0)
|
||||
(end-offset 0))
|
||||
(let* ((attribs (mapcar (lambda (attrib)
|
||||
(let ((symb (first attrib))
|
||||
(type (second attrib))
|
||||
(size (third attrib))
|
||||
(buffer (fourth attrib)))
|
||||
(prog1
|
||||
(make-attrib :symb (intern (symbol-name symb) :keyword) :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 (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)))
|
||||
(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-mesh (&optional streams faces)
|
||||
(make-instance 'mesh :streams streams :faces faces))
|
||||
|
||||
(defun make-index-buffer (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)))
|
||||
(defclass stream-array ()
|
||||
((array :initarg :array :reader raw-data)
|
||||
(ctype :initarg :ctype :reader ctype)
|
||||
(count :initarg :count)))
|
||||
|
||||
(defun %set-mesh-stream-program (stream symbol)
|
||||
(setf (mesh-stream-program stream) symbol))
|
||||
(defclass vertex-stream (stream-array)
|
||||
((attrib :initarg :attrib :reader attrib)
|
||||
(stride :initarg :stride)))
|
||||
|
||||
(defun %set-mesh-stream-vertex-buffer (stream data)
|
||||
(setf (mesh-stream-vertex-buffer stream) (make-vertex-buffer data)))
|
||||
(defclass index-stream (stream-array)
|
||||
((mode :initarg :mode :reader mode)))
|
||||
|
||||
(defun %set-mesh-stream-index-buffer (stream data)
|
||||
(setf (mesh-stream-index-buffer stream) (make-index-buffer data)))
|
||||
(defun make-stream-array (array ctype count stride)
|
||||
(make-instance 'stream-array :array array :ctype ctype :count count :stride stride))
|
||||
|
||||
(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))) :stoe/engine/mesh)
|
||||
stream (list (second pair))))
|
||||
alist)
|
||||
stream))
|
||||
(defun make-vertex-stream (array ctype count attrib stride)
|
||||
(make-instance 'vertex-stream :array array :ctype ctype :count count :attrib attrib :stride stride))
|
||||
|
||||
(defun %set-mesh-name (mesh name)
|
||||
(setf (slot-value mesh 'name) name))
|
||||
(defun make-index-stream (array ctype count mode)
|
||||
(make-instance 'index-stream :array array :ctype ctype :count count :mode mode))
|
||||
|
||||
(defun %set-mesh-streams (mesh streams)
|
||||
(setf (slot-value mesh 'streams) (mapcar 'make-mesh-stream streams)))
|
||||
(defmethod size ((stream stream-array))
|
||||
(length (raw-data stream)))
|
||||
|
||||
(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))) :stoe/engine/mesh)
|
||||
mesh (list (second pair))))
|
||||
alist)
|
||||
mesh))
|
||||
(defgeneric bsize (object))
|
||||
(defmethod bsize ((stream stream-array))
|
||||
(* (ctype-size (ctype stream)) (length (raw-data stream))))
|
||||
|
||||
;; (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)))
|
||||
(defun render-mesh (mesh program)
|
||||
(loop for stream in (vertex-streams mesh)
|
||||
with offset = 0
|
||||
do (let* ((ctype (ctype stream)) (size (size stream)) (bsize (bsize stream))
|
||||
(data (raw-data stream)) (attrib (attrib stream))
|
||||
(ptr (foreign-alloc ctype :count size)))
|
||||
;; create the data for opengl
|
||||
(dotimes (i (length data))
|
||||
(setf (mem-aref ptr ctype i) (aref data i)))
|
||||
(let ((buffer-object (first (gl:gen-buffers 1))))
|
||||
(gl:bind-buffer :array-buffer buffer-object)
|
||||
(%gl:buffer-data :array-buffer bsize ptr :static-draw)
|
||||
;; use it
|
||||
(let ((loc (get-location program attrib)))
|
||||
(gl-assert (gl:enable-vertex-attrib-array loc)
|
||||
(gl:vertex-attrib-pointer loc 3 ctype :false 0 offset))
|
||||
(incf offset bsize)
|
||||
(foreign-free ptr)))))
|
||||
(let* ((faces (faces mesh)) (data (raw-data faces))
|
||||
(size (size faces)) (bsize (bsize faces))
|
||||
(index-object (first (gl:gen-buffers 1)))
|
||||
(ptr (foreign-alloc (ctype faces) :initial-contents data :count size)))
|
||||
(gl:bind-buffer :element-array-buffer index-object)
|
||||
(%gl:buffer-data :element-array-buffer bsize ptr :static-draw)
|
||||
(foreign-free ptr)
|
||||
(gl-assert (%gl:draw-elements (mode faces) bsize (ctype-to-gltype (ctype faces)) 0)))
|
||||
;; cleanup data
|
||||
(loop for stream in (vertex-streams mesh)
|
||||
do (let ((loc (get-location program (attrib stream))))
|
||||
(gl:disable-vertex-attrib-array loc)))
|
||||
(gl:bind-buffer :element-array-buffer 0)
|
||||
(gl:bind-buffer :array-buffer 0))
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
#|
|
||||
This file is a part of stoe project.
|
||||
Copyright (c) 2015 Renaud Casenave-Péré (renaud@casenave-pere.fr)
|
||||
|#
|
||||
|
||||
(uiop:define-package :stoe/engine/object
|
||||
(:use :cl :maths)
|
||||
(:export #:object #:pos #:dir #:trans-mat #:components
|
||||
#:make-object #:update-trans-matrix)
|
||||
(:import-from :stoe/engine/scene
|
||||
#:scene-node #:parent))
|
||||
(in-package :stoe/engine/object)
|
||||
|
||||
(defclass object (scene-node)
|
||||
((position :initarg :position :accessor pos :type 'float3)
|
||||
(direction :initarg :direction :accessor dir :type 'quaternion)
|
||||
(trans-matrix :initform (mat-id 4 'single-float) :accessor trans-mat :type 'float44)
|
||||
(components :initform nil :reader components))
|
||||
(:documentation "Base class for all objects existing in the game world."))
|
||||
|
||||
(defun make-object (&key (pos (vec 0.0 0.0 0.0)) (dir (quat (vec 0.0 0.0 1.0) 0.0)) mesh)
|
||||
(let ((obj (make-instance 'object :position pos :direction dir)))
|
||||
(when mesh
|
||||
(with-slots (components) obj
|
||||
(push mesh components)))
|
||||
obj))
|
||||
|
||||
(defun update-trans-matrix (node)
|
||||
(setf (trans-mat node) (m* (trans-mat (parent node))
|
||||
(mtranslate (pos node))
|
||||
(quat-to-mat4 (dir node)))))
|
||||
|
|
@ -4,12 +4,15 @@
|
|||
|#
|
||||
|
||||
(uiop:define-package :stoe/engine/render
|
||||
(:use :cl :maths :shader
|
||||
(:use :cl :cffi :maths :shader
|
||||
:stoe/core/utils
|
||||
:stoe/core/containers
|
||||
:stoe/core/time
|
||||
:stoe/core/modules
|
||||
:stoe/core/thread
|
||||
:stoe/core/jobs
|
||||
:stoe/engine/gl-utils
|
||||
:stoe/engine/mesh
|
||||
:stoe/engine/viewport
|
||||
:stoe/engine/scene))
|
||||
(in-package :stoe/engine/render)
|
||||
|
|
@ -36,6 +39,27 @@ Destroy the opengl context and the related resources."
|
|||
(declare (ignore delta-time)))
|
||||
|
||||
(defmodule stoe/engine/render)
|
||||
|
||||
(defun render-single-mesh (mesh transform)
|
||||
(using-program (program 'blue-shader)
|
||||
(with-locations (model-to-camera camera-to-clip) program
|
||||
(let ((mtc (m* (view (get-current-camera)) transform))
|
||||
(ctc (projection (get-current-camera))))
|
||||
(gl:uniform-matrix model-to-camera 4 (vector (raw-data mtc)) nil)
|
||||
(gl:uniform-matrix camera-to-clip 4 (vector (raw-data ctc)) nil)))
|
||||
(render-mesh mesh program)))
|
||||
|
||||
(defun render-scene-node (node scene)
|
||||
(loop for mesh-idx in (meshes node)
|
||||
do (render-single-mesh (aref (meshes scene) mesh-idx) (transform node)))
|
||||
(loop for child in (children node)
|
||||
do (render-scene-node child scene)))
|
||||
|
||||
(defun render-world (world)
|
||||
(with-lock-held ((scene-lock world))
|
||||
(with-accessors ((scene world-scene)) world
|
||||
(render-scene-node (root-node scene) scene))))
|
||||
|
||||
(defmethod thread-initialize ((thread render-thread))
|
||||
(format t "Initialize ~a~%" (name thread))
|
||||
(viewport-initialize)
|
||||
|
|
@ -55,5 +79,6 @@ Destroy the opengl context and the related resources."
|
|||
while job
|
||||
do (progn
|
||||
(format t "Thread ~a: Running job ~a~%" (name thread) (id job))
|
||||
(job-run job thread))))
|
||||
(job-run job thread)))
|
||||
(render-world (get-world)))
|
||||
(update-clock clock)))))
|
||||
|
|
|
|||
|
|
@ -4,20 +4,39 @@
|
|||
|#
|
||||
|
||||
(uiop:define-package :stoe/engine/scene
|
||||
(:use :cl)
|
||||
(:export #:scene-node #:make-scene-node #:attach-child
|
||||
#:scene #:make-scene
|
||||
#:mesh #:make-mesh
|
||||
#:stream-array
|
||||
#:make-stream-array))
|
||||
(:use :cl :maths
|
||||
:stoe/core/utils
|
||||
:stoe/core/thread
|
||||
:stoe/engine/gl-utils
|
||||
:stoe/engine/mesh)
|
||||
(:export #:world #:world-scene #:world-camera #:scene-lock #:scenes #:world-initialize
|
||||
#:get-world #:get-current-scene #:get-current-camera
|
||||
#:scene-node #:transform #:children #:meshes #:make-scene-node #:attach-child
|
||||
#:scene #:root-node #:make-scene
|
||||
#:object #:pos #:dir #:make-object #:update-transform
|
||||
#:camera #:projection #:view #:update-view #:make-camera))
|
||||
(in-package :stoe/engine/scene)
|
||||
|
||||
(defvar *world* nil)
|
||||
|
||||
(defclass world ()
|
||||
((current-scene :initform nil :accessor world-scene)
|
||||
(current-camera :initform nil :accessor world-camera)
|
||||
(lock :initform (make-lock "scene-lock") :accessor scene-lock)
|
||||
(scenes :initform nil :accessor scenes)))
|
||||
|
||||
(defun make-world () (make-instance 'world))
|
||||
(defun world-initialize () (setf *world* (make-world)))
|
||||
(defun get-world () *world*)
|
||||
(defun get-current-scene () (world-scene *world*))
|
||||
(defun get-current-camera () (world-camera *world*))
|
||||
|
||||
(defclass scene-node ()
|
||||
((name :initarg :name)
|
||||
(parent :initform nil)
|
||||
(transform :initarg :transform)
|
||||
(children :initarg :children)
|
||||
(meshes :initarg :meshes))
|
||||
((name :initarg :name :accessor name)
|
||||
(parent :initform nil :accessor parent)
|
||||
(transform :initarg :transform :accessor transform)
|
||||
(children :initarg :children :initform nil :accessor children)
|
||||
(meshes :initarg :meshes :accessor meshes))
|
||||
(:documentation "Base class for a node in the scene graph."))
|
||||
|
||||
(defun make-scene-node (name &optional parent transform meshes)
|
||||
|
|
@ -27,7 +46,7 @@
|
|||
node))
|
||||
|
||||
(defun attach-child (node parent)
|
||||
(with-slots (node-parent) node
|
||||
(with-slots ((node-parent parent)) node
|
||||
(when parent
|
||||
(with-slots (children) parent
|
||||
(setf children (append children (list node)))
|
||||
|
|
@ -41,26 +60,45 @@
|
|||
(delete node children)))))
|
||||
|
||||
(defclass scene ()
|
||||
((root-node :initarg :root-node)
|
||||
(meshes :initarg :meshes))
|
||||
((root-node :initarg :root-node :accessor root-node)
|
||||
(cameras :initarg :cameras :accessor cameras)
|
||||
(meshes :initarg :meshes :accessor meshes))
|
||||
(:documentation "Class for the current scene."))
|
||||
|
||||
(defun make-scene ()
|
||||
(make-instance 'scene))
|
||||
|
||||
(defclass mesh ()
|
||||
((vertices :initarg :vertices)
|
||||
(colors :initarg :colors)
|
||||
(faces :initarg :faces))
|
||||
(:documentation "Class for a single mesh."))
|
||||
(defclass object (scene-node)
|
||||
((position :initarg :pos :accessor pos :type 'float3)
|
||||
(direction :initarg :dir :accessor dir :type 'quaternion))
|
||||
(:documentation "Base class for all objects existing in the game world."))
|
||||
|
||||
(defun make-mesh (name)
|
||||
(make-instance 'mesh :name name))
|
||||
(defun make-object (&key (pos (vec 0.0 0.0 0.0)) (dir (quat (vec 0.0 0.0 1.0) 0.0)))
|
||||
(make-instance 'object :pos pos :dir dir))
|
||||
|
||||
(defclass stream-array ()
|
||||
((array :initarg :array)
|
||||
(count :initarg :count)
|
||||
(stride :initarg :stride)))
|
||||
(defun update-transform (object)
|
||||
(setf (transform object) (m* (transform (parent object))
|
||||
(mtranslate (pos object))
|
||||
(quat-to-mat4 (dir object)))))
|
||||
|
||||
(defun make-stream-array (array count stride)
|
||||
(make-instance 'stream-array :array array :count count :stride stride))
|
||||
(defclass camera (object)
|
||||
((fovy :initarg :fovy)
|
||||
(aspect :initarg :aspect)
|
||||
(near :initarg :near)
|
||||
(far :initarg :far)
|
||||
(projection :initarg :projection :accessor projection)
|
||||
(view :accessor view))
|
||||
(:documentation "Base class for a camera representing a view of the game world."))
|
||||
|
||||
(defun update-view (camera)
|
||||
"Compute the world to view matrix from the position and the direction of CAMERA."
|
||||
(with-accessors ((pos pos) (dir dir) (view view)) camera
|
||||
(setf view (m* (transpose (quat-to-mat4 dir)) (mtranslate (v- pos))))))
|
||||
|
||||
(defun make-camera (fovy aspect near far)
|
||||
(let ((camera (make-instance 'camera :pos (vec 0.0 0.0 2.0)
|
||||
:dir (quat (vec 0.0 0.0 1.0) 0.0)
|
||||
:fovy fovy :aspect aspect :near near :far far
|
||||
:projection (mperspective fovy aspect near far))))
|
||||
(update-view camera)
|
||||
camera))
|
||||
|
|
|
|||
|
|
@ -23,3 +23,15 @@
|
|||
(defprogram simple-shader ()
|
||||
:vertex-shader simple-vertex
|
||||
:fragment-shader simple-fragment)
|
||||
|
||||
(defshader nocolor-vertex ((position :vec4 :in)
|
||||
(camera-to-clip :mat4 :uniform)
|
||||
(model-to-camera :mat4 :uniform))
|
||||
(setf gl-position (* camera-to-clip model-to-camera position)))
|
||||
|
||||
(defshader blue-fragment ((frag-color :vec4 :out))
|
||||
(setf frag-color (vec4 0.0 0.0 1.0 0.0)))
|
||||
|
||||
(defprogram blue-shader ()
|
||||
:vertex-shader nocolor-vertex
|
||||
:fragment-shader blue-fragment)
|
||||
|
|
|
|||
25
startup.lisp
Normal file
25
startup.lisp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
(uiop:define-package :startup
|
||||
(:use :cl :maths :core :engine :shader))
|
||||
(in-package :startup)
|
||||
|
||||
(defun startup ()
|
||||
(world-initialize)
|
||||
(load-cube)
|
||||
(stoe/engine/render::initialize))
|
||||
|
||||
(defun quit ()
|
||||
(stoe/engine/render::finalize))
|
||||
|
||||
(defun load-cube ()
|
||||
(with-lock-held ((scene-lock (get-world)))
|
||||
(with-accessors ((scene world-scene) (camera world-camera) (scenes scenes)) (get-world)
|
||||
(push (import-graphic-assets #P"data/Cube.dae") scenes)
|
||||
(setf scene (first scenes))
|
||||
(setf camera (make-camera 90 (/ 16 9) 1.0 1000.0)))))
|
||||
|
||||
(defun load-tie ()
|
||||
(with-lock-held ((scene-lock (get-world)))
|
||||
(with-accessors ((scene world-scene) (camera world-camera) (scenes scenes)) (get-world)
|
||||
(push (import-graphic-assets #P"data/TieFighter.dae") scenes)
|
||||
(setf scene (first scenes))
|
||||
(setf camera (make-camera 90 (/ 16 9) 1.0 1000.0)))))
|
||||
3
stoe.asd
3
stoe.asd
|
|
@ -14,6 +14,8 @@
|
|||
(:use :cl :asdf))
|
||||
(in-package :stoe-asd)
|
||||
|
||||
(pushnew :stoe-foreign-assets *features*)
|
||||
|
||||
(defsystem stoe
|
||||
:version (:read-file-form "VERSION")
|
||||
:author "Renaud Casenave-Péré"
|
||||
|
|
@ -48,6 +50,7 @@
|
|||
"stoe/maths/all"
|
||||
"stoe/engine/all"
|
||||
"stoe/shader/all")
|
||||
:components ((:file "startup"))
|
||||
:in-order-to ((test-op (load-op stoe/test))))
|
||||
|
||||
(defsystem stoe/test
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue