Skip to content

Instantly share code, notes, and snippets.

@c0gent
Created July 28, 2016 15:59
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save c0gent/73dfac1c7a6b9207354a3ec6fcb9f376 to your computer and use it in GitHub Desktop.
Save c0gent/73dfac1c7a6b9207354a3ec6fcb9f376 to your computer and use it in GitHub Desktop.
Glium - instancing over a vertex buffer slice
//! 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::{DisplayBuild, 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 display = glium::glutin::WindowBuilder::new().with_vsync().build_glium().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, &params).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, &params).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, &params).unwrap();
surface.finish().unwrap();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment