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 zcmYe#32|d$U|?uqV_>+$%)sCk?C)2tlvrGxTB2lCt(2acms*rql3%1`rR41IOT_l2x=}td3G{Vo6bE1&E_(pksgq>lz{nBD0Yd8|oRv*6LI%<)#*A zC|MbRYy>gE4yaZtD9X&uEXgc`auZ8RiZYW*OF-OeB|rZlUq>G$D?=Tn0RLdm5Kn(U zB`c#^9i_~?l+0w18Ur1r-29YOB`XuKb5n~l6LX-Jxo(Z?}J3FKvDOAK|C2wGwWx5NnSACM)W zV1;71ZQyW+69}urT%C;xS!`rs0kQ?%f7q-x&@4+>ZJ=ji00xGJmPQ7aMwajt z2TDLXO1V&DU>Xec3~F_hpphJunxX`XV?=;MtcUP1V%XH&3=$hYsd?!o8A?{>MmkC* ziACw4{AFxnX=aRwJq*nTs9ND>1(y_Mf>NR(nps8&hd~`xS&|B~*v!PDHnz5diGjh% z(~kiG8tjQ@H|$4JOMp#^xiC{n(L;(`VCI8pqV<9N2g0E60bv*$MuWuAF-#6bgD^}U z#74(3IT#I+hp|C4j1Qt=7$lC4L2@857!6~C_#h19gJ=*2i6LWbVjy{#IE;pgLHUdf zObpBnObm<+EDWp+Yz*uSYz(Xn91NTcTnyX{TnwBHJPf=Hd<^^yd + 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() + } +}