Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mesh overhaul with custom vertex attributes #592 #599

Merged
merged 35 commits into from
Oct 31, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
35a9bf8
first draft
Sep 28, 2020
4c5d883
clean up + format
Oct 1, 2020
92bae44
Update mesh.rs
Oct 1, 2020
d47897c
Update mesh.rs
Oct 1, 2020
6253a95
clippy nightly
Oct 1, 2020
ccbc1bc
changed vertex buffer slots now taken from binding; shader naming con…
Oct 4, 2020
66640b7
simplified shader vertex attribute reflection, removed VertexBufferDe…
Oct 4, 2020
519b6b0
format
Oct 4, 2020
ae2e670
format nightly
Oct 4, 2020
049e5a9
Draw panics now when vertex buffer is missing; Name based hashmap for…
Oct 5, 2020
21bd324
added proper clean up for mesh resources (untested)
Oct 6, 2020
5a09a47
fixed bevy_text to work with new vertex system
Oct 6, 2020
f59bacd
using fnv hash for vertex attributes; refactor
Oct 7, 2020
80eafc8
restored old vertex naming convention
Oct 7, 2020
8d54839
reintroduced multiple attributes per buffer
Oct 9, 2020
ab37614
changed internal resource id to u64; using AHasher for vertex attribu…
Oct 9, 2020
9734db5
Reintroduced interleaved buffers, but flexible. :smile: Pipeline spec…
Oct 13, 2020
20d101b
made fallback buffer obtional. readded properties to rendering structs
Oct 14, 2020
8ff3bbb
HashMap for attributes for consisten order and uniqueness. Removed Ve…
Oct 16, 2020
5608eb2
fixed text. cleanup
Oct 19, 2020
0d61e81
Removed mesh.insert_attribute. removed VertexBufferDescriptor hack in…
Oct 21, 2020
39740c4
Merge remote-tracking branch 'upstream/master' into render_mesh_seper…
Oct 22, 2020
1417b2c
post merge fixes
Oct 22, 2020
8fb3874
fmt
Oct 22, 2020
01f79c7
Update CHANGELOG.md
Oct 22, 2020
63c4574
Merge branch 'master' into render_mesh_seperate_buffers
Oct 22, 2020
1b39ca9
Sort attributes before turning them into bytes. Removed indices from …
Oct 30, 2020
8ce53ee
Merge branch 'master' into render_mesh_seperate_buffers
Oct 30, 2020
789de51
Update sprite_sheet.vert
Oct 30, 2020
f759aa6
Update mesh.rs
Oct 30, 2020
b766c9a
fixed a bug related to more attributes defined by mesh than used by s…
Oct 31, 2020
223f5a2
format
Oct 31, 2020
5a4d6e2
Revert "format"
Oct 31, 2020
87fde6d
Update pipeline_compiler.rs
Oct 31, 2020
e665298
Update pipeline_compiler.rs
Oct 31, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions crates/bevy_render/src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ pub enum DrawError {
PipelineHasNoLayout,
#[error("Failed to get a buffer for the given RenderResource.")]
BufferAllocationFailure,
#[error("Could not get buffer for Vertex Attribute")]
NoBufferForVertexAttribute,
}

pub struct DrawContext<'a> {
Expand Down Expand Up @@ -350,21 +352,24 @@ impl<'a> DrawContext<'a> {
let layout = pipeline_descriptor
.get_layout()
.ok_or(DrawError::PipelineHasNoLayout)?;

println!("{:?}", layout.vertex_buffer_descriptors);
for (slot, vertex_buffer_descriptor) in layout.vertex_buffer_descriptors.iter().enumerate()
{
println!("trying to get buffer for slot {} -> {}", slot, &vertex_buffer_descriptor.name);
for bindings in render_resource_bindings.iter() {
if let Some((vertex_buffer, index_buffer)) =
bindings.get_vertex_buffer(&vertex_buffer_descriptor.name)
{
draw.set_vertex_buffer(slot as u32, vertex_buffer, 0);
if let Some(index_buffer) = index_buffer {
draw.set_index_buffer(index_buffer, 0);
}

break;
println!("\t binding {:?}", &bindings.id);
// TODO: fix this, it is setting the buffer multiply times
for vertex_buffer in &bindings.vertex_buffers{
println!("\t \t set slot{:?}", &vertex_buffer.0);
draw.set_vertex_buffer(vertex_buffer.0.clone() as u32 - 1, vertex_buffer.1.clone(), 0);
}
if let Some(index_buffer) = bindings.index_buffer{
draw.set_index_buffer(index_buffer, 0);
}
}
}
println!("done with vertex_buffer_descriptors");
Ok(())
}
}
Expand Down
146 changes: 100 additions & 46 deletions crates/bevy_render/src/mesh/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ use bevy_math::*;
use bevy_utils::HashSet;
use std::borrow::Cow;
use thiserror::Error;
use crate::pipeline::VertexAttributeDescriptor;
use downcast_rs::Downcast;

