summaryrefslogtreecommitdiffstats
path: root/src/canvas.rs
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-04-15 16:53:58 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-04-15 16:53:58 -0400
commitb5ced3af46c96ceb959fbbf1addfeba3bd4f76d5 (patch)
tree06d06fc9562dc99eede655b53635576f67c37e3b /src/canvas.rs
downloadsystemic4x-b5ced3af46c96ceb959fbbf1addfeba3bd4f76d5.tar.gz
systemic4x-b5ced3af46c96ceb959fbbf1addfeba3bd4f76d5.tar.bz2
systemic4x-b5ced3af46c96ceb959fbbf1addfeba3bd4f76d5.zip
first commit. working body rendering
Diffstat (limited to 'src/canvas.rs')
-rw-r--r--src/canvas.rs176
1 files changed, 176 insertions, 0 deletions
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<f32>,
+ size: winit::dpi::LogicalSize<f32>
+}
+
+impl Canvas
+{
+ fn create_canvas_texture(
+ wgpuctx: &WgpuCtx,
+ canvas_size: winit::dpi::LogicalSize<f32>,
+ window_size: winit::dpi::PhysicalSize<u32>)
+ -> CanvasTexture
+ {
+ let canvas_physical_size = winit::dpi::PhysicalSize::<u32>::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<u32>,
+ position: winit::dpi::LogicalPosition<f32>,
+ size: winit::dpi::LogicalSize<f32>
+ ) -> Result<Self, ()> {
+
+ 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<u32>)
+ -> Self
+ {
+ let u32_size = std::mem::size_of::<u32>() 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<u32>)
+ -> 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)
+ }
+}