gdritter repos utmyen / bf4ea14
Some basic shading; textures now supported in the Utmyen model format Getty Ritter 8 years ago
4 changed file(s) with 97 addition(s) and 38 deletion(s). Collapse all Expand all
44 authors = ["Getty Ritter <gdritter@galois.com>"]
55
66 [dependencies]
7 image = "*"
78 glium = "*"
163163 }
164164 }
165165
166 pub fn as_bytes(&self) -> Result<Vec<u8>, String> {
167 match self {
168 &Bencode::Str(ref bs) => Ok(bs.clone()),
169 _ => fail("not a string"),
170 }
171 }
172
166173 pub fn map<A, F>(&self, func: F) -> Result<Vec<A>, String>
167174 where F: 'static + Fn(&Bencode) -> Result<A, String>
168175 {
11 extern crate core;
22 #[macro_use]
33 extern crate glium;
4 extern crate image;
45
56 // mod adnot;
67 mod bencode;
910 use glium::{DisplayBuild, Program, Surface};
1011 use glium::glutin::Event;
1112 use glium::glutin::WindowBuilder;
12
13 // use bencode::Bencode;
13 use glium::texture::Texture2d;
1414
1515 fn sample() -> model::Model {
1616 let file = std::env::args().nth(1)
1818 model::Model::load_from_file(&file).unwrap()
1919 }
2020
21 fn sample_texture(display: &glium::Display) -> Texture2d {
22 use std::io::Cursor;
23 let img = image::load(Cursor::new(&include_bytes!("/home/gdritter/pictures/cube-uv.png")[..]),
24 image::PNG).unwrap().to_rgba();
25 let dims = img.dimensions();
26 let img = glium::texture::RawImage2d::from_raw_rgba_reversed(img.into_raw(), dims);
27 Texture2d::new(display, img).unwrap()
28 }
29
2130 const VERTEX_SHADER: &'static str = r#"
2231 #version 140
32
2333 in vec3 pos;
34 in vec3 nrm;
35 in vec2 tex;
2436
2537 uniform mat4 perspective;
2638 uniform mat4 matrix;
2739
28 out vec3 o_pos;
40 out vec3 o_nrm;
41 out vec2 o_tex;
2942
3043 void main() {
31 o_pos = pos;
44 o_nrm = transpose(inverse(mat3(matrix))) * nrm;
45 o_tex = tex;
3246 gl_Position = perspective * matrix * vec4(pos, 1.0);
3347 }
3448 "#;
3549
3650 const FRAGMENT_SHADER: &'static str = r#"
3751 #version 140
38 in vec3 o_pos;
52
53 in vec3 o_nrm;
54 in vec2 o_tex;
55
56 uniform vec3 u_light;
57 uniform sampler2D tex;
58
3959 out vec4 color;
60
4061 void main() {
41 color = vec4(o_pos.z * 2.0, 0.0, 1.0 - (o_pos.z * 2.0), 1.0);
62 float brightness = dot(normalize(o_nrm), normalize(u_light));
63 float factor = 0.5 + (brightness * 0.5);
64 color = texture(tex, o_tex) * factor;
4265 }
4366 "#;
4467
4972 .with_depth_buffer(24)
5073 .build_glium()
5174 .unwrap();
75
5276 let vbuf = md.get_vbuf(&display);
5377 let idxs = md.get_ibuf(&display);
78 let tx = md.get_tex(&display).unwrap_or(sample_texture(&display));
79
5480 let program = Program::from_source(
5581 &display,
5682 VERTEX_SHADER,
5783 FRAGMENT_SHADER,
5884 None).unwrap();
5985
86 let light = [-1.0, 0.4, 0.9f32];
6087 let mut px = 0f32;
6188 let mut py = 0.02f32;
89 let mut pz = 0.0f32;
6290 let mut rt = 0f32;
6391 let dx = 0.001;
6492 let sx = 0.01f32;
86114
87115 let uniforms = uniform! {
88116 perspective: perspective,
117 u_light: light,
118 tex: &tx,
89119 matrix: [ [ rt.cos() * sx, 0.0, -rt.sin() * sx, 0.0 ],
90120 [ 0.0, sx, 0.0, 0.0 ],
91121 [ rt.sin() * sx, 0.0, rt.cos() * sx, 0.0 ],
92 [ px, 0.0, py, sx ]
122 [ px, pz, py, sx ]
93123 ]
94124 };
95125
113143 for ev in display.poll_events() {
114144 match ev {
115145 Event::Closed => return,
116 Event::KeyboardInput(_, 9, _) => return,
117 Event::KeyboardInput(_, 24, _) => {
118 rt -= 0.1;
119 },
120 Event::KeyboardInput(_, 25, _) => {
121 py -= dx;
122 },
123 Event::KeyboardInput(_, 26, _) => {
124 rt += 0.1;
125 },
126 Event::KeyboardInput(_, 38, _) => {
127 px -= dx;
128 },
129 Event::KeyboardInput(_, 39, _) => {
130 py += dx;
131 },
132 Event::KeyboardInput(_, 40, _) => {
133 px += dx;
134 },
135 evt => {
136 },
146 Event::KeyboardInput(_, n, _) =>
147 match n {
148 9 => return,
149 24 => rt -= 0.1,
150 25 => py -= dx,
151 26 => rt += 0.1,
152 38 => px -= dx,
153 39 => py += dx,
154 40 => px += dx,
155 44 => pz -= dx,
156 45 => pz += dx,
157 _ => {},
158 },
159 _ => {},
137160 }
138161 }
139162 }
11 extern crate glium;
2 extern crate image;
23
34 use bencode::Bencode;
5 use glium::{VertexBuffer, IndexBuffer};
6 use glium::texture::Texture2d;
47
58 #[derive(Debug, Copy, Clone)]
69 pub struct V3D {
710 pub pos: [f32; 3],
11 pub nrm: [f32; 3],
812 pub tex: [f32; 2],
913 }
1014
11 implement_vertex!(V3D, pos, tex);
15 implement_vertex!(V3D, pos, nrm, tex);
1216
1317 #[derive(Debug, Clone)]
1418 pub struct Model {
15 pub points: Vec<V3D>,
16 pub tris: Vec<u16>,
19 pub points: Vec<V3D>,
20 pub tris: Vec<u16>,
21 pub texture: Option<Vec<u8>>,
1722 }
1823
1924 impl Model {
3136
3237 pub fn load(is: &[u8]) -> Result<Model, String> {
3338 let bs = try!(Bencode::parse(is));
34 println!("{:?}", bs);
39 let tex = match bs.get_field("tex") {
40 Ok(t) => Some(try!(t.as_bytes())),
41 Err(_) => None,
42 };
3543 Ok(Model {
3644 points: try!(try!(bs.get_field("pts")).map(load_v3d)),
3745 tris: try!(try!(bs.get_field("tris")).map(|v| v.as_u16())),
46 texture: tex,
3847 })
3948 }
4049
41 pub fn get_vbuf(&self, display: &glium::Display) -> glium::VertexBuffer<V3D> {
42 glium::VertexBuffer::new(display, self.points.as_slice()).unwrap()
50 pub fn get_vbuf(&self, display: &glium::Display) -> VertexBuffer<V3D> {
51 VertexBuffer::new(display, self.points.as_slice()).unwrap()
4352 }
4453
45 pub fn get_ibuf(&self, display: &glium::Display) -> glium::IndexBuffer<u16> {
46 glium::IndexBuffer::new(
54 pub fn get_ibuf(&self, display: &glium::Display) -> IndexBuffer<u16> {
55 IndexBuffer::new(
4756 display,
4857 glium::index::PrimitiveType::TrianglesList,
4958 &self.tris).unwrap()
59 }
60
61 pub fn get_tex(&self, display: &glium::Display) -> Option<Texture2d> {
62 use std::io::Cursor;
63 use glium::texture::RawImage2d;
64 if let Some(ref tex) = self.texture {
65 let img = image::load(Cursor::new(tex.clone()),
66 image::PNG).unwrap().to_rgba();
67 let dims = img.dimensions();
68 let img = RawImage2d::from_raw_rgba_reversed(img.into_raw(),
69 dims);
70 Some(Texture2d::new(display, img).unwrap())
71 } else {
72 None
73 }
5074 }
5175 }
5276
5377 fn load_v3d(bs: &Bencode) -> Result<V3D, String> {
5478 Ok(V3D {
55 pos: [ try!(try!(bs.get_idx(1)).as_float()) * 0.5,
79 pos: [ try!(try!(bs.get_idx(0)).as_float()) * 0.5,
80 try!(try!(bs.get_idx(1)).as_float()) * 0.5,
5681 try!(try!(bs.get_idx(2)).as_float()) * 0.5,
57 try!(try!(bs.get_idx(0)).as_float()) * 0.5,
82 ],
83 nrm: [ try!(try!(bs.get_idx(5)).as_float()),
84 try!(try!(bs.get_idx(6)).as_float()),
85 try!(try!(bs.get_idx(7)).as_float()),
5886 ],
5987 tex: [ try!(try!(bs.get_idx(3)).as_float()),
6088 try!(try!(bs.get_idx(4)).as_float()),