Skip to content

Commit

Permalink
Migrate vertex-instancing.
Browse files Browse the repository at this point in the history
  • Loading branch information
hadronized committed Jun 20, 2021
1 parent b63ccfa commit 2b5c2c7
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 2 deletions.
12 changes: 12 additions & 0 deletions examples/common/src/instancing-fs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
in vec3 v_color;
in float v_instance_bias;

out vec4 frag;

uniform float t;

void main() {
float q = v_instance_bias * 10. + t;
frag = vec4(v_color * vec3(pow(cos(q), 2.), pow(sin(q), 2.), cos(q * .5)), 1.);
frag = pow(frag, vec4(1./2.2));
}
13 changes: 13 additions & 0 deletions examples/common/src/instancing-vs.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
in vec2 co;
in vec3 color;
in vec2 position;
in float weight;

out vec3 v_color;
out float v_instance_bias;

void main() {
gl_Position = vec4(co * weight + position, 0., 1.);
v_color = color;
v_instance_bias = float(gl_InstanceID);
}
1 change: 1 addition & 0 deletions examples/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub mod shader_uniforms;
pub mod shared;
pub mod sliced_tess;
pub mod texture;
pub mod vertex_instancing;

/// Example interface.
pub trait Example: Sized {
Expand Down
138 changes: 138 additions & 0 deletions examples/common/src/vertex_instancing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
//! This program shows you how to do *vertex instancing*, the easy way.
//!
//! Press <escape> to quit or close the window.
//!
//! https://docs.rs/luminance

use crate::{
shared::{
Instance, Semantics, Vertex, VertexColor, VertexInstancePosition, VertexPosition, VertexWeight,
},
Example, InputAction, LoopFeedback, PlatformServices,
};
use luminance::context::GraphicsContext;
use luminance_front::{
framebuffer::Framebuffer,
pipeline::PipelineState,
render_state::RenderState,
shader::Program,
tess::{Mode, Tess},
texture::Dim2,
Backend,
};

const VS: &'static str = include_str!("instancing-vs.glsl");
const FS: &'static str = include_str!("instancing-fs.glsl");

// Only one triangle this time.
const TRI_VERTICES: [Vertex; 3] = [
Vertex {
pos: VertexPosition::new([0.5, -0.5]),
rgb: VertexColor::new([1., 0., 0.]),
},
Vertex {
pos: VertexPosition::new([0.0, 0.5]),
rgb: VertexColor::new([0., 1., 0.]),
},
Vertex {
pos: VertexPosition::new([-0.5, -0.5]),
rgb: VertexColor::new([0., 0., 1.]),
},
];

// Instances. We’ll be using five triangles.
const INSTANCES: [Instance; 5] = [
Instance {
pos: VertexInstancePosition::new([0., 0.]),
w: VertexWeight::new(0.1),
},
Instance {
pos: VertexInstancePosition::new([-0.5, 0.5]),
w: VertexWeight::new(0.5),
},
Instance {
pos: VertexInstancePosition::new([-0.25, -0.1]),
w: VertexWeight::new(0.1),
},
Instance {
pos: VertexInstancePosition::new([0.45, 0.25]),
w: VertexWeight::new(0.75),
},
Instance {
pos: VertexInstancePosition::new([0.6, -0.3]),
w: VertexWeight::new(0.3),
},
];

pub struct LocalExample {
program: Program<Semantics, (), ()>,
triangle: Tess<Vertex, (), Instance>,
}

impl Example for LocalExample {
fn bootstrap(
_: &mut impl PlatformServices,
context: &mut impl GraphicsContext<Backend = Backend>,
) -> Self {
// notice that we don’t set a uniform interface here: we’re going to look it up on the fly
let program = context
.new_shader_program::<Semantics, (), ()>()
.from_strings(VS, None, None, FS)
.expect("program creation")
.ignore_warnings();

let triangle = context
.new_tess()
.set_vertices(&TRI_VERTICES[..])
.set_instances(&INSTANCES[..])
.set_mode(Mode::Triangle)
.build()
.unwrap();

Self { program, triangle }
}

fn render_frame(
mut self,
t: f32,
back_buffer: Framebuffer<Dim2, (), ()>,
actions: impl Iterator<Item = InputAction>,
context: &mut impl GraphicsContext<Backend = Backend>,
) -> LoopFeedback<Self> {
for action in actions {
match action {
InputAction::Quit => return LoopFeedback::Exit,

_ => (),
}
}

let program = &mut self.program;
let triangle = &self.triangle;

let render = context
.new_pipeline_gate()
.pipeline(
&back_buffer,
&PipelineState::default(),
|_, mut shd_gate| {
shd_gate.shade(program, |mut iface, _, mut rdr_gate| {
if let Ok(ref time_u) = iface.query().unwrap().ask("t") {
iface.set(time_u, t);
}

rdr_gate.render(&RenderState::default(), |mut tess_gate| {
tess_gate.render(triangle)
})
})
},
)
.assume();

if render.is_ok() {
LoopFeedback::Continue(self)
} else {
LoopFeedback::Exit
}
}
}
3 changes: 2 additions & 1 deletion examples/desktop/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ examples! {
"texture", texture,
"offscreen", offscreen,
"shader-uniform-adapt", shader_uniform_adapt,
"dynamic-uniform-interface", dynamic_uniform_interface
"dynamic-uniform-interface", dynamic_uniform_interface,
"vertex-instancing", vertex_instancing
}

fn main() {
Expand Down
3 changes: 2 additions & 1 deletion examples/web/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,8 @@ examples! {
"texture", texture,
"offscreen", offscreen,
"shader-uniform-adapt", shader_uniform_adapt,
"dynamic-uniform-interface", dynamic_uniform_interface
"dynamic-uniform-interface", dynamic_uniform_interface,
"vertex-instancing", vertex_instancing
}

#[wasm_bindgen]
Expand Down

0 comments on commit 2b5c2c7

Please sign in to comment.