Import a model
This commit is contained in:
8
src/cube.frag
Normal file
8
src/cube.frag
Normal 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
12
src/cube.vert
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
19
src/main.rs
19
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::<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
46
src/model.rs
Normal 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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user