use notan::prelude::*; const VERT: ShaderSource = notan::vertex_shader! { r#" #version 450 layout(location = 0) in vec2 a_pos; layout(location = 1) in vec3 a_color; layout(location = 0) out vec3 v_color; void main() { v_color = a_color; gl_Position = vec4(a_pos - 0.5, 0.0, 1.0); } "# }; const FRAG: ShaderSource = notan::fragment_shader! { r#" #version 450 precision mediump float; layout(location = 0) in vec3 v_color; layout(location = 0) out vec4 color; void main() { color = vec4(v_color, 1.0); } "# }; #[derive(AppState)] struct State { clear_options: ClearOptions, mask_pipeline: Pipeline, pipeline: Pipeline, mask_vbo: Buffer, vbo: Buffer, } #[notan_main] fn main() -> Result<(), String> { notan::init_with(setup).draw(draw).build() } fn setup(gfx: &mut Graphics) -> State { let clear_options = ClearOptions { color: Some(Color::new(0.1, 0.2, 0.3, 1.0)), depth: None, stencil: Some(0), }; let vertex_info = VertexInfo::new() .attr(0, VertexFormat::Float32x2) .attr(1, VertexFormat::Float32x3); let stencil_maks_opts = StencilOptions { stencil_fail: StencilAction::Keep, depth_fail: StencilAction::Keep, pass: StencilAction::Replace, compare: CompareMode::Always, read_mask: 0xff, write_mask: 0xff, reference: 1, }; let mask_pipeline = gfx .create_pipeline() .from(&VERT, &FRAG) .with_vertex_info(&vertex_info) .with_stencil(stencil_maks_opts) .build() .unwrap(); let stencil_opts = StencilOptions { stencil_fail: StencilAction::Keep, depth_fail: StencilAction::Keep, pass: StencilAction::Keep, compare: CompareMode::Equal, read_mask: 0xff, write_mask: 0x00, reference: 1, }; let pipeline = gfx .create_pipeline() .from(&VERT, &FRAG) .with_vertex_info(&vertex_info) .with_stencil(stencil_opts) .build() .unwrap(); // masking vertices #[rustfmt::skip] let mask_vertices = [ 0.5, 1.35, 1.0, 1.0, 1.0, 0.25, 0.85, 1.0, 1.0, 1.0, 0.75, 0.85, 1.0, 1.0, 1.0, 0.75, 0.85, 1.0, 1.0, 1.0, 0.5, 0.35, 1.0, 1.0, 1.0, 1.0, 0.35, 1.0, 1.0, 1.0, 0.25, 0.85, 1.0, 1.0, 1.0, 0.0, 0.35, 1.0, 1.0, 1.0, 0.5, 0.35, 1.0, 1.0, 1.0, 0.5, 0.35, 1.0, 1.0, 1.0, 0.25, -0.15, 1.0, 1.0, 1.0, 0.75, -0.15, 1.0, 1.0, 1.0, 1.0, 0.35, 1.0, 1.0, 1.0, 0.75, -0.15, 1.0, 1.0, 1.0, 1.25, -0.15, 1.0, 1.0, 1.0, 0.0, 0.35, 1.0, 1.0, 1.0, -0.25, -0.15, 1.0, 1.0, 1.0, 0.25, -0.15, 1.0, 1.0, 1.0, ]; let mask_vbo = gfx .create_vertex_buffer() .with_info(&vertex_info) .with_data(&mask_vertices) .build() .unwrap(); // triangle #[rustfmt::skip] let vertices = [ 0.5, 1.0, 1.0, 0.2, 0.3, 0.0, 0.0, 0.1, 1.0, 0.3, 1.0, 0.0, 0.1, 0.2, 1.0, ]; let vbo = gfx .create_vertex_buffer() .with_info(&vertex_info) .with_data(&vertices) .build() .unwrap(); State { clear_options, mask_pipeline: mask_pipeline, pipeline: pipeline, mask_vbo: mask_vbo, vbo: vbo, } } fn draw(gfx: &mut Graphics, state: &mut State) { let mut renderer = gfx.create_renderer(); renderer.begin(Some(state.clear_options)); // Render the mask renderer.set_pipeline(&state.mask_pipeline); renderer.bind_buffer(&state.mask_vbo); renderer.draw(0, 18); renderer.end(); // render the triangle renderer.begin(None); renderer.set_pipeline(&state.pipeline); renderer.bind_buffer(&state.vbo); renderer.draw(0, 3); renderer.end(); gfx.render(&renderer); }