Skip to content

Commit

Permalink
clipping done
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelselleck committed Oct 31, 2024
1 parent bfbc217 commit 35127ea
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 34 deletions.
2 changes: 1 addition & 1 deletion pax-chassis-web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ include = ["/src", "/interface/public"]
crate-type = ["cdylib", "rlib"]

[features]
default = ["console_error_panic_hook", "gpu"]
default = ["console_error_panic_hook"]
designtime = ["dep:pax-designtime", "pax-runtime/designtime"]
gpu = []

Expand Down
1 change: 1 addition & 0 deletions pax-pixels/src/render_backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ impl<'w> RenderBackend<'w> {
&self.queue,
&screen_texture,
&self.globals_buffer,
&self.stencil_renderer,
&image.rgba,
image.pixel_width,
transform,
Expand Down
52 changes: 24 additions & 28 deletions pax-pixels/src/render_backend/stencil.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
use std::path::Path;

use bytemuck::{Pod, Zeroable};
use lyon::tessellation::VertexBuffers;
use wgpu::util::DeviceExt;
use wgpu::{BufferUsages, Device, Queue, RenderPipeline};

use crate::Transform2D;

pub struct StencilRenderer {
stencil_pipeline: RenderPipeline,
decrement_pipeline: RenderPipeline,
vertices_buffer: wgpu::Buffer,
indices_buffer: wgpu::Buffer,
fullscreen_vertices_buffer: wgpu::Buffer,
stencil_texture: wgpu::Texture,
stencil_view: wgpu::TextureView,
stencil_layer: u32,
stencil_geometry_stack: Vec<VertexBuffers<Vertex, u16>>,
width: u32,
height: u32,
stencil_bind_group: wgpu::BindGroup,
Expand Down Expand Up @@ -183,38 +179,19 @@ impl StencilRenderer {
usage: BufferUsages::INDEX | BufferUsages::COPY_DST,
});

// Create fullscreen quad vertices for decrement operation
let fullscreen_vertices = [
Vertex {
position: [-1.0, -1.0],
},
Vertex {
position: [3.0, -1.0],
},
Vertex {
position: [-1.0, 3.0],
},
];
let fullscreen_vertices_buffer =
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Fullscreen Vertices"),
contents: bytemuck::cast_slice(&fullscreen_vertices),
usage: BufferUsages::VERTEX,
});

let (stencil_texture, stencil_view) = Self::create_stencil_texture(device, width, height);

Self {
stencil_pipeline,
decrement_pipeline,
vertices_buffer,
indices_buffer,
fullscreen_vertices_buffer,
stencil_texture,
stencil_view,
width,
height,
stencil_layer: 0,
stencil_geometry_stack: vec![],
stencil_bind_group,
_stencil_bind_group_layout: stencil_bind_group_layout,
}
Expand Down Expand Up @@ -300,11 +277,27 @@ impl StencilRenderer {
}

queue.submit(std::iter::once(encoder.finish()));
self.stencil_geometry_stack.push(geometry);
self.stencil_layer += 1;
}

pub fn reset_stencil_depth_to(&mut self, device: &Device, queue: &Queue, depth: u32) {
while self.stencil_layer > depth {
let Some(geometry) = self.stencil_geometry_stack.pop() else {
log::error!("geometry stack shouldn't be embty when stencil layer > 0");
break;
};
queue.write_buffer(
&self.vertices_buffer,
0,
bytemuck::cast_slice(&geometry.vertices),
);
queue.write_buffer(
&self.indices_buffer,
0,
bytemuck::cast_slice(&geometry.indices),
);

let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("Stencil Pop Encoder"),
});
Expand All @@ -325,11 +318,13 @@ impl StencilRenderer {
occlusion_query_set: None,
});

// Use the decrement pipeline and fullscreen quad to decrease all stencil values
render_pass.set_pipeline(&self.decrement_pipeline);
render_pass.set_bind_group(0, &self.stencil_bind_group, &[]);
render_pass.set_vertex_buffer(0, self.fullscreen_vertices_buffer.slice(..));
render_pass.draw(0..3, 0..1);
render_pass.set_vertex_buffer(0, self.vertices_buffer.slice(..));
render_pass.set_bind_group(0, &self.stencil_bind_group, &[]);
render_pass
.set_index_buffer(self.indices_buffer.slice(..), wgpu::IndexFormat::Uint16);
render_pass.draw_indexed(0..(geometry.indices.len() as u32), 0, 0..1);
}

