Import a model

This commit is contained in:
2022-04-07 16:18:46 -05:00
parent 702232d994
commit 8f24e5f988
8 changed files with 279 additions and 10 deletions

8
src/cube.frag Normal file
View File

@@ -0,0 +1,8 @@
#version 330
in vec3 DIFFUSE;
out vec4 color;
void main() {
color = vec4(DIFFUSE, 1.0);
}

12
src/cube.vert Normal file
View File

@@ -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);
}

View File

@@ -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<VirtualKeyCode, ElementState>
key_map: HashMap<Key, ElementState>
}
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);
}
}

View File

@@ -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::<f32>(1.0, 45.0_f32.to_radians(), 0.2, 100.0);
let mvp = glm::translate::<f32>(&mvp, &glm::vec3(0.0, 0.0, -10.0 + offset));
let mvp = glm::rotate::<f32>(&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();

46
src/model.rs Normal file
View File

@@ -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<Vertex>,
ib: IndexBuffer<u16>,
}
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::<Vec<Vertex>>();
let vb = VertexBuffer::new(display, &vertices).unwrap();
let indices = reader
.read_indices()
.unwrap()
.into_u32()
.map(|x| x as u16)
.collect::<Vec<u16>>();
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()
}
}