Skip to content

Commit 37ebe1d

Browse files
authored
Quads scissor_rect (#273)
1 parent 96ee948 commit 37ebe1d

7 files changed

Lines changed: 111 additions & 35 deletions

File tree

neothesia-cli/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ impl Recorder {
176176
let bg_color = wgpu_jumpstart::Color::from(bg_color).into_linear_wgpu_color();
177177

178178
{
179-
let mut rpass = self
179+
let rpass = self
180180
.gpu
181181
.encoder
182182
.begin_render_pass(&wgpu::RenderPassDescriptor {
@@ -194,6 +194,7 @@ impl Recorder {
194194
timestamp_writes: None,
195195
occlusion_query_set: None,
196196
});
197+
let mut rpass = wgpu_jumpstart::RenderPass::new(rpass, texture.size());
197198

198199
self.quad_pipeline.render(0, &mut rpass);
199200
self.waterfall.render(&mut rpass);

neothesia-core/src/render/quad/mod.rs

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ pub use instance_data::QuadInstance;
33

44
use wgpu_jumpstart::{wgpu, Gpu, Instances, Shape, TransformUniform, Uniform};
55

6-
type QuadsLayer = Instances<QuadInstance>;
6+
use crate::utils::Rect;
7+
8+
pub struct QuadsLayer {
9+
scissor_rect: Rect,
10+
quads: Instances<QuadInstance>,
11+
}
712

813
#[derive(Clone)]
914
pub struct QuadPipeline {
@@ -55,20 +60,23 @@ impl QuadPipeline {
5560
}
5661

5762
pub fn new_layer(device: &wgpu::Device, size: usize) -> QuadsLayer {
58-
Instances::new(device, size)
63+
QuadsLayer {
64+
scissor_rect: Rect::zero(),
65+
quads: Instances::new(device, size),
66+
}
5967
}
6068

6169
#[profiling::function]
62-
pub fn render<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>, instances: &QuadsLayer) {
70+
pub fn render<'a>(&'a self, render_pass: &mut wgpu::RenderPass<'a>, layer: &QuadsLayer) {
6371
render_pass.set_pipeline(&self.render_pipeline);
6472
render_pass.set_bind_group(0, &self.transform_uniform_bind_group, &[]);
6573

6674
render_pass.set_vertex_buffer(0, self.quad.vertex_buffer.slice(..));
67-
render_pass.set_vertex_buffer(1, instances.buffer.slice(..));
75+
render_pass.set_vertex_buffer(1, layer.quads.buffer.slice(..));
6876

6977
render_pass.set_index_buffer(self.quad.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
7078

71-
render_pass.draw_indexed(0..self.quad.indices_len, 0, 0..instances.len());
79+
render_pass.draw_indexed(0..self.quad.indices_len, 0, 0..layer.quads.len());
7280
}
7381
}
7482

@@ -89,34 +97,71 @@ impl<'a> QuadRenderer {
8997
}
9098
}
9199

100+
pub fn is_empty(&self) -> bool {
101+
self.len() == 0
102+
}
103+
104+
pub fn len(&self) -> usize {
105+
self.layers.len()
106+
}
107+
108+
pub fn ensure_n_layers(&mut self, count: usize) {
109+
self.layers
110+
.resize_with(count, || QuadPipeline::new_layer(&self.device, 100));
111+
}
112+
92113
pub fn init_layer(&mut self, size: usize) {
93114
self.layers
94115
.push(QuadPipeline::new_layer(&self.device, size));
95116
}
96117

97118
#[profiling::function]
98-
pub fn render(&'a self, layer_id: usize, render_pass: &mut wgpu::RenderPass<'a>) {
99-
self.pipeline.render(render_pass, &self.layers[layer_id]);
119+
pub fn render(&'a self, layer_id: usize, render_pass: &mut wgpu_jumpstart::RenderPass<'a>) {
120+
let layer = &self.layers[layer_id];
121+
122+
let pass_size = render_pass.size();
123+
124+
if layer.scissor_rect == Rect::zero() {
125+
render_pass.set_scissor_rect(0, 0, pass_size.width, pass_size.height);
126+
} else {
127+
render_pass.set_scissor_rect(
128+
layer.scissor_rect.origin.x as u32,
129+
layer.scissor_rect.origin.y as u32,
130+
layer.scissor_rect.size.width as u32,
131+
layer.scissor_rect.size.height as u32,
132+
);
133+
}
134+
135+
self.pipeline.render(render_pass, layer);
136+
137+
// Revert
138+
if layer.scissor_rect != Rect::zero() {
139+
render_pass.set_scissor_rect(0, 0, pass_size.width, pass_size.height);
140+
}
100141
}
101142

102143
pub fn clear(&mut self) {
103144
for layer in self.layers.iter_mut() {
104-
layer.data.clear();
145+
layer.quads.data.clear();
105146
}
106147
}
107148

108149
pub fn layer(&mut self, layer_id: usize) -> &mut Vec<QuadInstance> {
109-
&mut self.layers[layer_id].data
150+
&mut self.layers[layer_id].quads.data
151+
}
152+
153+
pub fn set_scissor_rect(&mut self, layer_id: usize, rect: Rect) {
154+
self.layers[layer_id].scissor_rect = rect;
110155
}
111156

112157
pub fn push(&mut self, layer_id: usize, quad: QuadInstance) {
113-
self.layers[layer_id].data.push(quad)
158+
self.layers[layer_id].quads.data.push(quad)
114159
}
115160

116161
#[profiling::function]
117162
pub fn prepare(&mut self) {
118163
for layer in self.layers.iter_mut() {
119-
layer.update(&self.device, &self.queue);
164+
layer.quads.update(&self.device, &self.queue);
120165
}
121166
}
122167
}

neothesia/src/main.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -182,26 +182,28 @@ impl Neothesia {
182182
{
183183
let bg_color = self.context.config.background_color();
184184
let bg_color = wgpu_jumpstart::Color::from(bg_color).into_linear_wgpu_color();
185-
let mut rpass =
186-
self.context
187-
.gpu
188-
.encoder
189-
.begin_render_pass(&wgpu::RenderPassDescriptor {
190-
label: Some("Main Neothesia Pass"),
191-
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
192-
view,
193-
resolve_target: None,
194-
ops: wgpu::Operations {
195-
load: wgpu::LoadOp::Clear(bg_color),
196-
store: wgpu::StoreOp::Store,
197-
},
198-
depth_slice: None,
199-
})],
200-
201-
depth_stencil_attachment: None,
202-
timestamp_writes: None,
203-
occlusion_query_set: None,
204-
});
185+
let rpass = self
186+
.context
187+
.gpu
188+
.encoder
189+
.begin_render_pass(&wgpu::RenderPassDescriptor {
190+
label: Some("Main Neothesia Pass"),
191+
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
192+
view,
193+
resolve_target: None,
194+
ops: wgpu::Operations {
195+
load: wgpu::LoadOp::Clear(bg_color),
196+
store: wgpu::StoreOp::Store,
197+
},
198+
depth_slice: None,
199+
})],
200+
201+
depth_stencil_attachment: None,
202+
timestamp_writes: None,
203+
occlusion_query_set: None,
204+
});
205+
206+
let mut rpass = wgpu_jumpstart::RenderPass::new(rpass, frame.texture.size());
205207

