-
-
Save jimblandy/925f10a48fdd3958288f9d63a564d066 to your computer and use it in GitHub Desktop.
Glium - instancing over a vertex buffer slice
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! An example demonstrating that glium has a problem using instancing when | |
//! the vertex buffer is a slice with a non-zero starting index. | |
//! | |
#[macro_use] extern crate glium; | |
use glium::{glutin, Surface}; | |
// Vertex Shader: | |
static VERTEX_SHADER_SRC: &'static str = r#" | |
#version 140 | |
in vec2 position; | |
in float x_shift; | |
void main() { | |
gl_Position = vec4(position.x + x_shift, position.y, 0.0, 1.0); | |
} | |
"#; | |
// Fragment Shader: | |
static FRAGMENT_SHADER_SRC: &'static str = r#" | |
#version 140 | |
out vec4 color; | |
void main() { | |
color = vec4(0.1, 0.1, 0.4, 1.0); | |
} | |
"#; | |
#[derive(Copy, Clone)] | |
struct PosVertex { | |
position: [f32; 2], | |
} | |
implement_vertex!(PosVertex, position); | |
#[derive(Copy, Clone)] | |
struct TransVertex { | |
x_shift: f32, | |
} | |
implement_vertex!(TransVertex, x_shift); | |
fn main() { | |
let events_loop = glutin::EventsLoop::new(); | |
let window = glutin::WindowBuilder::new(); | |
let context = glutin::ContextBuilder::new(); | |
let display = glium::Display::new(window, context, &events_loop).unwrap(); | |
let program = glium::Program::from_source(&display, VERTEX_SHADER_SRC, | |
FRAGMENT_SHADER_SRC, None).unwrap(); | |
let triangle_models = vec![ | |
PosVertex { position: [-0.125, -0.125] }, | |
PosVertex { position: [ 0.0, 0.125] }, | |
PosVertex { position: [ 0.125, -0.35] }, | |
PosVertex { position: [-0.1, -0.1] }, | |
PosVertex { position: [ 0.0, 0.15] }, | |
PosVertex { position: [ 0.125, -0.10] }, | |
PosVertex { position: [-0.35, -0.25] }, | |
PosVertex { position: [ 0.0, 0.35] }, | |
PosVertex { position: [ 0.125, -0.10] }, | |
]; | |
let instances = &vec![ | |
TransVertex { x_shift: 0.2 }, | |
TransVertex { x_shift: 0.5 }, | |
TransVertex { x_shift: 0.0 }, | |
TransVertex { x_shift: -0.4 }, | |
TransVertex { x_shift: 0.3 }, | |
TransVertex { x_shift: -0.1 }, | |
TransVertex { x_shift: -0.6 }, | |
]; | |
let model_buf = glium::VertexBuffer::new(&display, &triangle_models).unwrap(); | |
let instance_buf = glium::VertexBuffer::new(&display, &instances).unwrap(); | |
let (indices, uniforms, params) = ( | |
glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList), | |
glium::uniforms::EmptyUniforms, | |
Default::default(), | |
); | |
for _ in 0..600 { | |
let mut surface = display.draw(); | |
// Drawing the entire models vertex buffer (all three triangles, a | |
// total of 9 vertices * 7 instances) works just fine: | |
surface.draw((&model_buf, instance_buf.per_instance().unwrap()), | |
&indices, &program, &uniforms, ¶ms).unwrap(); | |
// Likewise, drawing only the first triangle, or any number of | |
// vertices from the start of the models vertex buffer, is fine: | |
surface.draw((model_buf.slice(0..3).unwrap(), instance_buf.per_instance().unwrap()), | |
&indices, &program, &uniforms, ¶ms).unwrap(); | |
// As soon as we attempt to draw the second triangle model (or any | |
// other range of vertices which does not start at the beginning of | |
// the buffer), we get a subtraction overflow: | |
surface.draw((model_buf.slice(3..6).unwrap(), instance_buf.per_instance().unwrap()), | |
&indices, &program, &uniforms, ¶ms).unwrap(); | |
surface.finish().unwrap(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment