parent
3ca0a2b0ac
commit
f7c8882c04
@ -1,11 +1,14 @@
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
mesh::{Mesh, VertexAttribute},
|
mesh::{Indices, Mesh, VertexAttribute},
|
||||||
pipeline::PrimitiveTopology,
|
pipeline::PrimitiveTopology,
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use bevy_asset::AssetLoader;
|
use bevy_asset::AssetLoader;
|
||||||
use gltf::{buffer::Source, mesh::Mode};
|
use gltf::{
|
||||||
|
buffer::Source,
|
||||||
|
mesh::{util::ReadIndices, Mode},
|
||||||
|
};
|
||||||
use std::{fs, io, path::Path};
|
use std::{fs, io, path::Path};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@ -98,7 +101,11 @@ fn load_node(buffer_data: &[Vec<u8>], node: &gltf::Node, depth: i32) -> Result<M
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(indices) = reader.read_indices() {
|
if let Some(indices) = reader.read_indices() {
|
||||||
mesh.indices = Some(indices.into_u32().collect::<Vec<u32>>());
|
mesh.indices = match indices {
|
||||||
|
ReadIndices::U8(iter) => Some(Indices::U16(iter.map(|i| i as u16).collect())),
|
||||||
|
ReadIndices::U16(iter) => Some(Indices::U16(iter.collect())),
|
||||||
|
ReadIndices::U32(iter) => Some(Indices::U32(iter.collect())),
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(mesh);
|
return Ok(mesh);
|
||||||
|
|||||||
@ -341,8 +341,7 @@ impl<'a> DrawContext<'a> {
|
|||||||
&self,
|
&self,
|
||||||
draw: &mut Draw,
|
draw: &mut Draw,
|
||||||
render_resource_bindings: &[&RenderResourceBindings],
|
render_resource_bindings: &[&RenderResourceBindings],
|
||||||
) -> Result<Option<Range<u32>>, DrawError> {
|
) -> Result<(), DrawError> {
|
||||||
let mut indices = None;
|
|
||||||
let pipeline = self.current_pipeline.ok_or(DrawError::NoPipelineSet)?;
|
let pipeline = self.current_pipeline.ok_or(DrawError::NoPipelineSet)?;
|
||||||
let pipeline_descriptor = self
|
let pipeline_descriptor = self
|
||||||
.pipelines
|
.pipelines
|
||||||
@ -359,13 +358,6 @@ impl<'a> DrawContext<'a> {
|
|||||||
{
|
{
|
||||||
draw.set_vertex_buffer(slot as u32, vertex_buffer, 0);
|
draw.set_vertex_buffer(slot as u32, vertex_buffer, 0);
|
||||||
if let Some(index_buffer) = index_buffer {
|
if let Some(index_buffer) = index_buffer {
|
||||||
if let Some(buffer_info) =
|
|
||||||
self.render_resource_context.get_buffer_info(index_buffer)
|
|
||||||
{
|
|
||||||
indices = Some(0..(buffer_info.size / 2) as u32);
|
|
||||||
} else {
|
|
||||||
panic!("expected buffer type");
|
|
||||||
}
|
|
||||||
draw.set_index_buffer(index_buffer, 0);
|
draw.set_index_buffer(index_buffer, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,8 +365,7 @@ impl<'a> DrawContext<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
Ok(indices)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use super::Vertex;
|
use super::Vertex;
|
||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{
|
pipeline::{
|
||||||
AsVertexBufferDescriptor, IndexFormat, PrimitiveTopology, RenderPipelines,
|
AsVertexBufferDescriptor, PrimitiveTopology, RenderPipelines, VertexBufferDescriptor,
|
||||||
VertexBufferDescriptor, VertexBufferDescriptors, VertexFormat,
|
VertexBufferDescriptors, VertexFormat,
|
||||||
},
|
},
|
||||||
renderer::{BufferInfo, BufferUsage, RenderResourceContext, RenderResourceId},
|
renderer::{BufferInfo, BufferUsage, RenderResourceContext, RenderResourceId},
|
||||||
};
|
};
|
||||||
@ -106,11 +106,17 @@ pub enum MeshToVertexBufferError {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Indices {
|
||||||
|
U16(Vec<u16>),
|
||||||
|
U32(Vec<u32>),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Mesh {
|
pub struct Mesh {
|
||||||
pub primitive_topology: PrimitiveTopology,
|
pub primitive_topology: PrimitiveTopology,
|
||||||
pub attributes: Vec<VertexAttribute>,
|
pub attributes: Vec<VertexAttribute>,
|
||||||
pub indices: Option<Vec<u32>>,
|
pub indices: Option<Indices>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mesh {
|
impl Mesh {
|
||||||
@ -159,23 +165,17 @@ impl Mesh {
|
|||||||
Ok(bytes)
|
Ok(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_index_buffer_bytes(&self, index_format: IndexFormat) -> Option<Vec<u8>> {
|
pub fn get_index_buffer_bytes(&self) -> Option<Vec<u8>> {
|
||||||
self.indices.as_ref().map(|indices| match index_format {
|
self.indices.as_ref().map(|indices| match &indices {
|
||||||
IndexFormat::Uint16 => indices
|
Indices::U16(indices) => indices.as_slice().as_bytes().to_vec(),
|
||||||
.iter()
|
Indices::U32(indices) => indices.as_slice().as_bytes().to_vec(),
|
||||||
.map(|i| *i as u16)
|
|
||||||
.collect::<Vec<u16>>()
|
|
||||||
.as_slice()
|
|
||||||
.as_bytes()
|
|
||||||
.to_vec(),
|
|
||||||
IndexFormat::Uint32 => indices.as_slice().as_bytes().to_vec(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generation for some primitive shape meshes.
|
/// Generation for some primitive shape meshes.
|
||||||
pub mod shape {
|
pub mod shape {
|
||||||
use super::{Mesh, VertexAttribute};
|
use super::{Indices, Mesh, VertexAttribute};
|
||||||
use crate::pipeline::PrimitiveTopology;
|
use crate::pipeline::PrimitiveTopology;
|
||||||
use bevy_math::*;
|
use bevy_math::*;
|
||||||
use hexasphere::Hexasphere;
|
use hexasphere::Hexasphere;
|
||||||
@ -237,14 +237,14 @@ pub mod shape {
|
|||||||
uvs.push(*uv);
|
uvs.push(*uv);
|
||||||
}
|
}
|
||||||
|
|
||||||
let indices = vec![
|
let indices = Indices::U16(vec![
|
||||||
0, 1, 2, 2, 3, 0, // top
|
0, 1, 2, 2, 3, 0, // top
|
||||||
4, 5, 6, 6, 7, 4, // bottom
|
4, 5, 6, 6, 7, 4, // bottom
|
||||||
8, 9, 10, 10, 11, 8, // right
|
8, 9, 10, 10, 11, 8, // right
|
||||||
12, 13, 14, 14, 15, 12, // left
|
12, 13, 14, 14, 15, 12, // left
|
||||||
16, 17, 18, 18, 19, 16, // front
|
16, 17, 18, 18, 19, 16, // front
|
||||||
20, 21, 22, 22, 23, 20, // back
|
20, 21, 22, 22, 23, 20, // back
|
||||||
];
|
]);
|
||||||
|
|
||||||
Mesh {
|
Mesh {
|
||||||
primitive_topology: PrimitiveTopology::TriangleList,
|
primitive_topology: PrimitiveTopology::TriangleList,
|
||||||
@ -333,7 +333,7 @@ pub mod shape {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
let indices = vec![0, 2, 1, 0, 3, 2];
|
let indices = Indices::U16(vec![0, 2, 1, 0, 3, 2]);
|
||||||
|
|
||||||
let mut positions = Vec::new();
|
let mut positions = Vec::new();
|
||||||
let mut normals = Vec::new();
|
let mut normals = Vec::new();
|
||||||
@ -373,7 +373,7 @@ pub mod shape {
|
|||||||
([-extent, 0.0, -extent], [0.0, 1.0, 0.0], [0.0, 1.0]),
|
([-extent, 0.0, -extent], [0.0, 1.0, 0.0], [0.0, 1.0]),
|
||||||
];
|
];
|
||||||
|
|
||||||
let indices = vec![0, 2, 1, 0, 3, 2];
|
let indices = Indices::U16(vec![0, 2, 1, 0, 3, 2]);
|
||||||
|
|
||||||
let mut positions = Vec::new();
|
let mut positions = Vec::new();
|
||||||
let mut normals = Vec::new();
|
let mut normals = Vec::new();
|
||||||
@ -455,6 +455,8 @@ pub mod shape {
|
|||||||
hexasphere.get_indices(i, &mut indices);
|
hexasphere.get_indices(i, &mut indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let indices = Indices::U32(indices);
|
||||||
|
|
||||||
Mesh {
|
Mesh {
|
||||||
primitive_topology: PrimitiveTopology::TriangleList,
|
primitive_topology: PrimitiveTopology::TriangleList,
|
||||||
attributes: vec![
|
attributes: vec![
|
||||||
@ -544,7 +546,7 @@ pub fn mesh_resource_provider_system(
|
|||||||
&vertex_bytes,
|
&vertex_bytes,
|
||||||
);
|
);
|
||||||
|
|
||||||
let index_bytes = mesh.get_index_buffer_bytes(IndexFormat::Uint16).unwrap();
|
let index_bytes = mesh.get_index_buffer_bytes().unwrap();
|
||||||
let index_buffer = render_resource_context.create_buffer_with_data(
|
let index_buffer = render_resource_context.create_buffer_with_data(
|
||||||
BufferInfo {
|
BufferInfo {
|
||||||
buffer_usage: BufferUsage::INDEX,
|
buffer_usage: BufferUsage::INDEX,
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
use super::{state_descriptors::PrimitiveTopology, PipelineDescriptor, VertexBufferDescriptors};
|
use super::{
|
||||||
|
state_descriptors::PrimitiveTopology, IndexFormat, PipelineDescriptor, VertexBufferDescriptors,
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
renderer::RenderResourceContext,
|
renderer::RenderResourceContext,
|
||||||
shader::{Shader, ShaderSource},
|
shader::{Shader, ShaderSource},
|
||||||
@ -14,6 +16,7 @@ pub struct PipelineSpecialization {
|
|||||||
pub shader_specialization: ShaderSpecialization,
|
pub shader_specialization: ShaderSpecialization,
|
||||||
pub primitive_topology: PrimitiveTopology,
|
pub primitive_topology: PrimitiveTopology,
|
||||||
pub dynamic_bindings: Vec<DynamicBinding>,
|
pub dynamic_bindings: Vec<DynamicBinding>,
|
||||||
|
pub index_format: IndexFormat,
|
||||||
pub sample_count: u32,
|
pub sample_count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,6 +27,7 @@ impl Default for PipelineSpecialization {
|
|||||||
shader_specialization: Default::default(),
|
shader_specialization: Default::default(),
|
||||||
primitive_topology: Default::default(),
|
primitive_topology: Default::default(),
|
||||||
dynamic_bindings: Default::default(),
|
dynamic_bindings: Default::default(),
|
||||||
|
index_format: IndexFormat::Uint16,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,6 +165,7 @@ impl PipelineCompiler {
|
|||||||
|
|
||||||
specialized_descriptor.sample_count = pipeline_specialization.sample_count;
|
specialized_descriptor.sample_count = pipeline_specialization.sample_count;
|
||||||
specialized_descriptor.primitive_topology = pipeline_specialization.primitive_topology;
|
specialized_descriptor.primitive_topology = pipeline_specialization.primitive_topology;
|
||||||
|
specialized_descriptor.index_format = pipeline_specialization.index_format;
|
||||||
|
|
||||||
let specialized_pipeline_handle = pipelines.add(specialized_descriptor);
|
let specialized_pipeline_handle = pipelines.add(specialized_descriptor);
|
||||||
render_resource_context.create_render_pipeline(
|
render_resource_context.create_render_pipeline(
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
use super::{PipelineDescriptor, PipelineSpecialization};
|
use super::{IndexFormat, PipelineDescriptor, PipelineSpecialization};
|
||||||
use crate::{
|
use crate::{
|
||||||
draw::{Draw, DrawContext},
|
draw::{Draw, DrawContext},
|
||||||
|
mesh::{Indices, Mesh},
|
||||||
prelude::Msaa,
|
prelude::Msaa,
|
||||||
renderer::RenderResourceBindings,
|
renderer::RenderResourceBindings,
|
||||||
};
|
};
|
||||||
use bevy_asset::Handle;
|
use bevy_asset::{Assets, Handle};
|
||||||
use bevy_ecs::{Query, Res, ResMut};
|
use bevy_ecs::{Query, Res, ResMut};
|
||||||
use bevy_property::Properties;
|
use bevy_property::Properties;
|
||||||
|
|
||||||
@ -75,15 +76,25 @@ pub fn draw_render_pipelines_system(
|
|||||||
mut draw_context: DrawContext,
|
mut draw_context: DrawContext,
|
||||||
mut render_resource_bindings: ResMut<RenderResourceBindings>,
|
mut render_resource_bindings: ResMut<RenderResourceBindings>,
|
||||||
msaa: Res<Msaa>,
|
msaa: Res<Msaa>,
|
||||||
mut query: Query<(&mut Draw, &mut RenderPipelines)>,
|
meshes: Res<Assets<Mesh>>,
|
||||||
|
mut query: Query<(&mut Draw, &mut RenderPipelines, &Handle<Mesh>)>,
|
||||||
) {
|
) {
|
||||||
for (mut draw, mut render_pipelines) in &mut query.iter() {
|
for (mut draw, mut render_pipelines, mesh_handle) in &mut query.iter() {
|
||||||
if !draw.is_visible {
|
if !draw.is_visible {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mesh = meshes.get(mesh_handle).unwrap();
|
||||||
|
let (index_range, index_format) = match mesh.indices.as_ref() {
|
||||||
|
Some(Indices::U32(indices)) => (Some(0..indices.len() as u32), IndexFormat::Uint32),
|
||||||
|
Some(Indices::U16(indices)) => (Some(0..indices.len() as u32), IndexFormat::Uint16),
|
||||||
|
None => (None, IndexFormat::Uint16),
|
||||||
|
};
|
||||||
|
|
||||||
let render_pipelines = &mut *render_pipelines;
|
let render_pipelines = &mut *render_pipelines;
|
||||||
for pipeline in render_pipelines.pipelines.iter_mut() {
|
for pipeline in render_pipelines.pipelines.iter_mut() {
|
||||||
pipeline.specialization.sample_count = msaa.samples;
|
pipeline.specialization.sample_count = msaa.samples;
|
||||||
|
pipeline.specialization.index_format = index_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
for render_pipeline in render_pipelines.pipelines.iter() {
|
for render_pipeline in render_pipelines.pipelines.iter() {
|
||||||
@ -103,10 +114,10 @@ pub fn draw_render_pipelines_system(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let indices = draw_context
|
draw_context
|
||||||
.set_vertex_buffers_from_bindings(&mut draw, &[&render_pipelines.bindings])
|
.set_vertex_buffers_from_bindings(&mut draw, &[&render_pipelines.bindings])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if let Some(indices) = indices {
|
if let Some(indices) = index_range.clone() {
|
||||||
draw.draw_indexed(indices, 0, 0..1);
|
draw.draw_indexed(indices, 0, 0..1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -182,7 +182,7 @@ impl Default for BlendOperation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize, Property)]
|
||||||
pub enum IndexFormat {
|
pub enum IndexFormat {
|
||||||
Uint16 = 0,
|
Uint16 = 0,
|
||||||
Uint32 = 1,
|
Uint32 = 1,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user