Created
July 28, 2016 15:59
-
-
Save c0gent/73dfac1c7a6b9207354a3ec6fcb9f376 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::{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, ¶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