Implement non-indexed mesh rendering (#3415)
# Objective Instead of panicking when the `indices` field of a mesh is `None`, actually manage it. This is just a question of keeping track of the vertex buffer size. ## Notes * Relying on this change to improve performance on [bevy_debug_lines using the new renderer](https://github.com/Toqozz/bevy_debug_lines/pull/10) * I'm still new to rendering, my only expertise with wgpu is the learn-wgpu tutorial, likely I'm overlooking something.
This commit is contained in:
parent
851b5939ce
commit
035ec7b763
@ -11,7 +11,7 @@ use bevy_ecs::{
|
|||||||
use bevy_math::Mat4;
|
use bevy_math::Mat4;
|
||||||
use bevy_reflect::TypeUuid;
|
use bevy_reflect::TypeUuid;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
mesh::Mesh,
|
mesh::{GpuBufferInfo, Mesh},
|
||||||
render_asset::RenderAssets,
|
render_asset::RenderAssets,
|
||||||
render_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
|
render_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
|
||||||
render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
|
render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass},
|
||||||
@ -720,13 +720,19 @@ impl EntityRenderCommand for DrawMesh {
|
|||||||
let mesh_handle = mesh_query.get(item).unwrap();
|
let mesh_handle = mesh_query.get(item).unwrap();
|
||||||
if let Some(gpu_mesh) = meshes.into_inner().get(mesh_handle) {
|
if let Some(gpu_mesh) = meshes.into_inner().get(mesh_handle) {
|
||||||
pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..));
|
pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..));
|
||||||
if let Some(index_info) = &gpu_mesh.index_info {
|
match &gpu_mesh.buffer_info {
|
||||||
pass.set_index_buffer(index_info.buffer.slice(..), 0, index_info.index_format);
|
GpuBufferInfo::Indexed {
|
||||||
pass.draw_indexed(0..index_info.count, 0, 0..1);
|
buffer,
|
||||||
} else {
|
index_format,
|
||||||
panic!("non-indexed drawing not supported yet")
|
count,
|
||||||
|
} => {
|
||||||
|
pass.set_index_buffer(buffer.slice(..), 0, *index_format);
|
||||||
|
pass.draw_indexed(0..*count, 0, 0..1);
|
||||||
|
}
|
||||||
|
GpuBufferInfo::NonIndexed { vertex_count } => {
|
||||||
|
pass.draw(0..*vertex_count, 0..1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderCommandResult::Success
|
RenderCommandResult::Success
|
||||||
} else {
|
} else {
|
||||||
RenderCommandResult::Failure
|
RenderCommandResult::Failure
|
||||||
|
|||||||
@ -591,18 +591,23 @@ impl From<&Indices> for IndexFormat {
|
|||||||
pub struct GpuMesh {
|
pub struct GpuMesh {
|
||||||
/// Contains all attribute data for each vertex.
|
/// Contains all attribute data for each vertex.
|
||||||
pub vertex_buffer: Buffer,
|
pub vertex_buffer: Buffer,
|
||||||
pub index_info: Option<GpuIndexInfo>,
|
pub buffer_info: GpuBufferInfo,
|
||||||
pub has_tangents: bool,
|
pub has_tangents: bool,
|
||||||
pub primitive_topology: PrimitiveTopology,
|
pub primitive_topology: PrimitiveTopology,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The index info of a [`GpuMesh`].
|
/// The index/vertex buffer info of a [`GpuMesh`].
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct GpuIndexInfo {
|
pub enum GpuBufferInfo {
|
||||||
/// Contains all index data of a mesh.
|
Indexed {
|
||||||
pub buffer: Buffer,
|
/// Contains all index data of a mesh.
|
||||||
pub count: u32,
|
buffer: Buffer,
|
||||||
pub index_format: IndexFormat,
|
count: u32,
|
||||||
|
index_format: IndexFormat,
|
||||||
|
},
|
||||||
|
NonIndexed {
|
||||||
|
vertex_count: u32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderAsset for Mesh {
|
impl RenderAsset for Mesh {
|
||||||
@ -627,19 +632,24 @@ impl RenderAsset for Mesh {
|
|||||||
contents: &vertex_buffer_data,
|
contents: &vertex_buffer_data,
|
||||||
});
|
});
|
||||||
|
|
||||||
let index_info = mesh.get_index_buffer_bytes().map(|data| GpuIndexInfo {
|
let buffer_info = mesh.get_index_buffer_bytes().map_or(
|
||||||
buffer: render_device.create_buffer_with_data(&BufferInitDescriptor {
|
GpuBufferInfo::NonIndexed {
|
||||||
usage: BufferUsages::INDEX,
|
vertex_count: mesh.count_vertices() as u32,
|
||||||
contents: data,
|
},
|
||||||
label: Some("Mesh Index Buffer"),
|
|data| GpuBufferInfo::Indexed {
|
||||||
}),
|
buffer: render_device.create_buffer_with_data(&BufferInitDescriptor {
|
||||||
count: mesh.indices().unwrap().len() as u32,
|
usage: BufferUsages::INDEX,
|
||||||
index_format: mesh.indices().unwrap().into(),
|
contents: data,
|
||||||
});
|
label: Some("Mesh Index Buffer"),
|
||||||
|
}),
|
||||||
|
count: mesh.indices().unwrap().len() as u32,
|
||||||
|
index_format: mesh.indices().unwrap().into(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
Ok(GpuMesh {
|
Ok(GpuMesh {
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
index_info,
|
buffer_info,
|
||||||
has_tangents: mesh.attributes.contains_key(Mesh::ATTRIBUTE_TANGENT),
|
has_tangents: mesh.attributes.contains_key(Mesh::ATTRIBUTE_TANGENT),
|
||||||
primitive_topology: mesh.primitive_topology(),
|
primitive_topology: mesh.primitive_topology(),
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user