typed primitive buffers + macro for creation
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
primitive::{PrimitiveInstance, Primitives},
|
||||
render::util::ArrBuf,
|
||||
primitive::{PrimitiveBuffers, Primitives},
|
||||
render::{data::PrimitiveInstance, util::ArrBuf},
|
||||
};
|
||||
use data::WindowUniform;
|
||||
use wgpu::{
|
||||
@@ -16,40 +16,34 @@ mod util;
|
||||
const SHAPE_SHADER: &str = include_str!("./shader.wgsl");
|
||||
|
||||
pub struct UIRenderNode {
|
||||
bind_group_layout: BindGroupLayout,
|
||||
bind_group: BindGroup,
|
||||
layout0: BindGroupLayout,
|
||||
group0: BindGroup,
|
||||
primitive_layout: BindGroupLayout,
|
||||
primitive_group: BindGroup,
|
||||
pipeline: RenderPipeline,
|
||||
|
||||
window_buffer: Buffer,
|
||||
instance: ArrBuf<PrimitiveInstance>,
|
||||
data: ArrBuf<u32>,
|
||||
primitives: PrimitiveBuffers,
|
||||
}
|
||||
|
||||
impl UIRenderNode {
|
||||
pub fn draw<'a>(&'a self, pass: &mut RenderPass<'a>) {
|
||||
pass.set_pipeline(&self.pipeline);
|
||||
pass.set_bind_group(0, &self.bind_group, &[]);
|
||||
if self.instance.len() != 0 {
|
||||
pass.set_pipeline(&self.pipeline);
|
||||
pass.set_bind_group(0, &self.group0, &[]);
|
||||
pass.set_bind_group(1, &self.primitive_group, &[]);
|
||||
pass.set_vertex_buffer(0, self.instance.buffer.slice(..));
|
||||
pass.draw(0..4, 0..self.instance.len() as u32);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
device: &Device,
|
||||
queue: &Queue,
|
||||
primitives: Option<&Primitives>,
|
||||
) {
|
||||
pub fn update(&mut self, device: &Device, queue: &Queue, primitives: Option<&Primitives>) {
|
||||
if let Some(primitives) = primitives {
|
||||
self.instance.update(device, queue, &primitives.instances);
|
||||
self.data.update(device, queue, &primitives.data);
|
||||
self.bind_group = Self::bind_group(
|
||||
device,
|
||||
&self.bind_group_layout,
|
||||
&self.window_buffer,
|
||||
&self.data.buffer,
|
||||
)
|
||||
self.primitives.update(device, queue, &primitives.data);
|
||||
self.primitive_group =
|
||||
Self::primitive_group(device, &self.primitive_layout, self.primitives.buffers())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +63,7 @@ impl UIRenderNode {
|
||||
|
||||
let window_uniform = WindowUniform::default();
|
||||
let window_buffer = device.create_buffer_init(&BufferInitDescriptor {
|
||||
label: Some("Camera Buffer"),
|
||||
label: Some("window"),
|
||||
contents: bytemuck::cast_slice(&[window_uniform]),
|
||||
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
|
||||
});
|
||||
@@ -79,26 +73,28 @@ impl UIRenderNode {
|
||||
BufferUsages::VERTEX | BufferUsages::COPY_DST,
|
||||
"instance",
|
||||
);
|
||||
let data = ArrBuf::new(
|
||||
device,
|
||||
BufferUsages::STORAGE | BufferUsages::COPY_DST,
|
||||
"data",
|
||||
);
|
||||
let primitives = PrimitiveBuffers::new(device);
|
||||
|
||||
let bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||
entries: &[
|
||||
BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: ShaderStages::VERTEX,
|
||||
ty: BindingType::Buffer {
|
||||
ty: BufferBindingType::Uniform,
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
let layout0 = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||
entries: &[BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: ShaderStages::VERTEX,
|
||||
ty: BindingType::Buffer {
|
||||
ty: BufferBindingType::Uniform,
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
label: Some("window"),
|
||||
});
|
||||
|
||||
let group0 = Self::bind_group_0(device, &layout0, &window_buffer);
|
||||
|
||||
let primitive_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||
entries: &core::array::from_fn::<_, { PrimitiveBuffers::LEN }, _>(|i| {
|
||||
BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
binding: i as u32,
|
||||
visibility: ShaderStages::FRAGMENT,
|
||||
ty: BindingType::Buffer {
|
||||
ty: BufferBindingType::Storage { read_only: true },
|
||||
@@ -106,16 +102,17 @@ impl UIRenderNode {
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
label: Some("camera_bind_group_layout"),
|
||||
}
|
||||
}),
|
||||
label: Some("primitive"),
|
||||
});
|
||||
|
||||
let bind_group = Self::bind_group(device, &bind_group_layout, &window_buffer, &data.buffer);
|
||||
let primitive_group =
|
||||
Self::primitive_group(device, &primitive_layout, primitives.buffers());
|
||||
|
||||
let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
|
||||
label: Some("UI Shape Pipeline Layout"),
|
||||
bind_group_layouts: &[&bind_group_layout],
|
||||
bind_group_layouts: &[&layout0, &primitive_layout],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
|
||||
@@ -157,34 +154,44 @@ impl UIRenderNode {
|
||||
});
|
||||
|
||||
Self {
|
||||
bind_group_layout,
|
||||
bind_group,
|
||||
layout0,
|
||||
group0,
|
||||
primitive_layout,
|
||||
primitive_group,
|
||||
pipeline,
|
||||
window_buffer,
|
||||
instance,
|
||||
data,
|
||||
primitives,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bind_group(
|
||||
pub fn bind_group_0(
|
||||
device: &Device,
|
||||
layout: &BindGroupLayout,
|
||||
window_buffer: &Buffer,
|
||||
data: &Buffer,
|
||||
) -> BindGroup {
|
||||
device.create_bind_group(&BindGroupDescriptor {
|
||||
layout,
|
||||
entries: &[
|
||||
BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: window_buffer.as_entire_binding(),
|
||||
},
|
||||
BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: data.as_entire_binding(),
|
||||
},
|
||||
],
|
||||
label: Some("ui_bind_group"),
|
||||
entries: &[BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: window_buffer.as_entire_binding(),
|
||||
}],
|
||||
label: Some("ui window"),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn primitive_group(
|
||||
device: &Device,
|
||||
layout: &BindGroupLayout,
|
||||
buffers: [&Buffer; PrimitiveBuffers::LEN],
|
||||
) -> BindGroup {
|
||||
device.create_bind_group(&BindGroupDescriptor {
|
||||
layout,
|
||||
entries: &buffers.each_ref().map(|b| BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: b.as_entire_binding(),
|
||||
}),
|
||||
label: Some("ui primitives"),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user