Some improvments on UI
This commit is contained in:
parent
73b73f7bf3
commit
6cb76e9986
@ -21,8 +21,8 @@ use model_converter::renderer::camera::Camera;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
let mut model = parse("./assets/models/cube/cube.mtl").unwrap();
|
let mut model = parse("./assets/models/link/link.mtl").unwrap();
|
||||||
parse_into_model("./assets/models/cube/cube.obj", &mut model).unwrap();
|
parse_into_model("./assets/models/link/link.obj", &mut model).unwrap();
|
||||||
|
|
||||||
let mut events_loop = EventsLoop::new();
|
let mut events_loop = EventsLoop::new();
|
||||||
let window = WindowBuilder::new();
|
let window = WindowBuilder::new();
|
||||||
@ -40,7 +40,7 @@ fn main() {
|
|||||||
Vector3::new( 0.0, 1.0, 0.0),
|
Vector3::new( 0.0, 1.0, 0.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut controls = OrbitControls::new(&mut camera);
|
let mut controls = OrbitControls::around(&model, &mut camera);
|
||||||
|
|
||||||
while !closed {
|
while !closed {
|
||||||
|
|
||||||
|
@ -10,8 +10,9 @@ use glium::glutin::{
|
|||||||
MouseScrollDelta,
|
MouseScrollDelta,
|
||||||
};
|
};
|
||||||
|
|
||||||
use math::vector::Vector2;
|
use math::vector::{Vector2, Vector3};
|
||||||
use renderer::camera::Camera;
|
use renderer::camera::Camera;
|
||||||
|
use model::Model;
|
||||||
|
|
||||||
/// The trait that all controls should implement.
|
/// The trait that all controls should implement.
|
||||||
pub trait Controls {
|
pub trait Controls {
|
||||||
@ -41,26 +42,48 @@ pub struct OrbitControls {
|
|||||||
|
|
||||||
/// The sensitiviy of the rotation of the mouse.
|
/// The sensitiviy of the rotation of the mouse.
|
||||||
sensitivity: f32,
|
sensitivity: f32,
|
||||||
|
|
||||||
|
/// The center of the object.
|
||||||
|
center: Vector3<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OrbitControls {
|
impl OrbitControls {
|
||||||
|
|
||||||
/// Creates a new orbit controls, and initializes the camera.
|
/// Creates a new orbit controls, and initializes the camera.
|
||||||
pub fn new(camera: &mut Camera) -> OrbitControls {
|
pub fn new(center: Vector3<f32>, distance: f32, camera: &mut Camera) -> OrbitControls {
|
||||||
let controls = OrbitControls {
|
let controls = OrbitControls {
|
||||||
mouse_position: Vector2::new(0.0, 0.0),
|
mouse_position: Vector2::new(0.0, 0.0),
|
||||||
pressed: false,
|
pressed: false,
|
||||||
theta: 0.0,
|
theta: 0.0,
|
||||||
phi: 0.0,
|
phi: 0.0,
|
||||||
distance: 5.0,
|
distance: distance,
|
||||||
sensitivity: 200.0,
|
sensitivity: 200.0,
|
||||||
|
center: center,
|
||||||
};
|
};
|
||||||
|
|
||||||
*camera.position.x_mut() = controls.distance * controls.theta.cos();
|
*camera.position.x_mut() = controls.distance * controls.theta.cos();
|
||||||
*camera.position.y_mut() = 0.0;
|
*camera.position.y_mut() = 0.0;
|
||||||
*camera.position.z_mut() = controls.distance * controls.phi.sin();
|
*camera.position.z_mut() = controls.distance * controls.phi.sin();
|
||||||
|
camera.position += controls.center;
|
||||||
|
camera.target = controls.center;
|
||||||
|
|
||||||
controls
|
controls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates orbit controls that are mode to rotate around a model.
|
||||||
|
pub fn around(model: &Model, camera: &mut Camera) -> OrbitControls {
|
||||||
|
// Compute bounding box
|
||||||
|
let bounding_box = model.bounding_box();
|
||||||
|
let center = (bounding_box.min() + bounding_box.max()) / 2.0;
|
||||||
|
let distance = (bounding_box.max() - bounding_box.min()).norm();
|
||||||
|
|
||||||
|
OrbitControls::new(
|
||||||
|
Vector3::new(center.x() as f32, center.y() as f32, center.z() as f32),
|
||||||
|
distance as f32,
|
||||||
|
camera
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Controls for OrbitControls {
|
impl Controls for OrbitControls {
|
||||||
@ -86,6 +109,9 @@ impl Controls for OrbitControls {
|
|||||||
*camera.position.x_mut() = self.distance * self.phi.cos() * self.theta.cos();
|
*camera.position.x_mut() = self.distance * self.phi.cos() * self.theta.cos();
|
||||||
*camera.position.y_mut() = self.distance * self.phi.sin();
|
*camera.position.y_mut() = self.distance * self.phi.sin();
|
||||||
*camera.position.z_mut() = self.distance * self.phi.cos() * self.theta.sin();
|
*camera.position.z_mut() = self.distance * self.phi.cos() * self.theta.sin();
|
||||||
|
|
||||||
|
camera.position += self.center;
|
||||||
|
camera.target = self.center;
|
||||||
},
|
},
|
||||||
|
|
||||||
Event::WindowEvent{
|
Event::WindowEvent{
|
||||||
@ -109,6 +135,9 @@ impl Controls for OrbitControls {
|
|||||||
*camera.position.y_mut() = self.distance * self.phi.sin();
|
*camera.position.y_mut() = self.distance * self.phi.sin();
|
||||||
*camera.position.z_mut() = self.distance * self.phi.cos() * self.theta.sin();
|
*camera.position.z_mut() = self.distance * self.phi.cos() * self.theta.sin();
|
||||||
|
|
||||||
|
camera.position += self.center;
|
||||||
|
camera.target = self.center;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record new position
|
// Record new position
|
||||||
|
@ -20,11 +20,33 @@ use glium::{
|
|||||||
DrawParameters,
|
DrawParameters,
|
||||||
Depth,
|
Depth,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use glium::backend::Facade;
|
||||||
|
use glium::backend::glutin::headless::Headless;
|
||||||
|
|
||||||
use image;
|
use image;
|
||||||
|
|
||||||
use model::{Model, Vertex};
|
use model::{Model, Vertex};
|
||||||
use renderer::camera::RenderCamera;
|
use renderer::camera::RenderCamera;
|
||||||
|
|
||||||
|
/// Anything on which you can call draw to get a frame.
|
||||||
|
pub trait Drawer {
|
||||||
|
/// Get a frame from the drawer.
|
||||||
|
fn draw(&self) -> Frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drawer for Display {
|
||||||
|
fn draw(&self) -> Frame {
|
||||||
|
Display::draw(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drawer for Headless {
|
||||||
|
fn draw(&self) -> Frame {
|
||||||
|
Headless::draw(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A material that can be bound to OpenGL.
|
/// A material that can be bound to OpenGL.
|
||||||
///
|
///
|
||||||
/// Only textures are supported for now.
|
/// Only textures are supported for now.
|
||||||
@ -42,7 +64,7 @@ impl RenderMaterial {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a material from a path to an image file.
|
/// Creates a material from a path to an image file.
|
||||||
pub fn from_texture_path(path: &str, display: &Display) -> RenderMaterial {
|
pub fn from_texture_path<D: Drawer + Facade + Sized>(path: &str, drawer: &D) -> RenderMaterial {
|
||||||
let image = image::open(path);
|
let image = image::open(path);
|
||||||
|
|
||||||
if let Ok(image) = image {
|
if let Ok(image) = image {
|
||||||
@ -50,7 +72,7 @@ impl RenderMaterial {
|
|||||||
let dim = image.dimensions();
|
let dim = image.dimensions();
|
||||||
let image = RawImage2d::from_raw_rgba_reversed(&image.into_raw(), dim);
|
let image = RawImage2d::from_raw_rgba_reversed(&image.into_raw(), dim);
|
||||||
RenderMaterial {
|
RenderMaterial {
|
||||||
texture: SrgbTexture2d::new(display, image).ok()
|
texture: SrgbTexture2d::new(drawer, image).ok()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RenderMaterial {
|
RenderMaterial {
|
||||||
@ -61,30 +83,37 @@ impl RenderMaterial {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A renderer. It contains a display, shaders, and a vector of models it can render.
|
/// A renderer. It contains a display, shaders, and a vector of models it can render.
|
||||||
pub struct Renderer<'a> {
|
pub struct Renderer<'a, D: Drawer + Facade> {
|
||||||
display: Display,
|
drawer: D,
|
||||||
program: Program,
|
program: Program,
|
||||||
models: Vec<(&'a Model, Vec<(RenderMaterial, VertexBuffer<Vertex>)>)>,
|
models: Vec<(&'a Model, Vec<(RenderMaterial, VertexBuffer<Vertex>)>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Renderer<'a> {
|
impl<'a, D: Drawer + Facade + Sized> Renderer<'a, D> {
|
||||||
/// Creates a new renderer from a display.
|
/// Creates a new renderer from a display.
|
||||||
///
|
///
|
||||||
/// Is uses the default shaders and creates an empty vec of models.
|
/// Is uses the default shaders and creates an empty vec of models.
|
||||||
pub fn new(display: Display) -> Renderer<'a> {
|
pub fn new(drawer: D) -> Renderer<'a, D> {
|
||||||
|
|
||||||
let program = Program::from_source(
|
let program = Program::from_source(
|
||||||
&display,
|
&drawer,
|
||||||
include_str!("../../assets/shaders/shader.vert"),
|
include_str!("../../assets/shaders/shader.vert"),
|
||||||
include_str!("../../assets/shaders/shader.frag"),
|
include_str!("../../assets/shaders/shader.frag"),
|
||||||
None
|
None
|
||||||
).unwrap();
|
);
|
||||||
|
|
||||||
Renderer {
|
if let Ok(program) = program {
|
||||||
display: display,
|
Renderer {
|
||||||
program: program,
|
drawer: drawer,
|
||||||
models: vec![],
|
program: program,
|
||||||
|
models: vec![],
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("{:?}", program.err().unwrap());
|
||||||
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a model to the renderer, and compute the corresponding buffers for rendering.
|
/// Adds a model to the renderer, and compute the corresponding buffers for rendering.
|
||||||
@ -96,7 +125,7 @@ impl<'a> Renderer<'a> {
|
|||||||
let material = if let Some(ref material_name) = part.material_name {
|
let material = if let Some(ref material_name) = part.material_name {
|
||||||
if let Some(material) = model.materials.get(material_name) {
|
if let Some(material) = model.materials.get(material_name) {
|
||||||
if let Some(path) = material.textures.get("map_Kd") {
|
if let Some(path) = material.textures.get("map_Kd") {
|
||||||
RenderMaterial::from_texture_path(path, &self.display)
|
RenderMaterial::from_texture_path(path, &self.drawer)
|
||||||
} else {
|
} else {
|
||||||
RenderMaterial::new()
|
RenderMaterial::new()
|
||||||
}
|
}
|
||||||
@ -108,15 +137,20 @@ impl<'a> Renderer<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let shape = part.build_shape(&model.vertices, &model.texture_coordinates, &model.normals);
|
let shape = part.build_shape(&model.vertices, &model.texture_coordinates, &model.normals);
|
||||||
buffers.push((material, VertexBuffer::new(&self.display, &shape).unwrap()));
|
buffers.push((material, VertexBuffer::new(&self.drawer, &shape).unwrap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.models.push((model, buffers));
|
self.models.push((model, buffers));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the reference to the drawer used for this renderer.
|
||||||
|
pub fn facade(&self) -> &D {
|
||||||
|
&self.drawer
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a frame from the display.
|
/// Creates a frame from the display.
|
||||||
pub fn draw(&self) -> Frame {
|
pub fn draw(&self) -> Frame {
|
||||||
self.display.draw()
|
self.drawer.draw()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders the result of the models from the camera and paint it on the target.
|
/// Renders the result of the models from the camera and paint it on the target.
|
||||||
@ -166,5 +200,6 @@ impl<'a> Renderer<'a> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user