mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-25 03:41:09 +03:00
importing and simplifying glium teapot example
This commit is contained in:
parent
08db3bf27f
commit
87b885fcd7
@ -14,4 +14,3 @@
|
|||||||
- trailer
|
- trailer
|
||||||
- show common parts of routes in A/B, point of divergence
|
- show common parts of routes in A/B, point of divergence
|
||||||
- "Two parallel universes sit at your fingertips, and with the flick of a key, you can glide between the two. Buses jumping past traffic in one world, snarly traffic jam in the other. An A/B test revealing what currently is, and what could be, compared meticulously and deterministically. A/B Street -- which world do you prefer?"
|
- "Two parallel universes sit at your fingertips, and with the flick of a key, you can glide between the two. Buses jumping past traffic in one world, snarly traffic jam in the other. An A/B test revealing what currently is, and what could be, compared meticulously and deterministically. A/B Street -- which world do you prefer?"
|
||||||
|
|
||||||
|
@ -62,3 +62,9 @@
|
|||||||
- draw as one polygon when fixed
|
- draw as one polygon when fixed
|
||||||
- dashed thickness is way off
|
- dashed thickness is way off
|
||||||
- last dash shouldnt appear?
|
- last dash shouldnt appear?
|
||||||
|
|
||||||
|
## Switch to OpenGL (for speed)
|
||||||
|
|
||||||
|
- simpler geometry, with color per object
|
||||||
|
- render text
|
||||||
|
- switch ezgui (could make it generic and have piston or glium support, but maybe not worth it)
|
||||||
|
@ -5,7 +5,7 @@ authors = ["Dustin Carlino <dabreegster@gmail.com>"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gfx = "0.17.1"
|
genmesh = "0.6.2"
|
||||||
gfx_device_gl = "0.15.3"
|
glium = "0.23.0"
|
||||||
gfx_window_glutin = "0.26.0"
|
glutin = "0.19.0"
|
||||||
glutin = "0.18.0"
|
obj = { version = "0.9", features = ["genmesh"] }
|
||||||
|
170
tmp_gfx/src/camera.rs
Normal file
170
tmp_gfx/src/camera.rs
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
use glutin;
|
||||||
|
|
||||||
|
pub struct CameraState {
|
||||||
|
aspect_ratio: f32,
|
||||||
|
position: (f32, f32, f32),
|
||||||
|
direction: (f32, f32, f32),
|
||||||
|
|
||||||
|
moving_up: bool,
|
||||||
|
moving_left: bool,
|
||||||
|
moving_down: bool,
|
||||||
|
moving_right: bool,
|
||||||
|
moving_forward: bool,
|
||||||
|
moving_backward: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CameraState {
|
||||||
|
pub fn new() -> CameraState {
|
||||||
|
CameraState {
|
||||||
|
aspect_ratio: 1024.0 / 768.0,
|
||||||
|
position: (0.1, 0.1, 1.0),
|
||||||
|
direction: (0.0, 0.0, -1.0),
|
||||||
|
moving_up: false,
|
||||||
|
moving_left: false,
|
||||||
|
moving_down: false,
|
||||||
|
moving_right: false,
|
||||||
|
moving_forward: false,
|
||||||
|
moving_backward: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_perspective(&self) -> [[f32; 4]; 4] {
|
||||||
|
let fov: f32 = 3.141592 / 2.0;
|
||||||
|
let zfar = 1024.0;
|
||||||
|
let znear = 0.1;
|
||||||
|
|
||||||
|
let f = 1.0 / (fov / 2.0).tan();
|
||||||
|
|
||||||
|
// note: remember that this is column-major, so the lines of code are actually columns
|
||||||
|
[
|
||||||
|
[f / self.aspect_ratio, 0.0, 0.0, 0.0],
|
||||||
|
[0.0, f, 0.0, 0.0],
|
||||||
|
[0.0, 0.0, (zfar + znear) / (zfar - znear), 1.0],
|
||||||
|
[0.0, 0.0, -(2.0 * zfar * znear) / (zfar - znear), 0.0],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_view(&self) -> [[f32; 4]; 4] {
|
||||||
|
let f = {
|
||||||
|
let f = self.direction;
|
||||||
|
let len = f.0 * f.0 + f.1 * f.1 + f.2 * f.2;
|
||||||
|
let len = len.sqrt();
|
||||||
|
(f.0 / len, f.1 / len, f.2 / len)
|
||||||
|
};
|
||||||
|
|
||||||
|
let up = (0.0, 1.0, 0.0);
|
||||||
|
|
||||||
|
let s = (
|
||||||
|
f.1 * up.2 - f.2 * up.1,
|
||||||
|
f.2 * up.0 - f.0 * up.2,
|
||||||
|
f.0 * up.1 - f.1 * up.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
let s_norm = {
|
||||||
|
let len = s.0 * s.0 + s.1 * s.1 + s.2 * s.2;
|
||||||
|
let len = len.sqrt();
|
||||||
|
(s.0 / len, s.1 / len, s.2 / len)
|
||||||
|
};
|
||||||
|
|
||||||
|
let u = (
|
||||||
|
s_norm.1 * f.2 - s_norm.2 * f.1,
|
||||||
|
s_norm.2 * f.0 - s_norm.0 * f.2,
|
||||||
|
s_norm.0 * f.1 - s_norm.1 * f.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
let p = (
|
||||||
|
-self.position.0 * s.0 - self.position.1 * s.1 - self.position.2 * s.2,
|
||||||
|
-self.position.0 * u.0 - self.position.1 * u.1 - self.position.2 * u.2,
|
||||||
|
-self.position.0 * f.0 - self.position.1 * f.1 - self.position.2 * f.2,
|
||||||
|
);
|
||||||
|
|
||||||
|
// note: remember that this is column-major, so the lines of code are actually columns
|
||||||
|
[
|
||||||
|
[s_norm.0, u.0, f.0, 0.0],
|
||||||
|
[s_norm.1, u.1, f.1, 0.0],
|
||||||
|
[s_norm.2, u.2, f.2, 0.0],
|
||||||
|
[p.0, p.1, p.2, 1.0],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self) {
|
||||||
|
let f = {
|
||||||
|
let f = self.direction;
|
||||||
|
let len = f.0 * f.0 + f.1 * f.1 + f.2 * f.2;
|
||||||
|
let len = len.sqrt();
|
||||||
|
(f.0 / len, f.1 / len, f.2 / len)
|
||||||
|
};
|
||||||
|
|
||||||
|
let up = (0.0, 1.0, 0.0);
|
||||||
|
|
||||||
|
let s = (
|
||||||
|
f.1 * up.2 - f.2 * up.1,
|
||||||
|
f.2 * up.0 - f.0 * up.2,
|
||||||
|
f.0 * up.1 - f.1 * up.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
let s = {
|
||||||
|
let len = s.0 * s.0 + s.1 * s.1 + s.2 * s.2;
|
||||||
|
let len = len.sqrt();
|
||||||
|
(s.0 / len, s.1 / len, s.2 / len)
|
||||||
|
};
|
||||||
|
|
||||||
|
let u = (
|
||||||
|
s.1 * f.2 - s.2 * f.1,
|
||||||
|
s.2 * f.0 - s.0 * f.2,
|
||||||
|
s.0 * f.1 - s.1 * f.0,
|
||||||
|
);
|
||||||
|
|
||||||
|
let speed = 0.1;
|
||||||
|
|
||||||
|
if self.moving_up {
|
||||||
|
self.position.0 += u.0 * speed;
|
||||||
|
self.position.1 += u.1 * speed;
|
||||||
|
self.position.2 += u.2 * speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.moving_left {
|
||||||
|
self.position.0 -= s.0 * speed;
|
||||||
|
self.position.1 -= s.1 * speed;
|
||||||
|
self.position.2 -= s.2 * speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.moving_down {
|
||||||
|
self.position.0 -= u.0 * speed;
|
||||||
|
self.position.1 -= u.1 * speed;
|
||||||
|
self.position.2 -= u.2 * speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.moving_right {
|
||||||
|
self.position.0 += s.0 * speed;
|
||||||
|
self.position.1 += s.1 * speed;
|
||||||
|
self.position.2 += s.2 * speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.moving_forward {
|
||||||
|
self.position.0 += f.0 * speed;
|
||||||
|
self.position.1 += f.1 * speed;
|
||||||
|
self.position.2 += f.2 * speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.moving_backward {
|
||||||
|
self.position.0 -= f.0 * speed;
|
||||||
|
self.position.1 -= f.1 * speed;
|
||||||
|
self.position.2 -= f.2 * speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_input(&mut self, input: glutin::KeyboardInput) {
|
||||||
|
let pressed = input.state == glutin::ElementState::Pressed;
|
||||||
|
match input.virtual_keycode {
|
||||||
|
Some(glutin::VirtualKeyCode::Up) => self.moving_up = pressed,
|
||||||
|
Some(glutin::VirtualKeyCode::Down) => self.moving_down = pressed,
|
||||||
|
Some(glutin::VirtualKeyCode::Left) => self.moving_left = pressed,
|
||||||
|
Some(glutin::VirtualKeyCode::Right) => self.moving_right = pressed,
|
||||||
|
Some(glutin::VirtualKeyCode::Q) => self.moving_forward = pressed,
|
||||||
|
Some(glutin::VirtualKeyCode::A) => self.moving_backward = pressed,
|
||||||
|
_ => {}
|
||||||
|
};
|
||||||
|
self.update();
|
||||||
|
}
|
||||||
|
}
|
@ -1,187 +1,136 @@
|
|||||||
// Can't figure out what macros to import using the 2018 use style.
|
use glium::vertex::VertexBufferAny;
|
||||||
#[macro_use]
|
use glium::{glutin, program, uniform, Surface};
|
||||||
extern crate gfx;
|
use std::thread;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
use std::{env, process};
|
||||||
|
|
||||||
use gfx::traits::{Device, FactoryExt};
|
mod camera;
|
||||||
use glutin::dpi::LogicalSize;
|
mod support;
|
||||||
use glutin::GlContext;
|
|
||||||
|
|
||||||
type ColorFormat = gfx::format::Rgba8;
|
|
||||||
type DepthFormat = gfx::format::DepthStencil;
|
|
||||||
|
|
||||||
const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];
|
|
||||||
|
|
||||||
gfx_defines! {
|
|
||||||
vertex GpuFillVertex {
|
|
||||||
position: [f32; 2] = "a_position",
|
|
||||||
}
|
|
||||||
|
|
||||||
pipeline fill_pipeline {
|
|
||||||
vbo: gfx::VertexBuffer<GpuFillVertex> = (),
|
|
||||||
out_color: gfx::RenderTarget<ColorFormat> = "out_color",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
// DPI is broken on my system; force the old behavior.
|
||||||
|
env::set_var("WINIT_HIDPI_FACTOR", "1.0");
|
||||||
|
|
||||||
let mut events_loop = glutin::EventsLoop::new();
|
let mut events_loop = glutin::EventsLoop::new();
|
||||||
|
let window = glutin::WindowBuilder::new()
|
||||||
|
.with_title("testing glium")
|
||||||
|
.with_dimensions(glutin::dpi::LogicalSize::new(1024.0, 768.0));
|
||||||
|
let context = glutin::ContextBuilder::new().with_depth_buffer(24);
|
||||||
|
let display = glium::Display::new(window, context, &events_loop).unwrap();
|
||||||
|
|
||||||
let (initial_width, initial_height) = (700.0, 700.0);
|
// TODO The geometry...
|
||||||
|
let vertex_buffer = support::load_wavefront(&display, include_bytes!("teapot.obj"));
|
||||||
|
|
||||||
let glutin_builder = glutin::WindowBuilder::new()
|
let program = program!(&display,
|
||||||
.with_dimensions(LogicalSize::new(initial_width, initial_height))
|
140 => {
|
||||||
.with_decorations(true)
|
vertex: "
|
||||||
.with_title("gfx playground".to_string());
|
#version 140
|
||||||
|
|
||||||
let context = glutin::ContextBuilder::new().with_vsync(true);
|
uniform mat4 persp_matrix;
|
||||||
|
uniform mat4 view_matrix;
|
||||||
|
|
||||||
let (window, mut device, mut factory, mut main_fbo, mut main_depth) =
|
in vec3 position;
|
||||||
gfx_window_glutin::init::<ColorFormat, DepthFormat>(glutin_builder, context, &events_loop);
|
in vec3 normal;
|
||||||
|
out vec3 v_position;
|
||||||
|
out vec3 v_normal;
|
||||||
|
|
||||||
let shader = factory
|
void main() {
|
||||||
.link_program(VERTEX_SHADER.as_bytes(), FRAGMENT_SHADER.as_bytes())
|
v_position = position;
|
||||||
.unwrap();
|
v_normal = normal;
|
||||||
|
gl_Position = persp_matrix * view_matrix * vec4(v_position * 0.005, 1.0);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
|
||||||
let pso = factory
|
fragment: "
|
||||||
.create_pipeline_from_program(
|
#version 140
|
||||||
&shader,
|
|
||||||
gfx::Primitive::TriangleList,
|
in vec3 v_normal;
|
||||||
gfx::state::Rasterizer::new_fill(),
|
out vec4 f_color;
|
||||||
fill_pipeline::new(),
|
|
||||||
|
const vec3 LIGHT = vec3(-0.2, 0.8, 0.1);
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float lum = max(dot(normalize(v_normal), normalize(LIGHT)), 0.0);
|
||||||
|
vec3 color = (0.3 + 0.7 * lum) * vec3(1.0, 1.0, 1.0);
|
||||||
|
f_color = vec4(color, 1.0);
|
||||||
|
}
|
||||||
|
",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// The geometry!
|
let mut camera = camera::CameraState::new();
|
||||||
let vertices = vec![
|
|
||||||
// 0 = Top-left
|
|
||||||
GpuFillVertex {
|
|
||||||
position: [-1.0, 0.7],
|
|
||||||
},
|
|
||||||
// 1 = Top-right
|
|
||||||
GpuFillVertex {
|
|
||||||
position: [1.0, 1.0],
|
|
||||||
},
|
|
||||||
// 2 = Bottom-left
|
|
||||||
GpuFillVertex {
|
|
||||||
position: [-1.0, -1.0],
|
|
||||||
},
|
|
||||||
// 3 = Bottom-right
|
|
||||||
GpuFillVertex {
|
|
||||||
position: [1.0, -1.0],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
let indices: Vec<u16> = vec![0, 1, 2, 1, 2, 3];
|
|
||||||
let (vbo, ibo) = factory.create_vertex_buffer_with_slice(&vertices, &indices[..]);
|
|
||||||
|
|
||||||
let mut cmd_queue: gfx::Encoder<_, _> = factory.create_command_buffer().into();
|
let mut accumulator = Duration::new(0, 0);
|
||||||
|
let mut previous_clock = Instant::now();
|
||||||
|
|
||||||
let mut cam = Camera {
|
|
||||||
center_x: initial_width / 2.0,
|
|
||||||
center_y: initial_height / 2.0,
|
|
||||||
//zoom: 1.0,
|
|
||||||
};
|
|
||||||
loop {
|
loop {
|
||||||
if !handle_input(&mut events_loop, &mut cam) {
|
draw(&camera, &display, &program, &vertex_buffer);
|
||||||
break;
|
handle_events(&mut camera, &mut events_loop);
|
||||||
|
|
||||||
|
let now = Instant::now();
|
||||||
|
accumulator += now - previous_clock;
|
||||||
|
previous_clock = now;
|
||||||
|
|
||||||
|
let fixed_time_stamp = Duration::new(0, 16666667);
|
||||||
|
while accumulator >= fixed_time_stamp {
|
||||||
|
accumulator -= fixed_time_stamp;
|
||||||
|
// TODO send off an update event
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx_window_glutin::update_views(&window, &mut main_fbo, &mut main_depth);
|
thread::sleep(fixed_time_stamp - accumulator);
|
||||||
|
|
||||||
cmd_queue.clear(&main_fbo.clone(), BLACK);
|
|
||||||
cmd_queue.draw(
|
|
||||||
&ibo,
|
|
||||||
&pso,
|
|
||||||
&fill_pipeline::Data {
|
|
||||||
vbo: vbo.clone(),
|
|
||||||
out_color: main_fbo.clone(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
cmd_queue.flush(&mut device);
|
|
||||||
|
|
||||||
window.swap_buffers().unwrap();
|
|
||||||
|
|
||||||
device.cleanup();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Camera {
|
fn draw(
|
||||||
// Center on some point
|
camera: &camera::CameraState,
|
||||||
center_x: f64,
|
display: &glium::Display,
|
||||||
center_y: f64,
|
program: &glium::Program,
|
||||||
//zoom: f64,
|
vertex_buffer: &VertexBufferAny,
|
||||||
|
) {
|
||||||
|
let uniforms = uniform! {
|
||||||
|
persp_matrix: camera.get_perspective(),
|
||||||
|
view_matrix: camera.get_view(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let params = glium::DrawParameters {
|
||||||
|
depth: glium::Depth {
|
||||||
|
test: glium::DepthTest::IfLess,
|
||||||
|
write: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut target = display.draw();
|
||||||
|
target.clear_color_and_depth((0.0, 0.0, 0.0, 0.0), 1.0);
|
||||||
|
target
|
||||||
|
.draw(
|
||||||
|
vertex_buffer,
|
||||||
|
&glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList),
|
||||||
|
&program,
|
||||||
|
&uniforms,
|
||||||
|
¶ms,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
target.finish().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_input(event_loop: &mut glutin::EventsLoop, cam: &mut Camera) -> bool {
|
fn handle_events(camera: &mut camera::CameraState, events_loop: &mut glutin::EventsLoop) {
|
||||||
use glutin::ElementState::Pressed;
|
events_loop.poll_events(|event| match event {
|
||||||
use glutin::Event;
|
glutin::Event::WindowEvent { event, .. } => match event {
|
||||||
use glutin::VirtualKeyCode;
|
glutin::WindowEvent::CloseRequested => {
|
||||||
|
process::exit(0);
|
||||||
|
}
|
||||||
|
glutin::WindowEvent::KeyboardInput { input, .. } => {
|
||||||
|
if input.virtual_keycode == Some(glutin::VirtualKeyCode::Escape) {
|
||||||
|
process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
let mut keep_running = true;
|
camera.process_input(input);
|
||||||
|
|
||||||
event_loop.poll_events(|event| match event {
|
|
||||||
Event::WindowEvent {
|
|
||||||
event: glutin::WindowEvent::CloseRequested,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
println!("Window Closed!");
|
|
||||||
keep_running = false;
|
|
||||||
}
|
|
||||||
Event::WindowEvent {
|
|
||||||
event:
|
|
||||||
glutin::WindowEvent::KeyboardInput {
|
|
||||||
input:
|
|
||||||
glutin::KeyboardInput {
|
|
||||||
state: Pressed,
|
|
||||||
virtual_keycode: Some(key),
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} => match key {
|
|
||||||
VirtualKeyCode::Escape => {
|
|
||||||
keep_running = false;
|
|
||||||
}
|
|
||||||
VirtualKeyCode::Left => {
|
|
||||||
cam.center_x -= 1.0;
|
|
||||||
}
|
|
||||||
VirtualKeyCode::Right => {
|
|
||||||
cam.center_x += 1.0;
|
|
||||||
}
|
|
||||||
VirtualKeyCode::Up => {
|
|
||||||
cam.center_y += 1.0;
|
|
||||||
}
|
|
||||||
VirtualKeyCode::Down => {
|
|
||||||
cam.center_y -= 1.0;
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
keep_running
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Coordinate system is math-like -- Y increases up.
|
|
||||||
|
|
||||||
static VERTEX_SHADER: &'static str = "
|
|
||||||
#version 140
|
|
||||||
|
|
||||||
in vec2 a_position;
|
|
||||||
out vec4 v_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
||||||
// gl_Position.y *= -1.0;
|
|
||||||
v_color = vec4(1.0, 0.0, 0.0, 0.5);
|
|
||||||
}
|
|
||||||
";
|
|
||||||
|
|
||||||
static FRAGMENT_SHADER: &'static str = "
|
|
||||||
#version 140
|
|
||||||
in vec4 v_color;
|
|
||||||
out vec4 out_color;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
out_color = v_color;
|
|
||||||
}
|
|
||||||
";
|
|
||||||
|
53
tmp_gfx/src/support.rs
Normal file
53
tmp_gfx/src/support.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use genmesh;
|
||||||
|
use glium::vertex::VertexBufferAny;
|
||||||
|
use glium::{self, implement_vertex, Display};
|
||||||
|
use obj;
|
||||||
|
|
||||||
|
/// Returns a vertex buffer that should be rendered as `TrianglesList`.
|
||||||
|
pub fn load_wavefront(display: &Display, data: &[u8]) -> VertexBufferAny {
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
struct Vertex {
|
||||||
|
position: [f32; 3],
|
||||||
|
normal: [f32; 3],
|
||||||
|
texture: [f32; 2],
|
||||||
|
}
|
||||||
|
|
||||||
|
implement_vertex!(Vertex, position, normal, texture);
|
||||||
|
|
||||||
|
let mut data = ::std::io::BufReader::new(data);
|
||||||
|
let data = obj::Obj::load_buf(&mut data).unwrap();
|
||||||
|
|
||||||
|
let mut vertex_data = Vec::new();
|
||||||
|
|
||||||
|
for object in data.objects.iter() {
|
||||||
|
for polygon in object.groups.iter().flat_map(|g| g.polys.iter()) {
|
||||||
|
match polygon {
|
||||||
|
&genmesh::Polygon::PolyTri(genmesh::Triangle {
|
||||||
|
x: v1,
|
||||||
|
y: v2,
|
||||||
|
z: v3,
|
||||||
|
}) => {
|
||||||
|
for v in [v1, v2, v3].iter() {
|
||||||
|
let position = data.position[v.0];
|
||||||
|
let texture = v.1.map(|index| data.texture[index]);
|
||||||
|
let normal = v.2.map(|index| data.normal[index]);
|
||||||
|
|
||||||
|
let texture = texture.unwrap_or([0.0, 0.0]);
|
||||||
|
let normal = normal.unwrap_or([0.0, 0.0, 0.0]);
|
||||||
|
|
||||||
|
vertex_data.push(Vertex {
|
||||||
|
position: position,
|
||||||
|
normal: normal,
|
||||||
|
texture: texture,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glium::vertex::VertexBuffer::new(display, &vertex_data)
|
||||||
|
.unwrap()
|
||||||
|
.into_vertex_buffer_any()
|
||||||
|
}
|
2090
tmp_gfx/src/teapot.obj
Normal file
2090
tmp_gfx/src/teapot.obj
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user