Don't force loaded model indicies to U32
This commit is contained in:
parent
8f7288339d
commit
02a0eea7b3
|
@ -2,7 +2,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use base64::Engine;
|
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;
|
use tracing::debug;
|
||||||
|
|
||||||
|
@ -67,10 +67,11 @@ impl ModelLoader {
|
||||||
|
|
||||||
// read the indices
|
// read the indices
|
||||||
if let Some(indices) = reader.read_indices() {
|
if let Some(indices) = reader.read_indices() {
|
||||||
let indices: Vec<u32> = match indices {
|
let indices: MeshIndices = match indices {
|
||||||
gltf::mesh::util::ReadIndices::U8(i) => i.map(|i| i as u32).collect(),
|
// wpgu doesn't support u8 indices, so those must be converted to u16
|
||||||
gltf::mesh::util::ReadIndices::U16(i) => i.map(|i| i as u32).collect(),
|
gltf::mesh::util::ReadIndices::U8(i) => MeshIndices::U16(i.map(|i| i as u16).collect()),
|
||||||
gltf::mesh::util::ReadIndices::U32(i) => i.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);
|
new_mesh.indices = Some(indices);
|
||||||
|
|
|
@ -1,6 +1,32 @@
|
||||||
use std::collections::HashMap;
|
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)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
@ -45,7 +71,7 @@ pub enum MeshVertexAttribute {
|
||||||
#[derive(Clone, Default, edict::Component)]
|
#[derive(Clone, Default, edict::Component)]
|
||||||
pub struct Mesh {
|
pub struct Mesh {
|
||||||
pub attributes: HashMap<MeshVertexAttribute, VertexAttributeData>,
|
pub attributes: HashMap<MeshVertexAttribute, VertexAttributeData>,
|
||||||
pub indices: Option<Vec<u32>>,
|
pub indices: Option<MeshIndices>,
|
||||||
material: Option<Material>,
|
material: Option<Material>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::{ops::Range, cell::Ref};
|
use std::ops::Range;
|
||||||
|
|
||||||
use wgpu::{PipelineLayout, RenderPipeline, RenderPass, VertexBufferLayout, BindGroupLayout};
|
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 {
|
pub struct FullRenderPipeline {
|
||||||
layout: PipelineLayout,
|
layout: PipelineLayout,
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub trait Renderer {
|
||||||
|
|
||||||
struct RenderBufferStorage {
|
struct RenderBufferStorage {
|
||||||
buffer_vertex: BufferStorage,
|
buffer_vertex: BufferStorage,
|
||||||
buffer_indices: Option<BufferStorage>,
|
buffer_indices: Option<(wgpu::IndexFormat, BufferStorage)>,
|
||||||
|
|
||||||
render_texture: Option<RenderTexture>,
|
render_texture: Option<RenderTexture>,
|
||||||
texture_bindgroup: Option<BindGroup>,
|
texture_bindgroup: Option<BindGroup>,
|
||||||
|
@ -404,14 +404,6 @@ impl BasicRenderer {
|
||||||
s
|
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) {
|
fn update_mesh_buffers(&mut self, entity: EntityId, mesh: &Mesh) {
|
||||||
if let Some(buffers) = self.buffer_storage.get_mut(&entity) {
|
if let Some(buffers) = self.buffer_storage.get_mut(&entity) {
|
||||||
// check if the buffer sizes dont match. If they dont, completely remake the buffers
|
// 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
|
// update the indices if they're given
|
||||||
if let Some(index_buffer) = buffers.buffer_indices.as_ref() {
|
if let Some(index_buffer) = buffers.buffer_indices.as_ref() {
|
||||||
let index_buffer = index_buffer.buffer();
|
let aligned_indices = match mesh.indices.as_ref().unwrap() {
|
||||||
let indices = mesh.indices.as_ref().unwrap().as_slice();
|
// U16 indices need to be aligned to u32, for wpgu, which are 4-bytes in size.
|
||||||
let (_, indices, _) = bytemuck::pod_align_to::<u32, u32>(indices); // TODO: Don't force indicies into u32
|
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,
|
||||||
self.queue.write_buffer(index_buffer, 0, bytemuck::cast_slice(&indices));
|
};
|
||||||
|
|
||||||
|
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 vertices = mesh.position().unwrap();
|
||||||
let vertex_buffer = self.device.create_buffer_init(
|
let vertex_buffer = self.device.create_buffer_init(
|
||||||
&wgpu::util::BufferInitDescriptor {
|
&wgpu::util::BufferInitDescriptor {
|
||||||
|
@ -458,26 +453,31 @@ impl BasicRenderer {
|
||||||
);
|
);
|
||||||
let vertex_buffer = BufferStorage::new(vertex_buffer, 0, vertices.len());
|
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) => {
|
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(
|
let index_buffer = self.device.create_buffer_init(
|
||||||
&wgpu::util::BufferInitDescriptor {
|
&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Index Buffer"),
|
label: Some("Index Buffer"),
|
||||||
contents: bytemuck::cast_slice(&indices),
|
contents,
|
||||||
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages:: COPY_DST,
|
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 => {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
( vertex_buffer, buffer_indices )
|
( vertex_buffer, indices )
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_mesh_buffers(&mut self, mesh: &Mesh, transform_indices: TransformBufferIndices) -> RenderBufferStorage {
|
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, &[]);
|
render_pass.set_bind_group(2, &self.camera_bind_group, &[]);
|
||||||
|
|
||||||
// if this mesh uses indices, use them to draw the mesh
|
// 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;
|
let indices_len = indices.count() as u32;
|
||||||
|
|
||||||
render_pass.set_vertex_buffer(buffers.buffer_vertex.slot(), buffers.buffer_vertex.buffer().slice(..));
|
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);
|
render_pass.draw_indexed(0..indices_len, 0, 0..1);
|
||||||
} else {
|
} else {
|
||||||
let vertices = mesh.position().unwrap();
|
let vertices = mesh.position().unwrap();
|
||||||
|
|
Loading…
Reference in New Issue