From b5ced3af46c96ceb959fbbf1addfeba3bd4f76d5 Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Wed, 15 Apr 2026 16:53:58 -0400 Subject: first commit. working body rendering --- src/canvas.rs | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 src/canvas.rs (limited to 'src/canvas.rs') diff --git a/src/canvas.rs b/src/canvas.rs new file mode 100644 index 0000000..dbcac7f --- /dev/null +++ b/src/canvas.rs @@ -0,0 +1,176 @@ +use wgpu::RenderPipeline; + +use crate::wgpuctx::WgpuCtx; +use crate::texture::Texture; +use crate::vertex::Vertex; +use crate::wgpuctx::pipeline::RenderPipelineBuilder; + +struct CanvasTexture +{ + pub texture: Texture, + buffer: wgpu::Buffer +} + +pub struct Canvas +{ + pipeline: wgpu::RenderPipeline, + vertex_buffer: wgpu::Buffer, + texture: CanvasTexture, + + position: winit::dpi::LogicalPosition, + size: winit::dpi::LogicalSize +} + +impl Canvas +{ + fn create_canvas_texture( + wgpuctx: &WgpuCtx, + canvas_size: winit::dpi::LogicalSize, + window_size: winit::dpi::PhysicalSize) + -> CanvasTexture + { + let canvas_physical_size = winit::dpi::PhysicalSize::::new( + (window_size.width as f32 * canvas_size.width).floor() as u32, + (window_size.height as f32 * canvas_size.height).floor() as u32 + ); + + CanvasTexture::new(wgpuctx, canvas_physical_size) + } + + pub fn new( + wgpuctx: &WgpuCtx, + window_size: winit::dpi::PhysicalSize, + position: winit::dpi::LogicalPosition, + size: winit::dpi::LogicalSize + ) -> Result { + + let pos_x = position.x * 2.0 - 1.0; + let pos_y = position.y * 2.0 - 1.0; + let size_x = size.width * 2.0; + let size_y = size.height * 2.0; + + let vertices: &[Vertex] = &[ + Vertex { position: [ pos_x, pos_y, 0.0 ], uv: [ 0.0, 1.0 ] }, + Vertex { position: [ pos_x+size_x, pos_y, 0.0 ], uv: [ 1.0, 1.0 ] }, + Vertex { position: [ pos_x+size_x, pos_y+size_y, 0.0 ], uv: [ 1.0, 0.0 ] }, + Vertex { position: [ pos_x+size_x, pos_y+size_y, 0.0 ], uv: [ 1.0, 0.0 ] }, + Vertex { position: [ pos_x, pos_y+size_y, 0.0 ], uv: [ 0.0, 0.0 ] }, + Vertex { position: [ pos_x, pos_y, 0.0 ], uv: [ 0.0, 1.0 ] }, + ]; + + let vertex_buffer = wgpuctx.create_buffer_init( + &wgpu::util::BufferInitDescriptor { + label: Some("Vertex Buffer"), + contents: bytemuck::cast_slice(vertices), + usage: wgpu::BufferUsages::VERTEX + } + ); + + let shader = wgpuctx.create_shader( + wgpu::include_wgsl!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/assets/shaders/canvas.wgsl") + )); + + let canvas_texture = Canvas::create_canvas_texture(wgpuctx, size, window_size); + + let render_pipeline = RenderPipelineBuilder::new( + &shader) + .add_bindgroup(&canvas_texture.texture.bindgrouplayout) + .add_vertex_layout(Vertex::descr()) + .build(Some("Canvas render pipleine"), wgpuctx); + + Ok(Self { + pipeline: render_pipeline, + vertex_buffer: vertex_buffer, + texture: canvas_texture, + position: position, + size: size + }) + } + + pub fn resize( + &mut self, + wgpuctx: &WgpuCtx, + width: u32, + height: u32) + { + let window_size = winit::dpi::PhysicalSize::new(width, height); + self.texture = Canvas::create_canvas_texture(wgpuctx, self.size, window_size); + } + + pub fn present( + &mut self, + screen_pass: &mut wgpu::RenderPass + ) + -> Result<(), wgpu::SurfaceError> { + + screen_pass.set_pipeline(&self.pipeline); + self.texture.texture.use_on_pass(screen_pass, 0); + screen_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); + screen_pass.draw(0..6,0..1); + Ok(()) + } + + pub fn view(&self) + -> &wgpu::TextureView + { + self.texture.texture.view() + } +} //impl Canvas + +impl CanvasTexture +{ + pub fn new( + wgpuctx: &WgpuCtx, + size: winit::dpi::PhysicalSize) + -> Self + { + let u32_size = std::mem::size_of::() as u32; + + let buffer_size = (u32_size * size.width * size.height) as wgpu::BufferAddress; + let buffer_descr = wgpu::BufferDescriptor { + size: buffer_size, + usage: wgpu::BufferUsages::COPY_DST, + label: None, + mapped_at_creation: false + }; + + let texture = wgpuctx.new_render_texture(size); + let buffer = wgpuctx.create_buffer(&buffer_descr); + + Self { + texture: texture, + buffer: buffer + } + } +} + +impl WgpuCtx +{ + pub fn new_render_texture( + &self, + size: winit::dpi::PhysicalSize) + -> Texture + { + let descr = wgpu::TextureDescriptor { + size: wgpu::Extent3d { + width: size.width, + height: size.height, + depth_or_array_layers: 1 + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format: wgpu::TextureFormat::Bgra8UnormSrgb, + view_formats: &[ + wgpu::TextureFormat::Bgra8UnormSrgb + ], + usage: wgpu::TextureUsages::TEXTURE_BINDING | + wgpu::TextureUsages::COPY_SRC | + wgpu::TextureUsages::RENDER_ATTACHMENT, + label: None + }; + self.new_texture(descr) + } +} -- cgit v1.2.3