update
This commit is contained in:
@@ -115,6 +115,7 @@ pub struct BackgroundRenderResources {
|
||||
hand_image_pipeline: wgpu::RenderPipeline,
|
||||
glyph_pipeline: wgpu::RenderPipeline,
|
||||
dot_pipeline: wgpu::RenderPipeline,
|
||||
hand_membrane_pipeline: wgpu::RenderPipeline,
|
||||
hand_dot_pipeline: wgpu::RenderPipeline,
|
||||
hand_image_bind_group: wgpu::BindGroup,
|
||||
hand_image_texture: texture::Texture,
|
||||
@@ -122,6 +123,8 @@ pub struct BackgroundRenderResources {
|
||||
glyph_vertex_buffer: wgpu::Buffer,
|
||||
glyph_instance_buffer: wgpu::Buffer,
|
||||
glyph_instances: Vec<GlyphInstance>,
|
||||
hand_membrane_instance_buffer: wgpu::Buffer,
|
||||
hand_membrane_instances: Vec<GlyphInstance>,
|
||||
hand_dot_instance_buffer: wgpu::Buffer,
|
||||
hand_dot_instances: Vec<GlyphInstance>,
|
||||
render_options: RenderOptions,
|
||||
@@ -445,6 +448,8 @@ impl BackgroundRenderResources {
|
||||
let glyph_pipeline =
|
||||
create_glyph_pipeline(device, target_format, &shader, &pipeline_layout);
|
||||
let dot_pipeline = create_dot_pipeline(device, target_format, &shader, &pipeline_layout);
|
||||
let hand_membrane_pipeline =
|
||||
create_hand_membrane_pipeline(device, target_format, &shader, &pipeline_layout);
|
||||
let hand_dot_pipeline =
|
||||
create_hand_dot_pipeline(device, target_format, &shader, &pipeline_layout);
|
||||
|
||||
@@ -474,6 +479,16 @@ impl BackgroundRenderResources {
|
||||
contents: bytemuck::cast_slice(&glyph_instances),
|
||||
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
|
||||
});
|
||||
let hand_membrane_instances = build_hand_membrane_instances(
|
||||
hand_image_texture.width as f32,
|
||||
hand_image_texture.height as f32,
|
||||
);
|
||||
let hand_membrane_instance_buffer =
|
||||
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Hand Fingertip Membrane Instance Buffer"),
|
||||
contents: bytemuck::cast_slice(&hand_membrane_instances),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let hand_dot_instances = build_hand_dot_instances(
|
||||
rows,
|
||||
cols,
|
||||
@@ -500,12 +515,15 @@ impl BackgroundRenderResources {
|
||||
hand_image_pipeline,
|
||||
glyph_pipeline,
|
||||
dot_pipeline,
|
||||
hand_membrane_pipeline,
|
||||
hand_dot_pipeline,
|
||||
hand_image_bind_group,
|
||||
hand_image_texture,
|
||||
glyph_vertex_buffer,
|
||||
glyph_instance_buffer,
|
||||
glyph_instances,
|
||||
hand_membrane_instance_buffer,
|
||||
hand_membrane_instances,
|
||||
hand_dot_instance_buffer,
|
||||
hand_dot_instances,
|
||||
render_options,
|
||||
@@ -595,7 +613,12 @@ impl BackgroundRenderResources {
|
||||
fn paint_hand(&self, render_pass: &mut wgpu::RenderPass<'_>, mode: &HandGatewayMode) {
|
||||
let _range = mode.range.clone();
|
||||
|
||||
// Draw the five fingertip dot matrices after hand.png, so they sit on top of the texture.
|
||||
// First draw the translucent sensor membranes, then draw live pressure beads on their grid.
|
||||
render_pass.set_pipeline(&self.hand_membrane_pipeline);
|
||||
render_pass.set_vertex_buffer(0, self.glyph_vertex_buffer.slice(..));
|
||||
render_pass.set_vertex_buffer(1, self.hand_membrane_instance_buffer.slice(..));
|
||||
render_pass.draw(0..6, 0..self.hand_membrane_instances.len() as u32);
|
||||
|
||||
render_pass.set_pipeline(&self.hand_dot_pipeline);
|
||||
render_pass.set_vertex_buffer(0, self.glyph_vertex_buffer.slice(..));
|
||||
render_pass.set_vertex_buffer(1, self.hand_dot_instance_buffer.slice(..));
|
||||
@@ -867,6 +890,39 @@ fn create_dot_pipeline(
|
||||
})
|
||||
}
|
||||
|
||||
fn create_hand_membrane_pipeline(
|
||||
device: &wgpu::Device,
|
||||
target_format: &wgpu::TextureFormat,
|
||||
shader: &wgpu::ShaderModule,
|
||||
layout: &wgpu::PipelineLayout,
|
||||
) -> wgpu::RenderPipeline {
|
||||
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Hand Fingertip Sensor Membrane Pipeline"),
|
||||
layout: Some(layout),
|
||||
vertex: wgpu::VertexState {
|
||||
module: shader,
|
||||
entry_point: Some("vs_hand_membrane"),
|
||||
compilation_options: Default::default(),
|
||||
buffers: &[GlyphVertex::desc(), GlyphInstance::desc()],
|
||||
},
|
||||
fragment: Some(wgpu::FragmentState {
|
||||
module: shader,
|
||||
entry_point: Some("fs_hand_membrane"),
|
||||
compilation_options: Default::default(),
|
||||
targets: &[Some(wgpu::ColorTargetState {
|
||||
format: *target_format,
|
||||
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
|
||||
write_mask: wgpu::ColorWrites::ALL,
|
||||
})],
|
||||
}),
|
||||
primitive: wgpu::PrimitiveState::default(),
|
||||
depth_stencil: None,
|
||||
multisample: wgpu::MultisampleState::default(),
|
||||
multiview_mask: None,
|
||||
cache: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn create_hand_dot_pipeline(
|
||||
device: &wgpu::Device,
|
||||
target_format: &wgpu::TextureFormat,
|
||||
@@ -900,6 +956,24 @@ fn create_hand_dot_pipeline(
|
||||
})
|
||||
}
|
||||
|
||||
fn build_hand_membrane_instances(image_width: f32, image_height: f32) -> Vec<GlyphInstance> {
|
||||
HAND_TIP_MATRICES
|
||||
.iter()
|
||||
.map(|tip| {
|
||||
let uv_x = tip.center_px[0] / image_width.max(1.0);
|
||||
let uv_y = tip.center_px[1] / image_height.max(1.0);
|
||||
let membrane_size = [tip.size_px[0] * 1.62, tip.size_px[1] * 1.56];
|
||||
|
||||
GlyphInstance {
|
||||
// Membrane shaders read xy as hand.png UV.
|
||||
world_position: [uv_x, uv_y, 0.0, 1.0],
|
||||
// Store angle and an oversized source-image pixel size for the floating sensor film.
|
||||
style: [tip.angle_rad, membrane_size[0], membrane_size[1], 0.0],
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn build_hand_dot_instances(
|
||||
rows: u32,
|
||||
cols: u32,
|
||||
|
||||
Reference in New Issue
Block a user