pub const VERTEX_BUFFER_ASSET_INDEX: usize = 0;
pub const INDEX_BUFFER_ASSET_INDEX: usize = 1;
use crate::pipeline::InputStepMode;

pub const VERTEX_BUFFER_ASSET_INDEX: usize = 1;
pub const INDEX_BUFFER_ASSET_INDEX: usize = 0;
#[derive(Clone, Debug)]
pub enum VertexAttributeValues {
Float(Vec<f32>),
Expand Down Expand Up @@ -127,6 +131,15 @@ impl Mesh {
indices: None,
}
}
// pub fn get_vertex_attribute_bytes(
// &self,
// fill_missing_attributes: bool,
// attribute_index: u32,
// ) -> Result<Vec<u8>, MeshToVertexBufferError>{
// let attribute
// let mut bytes = vec![0; vertex_buffer_descriptor.stride as usize];
//
// }

pub fn get_vertex_buffer_bytes(
&self,
Expand Down Expand Up @@ -502,16 +515,55 @@ pub fn mesh_resource_provider_system(
mesh_events: Res<Events<AssetEvent<Mesh>>>,
mut query: Query<(&Handle<Mesh>, &mut RenderPipelines)>,
) {
let vertex_buffer_descriptor = match state.vertex_buffer_descriptor {
Some(value) => value,
None => {
// TODO: allow pipelines to specialize on vertex_buffer_descriptor and index_format
let vertex_buffer_descriptor = Vertex::as_vertex_buffer_descriptor();
vertex_buffer_descriptors.set(vertex_buffer_descriptor.clone());
state.vertex_buffer_descriptor = Some(vertex_buffer_descriptor);
vertex_buffer_descriptor
}
};
if state.vertex_buffer_descriptor.is_none() {
// TODO: allow pipelines to specialize on vertex_buffer_descriptor and index_format
let mut vertex_buffer_descriptors_: VertexBufferDescriptors = VertexBufferDescriptors{
descriptors: Default::default()
};

// TODO: kinda messy
vertex_buffer_descriptors_.descriptors.insert(
"Vertex_Position".to_string(),
VertexBufferDescriptor{
name: "Vertex_Position".into(),
stride: VertexFormat::Float3.get_size(),
step_mode: InputStepMode::Vertex,
attributes: vec![VertexAttributeDescriptor{
name: "Vertex_Position".into(),
offset: 0,
format: VertexFormat::Float3,
shader_location: 0
}]
});
vertex_buffer_descriptors_.descriptors.insert(
"Vertex_Normal".to_string(),
VertexBufferDescriptor{
name: "Vertex_Normal".into(),
stride: VertexFormat::Float3.get_size(),
step_mode: InputStepMode::Vertex,
attributes: vec![VertexAttributeDescriptor{
name: "Vertex_Normal".into(),
offset: 0,
format: VertexFormat::Float3,
shader_location: 0
}]
});
vertex_buffer_descriptors_.descriptors.insert(
"Vertex_Uv".to_string(),
VertexBufferDescriptor{
name: "Vertex_Uv".into(),
stride: VertexFormat::Float2.get_size(),
step_mode: InputStepMode::Vertex,
attributes: vec![VertexAttributeDescriptor{
name: "Vertex_Uv".into(),
offset: 0,
format: VertexFormat::Float2,
shader_location: 0
}]
});
vertex_buffer_descriptors.set_many(vertex_buffer_descriptors_);
}
julhe marked this conversation as resolved.
Show resolved Hide resolved

let mut changed_meshes = HashSet::<Handle<Mesh>>::default();
let render_resource_context = &**render_resource_context;
for event in state.mesh_event_reader.iter(&mesh_events) {
Expand All @@ -534,32 +586,35 @@ pub fn mesh_resource_provider_system(

for changed_mesh_handle in changed_meshes.iter() {
if let Some(mesh) = meshes.get(changed_mesh_handle) {
let vertex_bytes = mesh
.get_vertex_buffer_bytes(&vertex_buffer_descriptor, true)
.unwrap();
// TODO: use a staging buffer here
let vertex_buffer = render_resource_context.create_buffer_with_data(
BufferInfo {
buffer_usage: BufferUsage::VERTEX,
..Default::default()
},
&vertex_bytes,
);

let index_bytes = mesh.get_index_buffer_bytes().unwrap();
let mut index = 1; // index 0 is reserved by INDEX_BUFFER_ASSET_INDEX
julhe marked this conversation as resolved.
Show resolved Hide resolved
for attribute in &mesh.attributes{
println!("insert index vertex buffer index {}", index);
// TODO: use a staging buffer here
let attribute_buffer = render_resource_context.create_buffer_with_data(
BufferInfo {
buffer_usage: BufferUsage::VERTEX,
..Default::default()
},
&attribute.values.get_bytes(),
);

render_resource_context.set_asset_resource(
*changed_mesh_handle,
RenderResourceId::Buffer(attribute_buffer),
index,
);
index += 1;
}

let index_buffer = render_resource_context.create_buffer_with_data(
BufferInfo {
buffer_usage: BufferUsage::INDEX,
..Default::default()
},
&index_bytes,
&mesh.get_index_buffer_bytes().unwrap(),
);

render_resource_context.set_asset_resource(
*changed_mesh_handle,
RenderResourceId::Buffer(vertex_buffer),
VERTEX_BUFFER_ASSET_INDEX,
);
render_resource_context.set_asset_resource(
*changed_mesh_handle,
RenderResourceId::Buffer(index_buffer),
Expand All @@ -576,23 +631,22 @@ pub fn mesh_resource_provider_system(
}
}

if let Some(RenderResourceId::Buffer(vertex_buffer)) =
render_resource_context.get_asset_resource(*handle, VERTEX_BUFFER_ASSET_INDEX)
{
render_pipelines.bindings.set_vertex_buffer(
"Vertex",
vertex_buffer,
render_resource_context
.get_asset_resource(*handle, INDEX_BUFFER_ASSET_INDEX)
.and_then(|r| {
if let RenderResourceId::Buffer(buffer) = r {
Some(buffer)
} else {
None
}
}),
);
// set index buffer into binding
let index_buffer_resource = render_resource_context.get_asset_resource(*handle, INDEX_BUFFER_ASSET_INDEX)
.expect("no index buffer resource found.").get_buffer().expect("resource is not a buffer");

render_pipelines.bindings.set_index_buffer(index_buffer_resource);
julhe marked this conversation as resolved.
Show resolved Hide resolved

// set vertex buffers into bindings
for index in 1..4 { //TODO: use actual vertex buffer count
if let Some(RenderResourceId::Buffer(vertex_buffer)) =
render_resource_context.get_asset_resource(*handle, index)
{
println!("setup vertex buffer {}", index);
render_pipelines.bindings.set_vertex_buffer(index as u8, vertex_buffer);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

based on my above comments, this would end up as something like

for pipeline in render_pipelines.pipelines {
    let pipeline_descriptor = pipeline_descriptors.get(pipeline.descriptor).unwrap();
    if let Some(layout) = pipelin_descriptor.layout {
        for (slot, vertex_buffer_descriptor) in layout.vertex_buffer_descriptors.iter().enumerate() {
            let handle = render_resource_context
                .get_asset_resource(*handle, vertex_buffer_descriptor.name)
                .expect("mesh does not provide required vertex attribute {} for pipeline {:?}", vertex_buffer_descriptor.name, pipeline_descriptor);
            println!("setup vertex buffer {}", slot);
            render_pipelines.bindings.set_vertex_buffer(slot as u8, handle);
        }
    }
}

}

}
}

Expand Down
1 change: 1 addition & 0 deletions crates/bevy_render/src/pipeline/pipeline_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ impl PipelineLayout {
}

for vertex_buffer_descriptor in shader_layouts[0].vertex_buffer_descriptors.iter() {
println!("vertex_buffer_descriptor {:?}", vertex_buffer_descriptor.clone());
vertex_buffer_descriptors.push(vertex_buffer_descriptor.clone());
}

Expand Down
8 changes: 7 additions & 1 deletion crates/bevy_render/src/pipeline/vertex_buffer_descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ pub struct VertexBufferDescriptor {
pub name: Cow<'static, str>,
pub stride: u64,
pub step_mode: InputStepMode,
pub attributes: Vec<VertexAttributeDescriptor>,
pub attributes: Vec<VertexAttributeDescriptor>, //TODO: remove the vec? should it be ever possible to have multiple attributes per buffer?
julhe marked this conversation as resolved.
Show resolved Hide resolved
}

impl VertexBufferDescriptor {
pub fn sync_with_descriptor(&mut self, descriptor: &VertexBufferDescriptor) {
for attribute in self.attributes.iter_mut() {
println!("sync attribute {} with reflection", attribute.name);
let descriptor_attribute = descriptor
.attributes
.iter()
Expand Down Expand Up @@ -52,13 +53,18 @@ pub struct VertexBufferDescriptors {
}

impl VertexBufferDescriptors {
//TODO: still needed?
pub fn set(&mut self, vertex_buffer_descriptor: VertexBufferDescriptor) {
self.descriptors.insert(
vertex_buffer_descriptor.name.to_string(),
vertex_buffer_descriptor,
);
}

pub fn set_many(&mut self, vertex_buffer_descriptor: VertexBufferDescriptors) {
self.descriptors.extend(vertex_buffer_descriptor.descriptors);
}

pub fn get(&self, name: &str) -> Option<&VertexBufferDescriptor> {
self.descriptors.get(name)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ pub struct RenderResourceBindings {
// TODO: remove this. it shouldn't be needed anymore
pub id: RenderResourceBindingsId,
bindings: HashMap<String, RenderResourceBinding>,
// TODO: remove this
vertex_buffers: HashMap<String, (BufferId, Option<BufferId>)>,
pub vertex_buffers: HashMap<u8, BufferId>,
pub index_buffer: Option<BufferId>,
bind_groups: HashMap<BindGroupId, BindGroup>,
bind_group_descriptors: HashMap<BindGroupDescriptorId, Option<BindGroupId>>,
dirty_bind_groups: HashSet<BindGroupId>,
Expand Down Expand Up @@ -140,24 +140,30 @@ impl RenderResourceBindings {
self.set(name, binding.clone());
}

for (name, (vertex_buffer, index_buffer)) in render_resource_bindings.vertex_buffers.iter()
{
self.set_vertex_buffer(name, *vertex_buffer, *index_buffer);
}
// for (name, (vertex_buffer, index_buffer)) in render_resource_bindings.vertex_buffers.iter()
// {
//
// self.set_vertex_buffer(name, *vertex_buffer, *index_buffer);
// }
julhe marked this conversation as resolved.
Show resolved Hide resolved
}

pub fn get_vertex_buffer(&self, name: &str) -> Option<(BufferId, Option<BufferId>)> {
self.vertex_buffers.get(name).cloned()
pub fn get_vertex_buffer(&self, slot: u8) -> Option<(BufferId)> {
self.vertex_buffers.get(&slot).cloned()
}

pub fn set_vertex_buffer(
&mut self,
name: &str,
vertex_buffer: BufferId,
index_buffer: Option<BufferId>,
slot: u8,
vertex_buffer: BufferId
) {
self.vertex_buffers.insert(slot, vertex_buffer);
}

pub fn set_index_buffer(
&mut self,
index_buffer: BufferId,
) {
self.vertex_buffers
.insert(name.to_string(), (vertex_buffer, index_buffer));
self.index_buffer = Some(index_buffer);
}

fn create_bind_group(&mut self, descriptor: &BindGroupDescriptor) -> BindGroupStatus {
Expand Down
Loading