turbine_scene3d/
lib.rs

1//! # Turbine-Scene3D
2//!
3//! Scene rendering for the Turbine game engine.
4//!
5//! <video width="320" height="240" controls>
6//!  <source src="https://i.imgur.com/M0frz9B.mp4" type="video/mp4">
7//! Your browser does not support the video tag.
8//! </video>
9//!
10//! ### Design
11//!
12//! - Scene object stores all resources used for rendering
13//! - Frame graph stores command lists
14//!
15//! This design allows flexible programming of scenes, without the need for
16//! a tree structure to store nodes for scene data.
17//! The frame graph can be used to debug the scene.
18
19#![deny(missing_docs)]
20
21extern crate piston;
22extern crate vecmath;
23extern crate wavefront_obj;
24extern crate image;
25
26mod gl_backend;
27
28pub use gl_backend::Scene;
29
30use std::path::Path;
31use std::io;
32
33use vecmath::*;
34
35/// Stores a scene command.
36#[derive(Copy, Clone, Debug, PartialEq)]
37pub enum Command {
38    /// Use program.
39    UseProgram(Program),
40    /// Set model-view-projection transform.
41    SetModelViewProjection(Matrix4Uniform),
42    /// Set model transform.
43    SetModel(Matrix4Uniform),
44    /// Set view transform.
45    SetView(Matrix4Uniform),
46    /// Set texture.
47    SetTexture(Texture),
48    /// Set f32 uniform.
49    SetF32(F32Uniform, f32),
50    /// Set 2D vector uniform.
51    SetVector2(Vector2Uniform, Vector2<f32>),
52    /// Set 3D vector uniform.
53    SetVector3(Vector3Uniform, Vector3<f32>),
54    /// Set matrx uniform.
55    SetMatrix4(Matrix4Uniform, Matrix4<f32>),
56    /// Enable framebuffer sRGB.
57    EnableFrameBufferSRGB,
58    /// Disable framebuffer sRGB.
59    DisableFrameBufferSRGB,
60    /// Enable blend.
61    EnableBlend,
62    /// Disable blend.
63    DisableBlend,
64    /// Enable cull face.
65    EnableCullFace,
66    /// Disable cull face.
67    DisableCullFace,
68    /// Cull front face.
69    CullFaceFront,
70    /// Cull back face.
71    CullFaceBack,
72    /// Cull both front and back face.
73    CullFaceFrontAndBack,
74    /// Draw triangles.
75    DrawTriangles(VertexArray, usize),
76    /// Draw triangle strip.
77    DrawTriangleStrip(VertexArray, usize),
78    /// Draw lines.
79    DrawLines(VertexArray, usize),
80    /// Draw points.
81    DrawPoints(VertexArray, usize),
82    /// Translate model.
83    Translate(Vector3<f32>),
84    /// Translate model in global coordinates.
85    TranslateGlobal(Vector3<f32>),
86    /// Scale model.
87    Scale(Vector3<f32>),
88    /// Rotate model around x axis with degrees.
89    RotateXDeg(f32),
90    /// Rotate model around y axis with degrees.
91    RotateYDeg(f32),
92    /// Rotate model around z axis with degrees.
93    RotateZDeg(f32),
94    /// Rotate model around axis with degrees.
95    RotateAxisDeg(Vector3<f32>, f32),
96    /// Push model transform to transform stack.
97    PushTransform,
98    /// Pop model transform from transform stack.
99    PopTransform,
100    /// Draw a command list.
101    Draw(CommandList),
102}
103
104/// Stores how stuff is rendered in a single frame.
105#[derive(Debug)]
106pub struct FrameGraph {
107    command_lists: Vec<Vec<Command>>,
108}
109
110impl FrameGraph {
111    /// Creates a new frame graph.
112    pub fn new() -> FrameGraph {
113        FrameGraph {
114            command_lists: vec![]
115        }
116    }
117
118    /// Create command list.
119    pub fn command_list(&mut self, commands: Vec<Command>) -> CommandList {
120        let id = self.command_lists.len();
121        self.command_lists.push(commands);
122        CommandList(id)
123    }
124}
125
126/// References a vertex shader.
127#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
128pub struct VertexShader(usize);
129/// References a fragment shader.
130#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
131pub struct FragmentShader(usize);
132/// References a program.
133#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
134pub struct Program(usize);
135/// References 4D matrix uniform.
136#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
137pub struct Matrix4Uniform(usize);
138/// References a 2D vector uniform.
139#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
140pub struct Vector2Uniform(usize);
141/// References a 3D vector uniform.
142#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
143pub struct Vector3Uniform(usize);
144/// References a f32 uniform.
145#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
146pub struct F32Uniform(usize);
147/// References a vertex array object.
148#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
149pub struct VertexArray(usize);
150/// References a color buffer object.
151#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
152pub struct ColorBuffer(usize, usize);
153/// References a 3D vertex buffer object.
154#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
155pub struct VertexBuffer3(usize, usize);
156/// References a 2D vertex buffer object.
157#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
158pub struct VertexBuffer2(usize, usize);
159/// References an UV buffer object.
160#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
161pub struct UVBuffer(usize, usize);
162/// References a normal buffer object.
163#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
164pub struct NormalBuffer(usize, usize);
165/// References a command list object.
166#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
167pub struct CommandList(usize);
168/// References a texture object.
169#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
170pub struct Texture(usize);
171
172impl ColorBuffer {
173    /// Length of color buffer.
174    pub fn len(&self) -> usize {self.1}
175}
176
177impl VertexBuffer3 {
178    /// Length of vertex buffer.
179    pub fn len(&self) -> usize {self.1}
180}
181
182impl VertexBuffer2 {
183    /// Length of vertex buffer.
184    pub fn len(&self) -> usize {self.1}
185}
186
187/// Stores OBJ mesh data.
188pub struct ObjMesh {
189    /// Stores vertex coordinates.
190    pub vertices: Vec<f32>,
191    /// Stores texture coordinates.
192    pub uvs: Vec<f32>,
193    /// Stores normal coordinates.
194    pub normals: Vec<f32>,
195}
196
197impl ObjMesh {
198    /// Load OBJ file.
199    pub fn load<P: AsRef<Path>>(path: P) -> Result<ObjMesh, io::Error> {
200        use std::fs::File;
201        use std::io::Read;
202
203        let mut obj_file = File::open(path)?;
204        let mut data = String::new();
205        obj_file.read_to_string(&mut data)?;
206        let obj_set = wavefront_obj::obj::parse(data).unwrap();
207        let obj = &obj_set.objects[0];
208        let temp_vertices = {
209            let mut res = vec![];
210            for v in &obj.vertices {
211                res.push(v.x as f32);
212                res.push(v.y as f32);
213                res.push(v.z as f32);
214            }
215            res
216        };
217        let temp_uvs = {
218            let mut res = vec![];
219            for uv in &obj.tex_vertices {
220                res.push(uv.u as f32);
221                res.push(1.0 - uv.v as f32);
222            }
223            res
224        };
225        let temp_normals = {
226            let mut res = vec![];
227            for normal in &obj.normals {
228                res.push(normal.x as gl::types::GLfloat);
229                res.push(normal.y as gl::types::GLfloat);
230                res.push(normal.z as gl::types::GLfloat);
231            }
232            res
233        };
234        let mut vertices = vec![];
235        let mut uvs = vec![];
236        let mut normals = vec![];
237        for geom in &obj.geometry {
238            for shape in &geom.shapes {
239                use wavefront_obj::obj::Primitive;
240
241                if let Primitive::Triangle(
242                    (a_v, Some(a_uv), Some(a_n)),
243                    (b_v, Some(b_uv), Some(b_n)),
244                    (c_v, Some(c_uv), Some(c_n))
245                ) = shape.primitive {
246                    vertices.push(temp_vertices[a_v * 3 + 0]);
247                    vertices.push(temp_vertices[a_v * 3 + 1]);
248                    vertices.push(temp_vertices[a_v * 3 + 2]);
249
250                    vertices.push(temp_vertices[b_v * 3 + 0]);
251                    vertices.push(temp_vertices[b_v * 3 + 1]);
252                    vertices.push(temp_vertices[b_v * 3 + 2]);
253
254                    vertices.push(temp_vertices[c_v * 3 + 0]);
255                    vertices.push(temp_vertices[c_v * 3 + 1]);
256                    vertices.push(temp_vertices[c_v * 3 + 2]);
257
258                    uvs.push(temp_uvs[a_uv * 2 + 0]);
259                    uvs.push(temp_uvs[a_uv * 2 + 1]);
260
261                    uvs.push(temp_uvs[b_uv * 2 + 0]);
262                    uvs.push(temp_uvs[b_uv * 2 + 1]);
263
264                    uvs.push(temp_uvs[c_uv * 2 + 0]);
265                    uvs.push(temp_uvs[c_uv * 2 + 1]);
266
267                    normals.push(temp_normals[a_n * 3 + 0]);
268                    normals.push(temp_normals[a_n * 3 + 1]);
269                    normals.push(temp_normals[a_n * 3 + 2]);
270
271                    normals.push(temp_normals[b_n * 3 + 0]);
272                    normals.push(temp_normals[b_n * 3 + 1]);
273                    normals.push(temp_normals[b_n * 3 + 2]);
274
275                    normals.push(temp_normals[c_n * 3 + 0]);
276                    normals.push(temp_normals[c_n * 3 + 1]);
277                    normals.push(temp_normals[c_n * 3 + 2]);
278                }
279            }
280        }
281        Ok(ObjMesh {
282            vertices,
283            uvs,
284            normals
285        })
286    }
287}
288
289/// Stores scene settings.
290#[derive(Clone)]
291pub struct SceneSettings {
292    clear_depth_buffer: bool,
293    clear_enable_depth_test: bool,
294}
295
296impl SceneSettings {
297    /// Returns new scene settings with default settings.
298    pub fn new() -> SceneSettings {
299        SceneSettings {
300            clear_depth_buffer: true,
301            clear_enable_depth_test: true,
302        }
303    }
304
305    /// Set whether to clear depth buffer on clear.
306    pub fn clear_depth_buffer(mut self, val: bool) -> Self {
307        self.clear_depth_buffer = val;
308        self
309    }
310
311    /// Set whether to enable depth test on clear.
312    ///
313    /// Uses depth test function `LESS` by default.
314    pub fn clear_enable_depth_test(mut self, val: bool) -> Self {
315        self.clear_enable_depth_test = val;
316        self
317    }
318}
319
320impl Default for SceneSettings {
321    fn default() -> Self {SceneSettings::new()}
322}
323
324#[cfg(test)]
325mod tests {
326    #[test]
327    fn it_works() {
328        assert_eq!(2 + 2, 4);
329    }
330}