diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-10 03:11:29 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-10 03:11:29 +0100 |
commit | 5d935c26589c014e6dc2941481988abf50e51fdf (patch) | |
tree | bc679c9e6ef6783749d3413c0e8368979dbb6b15 /client/src/ui.rs | |
parent | 3ecd4588d4aa85a93a06aa5a1a3a60b918a72557 (diff) | |
download | weareserver-5d935c26589c014e6dc2941481988abf50e51fdf.tar weareserver-5d935c26589c014e6dc2941481988abf50e51fdf.tar.bz2 weareserver-5d935c26589c014e6dc2941481988abf50e51fdf.tar.zst |
fix triple inverted projection madness
Diffstat (limited to 'client/src/ui.rs')
-rw-r--r-- | client/src/ui.rs | 173 |
1 files changed, 101 insertions, 72 deletions
diff --git a/client/src/ui.rs b/client/src/ui.rs index 638978a..3687276 100644 --- a/client/src/ui.rs +++ b/client/src/ui.rs @@ -15,26 +15,32 @@ along with this program. If not, see <https://www.gnu.org/licenses/>. */ use egui::{ - Context, TextureId, + Context, ImageData, TextureId, epaint::{Primitive, Vertex}, }; +use glam::Mat4; +use log::info; use std::{collections::HashMap, num::NonZeroU64}; use wgpu::{ - BindGroup, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, BlendState, Buffer, - BufferDescriptor, BufferUsages, Color, ColorTargetState, ColorWrites, CommandEncoder, - CompareFunction, DepthBiasState, DepthStencilState, Device, FragmentState, FrontFace, - IndexFormat, LoadOp, MultisampleState, Operations, PipelineCompilationOptions, - PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology, PushConstantRange, - Queue, RenderPassColorAttachment, RenderPassDescriptor, RenderPipeline, - RenderPipelineDescriptor, SamplerBindingType, ShaderStages, StencilState, StoreOp, Texture, - TextureFormat, TextureSampleType, TextureView, TextureViewDimension, VertexAttribute, - VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, include_wgsl, + BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor, + BindGroupLayoutEntry, BindingResource, BindingType, BlendState, Buffer, BufferDescriptor, + BufferUsages, Color, ColorTargetState, ColorWrites, CommandEncoder, CompareFunction, + DepthBiasState, DepthStencilState, Device, Extent3d, FragmentState, FrontFace, IndexFormat, + LoadOp, MultisampleState, Operations, PipelineCompilationOptions, PipelineLayoutDescriptor, + PolygonMode, PrimitiveState, PrimitiveTopology, PushConstantRange, Queue, + RenderPassColorAttachment, RenderPassDescriptor, RenderPipeline, RenderPipelineDescriptor, + SamplerBindingType, SamplerDescriptor, ShaderStages, StencilState, StoreOp, Texture, + TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages, + TextureView, TextureViewDescriptor, TextureViewDimension, VertexAttribute, VertexBufferLayout, + VertexFormat, VertexState, VertexStepMode, include_wgsl, + util::{DeviceExt, TextureDataOrder}, }; pub struct UiRenderer { ctx: Context, pipeline: RenderPipeline, + bind_group_layout: BindGroupLayout, index: Buffer, vertex: Buffer, @@ -131,13 +137,7 @@ impl UiRenderer { polygon_mode: PolygonMode::Fill, ..Default::default() }, - depth_stencil: Some(DepthStencilState { - depth_compare: CompareFunction::Greater, - depth_write_enabled: true, - format: TextureFormat::Depth32Float, - bias: DepthBiasState::default(), - stencil: StencilState::default(), - }), + depth_stencil: None, multisample: MultisampleState::default(), multiview: None, cache: None, @@ -147,60 +147,89 @@ impl UiRenderer { pipeline, index, vertex, + bind_group_layout, textures: HashMap::new(), } } - pub fn create_texture() { - // let texture = device.create_texture_with_data( - // &queue, - // &TextureDescriptor { - // label: None, - // size: Extent3d { - // depth_or_array_layers: 1, - // width, - // height, - // }, - // mip_level_count: 1, - // sample_count: 1, - // dimension: TextureDimension::D2, - // format: TextureFormat::Rgba8UnormSrgb, - // usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, - // view_formats: &[], - // }, - // TextureDataOrder::LayerMajor, - // data, - // ); - // let textureview = texture.create_view(&TextureViewDescriptor::default()); - // let sampler = device.create_sampler(&SamplerDescriptor { - // ..Default::default() - // }); - // let bindgroup = device.create_bind_group(&BindGroupDescriptor { - // label: None, - // layout: &bgl, - // entries: &[ - // BindGroupEntry { - // binding: 0, - // resource: BindingResource::TextureView(&textureview), - // }, - // BindGroupEntry { - // binding: 1, - // resource: BindingResource::Sampler(&sampler), - // }, - // ], - // }); - } + pub fn create_texture() {} - pub fn draw(&self, queue: &Queue, commands: &mut CommandEncoder, target: &TextureView) { + pub fn draw( + &mut self, + device: &Device, + queue: &Queue, + commands: &mut CommandEncoder, + target: &TextureView, + projection: Mat4, + ) { let raw_input = egui::RawInput::default(); let full_output = self.ctx.run(raw_input, |ctx| { egui::CentralPanel::default().show(&ctx, |ui| { ui.label("Hello world!"); + ui.label("I dont think this will ever work..."); ui.button("Click me").clicked(); }); }); - for (texid, delta) in full_output.textures_delta.set {} + for (texid, delta) in full_output.textures_delta.set { + if let Some((texbg, tex)) = self.textures.get_mut(&texid) { + drop((texbg, tex)); + todo!() + } else { + assert_eq!( + delta.pos, None, + "partial update impossible; texture does not yet exist" + ); + info!( + "uploading new UI texture: width={}, height={}", + delta.image.width(), + delta.image.height() + ); + let pixels = match &delta.image { + ImageData::Color(color_image) => color_image.pixels.clone(), + ImageData::Font(font_image) => font_image.srgba_pixels(None).collect(), + }; + + let texture = device.create_texture_with_data( + &queue, + &TextureDescriptor { + label: None, + size: Extent3d { + depth_or_array_layers: 1, + width: delta.image.width() as u32, + height: delta.image.height() as u32, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Rgba8UnormSrgb, + usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, + view_formats: &[], + }, + TextureDataOrder::LayerMajor, + bytemuck::cast_slice::<_, u8>(&pixels), + ); + let textureview = texture.create_view(&TextureViewDescriptor::default()); + let sampler = device.create_sampler(&SamplerDescriptor { + ..Default::default() + }); + let bindgroup = device.create_bind_group(&BindGroupDescriptor { + label: None, + layout: &self.bind_group_layout, + entries: &[ + BindGroupEntry { + binding: 0, + resource: BindingResource::TextureView(&textureview), + }, + BindGroupEntry { + binding: 1, + resource: BindingResource::Sampler(&sampler), + }, + ], + }); + self.textures.insert(texid, (bindgroup, texture)); + } + } let clipped_primitives = self .ctx @@ -210,8 +239,8 @@ impl UiRenderer { let mut vertex_count = 0; for p in &clipped_primitives { if let Primitive::Mesh(mesh) = &p.primitive { + index_count += mesh.indices.len(); vertex_count += mesh.vertices.len(); - index_count += mesh.vertices.len(); } } @@ -237,17 +266,19 @@ impl UiRenderer { let mut slices = Vec::new(); for p in clipped_primitives { if let Primitive::Mesh(mesh) = p.primitive { - mapped_index[index_offset..index_offset + (mesh.indices.len() * size_of::<u32>())] + mapped_index[index_offset * size_of::<u32>() + ..(index_offset + mesh.indices.len()) * size_of::<u32>()] .copy_from_slice(bytemuck::cast_slice(&mesh.indices)); - mapped_vertex - [vertex_offset..vertex_offset + (mesh.vertices.len() * size_of::<Vertex>())] + mapped_vertex[vertex_offset * size_of::<Vertex>() + ..(vertex_offset + mesh.vertices.len()) * size_of::<Vertex>()] .copy_from_slice(bytemuck::cast_slice(&mesh.vertices)); - index_offset += mesh.indices.len(); - vertex_offset += mesh.vertices.len(); slices.push(( index_offset as u32..index_offset as u32 + mesh.indices.len() as u32, vertex_offset as i32, + mesh.texture_id, )); + index_offset += mesh.indices.len(); + vertex_offset += mesh.vertices.len(); } } @@ -258,22 +289,20 @@ impl UiRenderer { resolve_target: None, ops: Operations { store: StoreOp::Store, - load: LoadOp::Clear(Color { - r: 0.01, - g: 0.01, - b: 0.01, - a: 1., - }), + load: LoadOp::Load, }, })], ..Default::default() }); + let projection = projection.to_cols_array().map(|v| v.to_le_bytes()); + rpass.set_pipeline(&self.pipeline); rpass.set_index_buffer(self.index.slice(..), IndexFormat::Uint32); rpass.set_vertex_buffer(0, self.vertex.slice(..)); - for (index, base_vertex) in slices { - // rpass.set_bind_group(0, &self.bind_group, &[]); + rpass.set_push_constants(ShaderStages::VERTEX, 0, projection.as_flattened()); + for (index, base_vertex, texid) in slices { + rpass.set_bind_group(0, &self.textures.get(&texid).unwrap().0, &[]); rpass.draw_indexed(index, base_vertex, 0..1); } } |