Don't force loaded model indicies to U32

This commit is contained in:
SeanOMik 2023-10-08 00:03:53 -04:00
parent 8f7288339d
commit 02a0eea7b3
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
4 changed files with 58 additions and 31 deletions

View File

@ -2,7 +2,7 @@ use std::sync::Arc;
use base64::Engine;
use crate::{ResourceLoader, LoaderError, Mesh, Model, MeshVertexAttribute, VertexAttributeData, Resource, Material, ResHandle};
use crate::{ResourceLoader, LoaderError, Mesh, Model, MeshVertexAttribute, VertexAttributeData, Resource, Material, MeshIndices};
use tracing::debug;
@ -67,10 +67,11 @@ impl ModelLoader {
// read the indices
if let Some(indices) = reader.read_indices() {
let indices: Vec<u32> = match indices {
gltf::mesh::util::ReadIndices::U8(i) => i.map(|i| i as u32).collect(),
gltf::mesh::util::ReadIndices::U16(i) => i.map(|i| i as u32).collect(),
gltf::mesh::util::ReadIndices::U32(i) => i.collect(),
let indices: MeshIndices = match indices {
// wpgu doesn't support u8 indices, so those must be converted to u16
gltf::mesh::util::ReadIndices::U8(i) => MeshIndices::U16(i.map(|i| i as u16).collect()),
gltf::mesh::util::ReadIndices::U16(i) => MeshIndices::U16(i.collect()),
gltf::mesh::util::ReadIndices::U32(i) => MeshIndices::U32(i.collect()),
};
new_mesh.indices = Some(indices);

View File

@ -1,6 +1,32 @@
use std::collections::HashMap;
use crate::{Material, ResHandle};
use crate::Material;
#[repr(C)]
#[derive(Clone, Debug, PartialEq)]
pub enum MeshIndices {
//U8(Vec<u8>),
U16(Vec<u16>),
U32(Vec<u32>),
}
/* impl From<Vec<u8>> for MeshIndices {
fn from(value: Vec<u8>) -> Self {
MeshIndices::U8(value)
}
} */
impl From<Vec<u16>> for MeshIndices {
fn from(value: Vec<u16>) -> Self {
MeshIndices::U16(value)
}
}
impl From<Vec<u32>> for MeshIndices {
fn from(value: Vec<u32>) -> Self {
MeshIndices::U32(value)
}
}
#[repr(C)]
#[derive(Clone, Debug, PartialEq)]
@ -45,7 +71,7 @@ pub enum MeshVertexAttribute {
#[derive(Clone, Default, edict::Component)]
pub struct Mesh {
pub attributes: HashMap<MeshVertexAttribute, VertexAttributeData>,
pub indices: Option<Vec<u32>>,
pub indices: Option<MeshIndices>,
material: Option<Material>,
}

View File

@ -1,8 +1,8 @@
use std::{ops::Range, cell::Ref};
use std::ops::Range;
use wgpu::{PipelineLayout, RenderPipeline, RenderPass, VertexBufferLayout, BindGroupLayout};
use super::{render_job::RenderJob, vertex::Vertex, desc_buf_lay::DescVertexBufferLayout, texture::RenderTexture};
use super::{render_job::RenderJob, texture::RenderTexture};
pub struct FullRenderPipeline {
layout: PipelineLayout,

View File

@ -36,7 +36,7 @@ pub trait Renderer {
struct RenderBufferStorage {
buffer_vertex: BufferStorage,
buffer_indices: Option<BufferStorage>,
buffer_indices: Option<(wgpu::IndexFormat, BufferStorage)>,
render_texture: Option<RenderTexture>,
texture_bindgroup: Option<BindGroup>,
@ -404,14 +404,6 @@ impl BasicRenderer {
s
}
fn find_next_multiple(n: u32, mul: u32) -> u32 {
if n % mul == 0 {
n
} else {
n + (mul - n % mul)
}
}
fn update_mesh_buffers(&mut self, entity: EntityId, mesh: &Mesh) {
if let Some(buffers) = self.buffer_storage.get_mut(&entity) {
// check if the buffer sizes dont match. If they dont, completely remake the buffers
@ -438,16 +430,19 @@ impl BasicRenderer {
// update the indices if they're given
if let Some(index_buffer) = buffers.buffer_indices.as_ref() {
let index_buffer = index_buffer.buffer();
let indices = mesh.indices.as_ref().unwrap().as_slice();
let (_, indices, _) = bytemuck::pod_align_to::<u32, u32>(indices); // TODO: Don't force indicies into u32
self.queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(&indices));
let aligned_indices = match mesh.indices.as_ref().unwrap() {
// U16 indices need to be aligned to u32, for wpgu, which are 4-bytes in size.
lyra_resource::MeshIndices::U16(v) => bytemuck::pod_align_to::<u16, u32>(v).1,
lyra_resource::MeshIndices::U32(v) => bytemuck::pod_align_to::<u32, u32>(v).1,
};
let index_buffer = index_buffer.1.buffer();
self.queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(&aligned_indices));
}
}
}
fn create_vertex_index_buffers(&mut self, mesh: &Mesh) -> (BufferStorage, Option<BufferStorage>) {
fn create_vertex_index_buffers(&mut self, mesh: &Mesh) -> (BufferStorage, Option<(wgpu::IndexFormat, BufferStorage)>) {
let vertices = mesh.position().unwrap();
let vertex_buffer = self.device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
@ -458,26 +453,31 @@ impl BasicRenderer {
);
let vertex_buffer = BufferStorage::new(vertex_buffer, 0, vertices.len());
let buffer_indices = match mesh.indices.as_ref() {
let indices = match mesh.indices.as_ref() {
Some(indices) => {
let (idx_type, len, contents) = match indices {
lyra_resource::MeshIndices::U16(v) => (wgpu::IndexFormat::Uint16, v.len(), bytemuck::cast_slice(&v)),
lyra_resource::MeshIndices::U32(v) => (wgpu::IndexFormat::Uint32, v.len(), bytemuck::cast_slice(&v)),
};
let index_buffer = self.device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: Some("Index Buffer"),
contents: bytemuck::cast_slice(&indices),
contents,
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages:: COPY_DST,
}
);
let buffer_indices = BufferStorage::new(index_buffer, 0, indices.len());
let buffer_indices = BufferStorage::new(index_buffer, 0, len);
Some(buffer_indices)
Some((idx_type, buffer_indices))
},
None => {
None
}
};
( vertex_buffer, buffer_indices )
( vertex_buffer, indices )
}
fn create_mesh_buffers(&mut self, mesh: &Mesh, transform_indices: TransformBufferIndices) -> RenderBufferStorage {
@ -676,11 +676,11 @@ impl Renderer for BasicRenderer {
render_pass.set_bind_group(2, &self.camera_bind_group, &[]);
// if this mesh uses indices, use them to draw the mesh
if let Some(indices) = buffers.buffer_indices.as_ref() {
if let Some((idx_type, indices)) = buffers.buffer_indices.as_ref() {
let indices_len = indices.count() as u32;
render_pass.set_vertex_buffer(buffers.buffer_vertex.slot(), buffers.buffer_vertex.buffer().slice(..));
render_pass.set_index_buffer(indices.buffer().slice(..), wgpu::IndexFormat::Uint32);
render_pass.set_index_buffer(indices.buffer().slice(..), idx_type.clone());
render_pass.draw_indexed(0..indices_len, 0, 0..1);
} else {
let vertices = mesh.position().unwrap();