summaryrefslogtreecommitdiff
path: root/client/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-10 20:49:28 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-10 20:49:28 +0100
commitcb46b760ae8d4aeaa0e92a9c313927ffdef27873 (patch)
tree6558cb19352b13ee3006fc1574ca82271e5a2398 /client/src
parent3ac853862b5965c1ebfb10b12fb35cf5c671232f (diff)
downloadweareserver-cb46b760ae8d4aeaa0e92a9c313927ffdef27873.tar
weareserver-cb46b760ae8d4aeaa0e92a9c313927ffdef27873.tar.bz2
weareserver-cb46b760ae8d4aeaa0e92a9c313927ffdef27873.tar.zst
fix interleaved vertex arrays
Diffstat (limited to 'client/src')
-rw-r--r--client/src/scene_prepare.rs104
-rw-r--r--client/src/scene_render.rs55
2 files changed, 73 insertions, 86 deletions
diff --git a/client/src/scene_prepare.rs b/client/src/scene_prepare.rs
index ae7e599..b5ac2cf 100644
--- a/client/src/scene_prepare.rs
+++ b/client/src/scene_prepare.rs
@@ -22,12 +22,13 @@ use std::{
collections::{HashMap, HashSet},
hash::Hash,
io::Cursor,
+ marker::PhantomData,
sync::{Arc, RwLock},
};
use weareshared::{
Affine3A,
packets::Resource,
- resources::{AttributeArray, Image, IndexArray, MeshPart, Prefab},
+ resources::{Image, MeshPart, Prefab},
};
use wgpu::{
AddressMode, BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindingResource,
@@ -79,8 +80,8 @@ pub struct ScenePreparer {
textures: DemandMap<Resource<Image>, (Arc<Texture>, Arc<BindGroup>)>,
placeholder_textures: DemandMap<(), (Arc<Texture>, Arc<BindGroup>)>,
- index_buffers: DemandMap<Resource<IndexArray>, (Arc<Buffer>, u32)>,
- vertex_buffers: DemandMap<Resource<AttributeArray>, (Arc<Buffer>, u32)>,
+ index_buffers: DemandMap<Resource<Vec<[u16; 3]>>, (Arc<Buffer>, u32)>,
+ vertex_buffers: DemandMap<Resource<Vec<f32>>, (Arc<Buffer>, u32)>,
placeholder_vertex_buffers: DemandMap<(u32, bool), Arc<Buffer>>,
mesh_parts: DemandMap<Resource<MeshPart>, Arc<RMeshPart>>,
pub prefabs: DemandMap<Resource<Prefab>, Arc<RPrefab>>,
@@ -90,9 +91,9 @@ pub struct RPrefab(pub Vec<(Affine3A, Arc<RMeshPart>)>);
pub struct RMeshPart {
pub index_count: u32,
pub index: Arc<Buffer>,
- pub position: [Arc<Buffer>; 3],
- pub normal: [Arc<Buffer>; 3],
- pub texcoord: [Arc<Buffer>; 2],
+ pub position: Arc<Buffer>,
+ pub normal: Arc<Buffer>,
+ pub texcoord: Arc<Buffer>,
pub texture: Arc<BindGroup>,
}
@@ -129,7 +130,6 @@ impl ScenePreparer {
for pres in self.index_buffers.needed() {
if let Some(buf) = dls.try_get(pres.clone())? {
let buf = buf
- .0
.into_iter()
.flatten()
.flat_map(u16::to_le_bytes)
@@ -147,10 +147,8 @@ impl ScenePreparer {
for pres in self.vertex_buffers.needed() {
if let Some(buf) = dls.try_get(pres.clone())? {
let buf = buf
- .0
.into_iter()
- .map(f32::to_le_bytes)
- .flatten()
+ .flat_map(f32::to_le_bytes)
.collect::<Vec<_>>();
let buffer = self.device.create_buffer_init(&BufferInitDescriptor {
contents: &buf,
@@ -196,54 +194,32 @@ impl ScenePreparer {
for pres in self.mesh_parts.needed() {
if let Some(part) = dls.try_get(pres.clone())? {
if let (Some(indexres), Some(positionres)) = (part.index, part.va_position) {
- let Some((index, index_count)) = self.index_buffers.try_get(indexres.clone())
- else {
- continue;
- };
- let mut position = Vec::new();
- let mut vertex_count = 0;
- for vr in positionres {
- if let Some((vertex, n)) = self.vertex_buffers.try_get(vr) {
- vertex_count = n;
- position.push(vertex);
- }
- }
- let mut normal = Vec::new();
- if let Some(normalres) = part.va_normal {
- for vr in normalres {
- if let Some((vertex, _)) = self.vertex_buffers.try_get(vr) {
- normal.push(vertex);
- }
- }
+ let index = self.index_buffers.try_get(indexres);
+ let position = self
+ .vertex_buffers
+ .try_get(Resource(positionres.0, PhantomData));
+ let vertex_count = position.as_ref().map(|(_, c)| *c / 3);
+
+ let normal = if let Some(res) = part.va_normal {
+ self.vertex_buffers
+ .try_get(Resource(res.0, PhantomData))
+ .map(|e| e.0)
} else {
- // TODO generate normals
- for _ in 0..3 {
- if let Some(buf) = self
- .placeholder_vertex_buffers
- .try_get((vertex_count, false))
- {
- normal.push(buf);
- }
- }
- }
- let mut texcoord = Vec::new();
- if let Some(texcoordres) = part.va_texcoord {
- for vr in texcoordres {
- if let Some((vertex, _)) = self.vertex_buffers.try_get(vr) {
- texcoord.push(vertex);
- }
- }
+ vertex_count
+ .map(|vc| self.placeholder_vertex_buffers.try_get((vc * 4, false)))
+ .flatten()
+ };
+
+ let texcoord = if let Some(res) = part.va_texcoord {
+ self.vertex_buffers
+ .try_get(Resource(res.0, PhantomData))
+ .map(|e| e.0)
} else {
- // TODO generate UVs
- for _ in 0..3 {
- if let Some(buf) = self
- .placeholder_vertex_buffers
- .try_get((vertex_count, false))
- {
- texcoord.push(buf);
- }
- }
- }
+ vertex_count
+ .map(|vc| self.placeholder_vertex_buffers.try_get((vc * 2, false)))
+ .flatten()
+ };
+
let mut texture = None;
if let Some(albedores) = part.tex_albedo {
if let Some((_tex, bg)) = self.textures.try_get(albedores) {
@@ -255,10 +231,12 @@ impl ScenePreparer {
}
}
- if texcoord.len() == 2
- && normal.len() == 3
- && position.len() == 3
- && texture.is_some()
+ if let (
+ Some(normal),
+ Some((index, index_count)),
+ Some(texcoord),
+ Some((position, _)),
+ ) = (normal, index, texcoord, position)
{
debug!("part created ({pres})");
self.mesh_parts.insert(
@@ -266,9 +244,9 @@ impl ScenePreparer {
Arc::new(RMeshPart {
index_count,
index,
- texcoord: texcoord.try_into().unwrap(),
- normal: normal.try_into().unwrap(),
- position: position.try_into().unwrap(),
+ texcoord,
+ normal,
+ position,
texture: texture.unwrap(),
}),
);
diff --git a/client/src/scene_render.rs b/client/src/scene_render.rs
index 047cee4..f6f7dbb 100644
--- a/client/src/scene_render.rs
+++ b/client/src/scene_render.rs
@@ -35,20 +35,6 @@ pub struct ScenePipeline {
pipeline: RenderPipeline,
}
-macro_rules! v_attr {
- ($($n:literal),*) => {
- [$(VertexBufferLayout {
- step_mode: VertexStepMode::Vertex,
- array_stride: 4,
- attributes: &[VertexAttribute {
- format: VertexFormat::Float32,
- offset: 0,
- shader_location: $n,
- }],
- }),*]
- };
-}
-
impl ScenePipeline {
pub fn new(device: &Device, format: TextureFormat) -> (Self, BindGroupLayout) {
let module = device.create_shader_module(include_wgsl!("shader.wgsl"));
@@ -98,7 +84,35 @@ impl ScenePipeline {
vertex: VertexState {
module: &module,
entry_point: Some("vs_main"),
- buffers: &v_attr!(0, 1, 2, 3, 4, 5, 6, 7),
+ buffers: &[
+ VertexBufferLayout {
+ step_mode: VertexStepMode::Vertex,
+ array_stride: 3 * size_of::<f32>() as u64,
+ attributes: &[VertexAttribute {
+ format: VertexFormat::Float32x3,
+ offset: 0,
+ shader_location: 0,
+ }],
+ },
+ VertexBufferLayout {
+ step_mode: VertexStepMode::Vertex,
+ array_stride: 3 * size_of::<f32>() as u64,
+ attributes: &[VertexAttribute {
+ format: VertexFormat::Float32x3,
+ offset: 0,
+ shader_location: 1,
+ }],
+ },
+ VertexBufferLayout {
+ step_mode: VertexStepMode::Vertex,
+ array_stride: 2 * size_of::<f32>() as u64,
+ attributes: &[VertexAttribute {
+ format: VertexFormat::Float32x2,
+ offset: 0,
+ shader_location: 2,
+ }],
+ },
+ ],
compilation_options: PipelineCompilationOptions::default(),
},
primitive: PrimitiveState {
@@ -177,14 +191,9 @@ impl ScenePipeline {
rpass.set_pipeline(&self.pipeline);
rpass.set_push_constants(ShaderStages::VERTEX, 0, projection.as_flattened());
rpass.set_index_buffer(part.index.slice(..), IndexFormat::Uint16);
- rpass.set_vertex_buffer(0, part.position[0].slice(..));
- rpass.set_vertex_buffer(1, part.position[1].slice(..));
- rpass.set_vertex_buffer(2, part.position[2].slice(..));
- rpass.set_vertex_buffer(3, part.normal[0].slice(..));
- rpass.set_vertex_buffer(4, part.normal[1].slice(..));
- rpass.set_vertex_buffer(5, part.normal[2].slice(..));
- rpass.set_vertex_buffer(6, part.texcoord[0].slice(..));
- rpass.set_vertex_buffer(7, part.texcoord[1].slice(..));
+ rpass.set_vertex_buffer(0, part.position.slice(..));
+ rpass.set_vertex_buffer(1, part.normal.slice(..));
+ rpass.set_vertex_buffer(2, part.texcoord.slice(..));
rpass.draw_indexed(0..part.index_count, 0, 0..1);
}
}