model-converter/src/renderer/mod.rs

155 lines
4.2 KiB
Rust
Raw Normal View History

2018-02-27 11:42:35 +01:00
pub mod camera;
2018-02-26 14:59:32 +01:00
use glium::draw_parameters::DepthTest;
use glium::texture::{
RawImage2d,
2018-02-27 11:42:35 +01:00
SrgbTexture2d,
2018-02-26 14:59:32 +01:00
};
2018-02-26 11:45:53 +01:00
use glium::index::{
NoIndices,
PrimitiveType
};
use glium::{
Program,
Display,
VertexBuffer,
Frame,
2018-02-26 14:59:32 +01:00
DrawParameters,
Depth,
2018-02-26 11:45:53 +01:00
};
2018-02-26 14:59:32 +01:00
use image;
2018-02-26 11:45:53 +01:00
use model::{Model, Vertex};
2018-02-27 11:42:35 +01:00
use renderer::camera::Camera;
2018-02-26 14:59:32 +01:00
pub struct RenderMaterial {
2018-02-27 11:42:35 +01:00
texture: Option<SrgbTexture2d>,
2018-02-26 14:59:32 +01:00
}
impl RenderMaterial {
pub fn new() -> RenderMaterial {
RenderMaterial {
texture: None
}
}
pub fn from_texture_name(path: &str, display: &Display) -> RenderMaterial {
let image = image::open(path);
if let Ok(image) = image {
let image = image.to_rgba();
let dim = image.dimensions();
let image = RawImage2d::from_raw_rgba_reversed(&image.into_raw(), dim);
RenderMaterial {
2018-02-27 11:42:35 +01:00
texture: SrgbTexture2d::new(display, image).ok()
2018-02-26 14:59:32 +01:00
}
} else {
RenderMaterial {
texture: None
}
}
}
}
2018-02-26 11:45:53 +01:00
pub struct Renderer<'a> {
display: Display,
program: Program,
2018-02-26 14:59:32 +01:00
models: Vec<(&'a Model, Vec<(RenderMaterial, VertexBuffer<Vertex>)>)>,
2018-02-26 11:45:53 +01:00
}
impl<'a> Renderer<'a> {
pub fn new(display: Display) -> Renderer<'a> {
let program = Program::from_source(
&display,
2018-02-27 11:42:35 +01:00
include_str!("../../assets/shaders/shader.vert"),
include_str!("../../assets/shaders/shader.frag"),
2018-02-26 11:45:53 +01:00
None
).unwrap();
Renderer {
display: display,
program: program,
models: vec![],
}
}
pub fn add_model(&mut self, model: &'a Model) {
let mut buffers = vec![];
for part in &model.parts {
2018-02-26 14:59:32 +01:00
let material = if let Some(ref material_name) = part.material_name {
if let Some(material) = model.materials.get(material_name) {
if let Some(path) = material.textures.get("map_Kd") {
RenderMaterial::from_texture_name(path, &self.display)
} else {
RenderMaterial::new()
}
} else {
RenderMaterial::new()
}
} else {
RenderMaterial::new()
};
2018-02-26 11:45:53 +01:00
let shape = part.build_shape(&model.vertices, &model.texture_coordinates, &model.normals);
2018-02-26 14:59:32 +01:00
buffers.push((material, VertexBuffer::new(&self.display, &shape).unwrap()));
2018-02-26 11:45:53 +01:00
}
self.models.push((model, buffers));
}
pub fn draw(&self) -> Frame {
self.display.draw()
}
2018-02-27 11:42:35 +01:00
pub fn render<C: Camera>(&self, camera: &C, target: &mut Frame) {
2018-02-26 11:45:53 +01:00
use glium::Surface;
2018-02-27 11:42:35 +01:00
target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
2018-02-26 14:59:32 +01:00
let params = DrawParameters {
depth: Depth {
test: DepthTest::IfLess,
write: true,
.. Default::default()
},
.. Default::default()
};
2018-02-26 11:45:53 +01:00
for &(_, ref buffers) in &self.models {
2018-02-26 14:59:32 +01:00
for &(ref material, ref buffer) in buffers {
2018-02-27 11:42:35 +01:00
let perspective = camera.get_perspective_matrix(target.get_dimensions());
2018-02-26 14:59:32 +01:00
let view = camera.get_view_matrix();
if let &Some(ref texture) = &material.texture {
target.draw(
buffer,
NoIndices(PrimitiveType::TrianglesList),
&self.program,
&uniform!(
tex: texture,
perspective: perspective,
view: view,
),
&params,
).unwrap();
} else {
target.draw(
buffer,
NoIndices(PrimitiveType::TrianglesList),
&self.program,
&uniform!(
perspective: perspective,
view: view,
),
&params,
).unwrap();
};
2018-02-26 11:45:53 +01:00
}
}
}
}