diff --git a/Box.glb b/Box.glb new file mode 100644 index 0000000..95ec886 Binary files /dev/null and b/Box.glb differ diff --git a/Cargo.lock b/Cargo.lock index 080f2d1..c2e883e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "android_glue" version = "0.2.3" @@ -48,11 +54,17 @@ dependencies = [ "cc", "cfg-if 1.0.0", "libc", - "miniz_oxide", + "miniz_oxide 0.4.4", "object", "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "bitflags" version = "1.3.2" @@ -77,6 +89,12 @@ version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "calloop" version = "0.9.3" @@ -145,6 +163,12 @@ dependencies = [ "objc", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "core-foundation" version = "0.7.0" @@ -232,9 +256,19 @@ name = "couch" version = "0.1.0" dependencies = [ "glium", + "gltf", "nalgebra-glm", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "cty" version = "0.2.2" @@ -276,6 +310,16 @@ dependencies = [ "syn", ] +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -351,6 +395,43 @@ dependencies = [ "takeable-option", ] +[[package]] +name = "gltf" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00e0a0eace786193fc83644907097285396360e9e82e30f81a21e9b1ba836a3e" +dependencies = [ + "base64", + "byteorder", + "gltf-json", + "image", + "lazy_static", +] + +[[package]] +name = "gltf-derive" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdd53d6e284bb2bf02a6926e4cc4984978c1990914d6cd9deae4e31cf37cd113" +dependencies = [ + "inflections", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gltf-json" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9949836a9ec5e7f83f76fb9bbcbc77f254a577ebbdb0820867bc11979ef97cad" +dependencies = [ + "gltf-derive", + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "glutin" version = "0.28.0" @@ -429,6 +510,28 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "image" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "jpeg-decoder", + "num-iter", + "num-rational 0.3.2", + "num-traits", + "png", +] + +[[package]] +name = "inflections" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a" + [[package]] name = "instant" version = "0.1.12" @@ -441,12 +544,24 @@ dependencies = [ "web-sys", ] +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "jni-sys" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +[[package]] +name = "jpeg-decoder" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" + [[package]] name = "js-sys" version = "0.3.56" @@ -551,6 +666,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + [[package]] name = "miniz_oxide" version = "0.4.4" @@ -593,7 +717,7 @@ dependencies = [ "approx", "matrixmultiply", "num-complex", - "num-rational", + "num-rational 0.4.0", "num-traits", "simba", "typenum", @@ -715,6 +839,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.0" @@ -832,6 +978,18 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "miniz_oxide 0.3.7", +] + [[package]] name = "proc-macro-crate" version = "1.1.3" @@ -890,6 +1048,12 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + [[package]] name = "safe_arch" version = "0.6.0" @@ -917,6 +1081,28 @@ version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "shared_library" version = "0.1.9" diff --git a/Cargo.toml b/Cargo.toml index 7332161..8a913dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,5 @@ edition = "2021" glium = "0.31.0" nalgebra-glm = "0.16.0" +gltf = { version = "1.0.0", features = ["utils"] } + diff --git a/src/cube.frag b/src/cube.frag new file mode 100644 index 0000000..f789f10 --- /dev/null +++ b/src/cube.frag @@ -0,0 +1,8 @@ +#version 330 + +in vec3 DIFFUSE; +out vec4 color; + +void main() { + color = vec4(DIFFUSE, 1.0); +} diff --git a/src/cube.vert b/src/cube.vert new file mode 100644 index 0000000..44b02d1 --- /dev/null +++ b/src/cube.vert @@ -0,0 +1,12 @@ +#version 330 + +in vec3 position; + +uniform mat4 MVP; + +out vec3 DIFFUSE; + +void main() { + gl_Position = MVP * vec4(position, 1.0); + DIFFUSE = vec3(1.0, 0.0, 0.0); +} diff --git a/src/device.rs b/src/device.rs index 71e55ae..3c251f7 100644 --- a/src/device.rs +++ b/src/device.rs @@ -3,8 +3,10 @@ use std::collections::HashMap; use glium::glutin; use glutin::event::*; +pub use glutin::event::VirtualKeyCode as Key; + pub struct DeviceManager { - key_map: HashMap + 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() + } +}