gdritter repos thermidor / 2cc33b9
Added model code to therm_model crate Getty Ritter 7 years ago
3 changed file(s) with 91 addition(s) and 0 deletion(s). Collapse all Expand all
44 authors = ["Getty Ritter <gdritter@galois.com>"]
55
66 [dependencies]
7 glium = "*"
8 image = "*"
9 therm_util = { path = "../therm_util" }
1 #[macro_use]
2 extern crate glium;
3 extern crate image;
4 extern crate therm_util;
5
6 pub mod model;
7
18 #[cfg(test)]
29 mod tests {
310 #[test]
1 extern crate glium;
2 extern crate image;
3
4 use glium::{VertexBuffer, IndexBuffer};
5 use glium::texture::Texture2d;
6 use therm_util::reader::ByteReader;
7
8 #[derive(Debug, Copy, Clone)]
9 pub struct V3D {
10 pub pos: [f32; 3],
11 pub nrm: [f32; 3],
12 pub tex: [f32; 2],
13 }
14
15 implement_vertex!(V3D, pos, nrm, tex);
16
17 impl V3D {
18 pub fn from_reader<Rd>(reader: &mut ByteReader<Rd>) -> Result<V3D, String>
19 where Rd: Iterator<Item=u8>
20 {
21 Ok(V3D { pos: [ try!(reader.read_twip()) * 0.1,
22 try!(reader.read_twip()) * 0.1,
23 try!(reader.read_twip()) * 0.1],
24 nrm: [ try!(reader.read_twip()),
25 try!(reader.read_twip()),
26 try!(reader.read_twip()) ],
27 tex: [ try!(reader.read_ratio()),
28 try!(reader.read_ratio()) ],
29 })
30 }
31 }
32
33 #[derive(Debug, Clone)]
34 pub struct Model {
35 pub points: Vec<V3D>,
36 pub tris: Vec<u16>,
37 pub texture: Option<Vec<u8>>,
38 }
39
40 impl Model {
41 pub fn load_from_file(path: &str) -> Result<Model, String> {
42 let mut reader = ByteReader::from_file(path).unwrap();
43 Model::from_reader(&mut reader)
44 }
45
46 pub fn from_reader<T>(reader: &mut ByteReader<T>) -> Result<Model, String>
47 where T: Iterator<Item=u8>
48 {
49 Ok(Model {
50 tris: try!(reader.read_several(|r| r.read_prefix_int().map(|x| x as u16))),
51 points: try!(reader.read_several(V3D::from_reader)),
52 texture: None,
53 })
54 }
55
56 pub fn get_vbuf(&self, display: &glium::Display) -> VertexBuffer<V3D> {
57 VertexBuffer::new(display, self.points.as_slice()).unwrap()
58 }
59
60 pub fn get_ibuf(&self, display: &glium::Display) -> IndexBuffer<u16> {
61 IndexBuffer::new(
62 display,
63 glium::index::PrimitiveType::TrianglesList,
64 &self.tris).unwrap()
65 }
66
67 pub fn get_tex(&self, display: &glium::Display) -> Option<Texture2d> {
68 use std::io::Cursor;
69 use glium::texture::RawImage2d;
70 if let Some(ref tex) = self.texture {
71 let img = image::load(Cursor::new(tex.clone()),
72 image::PNG).unwrap().to_rgba();
73 let dims = img.dimensions();
74 let img = RawImage2d::from_raw_rgba_reversed(img.into_raw(),
75 dims);
76 Some(Texture2d::new(display, img).unwrap())
77 } else {
78 None
79 }
80 }
81 }