206208
self.game_scene.render(&mut rpass);
207209
}

neothesia/src/scene/menu_scene/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ impl Scene for MenuScene {
7171
}
7272

7373
#[profiling::function]
74-
fn render<'pass>(&'pass mut self, rpass: &mut wgpu::RenderPass<'pass>) {
74+
fn render<'pass>(&'pass mut self, rpass: &mut wgpu_jumpstart::RenderPass<'pass>) {
7575
self.bg_pipeline.render(rpass);
7676
}
7777

neothesia/src/scene/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use winit::event::WindowEvent;
99

1010
pub trait Scene {
1111
fn update(&mut self, ctx: &mut Context, delta: Duration);
12-
fn render<'pass>(&'pass mut self, rpass: &mut wgpu::RenderPass<'pass>);
12+
fn render<'pass>(&'pass mut self, rpass: &mut wgpu_jumpstart::RenderPass<'pass>);
1313
fn window_event(&mut self, _ctx: &mut Context, _event: &WindowEvent) {}
1414
fn midi_event(&mut self, _ctx: &mut Context, _channel: u8, _message: &MidiMessage) {}
1515
}

neothesia/src/scene/playing_scene/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ impl Scene for PlayingScene {
266266
}
267267

268268
#[profiling::function]
269-
fn render<'pass>(&'pass mut self, rpass: &mut wgpu::RenderPass<'pass>) {
269+
fn render<'pass>(&'pass mut self, rpass: &mut wgpu_jumpstart::RenderPass<'pass>) {
270270
self.quad_pipeline.render(LAYER_BG, rpass);
271271
self.waterfall.render(rpass);
272272
if let Some(note_labels) = self.note_labels.as_mut() {

wgpu-jumpstart/src/lib.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#![allow(clippy::single_match)]
22

33
mod error;
4+
use std::ops::{Deref, DerefMut};
5+
46
pub use error::GpuInitError;
57

68
mod color;
@@ -24,3 +26,29 @@ pub use {
2426
transform_uniform::TransformUniform,
2527
uniform::Uniform,
2628
};
29+
30+
pub struct RenderPass<'a>(wgpu::RenderPass<'a>, wgpu::Extent3d);
31+
32+
impl<'a> RenderPass<'a> {
33+
pub fn new(rpass: wgpu::RenderPass<'a>, size: wgpu::Extent3d) -> Self {
34+
Self(rpass, size)
35+
}
36+
37+
pub fn size(&self) -> wgpu::Extent3d {
38+
self.1
39+
}
40+
}
41+
42+
impl<'a> Deref for RenderPass<'a> {
43+
type Target = wgpu::RenderPass<'a>;
44+
45+
fn deref(&self) -> &Self::Target {
46+
&self.0
47+
}
48+
}
49+
50+
impl<'a> DerefMut for RenderPass<'a> {
51+
fn deref_mut(&mut self) -> &mut Self::Target {
52+
&mut self.0
53+
}
54+
}

0 commit comments

Comments
 (0)