extern crate glutin;
#[macro_use]
extern crate glium;
use glium::Surface;
mod support;
fn main() {
use glium::DisplayBuild;
let display = glutin::WindowBuilder::new()
.build_glium()
.unwrap();
let vertex_buffer = {
#[derive(Copy, Clone)]
struct Vertex {
position: [f32; 2],
}
implement_vertex!(Vertex, position);
glium::VertexBuffer::new(&display,
vec![
Vertex { position: [-0.5, -0.5] },
Vertex { position: [ 0.0, 0.5] },
Vertex { position: [ 0.5, -0.5] },
]
)
};
let index_buffer = glium::IndexBuffer::new(&display,
glium::index::Patches(vec![0u16, 1, 2], 3));
let program = glium::Program::new(&display,
glium::program::SourceCode {
vertex_shader: "
#version 140
in vec2 position;
void main() {
gl_Position = vec4(position, 0.0, 1.0);
}
",
fragment_shader: "
#version 140
in vec3 color;
out vec4 f_color;
void main() {
f_color = vec4(color, 1.0);
}
",
geometry_shader: Some("
#version 330
uniform mat4 matrix;
layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;
out vec3 color;
float rand(vec2 co) {
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
void main() {
vec3 all_color = vec3(
rand(gl_in[0].gl_Position.xy + gl_in[1].gl_Position.yz),
rand(gl_in[1].gl_Position.yx + gl_in[2].gl_Position.zx),
rand(gl_in[0].gl_Position.xz + gl_in[2].gl_Position.zy)
);
gl_Position = matrix * gl_in[0].gl_Position;
color = all_color;
EmitVertex();
gl_Position = matrix * gl_in[1].gl_Position;
color = all_color;
EmitVertex();
gl_Position = matrix * gl_in[2].gl_Position;
color = all_color;
EmitVertex();
}
"),
tessellation_control_shader: Some("
#version 400
layout(vertices = 3) out;
uniform int tess_level = 5;
void main() {
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
gl_TessLevelOuter[0] = tess_level;
gl_TessLevelOuter[1] = tess_level;
gl_TessLevelOuter[2] = tess_level;
gl_TessLevelInner[0] = tess_level;
}
"),
tessellation_evaluation_shader: Some("
#version 400
layout(triangles, equal_spacing) in;
void main() {
vec3 position = vec3(gl_TessCoord.x) * gl_in[0].gl_Position.xyz +
vec3(gl_TessCoord.y) * gl_in[1].gl_Position.xyz +
vec3(gl_TessCoord.z) * gl_in[2].gl_Position.xyz;
gl_Position = vec4(position, 1.0);
}
"),
}).unwrap();
let mut tess_level: i32 = 5;
println!("The current tessellation level is {} ; use the Up and Down keys to change it", tess_level);
support::start_loop(|| {
let uniforms = uniform! {
matrix: [
[1.0, 0.0, 0.0, 0.0],
[0.0, 1.0, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0f32]
],
tess_level: tess_level
};
let mut target = display.draw();
target.clear_color(0.0, 0.0, 0.0, 0.0);
target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &std::default::Default::default()).unwrap();
target.finish();
for event in display.poll_events() {
match event {
glutin::Event::Closed => return support::Action::Stop,
glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Up)) => {
tess_level += 1;
println!("New tessellation level: {}", tess_level);
},
glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(glutin::VirtualKeyCode::Down)) => {
if tess_level >= 2 {
tess_level -= 1;
println!("New tessellation level: {}", tess_level);
}
},
_ => ()
}
}
support::Action::Continue
});
}