extern crate glium;
extern crate image;
use glium::{VertexBuffer, IndexBuffer};
use glium::texture::Texture2d;
use therm_util::reader::ByteReader;
#[derive(Debug, Copy, Clone)]
pub struct V3D {
pub pos: [f32; 3],
pub nrm: [f32; 3],
pub tex: [f32; 2],
}
implement_vertex!(V3D, pos, nrm, tex);
impl V3D {
pub fn from_reader<Rd>(reader: &mut ByteReader<Rd>) -> Result<V3D, String>
where Rd: Iterator<Item=u8>
{
Ok(V3D { pos: [ try!(reader.read_twip()) * 0.1,
try!(reader.read_twip()) * 0.1,
try!(reader.read_twip()) * 0.1],
nrm: [ try!(reader.read_twip()),
try!(reader.read_twip()),
try!(reader.read_twip()) ],
tex: [ try!(reader.read_ratio()),
try!(reader.read_ratio()) ],
})
}
}
#[derive(Debug, Clone)]
pub struct Model {
pub points: Vec<V3D>,
pub tris: Vec<u16>,
pub texture: Option<Vec<u8>>,
}
impl Model {
pub fn load_from_file(path: &str) -> Result<Model, String> {
let mut reader = ByteReader::from_file(path).unwrap();
Model::from_reader(&mut reader)
}
pub fn from_reader<T>(reader: &mut ByteReader<T>) -> Result<Model, String>
where T: Iterator<Item=u8>
{
Ok(Model {
tris: try!(reader.read_several(|r| r.read_prefix_int().map(|x| x as u16))),
points: try!(reader.read_several(V3D::from_reader)),
texture: None,
})
}
pub fn get_vbuf(&self, display: &glium::Display) -> VertexBuffer<V3D> {
VertexBuffer::new(display, self.points.as_slice()).unwrap()
}
pub fn get_ibuf(&self, display: &glium::Display) -> IndexBuffer<u16> {
IndexBuffer::new(
display,
glium::index::PrimitiveType::TrianglesList,
&self.tris).unwrap()
}
pub fn get_tex(&self, display: &glium::Display) -> Option<Texture2d> {
use std::io::Cursor;
use glium::texture::RawImage2d;
if let Some(ref tex) = self.texture {
let img = image::load(Cursor::new(tex.clone()),
image::PNG).unwrap().to_rgba();
let dims = img.dimensions();
let img = RawImage2d::from_raw_rgba_reversed(&img.into_raw(),
dims);
Some(Texture2d::new(display, img).unwrap())
} else {
None
}
}
}