From 8f24e5f98862fa2398ef9d99d96fba1e1fd50d78 Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Thu, 7 Apr 2022 16:18:46 -0500 Subject: [PATCH] Import a model --- Box.glb | Bin 0 -> 1664 bytes Cargo.lock | 190 +++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 + src/cube.frag | 8 +++ src/cube.vert | 12 ++++ src/device.rs | 12 ++-- src/main.rs | 19 ++++- src/model.rs | 46 ++++++++++++ 8 files changed, 279 insertions(+), 10 deletions(-) create mode 100644 Box.glb create mode 100644 src/cube.frag create mode 100644 src/cube.vert create mode 100644 src/model.rs diff --git a/Box.glb b/Box.glb new file mode 100644 index 0000000000000000000000000000000000000000..95ec886b6b92b134291fd41d34ac9d5349306e0a GIT binary patch literal 1664 zcmb7EOK;jh5S}DW+O$p6v`u^8GeNd_1bm4oEftl43Q#VHgE0$OGB&bJ+Q_oRvHz-n zq(7!Jix*Y|3Dweg=e6_A%bt4u#xVe_&H(fXY|f(@CPIkBiUbn22;I3GyAPRY#|SxE#v~@J z-RZV!7Blr6`_bt&`^`?9nFdzn`eWB2AFOMR#W1rd(&eFRdl`st&r#1>1WTZ{gEyie zT(@AfoJ@Fl@A97_$mlWVoykNr7-KrYd=dEEkNb}c3{ujK0x6e1_PSp7z%Cj)?0>TUa1Jlw h71BAph6{KDmq-`z7OvnOyhpl%4{!}1;S + key_map: HashMap } impl DeviceManager { @@ -21,11 +23,11 @@ impl DeviceManager { key_map: HashMap::new(), } } - pub fn is_pressed(&self, keycode: &VirtualKeyCode) -> bool { - matches!(self.key_map.get(keycode), Some(ElementState::Pressed)) + pub fn is_pressed(&self, key: &Key) -> bool { + matches!(self.key_map.get(key), Some(ElementState::Pressed)) } - fn update(&mut self, keycode: VirtualKeyCode, state: ElementState) { - self.key_map.insert(keycode, state); + fn update(&mut self, key: Key, state: ElementState) { + self.key_map.insert(key, state); } } diff --git a/src/main.rs b/src/main.rs index abd980a..9e3f4ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,12 @@ mod device; +mod model; #[macro_use] extern crate glium; extern crate nalgebra_glm as glm; +use model::Model; + #[derive(Copy, Clone)] struct Vertex { position: [f32; 3], @@ -32,26 +35,36 @@ fn main() { let vertex_shader_src = include_str!("flat.vert"); let fragment_shader_src = include_str!("flat.frag"); - let program = glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None).unwrap(); + let flat_program = glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None).unwrap(); + + let vertex_shader_src = include_str!("cube.vert"); + let fragment_shader_src = include_str!("cube.frag"); + let cube_program = glium::Program::from_source(&display, vertex_shader_src, fragment_shader_src, None).unwrap(); let mut device_manager = crate::device::DeviceManager::new(); let mut offset = 0.0; + let model = Model::new(&display, "Box.glb"); + events_loop.run(move |ev, _, control_flow| { - if device_manager.is_pressed(&glutin::event::VirtualKeyCode::W) { + if device_manager.is_pressed(&device::Key::W) { offset += 0.001; + } else if device_manager.is_pressed(&device::Key::S) { + offset -= 0.001; } let mvp = glm::perspective::(1.0, 45.0_f32.to_radians(), 0.2, 100.0); let mvp = glm::translate::(&mvp, &glm::vec3(0.0, 0.0, -10.0 + offset)); + let mvp = glm::rotate::(&mvp, 15.0_f32.to_radians(), &glm::vec3(1.0, 0.0, 0.0)); let uniforms = uniform! { MVP: *mvp.as_ref(), }; let mut target = display.draw(); target.clear_color(0.0, 0.0, 0.0, 1.0); - target.draw(&vertex_buffer, &indices, &program, &uniforms, + target.draw(&vertex_buffer, &indices, &flat_program, &uniforms, &Default::default()).unwrap(); + model.draw(&mut target, &cube_program, &uniforms); target.finish().unwrap(); diff --git a/src/model.rs b/src/model.rs new file mode 100644 index 0000000..0a85ac7 --- /dev/null +++ b/src/model.rs @@ -0,0 +1,46 @@ +extern crate gltf; + +use glium::{ VertexBuffer, IndexBuffer }; + +#[derive(Copy, Clone)] +struct Vertex { + position: [f32; 3], +} + +implement_vertex!(Vertex, position); + +pub struct Model { + vb: VertexBuffer, + ib: IndexBuffer, +} + +impl Model { + pub fn new(display: &glium::Display, file: &str) -> Self { + let (document, buffers, _images) = gltf::import(file).expect("Could not load gltf file"); + let mesh = document.meshes().next().expect("Could not find mesh"); + let primitive = mesh.primitives().next().expect("Could not find primitive"); + let reader = primitive.reader(|buffer| Some(&buffers[buffer.index()])); + let vertices = reader + .read_positions() + .unwrap() + .map(|position| Vertex { position }) + .collect::>(); + let vb = VertexBuffer::new(display, &vertices).unwrap(); + let indices = reader + .read_indices() + .unwrap() + .into_u32() + .map(|x| x as u16) + .collect::>(); + let ib = IndexBuffer::new(display, glium::index::PrimitiveType::TrianglesList, &indices).unwrap(); + Model { vb, ib } + } + + pub fn draw(&self, + target: &mut impl glium::Surface, + program: &glium::Program, + uniforms: &impl glium::uniforms::Uniforms + ) { + target.draw(&self.vb, &self.ib, program, uniforms, &Default::default()).unwrap() + } +}