queue.submit(std::iter::once(encoder.finish()));
Expand Down Expand Up @@ -367,5 +362,6 @@ impl StencilRenderer {

queue.submit(std::iter::once(encoder.finish()));
self.stencil_layer = 0;
self.stencil_geometry_stack.clear();
}
}
34 changes: 31 additions & 3 deletions pax-pixels/src/render_backend/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use crate::Transform2D;
use wgpu::util::DeviceExt;
use wgpu::TextureFormat;

use super::stencil::StencilRenderer;

pub struct TextureRenderer {
vertices_buffer: wgpu::Buffer,
indices_buffer: wgpu::Buffer,
Expand Down Expand Up @@ -93,7 +95,23 @@ impl TextureRenderer {
unclipped_depth: false,
conservative: false,
},
depth_stencil: None,
depth_stencil: Some(wgpu::DepthStencilState {
format: wgpu::TextureFormat::Stencil8,
depth_write_enabled: false,
depth_compare: wgpu::CompareFunction::Always,
stencil: wgpu::StencilState {
front: wgpu::StencilFaceState {
compare: wgpu::CompareFunction::Equal,
fail_op: wgpu::StencilOperation::Keep,
depth_fail_op: wgpu::StencilOperation::Keep,
pass_op: wgpu::StencilOperation::Keep,
},
back: wgpu::StencilFaceState::IGNORE,
read_mask: !0,
write_mask: !0,
},
bias: Default::default(),
}),
multisample: wgpu::MultisampleState {
count: 1,
mask: !0,
Expand All @@ -109,7 +127,7 @@ impl TextureRenderer {
contents: bytemuck::cast_slice(&vertices),
usage: BufferUsages::VERTEX | BufferUsages::COPY_DST,
});
let indices: &[u16] = &[0, 1, 2, 1, 2, 3];
let indices: &[u16] = &[1, 0, 2, 1, 2, 3];
let indices_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Index Buffer"),
contents: bytemuck::cast_slice(&indices),
Expand Down Expand Up @@ -139,6 +157,7 @@ impl TextureRenderer {
queue: &wgpu::Queue,
target: &wgpu::TextureView,
globals: &wgpu::Buffer,
stencil_renderer: &StencilRenderer,
rgba: &[u8],
rgba_width: u32,
transform: Transform2D,
Expand Down Expand Up @@ -223,6 +242,7 @@ impl TextureRenderer {
});

{
let (stencil_texture, stencil_index) = stencil_renderer.get_stencil();
//write image in render pass
let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Texture Pass"),
Expand All @@ -234,12 +254,20 @@ impl TextureRenderer {
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
view: stencil_texture,
depth_ops: None,
stencil_ops: Some(wgpu::Operations {
load: wgpu::LoadOp::Load,
store: wgpu::StoreOp::Store,
}),
}),
timestamp_writes: None,
occlusion_query_set: None,
});
render_pass.set_pipeline(&self.texture_pipeline);
render_pass.set_bind_group(0, &bind_group, &[]);
render_pass.set_stencil_reference(stencil_index);
render_pass.set_vertex_buffer(0, self.vertices_buffer.slice(..));
render_pass.set_index_buffer(self.indices_buffer.slice(..), IndexFormat::Uint16);
render_pass.draw_indexed(0..6, 0, 0..1);
Expand Down
2 changes: 1 addition & 1 deletion pax-pixels/src/render_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ impl<'w> WgpuRenderer<'w> {

pub fn clip(&mut self, path: Path) {
// fine to transform on CPU - shouldn't be large meshes
// let path = path.transformed(&self.current_transform());
let path = path.transformed(&self.current_transform());
if self.buffers.primitives.len() > 0 {
self.render_backend.render_primitives(&mut self.buffers);
let CpuBuffers {
Expand Down
2 changes: 1 addition & 1 deletion pax-runtime/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::ops::Range;
use std::rc::Rc;
use std::sync::atomic::{AtomicUsize, Ordering};

use kurbo::{BezPath, Rect, RoundedRect, Shape};
use kurbo::{BezPath, Circle, Rect, RoundedRect, Shape};
use pax_message::NativeMessage;
use pax_runtime_api::{
pax_value::PaxAny, use_RefCell, Event, Focus, SelectStart, Variable, Window, OS,
Expand Down

0 comments on commit 35127ea

Please sign in to comment.