separate uniforms from the pipeline
This commit is contained in:
parent
ec22c4a6e4
commit
972aee716a
47
src/lib.rs
47
src/lib.rs
|
|
@ -2,6 +2,8 @@ use std::error::Error;
|
||||||
|
|
||||||
use glam::{Mat4, UVec2, Vec3, Vec4, vec3, vec4};
|
use glam::{Mat4, UVec2, Vec3, Vec4, vec3, vec4};
|
||||||
|
|
||||||
|
use crate::render::mesh::GpuParams;
|
||||||
|
|
||||||
mod bevel_gear;
|
mod bevel_gear;
|
||||||
mod camera;
|
mod camera;
|
||||||
mod crown_gear;
|
mod crown_gear;
|
||||||
|
|
@ -56,10 +58,15 @@ pub struct Core {
|
||||||
device: wgpu::Device,
|
device: wgpu::Device,
|
||||||
queue: wgpu::Queue,
|
queue: wgpu::Queue,
|
||||||
surface: wgpu::Surface<'static>,
|
surface: wgpu::Surface<'static>,
|
||||||
|
depth: wgpu::Texture,
|
||||||
|
|
||||||
mesh_pipeline: render::mesh::Pipeline,
|
mesh_pipeline: render::mesh::Pipeline,
|
||||||
mesh_gray: render::mesh::GpuMeshIndexed,
|
|
||||||
depth: wgpu::Texture,
|
mesh_gear: render::mesh::GpuMeshIndexed,
|
||||||
|
mesh_cutter: render::mesh::GpuMeshIndexed,
|
||||||
|
|
||||||
|
params_gear: render::mesh::GpuParams,
|
||||||
|
params_cutter: render::mesh::GpuParams,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn srgb_to_linear(color: Vec3) -> Vec3 {
|
fn srgb_to_linear(color: Vec3) -> Vec3 {
|
||||||
|
|
@ -131,7 +138,11 @@ impl Core {
|
||||||
.to_standard_mesh()
|
.to_standard_mesh()
|
||||||
.into_indexed();
|
.into_indexed();
|
||||||
|
|
||||||
let mesh_gray = render::mesh::GpuMeshIndexed::new(&device, &bevel_gear_mesh);
|
let mesh_cutter = render::mesh::GpuMeshIndexed::new(&device, &crown_gear_mesh);
|
||||||
|
let mesh_gear = render::mesh::GpuMeshIndexed::new(&device, &bevel_gear_mesh);
|
||||||
|
|
||||||
|
let params_gear = GpuParams::new(&device, &mesh_pipeline);
|
||||||
|
let params_cutter = GpuParams::new(&device, &mesh_pipeline);
|
||||||
|
|
||||||
Self::configure_surface(&surface, &device, pixel_size);
|
Self::configure_surface(&surface, &device, pixel_size);
|
||||||
|
|
||||||
|
|
@ -139,9 +150,12 @@ impl Core {
|
||||||
device,
|
device,
|
||||||
queue,
|
queue,
|
||||||
surface,
|
surface,
|
||||||
mesh_pipeline,
|
|
||||||
mesh_gray,
|
|
||||||
depth,
|
depth,
|
||||||
|
mesh_pipeline,
|
||||||
|
mesh_gear,
|
||||||
|
mesh_cutter,
|
||||||
|
params_gear,
|
||||||
|
params_cutter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,16 +176,26 @@ impl Core {
|
||||||
.clamp_z_min(0.01 * args.cam_view_y)
|
.clamp_z_min(0.01 * args.cam_view_y)
|
||||||
.to_mat4();
|
.to_mat4();
|
||||||
let view = Mat4::from_mat3(camera::rotation(-args.cam_yaw, -args.cam_pitch));
|
let view = Mat4::from_mat3(camera::rotation(-args.cam_yaw, -args.cam_pitch));
|
||||||
self.mesh_pipeline.set_params(
|
let light = vec3(0.7, 0.5, 1.0).normalize();
|
||||||
|
|
||||||
|
self.params_gear.set(
|
||||||
&self.queue,
|
&self.queue,
|
||||||
render::mesh::Params {
|
render::mesh::Params {
|
||||||
mvp: proj * view,
|
mvp: proj * view,
|
||||||
light: vec3(0.7, 0.5, 1.0).normalize(),
|
light,
|
||||||
_zero: 0.,
|
_zero: 0.,
|
||||||
color: vec4(0.5, 0.5, 0.5, 1.0),
|
color: srgba_to_linear(vec4(0.2, 0.8, 0.1, 1.0)),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
self.params_cutter.set(
|
||||||
|
&self.queue,
|
||||||
|
render::mesh::Params {
|
||||||
|
mvp: proj * view,
|
||||||
|
light,
|
||||||
|
_zero: 0.,
|
||||||
|
color: srgba_to_linear(vec4(0.8, 0.2, 0.1, 1.0)),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.queue.submit([]); // flush buffer updates
|
|
||||||
|
|
||||||
let view = output.create_view(&wgpu::TextureViewDescriptor::default());
|
let view = output.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
let depth_view = self
|
let depth_view = self
|
||||||
|
|
@ -200,7 +224,10 @@ impl Core {
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
self.mesh_gray.render(&self.mesh_pipeline, &mut pass);
|
self.mesh_cutter
|
||||||
|
.render(&mut pass, &self.mesh_pipeline, &self.params_cutter);
|
||||||
|
self.mesh_gear
|
||||||
|
.render(&mut pass, &self.mesh_pipeline, &self.params_gear);
|
||||||
drop(pass);
|
drop(pass);
|
||||||
self.queue.submit(std::iter::once(encoder.finish()));
|
self.queue.submit(std::iter::once(encoder.finish()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ pub struct Params {
|
||||||
pub color: Vec4,
|
pub color: Vec4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Pipeline {
|
||||||
|
pipeline: wgpu::RenderPipeline,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GpuMesh {
|
pub struct GpuMesh {
|
||||||
vertices: wgpu::Buffer,
|
vertices: wgpu::Buffer,
|
||||||
vertex_count: u32,
|
vertex_count: u32,
|
||||||
|
|
@ -37,6 +41,11 @@ pub struct GpuMeshIndexed {
|
||||||
index_count: u32,
|
index_count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct GpuParams {
|
||||||
|
params: wgpu::Buffer,
|
||||||
|
bindings: wgpu::BindGroup,
|
||||||
|
}
|
||||||
|
|
||||||
impl GpuMesh {
|
impl GpuMesh {
|
||||||
pub fn new(device: &wgpu::Device, data: &CpuMesh) -> Self {
|
pub fn new(device: &wgpu::Device, data: &CpuMesh) -> Self {
|
||||||
let vertices = cast_slice::<_, Vertex>(&data.faces);
|
let vertices = cast_slice::<_, Vertex>(&data.faces);
|
||||||
|
|
@ -84,21 +93,8 @@ impl GpuMeshIndexed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Pipeline {
|
|
||||||
params: wgpu::Buffer,
|
|
||||||
bindings: wgpu::BindGroup,
|
|
||||||
pipeline: wgpu::RenderPipeline,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Pipeline {
|
impl Pipeline {
|
||||||
pub fn new(device: &wgpu::Device) -> Self {
|
pub fn new(device: &wgpu::Device) -> Self {
|
||||||
let params = device.create_buffer(&wgpu::BufferDescriptor {
|
|
||||||
label: None,
|
|
||||||
size: size_of::<Params>() as u64,
|
|
||||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
|
||||||
mapped_at_creation: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
source: wgpu::ShaderSource::Wgsl(SHADER.into()),
|
source: wgpu::ShaderSource::Wgsl(SHADER.into()),
|
||||||
|
|
@ -157,39 +153,47 @@ impl Pipeline {
|
||||||
multiview: None,
|
multiview: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
|
Self { pipeline }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GpuParams {
|
||||||
|
pub fn new(device: &wgpu::Device, pipeline: &Pipeline) -> Self {
|
||||||
|
let params = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
|
label: None,
|
||||||
|
size: size_of::<Params>() as u64,
|
||||||
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
|
mapped_at_creation: false,
|
||||||
|
});
|
||||||
let bindings = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let bindings = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
layout: &pipeline.get_bind_group_layout(0),
|
layout: &pipeline.pipeline.get_bind_group_layout(0),
|
||||||
entries: &[wgpu::BindGroupEntry {
|
entries: &[wgpu::BindGroupEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
resource: params.as_entire_binding(),
|
resource: params.as_entire_binding(),
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
Self {
|
Self { params, bindings }
|
||||||
params,
|
|
||||||
bindings,
|
|
||||||
pipeline,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_params(&self, queue: &wgpu::Queue, params: Params) {
|
pub fn set(&self, queue: &wgpu::Queue, params: Params) {
|
||||||
queue.write_buffer(&self.params, 0, bytes_of(¶ms));
|
queue.write_buffer(&self.params, 0, bytes_of(¶ms));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GpuMesh {
|
impl GpuMesh {
|
||||||
pub fn render(&self, pipeline: &Pipeline, pass: &mut wgpu::RenderPass) {
|
pub fn render(&self, pass: &mut wgpu::RenderPass, pipeline: &Pipeline, params: &GpuParams) {
|
||||||
pass.set_pipeline(&pipeline.pipeline);
|
pass.set_pipeline(&pipeline.pipeline);
|
||||||
pass.set_bind_group(0, &pipeline.bindings, &[]);
|
pass.set_bind_group(0, ¶ms.bindings, &[]);
|
||||||
pass.set_vertex_buffer(0, self.vertices.slice(..));
|
pass.set_vertex_buffer(0, self.vertices.slice(..));
|
||||||
pass.draw(0..self.vertex_count, 0..1);
|
pass.draw(0..self.vertex_count, 0..1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GpuMeshIndexed {
|
impl GpuMeshIndexed {
|
||||||
pub fn render(&self, pipeline: &Pipeline, pass: &mut wgpu::RenderPass) {
|
pub fn render(&self, pass: &mut wgpu::RenderPass, pipeline: &Pipeline, params: &GpuParams) {
|
||||||
pass.set_pipeline(&pipeline.pipeline);
|
pass.set_pipeline(&pipeline.pipeline);
|
||||||
pass.set_bind_group(0, &pipeline.bindings, &[]);
|
pass.set_bind_group(0, ¶ms.bindings, &[]);
|
||||||
pass.set_vertex_buffer(0, self.vertices.slice(..));
|
pass.set_vertex_buffer(0, self.vertices.slice(..));
|
||||||
pass.set_index_buffer(self.indices.slice(..), wgpu::IndexFormat::Uint16);
|
pass.set_index_buffer(self.indices.slice(..), wgpu::IndexFormat::Uint16);
|
||||||
pass.draw_indexed(0..self.index_count, 0, 0..1);
|
pass.draw_indexed(0..self.index_count, 0, 0..1);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user