diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-06 14:28:02 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-06 14:28:02 +0100 |
commit | 814cc1cb01692aa934a40636c9226ff7bb911266 (patch) | |
tree | 47a50a5dc1861ace4bc1854a9156618b70df3847 /client/src/scene_render.rs | |
parent | c2ee65a83838a0ce13402e2c4634bae409d55071 (diff) | |
download | weareserver-814cc1cb01692aa934a40636c9226ff7bb911266.tar weareserver-814cc1cb01692aa934a40636c9226ff7bb911266.tar.bz2 weareserver-814cc1cb01692aa934a40636c9226ff7bb911266.tar.zst |
new proto
Diffstat (limited to 'client/src/scene_render.rs')
-rw-r--r-- | client/src/scene_render.rs | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/client/src/scene_render.rs b/client/src/scene_render.rs new file mode 100644 index 0000000..cc15e3f --- /dev/null +++ b/client/src/scene_render.rs @@ -0,0 +1,129 @@ +use std::collections::HashMap; +use weareshared::{packets::Resource, tree::SceneTree}; +use wgpu::{ + BindGroup, BindGroupDescriptor, BindGroupLayoutDescriptor, BlendState, Buffer, Color, + ColorTargetState, ColorWrites, CommandEncoder, Device, FragmentState, FrontFace, IndexFormat, + LoadOp, MultisampleState, Operations, PipelineCompilationOptions, PipelineLayoutDescriptor, + PolygonMode, PrimitiveState, PrimitiveTopology, RenderPassColorAttachment, + RenderPassDescriptor, RenderPipeline, RenderPipelineDescriptor, StoreOp, TextureFormat, + TextureView, VertexAttribute, VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, + include_wgsl, +}; + +pub struct ScenePipeline { + pipeline: RenderPipeline, + bind_group: BindGroup, + prefabs: HashMap<Resource, RPrefab>, +} + +struct RPrefab(Vec<RPart>); +struct RPart { + index_count: u32, + index: Buffer, + positions: Buffer, + normals: Buffer, +} + +impl ScenePipeline { + pub fn new(device: &Device, format: TextureFormat) -> Self { + let module = device.create_shader_module(include_wgsl!("shader.wgsl")); + + let bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor { + entries: &[], + label: None, + }); + let bind_group = device.create_bind_group(&BindGroupDescriptor { + label: None, + layout: &bind_group_layout, + entries: &[], + }); + let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor { + label: None, + bind_group_layouts: &[&bind_group_layout], + push_constant_ranges: &[], + }); + let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor { + label: None, + layout: Some(&pipeline_layout), + fragment: Some(FragmentState { + module: &module, + entry_point: Some("fs_main"), + targets: &[Some(ColorTargetState { + blend: Some(BlendState::PREMULTIPLIED_ALPHA_BLENDING), + format, + write_mask: ColorWrites::all(), + })], + compilation_options: PipelineCompilationOptions::default(), + }), + vertex: VertexState { + module: &module, + entry_point: Some("vs_main"), + buffers: &[VertexBufferLayout { + step_mode: VertexStepMode::Vertex, + array_stride: 2 * 4 * 3, + attributes: &[ + VertexAttribute { + format: VertexFormat::Float32x3, + offset: 0, + shader_location: 0, + }, + VertexAttribute { + format: VertexFormat::Float32x3, + offset: 3 * 4, + shader_location: 1, + }, + ], + }], + compilation_options: PipelineCompilationOptions::default(), + }, + primitive: PrimitiveState { + topology: PrimitiveTopology::TriangleList, + front_face: FrontFace::Ccw, + cull_mode: None, //Some(Face::Back), + polygon_mode: PolygonMode::Fill, + ..Default::default() + }, + depth_stencil: Default::default(), + multisample: MultisampleState::default(), + multiview: None, + cache: None, + }); + Self { + bind_group, + pipeline, + prefabs: HashMap::new(), + } + } + pub fn draw(&self, commands: &mut CommandEncoder, target: &TextureView, scene: &SceneTree) { + let mut rpass = commands.begin_render_pass(&RenderPassDescriptor { + label: None, + color_attachments: &[Some(RenderPassColorAttachment { + view: target, + resolve_target: None, + ops: Operations { + store: StoreOp::Store, + load: LoadOp::Clear(Color { + r: 0.1, + g: 0.1, + b: 0.1, + a: 1., + }), + }, + })], + ..Default::default() + }); + rpass.set_bind_group(0, &self.bind_group, &[]); + rpass.set_pipeline(&self.pipeline); + + for ob in scene.objects.values() { + if let Some(prefab) = self.prefabs.get(&ob.res) { + for part in &prefab.0 { + rpass.set_index_buffer(part.index.slice(..), IndexFormat::Uint16); + rpass.set_vertex_buffer(0, part.positions.slice(..)); + rpass.set_vertex_buffer(1, part.normals.slice(..)); + rpass.draw_indexed(0..part.index_count, 0, 0..1); + } + } + } + } +} |