mirror of
https://github.com/bevyengine/bevy
synced 2024-11-24 21:53:07 +00:00
Add Uniforms proc macro
This commit is contained in:
parent
9078b67677
commit
5b48de96db
11 changed files with 92 additions and 75 deletions
|
@ -12,5 +12,6 @@ proc-macro = true
|
||||||
|
|
||||||
syn = "1.0"
|
syn = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
|
Inflector = { version = "0.11.4", default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
|
@ -1,14 +1,18 @@
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
||||||
|
use inflector::Inflector;
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use syn::{parse_macro_input, DeriveInput, Data, DataStruct, Fields};
|
use quote::{format_ident, quote};
|
||||||
use quote::quote;
|
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields};
|
||||||
|
|
||||||
#[proc_macro_derive(EntityArchetype)]
|
#[proc_macro_derive(EntityArchetype)]
|
||||||
pub fn derive_entity_archetype(input: TokenStream) -> TokenStream {
|
pub fn derive_entity_archetype(input: TokenStream) -> TokenStream {
|
||||||
let ast = parse_macro_input!(input as DeriveInput);
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
let fields = match &ast.data {
|
let fields = match &ast.data {
|
||||||
Data::Struct(DataStruct { fields: Fields::Named(fields), .. }) => &fields.named,
|
Data::Struct(DataStruct {
|
||||||
|
fields: Fields::Named(fields),
|
||||||
|
..
|
||||||
|
}) => &fields.named,
|
||||||
_ => panic!("expected a struct with named fields"),
|
_ => panic!("expected a struct with named fields"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,8 +23,74 @@ pub fn derive_entity_archetype(input: TokenStream) -> TokenStream {
|
||||||
impl EntityArchetype for #struct_name {
|
impl EntityArchetype for #struct_name {
|
||||||
fn insert(self, world: &mut World) -> Entity {
|
fn insert(self, world: &mut World) -> Entity {
|
||||||
*world.insert((), vec![(
|
*world.insert((), vec![(
|
||||||
#(self.#field_name),*
|
#(self.#field_name,)*
|
||||||
,)]).first().unwrap()
|
)]).first().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(Uniforms)]
|
||||||
|
pub fn derive_uniforms(input: TokenStream) -> TokenStream {
|
||||||
|
let ast = parse_macro_input!(input as DeriveInput);
|
||||||
|
let fields = match &ast.data {
|
||||||
|
Data::Struct(DataStruct {
|
||||||
|
fields: Fields::Named(fields),
|
||||||
|
..
|
||||||
|
}) => &fields.named,
|
||||||
|
_ => panic!("expected a struct with named fields"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let struct_name = &ast.ident;
|
||||||
|
let struct_name_screaming_snake = struct_name.to_string().to_screaming_snake_case();
|
||||||
|
let info_ident = format_ident!("{}_UNIFORM_INFO", struct_name_screaming_snake);
|
||||||
|
let layout_ident = format_ident!("{}_UNIFORM_LAYOUTS", struct_name_screaming_snake);
|
||||||
|
let layout_arrays = (0..fields.len()).map(|_| quote!(&[]));
|
||||||
|
let uniform_name_uniform_info = fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| format!("{}_{}", struct_name, field.ident.as_ref().unwrap()))
|
||||||
|
.collect::<Vec<String>>();
|
||||||
|
let get_uniform_bytes_field_name = fields.iter().map(|field| &field.ident);
|
||||||
|
let get_uniform_bytes_uniform_name = uniform_name_uniform_info.clone();
|
||||||
|
let get_uniform_info_uniform_name = uniform_name_uniform_info.clone();
|
||||||
|
let get_uniform_info_array_refs = (0..fields.len()).map(|i| quote!(&#info_ident[#i]));
|
||||||
|
|
||||||
|
TokenStream::from(quote! {
|
||||||
|
const #info_ident: &[UniformInfo] = &[
|
||||||
|
#(UniformInfo {
|
||||||
|
name: #uniform_name_uniform_info,
|
||||||
|
bind_type: BindType::Uniform {
|
||||||
|
dynamic: false,
|
||||||
|
// TODO: fill this in with properties
|
||||||
|
properties: Vec::new(),
|
||||||
|
},
|
||||||
|
},)*
|
||||||
|
];
|
||||||
|
|
||||||
|
const #layout_ident: &[&[UniformPropertyType]] = &[
|
||||||
|
#(#layout_arrays,)*
|
||||||
|
];
|
||||||
|
|
||||||
|
impl AsUniforms for #struct_name {
|
||||||
|
fn get_uniform_infos(&self) -> &[UniformInfo] {
|
||||||
|
#info_ident
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_uniform_layouts(&self) -> &[&[UniformPropertyType]] {
|
||||||
|
#layout_ident
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>> {
|
||||||
|
match name {
|
||||||
|
#(#get_uniform_bytes_uniform_name => Some(self.#get_uniform_bytes_field_name.get_bytes()),)*
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn get_uniform_info(&self, name: &str) -> Option<&UniformInfo> {
|
||||||
|
match name {
|
||||||
|
#(#get_uniform_info_uniform_name => Some(#get_uniform_info_array_refs),)*
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub mod resource_provider;
|
||||||
pub mod resource_providers;
|
pub mod resource_providers;
|
||||||
mod standard_material;
|
mod standard_material;
|
||||||
mod uniform;
|
mod uniform;
|
||||||
|
mod renderable;
|
||||||
|
|
||||||
pub use draw_target::*;
|
pub use draw_target::*;
|
||||||
pub use pass::*;
|
pub use pass::*;
|
||||||
|
@ -25,3 +26,4 @@ pub use resource::*;
|
||||||
pub use resource_provider::*;
|
pub use resource_provider::*;
|
||||||
pub use standard_material::*;
|
pub use standard_material::*;
|
||||||
pub use uniform::*;
|
pub use uniform::*;
|
||||||
|
pub use renderable::*;
|
||||||
|
|
|
@ -23,7 +23,7 @@ layout(set = 0, binding = 1) uniform Lights {
|
||||||
Light SceneLights[MAX_LIGHTS];
|
Light SceneLights[MAX_LIGHTS];
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 1, binding = 1) uniform StandardMaterial {
|
layout(set = 1, binding = 1) uniform StandardMaterial_albedo {
|
||||||
vec4 Albedo;
|
vec4 Albedo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ layout(set = 1, binding = 0) uniform Object {
|
||||||
mat4 Model;
|
mat4 Model;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 1, binding = 1) uniform StandardMaterial {
|
layout(set = 1, binding = 1) uniform StandardMaterial_albedo {
|
||||||
vec4 Albedo;
|
vec4 Albedo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ impl ForwardPipelineBuilder for RenderGraphBuilder {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Binding {
|
Binding {
|
||||||
name: "StandardMaterial".to_string(),
|
name: "StandardMaterial_albedo".to_string(),
|
||||||
bind_type: BindType::Uniform {
|
bind_type: BindType::Uniform {
|
||||||
dynamic: true,
|
dynamic: true,
|
||||||
properties: vec![UniformProperty {
|
properties: vec![UniformProperty {
|
||||||
|
|
|
@ -10,7 +10,7 @@ layout(set = 0, binding = 0) uniform Camera {
|
||||||
mat4 ViewProj;
|
mat4 ViewProj;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 1, binding = 1) uniform StandardMaterial {
|
layout(set = 1, binding = 1) uniform StandardMaterial_albedo {
|
||||||
vec4 Albedo;
|
vec4 Albedo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ layout(set = 1, binding = 0) uniform Object {
|
||||||
mat4 Model;
|
mat4 Model;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 1, binding = 1) uniform StandardMaterial {
|
layout(set = 1, binding = 1) uniform StandardMaterial_albedo {
|
||||||
vec4 Albedo;
|
vec4 Albedo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ impl ForwardFlatPipelineBuilder for RenderGraphBuilder {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Binding {
|
Binding {
|
||||||
name: "StandardMaterial".to_string(),
|
name: "StandardMaterial_albedo".to_string(),
|
||||||
bind_type: BindType::Uniform {
|
bind_type: BindType::Uniform {
|
||||||
dynamic: true,
|
dynamic: true,
|
||||||
properties: vec![UniformProperty {
|
properties: vec![UniformProperty {
|
||||||
|
|
6
src/render/render_graph_2/renderable.rs
Normal file
6
src/render/render_graph_2/renderable.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
use crate::{asset::Handle, render::Shader};
|
||||||
|
|
||||||
|
pub struct Renderable {
|
||||||
|
pub render: bool,
|
||||||
|
pub shaders: Vec<Handle<Shader>>,
|
||||||
|
}
|
|
@ -6,63 +6,14 @@ use crate::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use bevy_derive::Uniforms;
|
||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
|
#[derive(Uniforms)]
|
||||||
pub struct StandardMaterial {
|
pub struct StandardMaterial {
|
||||||
pub albedo: Vec4,
|
pub albedo: Vec4,
|
||||||
}
|
}
|
||||||
|
|
||||||
// create this from a derive macro
|
|
||||||
const STANDARD_MATERIAL_UNIFORM_INFO: &[UniformInfo] = &[UniformInfo {
|
|
||||||
name: "StandardMaterial",
|
|
||||||
bind_type: BindType::Uniform {
|
|
||||||
dynamic: false,
|
|
||||||
// TODO: fill this in with properties
|
|
||||||
properties: Vec::new(),
|
|
||||||
},
|
|
||||||
}];
|
|
||||||
|
|
||||||
// these are separate from BindType::Uniform{properties} because they need to be const
|
|
||||||
const STANDARD_MATERIAL_UNIFORM_LAYOUTS: &[&[UniformPropertyType]] = &[&[]];
|
|
||||||
|
|
||||||
// const
|
|
||||||
impl AsUniforms for StandardMaterial {
|
|
||||||
fn get_uniform_infos(&self) -> &[UniformInfo] {
|
|
||||||
STANDARD_MATERIAL_UNIFORM_INFO
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_uniform_layouts(&self) -> &[&[UniformPropertyType]] {
|
|
||||||
STANDARD_MATERIAL_UNIFORM_LAYOUTS
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>> {
|
|
||||||
match name {
|
|
||||||
"StandardMaterial" => Some(self.albedo.get_bytes()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn get_uniform_info(&self, name: &str) -> Option<&UniformInfo> {
|
|
||||||
match name {
|
|
||||||
"StandardMaterial" => Some(&STANDARD_MATERIAL_UNIFORM_INFO[0]),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn iter_properties(&self) -> std::slice::Iter<&'static str> {
|
|
||||||
// STANDARD_MATERIAL_PROPERTIES.iter()
|
|
||||||
// }
|
|
||||||
// fn get_property(&self, name: &str) -> Option<ShaderValue> {
|
|
||||||
// match name {
|
|
||||||
// "albedo" => Some(match self.albedo {
|
|
||||||
// Albedo::Color(color) => ShaderValue::Vec4(color),
|
|
||||||
// Albedo::Texture(ref texture) => ShaderValue::Texture(texture)
|
|
||||||
// }),
|
|
||||||
// _ => None,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// create this from a derive macro
|
|
||||||
const LOCAL_TO_WORLD_UNIFORM_INFO: &[UniformInfo] = &[UniformInfo {
|
const LOCAL_TO_WORLD_UNIFORM_INFO: &[UniformInfo] = &[UniformInfo {
|
||||||
name: "Object",
|
name: "Object",
|
||||||
bind_type: BindType::Uniform {
|
bind_type: BindType::Uniform {
|
||||||
|
@ -75,7 +26,6 @@ const LOCAL_TO_WORLD_UNIFORM_INFO: &[UniformInfo] = &[UniformInfo {
|
||||||
// these are separate from BindType::Uniform{properties} because they need to be const
|
// these are separate from BindType::Uniform{properties} because they need to be const
|
||||||
const LOCAL_TO_WORLD_UNIFORM_LAYOUTS: &[&[UniformPropertyType]] = &[&[]];
|
const LOCAL_TO_WORLD_UNIFORM_LAYOUTS: &[&[UniformPropertyType]] = &[&[]];
|
||||||
|
|
||||||
// const ST
|
|
||||||
impl AsUniforms for bevy_transform::prelude::LocalToWorld {
|
impl AsUniforms for bevy_transform::prelude::LocalToWorld {
|
||||||
fn get_uniform_infos(&self) -> &[UniformInfo] {
|
fn get_uniform_infos(&self) -> &[UniformInfo] {
|
||||||
LOCAL_TO_WORLD_UNIFORM_INFO
|
LOCAL_TO_WORLD_UNIFORM_INFO
|
||||||
|
@ -97,16 +47,4 @@ impl AsUniforms for bevy_transform::prelude::LocalToWorld {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// fn iter_properties(&self) -> std::slice::Iter<&'static str> {
|
|
||||||
// STANDARD_MATERIAL_PROPERTIES.iter()
|
|
||||||
// }
|
|
||||||
// fn get_property(&self, name: &str) -> Option<ShaderValue> {
|
|
||||||
// match name {
|
|
||||||
// "albedo" => Some(match self.albedo {
|
|
||||||
// Albedo::Color(color) => ShaderValue::Vec4(color),
|
|
||||||
// Albedo::Texture(ref texture) => ShaderValue::Texture(texture)
|
|
||||||
// }),
|
|
||||||
// _ => None,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue