Actually drawing things to the screen now: a basic model importer, but no way of 100% confirming that its working right
Getty Ritter
9 years ago
Binary diff not shown
Binary diff not shown
| 1 | 1 | use core::slice::Iter; |
| 2 | 2 | use std::collections::HashMap; |
| 3 | 3 | use std::iter::Peekable; |
| 4 | use std::mem; | |
| 4 | 5 | |
| 5 |
#[derive(Clone,Debug,PartialEq |
|
| 6 | #[derive(Clone,Debug,PartialEq)] | |
| 6 | 7 | pub enum Bencode { |
| 7 | 8 | Int(i64), |
| 9 | Float(f32), | |
| 8 | 10 | Str(Vec<u8>), |
| 9 | 11 | List(Vec<Bencode>), |
| 10 | 12 | Dict(HashMap<Vec<u8>, Bencode>), |
| 36 | 38 | num = num * 10 + to_digit_i64(n); |
| 37 | 39 | } |
| 38 | 40 | Ok(Bencode::Int(num)) |
| 41 | }, | |
| 42 | Some(&0x66) => { | |
| 43 | let mut next_byte = || { | |
| 44 | match is.next() { | |
| 45 | Some(n) => Ok(*n), | |
| 46 | None => Err("Unexpected end-of-stream"), | |
| 47 | } | |
| 48 | }; | |
| 49 | let mut buf = [ try!(next_byte()), | |
| 50 | try!(next_byte()), | |
| 51 | try!(next_byte()), | |
| 52 | try!(next_byte()) ]; | |
| 53 | let _ = next_byte(); | |
| 54 | let f = unsafe { mem::transmute::<[u8;4], f32>(buf) }; | |
| 55 | Ok(Bencode::Float(f)) | |
| 39 | 56 | }, |
| 40 | 57 | Some(&0x6c) => { |
| 41 | 58 | let mut list = Vec::new(); |
| 118 | 135 | } |
| 119 | 136 | } |
| 120 | 137 | |
| 121 |
pub fn as_ |
|
| 138 | pub fn as_i64(&self) -> Result<i64, String> { | |
| 122 | 139 | match self { |
| 123 | 140 | &Bencode::Int(n) => Ok(n), |
| 124 | 141 | _ => fail("not a number"), |
| 125 | 142 | } |
| 126 | 143 | } |
| 144 | ||
| 145 | pub fn as_usize(&self) -> Result<usize, String> { | |
| 146 | match self { | |
| 147 | &Bencode::Int(n) => Ok(n as usize), | |
| 148 | _ => fail("not a number"), | |
| 149 | } | |
| 150 | } | |
| 151 | ||
| 152 | pub fn as_float(&self) -> Result<f32, String> { | |
| 153 | match self { | |
| 154 | &Bencode::Float(f) => Ok(f), | |
| 155 | _ => fail("not a number"), | |
| 156 | } | |
| 157 | } | |
| 158 | ||
| 159 | pub fn map<A, F>(&self, func: F) -> Result<Vec<A>, String> | |
| 160 | where F: 'static + Fn(&Bencode) -> Result<A, String> | |
| 161 | { | |
| 162 | match self { | |
| 163 | &Bencode::List(ref lst) => { | |
| 164 | let mut vec = Vec::with_capacity(lst.len()); | |
| 165 | for x in lst { | |
| 166 | vec.insert(0, try!(func(x))); | |
| 167 | } | |
| 168 | Ok(vec) | |
| 169 | }, | |
| 170 | _ => fail("not a list"), | |
| 171 | } | |
| 172 | } | |
| 127 | 173 | } |
| 1 | 1 | extern crate core; |
| 2 | #[macro_use] | |
| 3 | extern crate glium; | |
| 2 | 4 | |
| 3 | 5 | mod adnot; |
| 4 | 6 | mod bencode; |
| 5 | 7 | mod model; |
| 6 | 8 | |
| 7 |
use |
|
| 9 | use glium::{DisplayBuild, Program, Surface}; | |
| 10 | use glium::glutin::Event; | |
| 11 | use glium::glutin::WindowBuilder; | |
| 12 | ||
| 13 | // use bencode::Bencode; | |
| 14 | ||
| 15 | fn sample() -> model::Model { | |
| 16 | model::Model::load_from_file("data/test/cube.model").unwrap() | |
| 17 | } | |
| 18 | ||
| 19 | const VERTEX_SHADER: &'static str = r#" | |
| 20 | #version 140 | |
| 21 | in vec3 pos; | |
| 22 | void main() { | |
| 23 | gl_Position = vec4(pos, 1.0); | |
| 24 | } | |
| 25 | "#; | |
| 26 | ||
| 27 | const FRAGMENT_SHADER: &'static str = r#" | |
| 28 | #version 140 | |
| 29 | out vec4 color; | |
| 30 | void main() { | |
| 31 | color = vec4(1.0, 0.0, 0.0, 1.0); | |
| 32 | } | |
| 33 | "#; | |
| 8 | 34 | |
| 9 | 35 | fn main() { |
| 10 | let input = "d3:foo3:bare"; | |
| 11 | println!("{:?}", Bencode::parse(&input.to_string().into_bytes())); | |
| 36 | let md = sample(); | |
| 37 | let display = WindowBuilder::new() | |
| 38 | .with_title(format!("utymen")) | |
| 39 | .build_glium() | |
| 40 | .unwrap(); | |
| 41 | let vbuf = md.get_vbuf(&display); | |
| 42 | let idxs = glium::index::NoIndices( | |
| 43 | glium::index::PrimitiveType::TrianglesList); | |
| 44 | let program = Program::from_source( | |
| 45 | &display, | |
| 46 | VERTEX_SHADER, | |
| 47 | FRAGMENT_SHADER, | |
| 48 | None).unwrap(); | |
| 49 | ||
| 50 | loop { | |
| 51 | let mut target = display.draw(); | |
| 52 | target.clear_color(0.0, 0.0, 0.0, 1.0); | |
| 53 | target.draw(&vbuf, | |
| 54 | &idxs, | |
| 55 | &program, | |
| 56 | &glium::uniforms::EmptyUniforms, | |
| 57 | &Default::default()).unwrap(); | |
| 58 | target.finish().unwrap(); | |
| 59 | for ev in display.poll_events() { | |
| 60 | match ev { | |
| 61 | Event::Closed => return, | |
| 62 | Event::KeyboardInput(_, 9, _) => return, | |
| 63 | _ => (), | |
| 64 | } | |
| 65 | } | |
| 66 | } | |
| 12 | 67 | } |
| 1 | extern crate glium; | |
| 2 | ||
| 1 | 3 | use bencode::Bencode; |
| 2 | 4 | |
| 3 |
#[derive( |
|
| 5 | #[derive(Debug, Copy, Clone)] | |
| 4 | 6 | pub struct V3D { |
| 5 | 7 | pub pos: [f32; 3], |
| 6 | 8 | pub tex: [f32; 2], |
| 7 | 9 | } |
| 8 | 10 | |
| 9 | #[derive(Clone)] | |
| 11 | implement_vertex!(V3D, pos, tex); | |
| 12 | ||
| 13 | #[derive(Debug, Clone)] | |
| 10 | 14 | pub struct Model { |
| 11 | 15 | pub points: Vec<V3D>, |
| 12 | 16 | pub tris: Vec<usize>, |
| 13 | 17 | } |
| 14 | 18 | |
| 15 | pub fn load_model(is: &[u8]) -> Result<Model, String> { | |
| 16 | let bs = try!(Bencode::parse(is)); | |
| 17 | let points_b = try!(bs.get_field("points")); | |
| 18 | let tris_b = try!(bs.get_field("tris")); | |
| 19 | let points = vec![]; | |
| 20 | let tris = vec![]; | |
| 21 | Ok(Model { | |
| 22 | points: points, | |
| 23 | tris: tris, | |
| 24 | }) | |
| 19 | impl Model { | |
| 20 | pub fn load_from_file(path: &str) -> Result<Model, String> { | |
| 21 | use std::fs::File; | |
| 22 | use std::io::Read; | |
| 23 | let mut f = match File::open(path) { | |
| 24 | Ok(f) => f, | |
| 25 | Err(_) => return Err("Unable to open file".to_string()), | |
| 26 | }; | |
| 27 | let mut buf = Vec::new(); | |
| 28 | let _ = f.read_to_end(&mut buf); | |
| 29 | Model::load(&buf) | |
| 30 | } | |
| 31 | ||
| 32 | pub fn load(is: &[u8]) -> Result<Model, String> { | |
| 33 | let bs = try!(Bencode::parse(is)); | |
| 34 | Ok(Model { | |
| 35 | points: try!(try!(bs.get_field("pts")).map(load_v3d)), | |
| 36 | tris: try!(try!(bs.get_field("tris")).map(|v| v.as_usize())), | |
| 37 | }) | |
| 38 | } | |
| 39 | ||
| 40 | pub fn get_vbuf(&self, display: &glium::Display) -> glium::VertexBuffer<V3D> { | |
| 41 | glium::VertexBuffer::new(display, self.points.as_slice()).unwrap() | |
| 42 | } | |
| 25 | 43 | } |
| 26 | 44 | |
| 27 | 45 | fn load_v3d(bs: &Bencode) -> Result<V3D, String> { |
| 28 | 46 | Ok(V3D { |
| 29 | pos: [ try!(try!(bs.get_idx(0)).as_num()) as f32, | |
| 30 | try!(try!(bs.get_idx(1)).as_num()) as f32, | |
| 31 |
|
|
| 47 | pos: [ try!(try!(bs.get_idx(0)).as_float()), | |
| 48 | try!(try!(bs.get_idx(1)).as_float()), | |
| 49 | try!(try!(bs.get_idx(2)).as_float()), | |
| 32 | 50 | ], |
| 33 | tex: [ try!(try!(bs.get_idx(3)).as_num()) as f32, | |
| 34 | try!(try!(bs.get_idx(5)).as_num()) as f32, | |
| 51 | tex: [ try!(try!(bs.get_idx(3)).as_float()), | |
| 52 | try!(try!(bs.get_idx(4)).as_float()), | |
| 35 | 53 | ] |
| 36 | 54 | }) |
| 37 | 55 | } |