Skip to content

Instantly share code, notes, and snippets.

@ucarion
Last active September 12, 2017 00:56
Show Gist options
  • Save ucarion/7aa6276ac101cd33537e2af8907ef7bb to your computer and use it in GitHub Desktop.
Save ucarion/7aa6276ac101cd33537e2af8907ef7bb to your computer and use it in GitHub Desktop.
[dependencies]
camera_controllers = "0.22"
gfx = "0.16"
pistoncore-sdl2_window = "0.44"
piston_window = "0.70"
vecmath = "0.3"
glutin = "*"
gfx_window_glutin = "*"
#version 150 core
uniform sampler2D t_texture;
in vec2 v_tex_coords;
out vec4 o_color;
void main() {
float depth = texture(t_texture, v_tex_coords).r;
o_color = vec4(depth, depth, depth, 1.0);
}
#version 150 core
in vec2 a_coords;
out vec2 v_tex_coords;
void main() {
v_tex_coords = (vec2(1.0, 1.0) + a_coords) / 2.0;
gl_Position = vec4(a_coords, 0.0, 1.0);
}
#[macro_use]
extern crate gfx;
extern crate camera_controllers;
extern crate gfx_window_glutin;
extern crate piston_window;
extern crate vecmath;
use camera_controllers::{CameraPerspective, OrbitZoomCamera, OrbitZoomCameraSettings};
use gfx::Factory;
use gfx::traits::FactoryExt;
use piston_window::{OpenGL, PistonWindow, RenderEvent, ResizeEvent, Window, WindowSettings};
gfx_vertex_struct!(Vertex {
position: [f32; 3] = "a_position",
tex_coords: [f32; 2] = "a_tex_coords",
});
// out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
// out_stencil: gfx::StencilTarget<gfx::format::DepthStencil> = gfx::state::Stencil::new(
// gfx::state::Comparison::LessEqual,
// 0,
// (gfx::state::StencilOp::IncrementClamp, gfx::state::StencilOp::Keep, gfx::state::StencilOp::Keep),
// ),
gfx_pipeline!(terrain_pipeline {
out_color: gfx::RenderTarget<gfx::format::Srgba8> = "o_color",
color_texture: gfx::TextureSampler<[f32; 4]> = "t_color",
mvp: gfx::Global<[[f32; 4]; 4]> = "u_mvp",
vertex_buffer: gfx::VertexBuffer<Vertex> = (),
out_depth_stencil: gfx::DepthStencilTarget<gfx::format::DepthStencil> = (
gfx::preset::depth::LESS_EQUAL_WRITE,
gfx::state::Stencil::new(
gfx::state::Comparison::LessEqual,
255,
(
gfx::state::StencilOp::IncrementClamp,
gfx::state::StencilOp::Keep,
gfx::state::StencilOp::Keep
),
),
),
});
gfx_vertex_struct!(PlainVertex {
// this is to make rustfmt go away
coords: [f32; 2] = "a_coords",
});
gfx_pipeline!(just_texture_pipeline {
out_color: gfx::RenderTarget<gfx::format::Srgba8> = "o_color",
out_depth: gfx::DepthTarget<gfx::format::DepthStencil> = gfx::preset::depth::LESS_EQUAL_WRITE,
color_texture: gfx::TextureSampler<f32> = "t_texture",
vertex_buffer: gfx::VertexBuffer<PlainVertex> = (),
});
// // XXX these only work for the z-fail approach
// gfx_pipeline!(back_face_pipeline {
// polyhedron: gfx::VertexBuffer<Vertex> = (),
// out_color: gfx::RenderTarget<gfx::format::Srgba8> = "o_color",
// out_depth: gfx::StencilTarget<gfx::format::DepthStencil> = gfx::state::Stencil::new(
// ),
// });
fn get_projection(window: &PistonWindow) -> [[f32; 4]; 4] {
let draw_size = window.window.draw_size();
CameraPerspective {
fov: 45.0,
near_clip: 10.0,
far_clip: 1000.0,
aspect_ratio: (draw_size.width as f32) / (draw_size.height as f32),
}.projection()
}
fn get_elevation(x: f32, y: f32) -> f32 {
((x / 10.0).sin() + (y / 5.0).sin()) * 10.0
}
const TERRAIN_SIDE_LENGTH: u16 = 100;
fn polygon_to_vertices_and_indices(polygon: &[(f32, f32)]) -> (Vec<Vertex>, Vec<u16>) {
let mut vertices = Vec::new();
let mut indices = Vec::new();
for (index, &(x, y)) in polygon.iter().enumerate() {
let above = [x, y, 20.1];
let below = [x, y, -20.1];
vertices.push(Vertex {
position: above,
tex_coords: [0.0, 0.0],
});
vertices.push(Vertex {
position: below,
tex_coords: [0.0, 0.0],
});
let a = 2 * index as u16;
let b = a + 1;
let c = 2 * ((index as u16 + 1) % (polygon.len() as u16));
let d = c + 1;
indices.extend_from_slice(&[a, b, d, d, c, a]);
if index != 0 && index != polygon.len() - 1 {
indices.extend_from_slice(&[0, a, c, 1, d, b]);
}
}
(vertices, indices)
}
fn main() {
let mut window: PistonWindow = WindowSettings::new("Shadow Volume Draping Demo", [800, 600])
.exit_on_esc(true)
.opengl(OpenGL::V3_2)
.build()
.unwrap();
let mut factory = window.factory.clone();
let mut terrain_vertices = Vec::new();
let mut terrain_indices = Vec::new();
let mut terrain_texture_data = Vec::new();
for y in 0..TERRAIN_SIDE_LENGTH {
for x in 0..TERRAIN_SIDE_LENGTH {
let max_value = TERRAIN_SIDE_LENGTH - 1;
if y != max_value && x != max_value {
let a = (x + 0) + (y + 0) * TERRAIN_SIDE_LENGTH;
let b = (x + 1) + (y + 0) * TERRAIN_SIDE_LENGTH;
let c = (x + 0) + (y + 1) * TERRAIN_SIDE_LENGTH;
let d = (x + 1) + (y + 1) * TERRAIN_SIDE_LENGTH;
terrain_indices.extend_from_slice(&[a, c, b, b, c, d]);
}
let (x, y) = (x as f32, y as f32);
let (u, v) = (x / max_value as f32, y / max_value as f32);
terrain_vertices.push(Vertex {
position: [x, -y, get_elevation(x, y)],
tex_coords: [u, v],
});
terrain_texture_data.push([(255.0 * u) as u8, (255.0 * v) as u8, 0, 255]);
}
}
let (terrain_vertex_buffer, terrain_slice) =
factory.create_vertex_buffer_with_slice(&terrain_vertices, terrain_indices.as_slice());
let (_, terrain_texture_view) = factory
.create_texture_immutable::<gfx::format::Srgba8>(
gfx::texture::Kind::D2(
TERRAIN_SIDE_LENGTH,
TERRAIN_SIDE_LENGTH,
gfx::texture::AaMode::Single,
),
&[terrain_texture_data.as_slice()],
)
.unwrap();
let terrain_sampler = factory.create_sampler(gfx::texture::SamplerInfo::new(
gfx::texture::FilterMethod::Bilinear,
gfx::texture::WrapMode::Clamp,
));
let terrain_shader_set = factory
.create_shader_set(
include_bytes!("shaders/terrain.vert"),
include_bytes!("shaders/terrain.frag"),
)
.unwrap();
let terrain_pso = factory
.create_pipeline_state(
&terrain_shader_set,
gfx::Primitive::TriangleList,
gfx::state::Rasterizer::new_fill().with_cull_back(),
terrain_pipeline::new(),
)
.unwrap();
let (depth_stencil_texture, depth_stencil_srv, depth_stencil_rtv) = factory
.create_depth_stencil::<gfx::format::DepthStencil>(800, 600)
.unwrap();
let (render_target_tex, render_target_srv, render_target_view) = factory
.create_render_target::<gfx::format::Srgba8>(800, 600)
.unwrap();
let terrain_data = terrain_pipeline::Data {
color_texture: (terrain_texture_view.clone(), terrain_sampler.clone()),
mvp: [[0.0; 4]; 4],
out_color: render_target_view.clone(),
out_depth_stencil: (depth_stencil_rtv.clone(), (0, 0)),
vertex_buffer: terrain_vertex_buffer,
};
let mut terrain_bundle = gfx::Bundle {
slice: terrain_slice,
pso: terrain_pso,
data: terrain_data,
};
let polygon_pso = factory
.create_pipeline_state(
&terrain_shader_set,
gfx::Primitive::TriangleList,
gfx::state::Rasterizer::new_fill().with_cull_back(),
terrain_pipeline::new(),
)
.unwrap();
let polygon = vec![
(40.0, -60.0),
(60.0, -60.0),
(60.0, -40.0),
(40.0, -40.0),
(40.0, -60.0),
];
let (polygon_vertices, polygon_indices) = polygon_to_vertices_and_indices(&polygon);
let (polygon_vertex_buffer, polygon_slice) =
factory.create_vertex_buffer_with_slice(&polygon_vertices, &polygon_indices[..]);
let polygon_data = terrain_pipeline::Data {
color_texture: (terrain_texture_view.clone(), terrain_sampler.clone()),
mvp: [[0.0; 4]; 4],
out_color: render_target_view.clone(),
out_depth_stencil: (depth_stencil_rtv.clone(), (0, 0)),
// out_depth: depth_rtv.clone(),
vertex_buffer: polygon_vertex_buffer,
// out_stencil: (depth_rtv.clone(), (800, 600)),
};
let mut polygon_bundle = gfx::Bundle {
slice: polygon_slice,
pso: polygon_pso,
data: polygon_data,
};
let jt_vertices = vec![
PlainVertex { coords: [-1.0, -1.0] },
PlainVertex { coords: [-1.0, 1.0] },
PlainVertex { coords: [ 1.0, -1.0] },
PlainVertex { coords: [ 1.0, 1.0] },
];
let jt_indices: Vec<u16> = vec![0, 1, 2, 1, 2, 3];
let (jt_vbuf, jt_slice) =
factory.create_vertex_buffer_with_slice(&jt_vertices, jt_indices.as_slice());
let jt_shader_set = factory
.create_shader_set(
include_bytes!("shaders/just_texture.vert"),
include_bytes!("shaders/just_texture.frag"),
)
.unwrap();
let jt_pso = factory
.create_pipeline_state(
&jt_shader_set,
gfx::Primitive::TriangleList,
gfx::state::Rasterizer::new_fill(),
just_texture_pipeline::new(),
)
.unwrap();
let render_target_sampler = factory.create_sampler(gfx::texture::SamplerInfo::new(
gfx::texture::FilterMethod::Bilinear,
gfx::texture::WrapMode::Clamp,
));
let jt_data = just_texture_pipeline::Data {
color_texture: (depth_stencil_srv, terrain_sampler.clone()),
// color_texture: (render_target_srv, terrain_sampler.clone()),
out_color: window.output_color.clone(),
out_depth: window.output_stencil.clone(),
vertex_buffer: jt_vbuf,
};
let mut just_texture_bundle = gfx::Bundle {
slice: jt_slice,
pso: jt_pso,
data: jt_data,
};
let mut camera_controller =
OrbitZoomCamera::new([0.0, 0.0, 0.0], OrbitZoomCameraSettings::default());
let mut new_dimensions = None;
while let Some(event) = window.next() {
camera_controller.event(&event);
event.resize(|height, width| {
println!("Resize!");
new_dimensions = Some((height, width));
});
window.draw_3d(&event, |window| {
if let Some((height, width)) = new_dimensions {
println!("Create new stuff");
let (window_render_target, window_depth_stencil) =
gfx_window_glutin::new_views(&window.window.window);
let (depth_stencil_texture, depth_stencil_srv, depth_stencil_rtv) = factory
.create_depth_stencil::<gfx::format::DepthStencil>(height as u16, width as u16)
.unwrap();
let (render_target_tex, render_target_srv, render_target_view) = factory
.create_render_target::<gfx::format::Srgba8>(height as u16, width as u16)
.unwrap();
terrain_bundle.data.out_color = render_target_view.clone();
terrain_bundle.data.out_depth_stencil = (depth_stencil_rtv.clone(), (0, 0));
polygon_bundle.data.out_color = render_target_view.clone();
polygon_bundle.data.out_depth_stencil = (depth_stencil_rtv.clone(), (0, 0));
just_texture_bundle.data.color_texture.0 = depth_stencil_srv;
// just_texture_bundle.data.out_color = window.output_color.clone();
// just_texture_bundle.data.out_depth = window.output_stencil.clone();
just_texture_bundle.data.out_color = window_render_target;
just_texture_bundle.data.out_depth = window_depth_stencil;
new_dimensions = None;
println!("Done creating new stuff");
} else {
println!("Drawing without resize");
}
let render_args = event.render_args().unwrap();
window.encoder.clear(
&window.output_color,
[0.3, 0.3, 0.3, 1.0],
);
window.encoder.clear_depth(&window.output_stencil, 1.0);
window.encoder.clear(
&terrain_bundle.data.out_color,
[0.3, 0.3, 0.3, 1.0],
);
window.encoder.clear_depth(
&terrain_bundle.data.out_depth_stencil.0,
1.0,
);
window.encoder.clear_stencil(
&terrain_bundle.data.out_depth_stencil.0,
0,
);
let mvp = camera_controllers::model_view_projection(
vecmath::mat4_id(),
camera_controller.camera(render_args.ext_dt).orthogonal(),
get_projection(window),
);
terrain_bundle.data.mvp = mvp;
terrain_bundle.encode(&mut window.encoder);
polygon_bundle.data.mvp = mvp;
polygon_bundle.encode(&mut window.encoder);
just_texture_bundle.encode(&mut window.encoder);
});
}
}
#version 150 core
in vec4 v_color;
out vec4 o_color;
void main() {
o_color = v_color;
}
#version 150 core
uniform mat4 u_mvp;
uniform sampler2D t_color;
in vec3 a_position;
in vec2 a_tex_coords;
out vec4 v_color;
void main() {
v_color = texture(t_color, a_tex_coords);
gl_Position = u_mvp * vec4(a_position, 1.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment