This commit is contained in:
Carter Anderson 2020-03-15 01:12:56 -07:00
parent 4d92ef0119
commit 1332630fa3
5 changed files with 41 additions and 39 deletions

View file

@ -108,7 +108,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
let struct_name = &ast.ident;
let struct_name_screaming_snake = struct_name.to_string().to_screaming_snake_case();
let field_uniform_names_ident = format_ident!("{}_FIELD_UNIFORM_NAMES", struct_name_screaming_snake);
let field_infos_ident = format_ident!("{}_FIELD_INFO", struct_name_screaming_snake);
let active_uniform_field_names = active_uniform_fields.iter().map(|field| {
&field.ident
@ -121,7 +121,7 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
let mut uniform_name_strings = Vec::new();
let mut texture_and_sampler_name_strings = Vec::new();
let mut texture_and_sampler_name_idents = Vec::new();
let field_uniform_names = active_uniform_fields.iter().map(|f| {
let field_infos = active_uniform_fields.iter().map(|f| {
let field_name = f.ident.as_ref().unwrap().to_string();
let uniform = format!("{}_{}", struct_name, field_name);
let texture = format!("{}_texture", uniform);
@ -131,23 +131,24 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
texture_and_sampler_name_strings.push(sampler.clone());
texture_and_sampler_name_idents.push(f.ident.clone());
texture_and_sampler_name_idents.push(f.ident.clone());
quote!(bevy::render::shader::FieldUniformName {
field: #field_name,
uniform: #uniform,
texture: #texture,
sampler: #sampler,
quote!(bevy::render::shader::FieldInfo {
name: #field_name,
uniform_name: #uniform,
texture_name: #texture,
sampler_name: #sampler,
is_vertex_buffer_member: false,
})
});
TokenStream::from(quote! {
const #field_uniform_names_ident: &[bevy::render::shader::FieldUniformName] = &[
#(#field_uniform_names,)*
const #field_infos_ident: &[bevy::render::shader::FieldInfo] = &[
#(#field_infos,)*
];
impl bevy::render::shader::AsUniforms for #struct_name {
// TODO: max this an iterator that feeds on field_uniform_names_ident
fn get_field_uniform_names(&self) -> &[bevy::render::shader::FieldUniformName] {
#field_uniform_names_ident
fn get_field_infos(&self) -> &[bevy::render::shader::FieldInfo] {
#field_infos_ident
}
fn get_field_bind_type(&self, name: &str) -> Option<bevy::render::shader::FieldBindType> {

View file

@ -9,8 +9,8 @@ pub use crate::{
pipeline::PipelineDescriptor,
render_resource::{resource_name, resource_providers::UniformResourceProvider},
shader::{uniforms::StandardMaterial, Shader, ShaderDefSuffixProvider, ShaderStage},
ActiveCamera, ActiveCamera2d, Camera, CameraType, Color, ColorSource, Light,
Renderable,
texture::{Texture, TextureType},
ActiveCamera, ActiveCamera2d, Camera, CameraType, Color, ColorSource, Light, Renderable,
},
ui::{Anchors, Margins, Node},
};

View file

@ -67,8 +67,8 @@ where
}
for (entity, (uniforms, _renderable)) in query.iter_entities(world) {
let field_uniform_names = uniforms.get_field_uniform_names();
for uniform_info in UniformInfoIter::new(field_uniform_names, uniforms.deref()) {
let field_infos = uniforms.get_field_infos();
for uniform_info in UniformInfoIter::new(field_infos, uniforms.deref()) {
match uniform_info.bind_type {
BindType::Uniform { .. } => {
// only add the first time a uniform info is processed

View file

@ -10,9 +10,8 @@ use crate::{
use legion::prelude::Entity;
use std::collections::HashMap;
// TODO: add ability to specify specific pipeline for uniforms
pub trait AsUniforms {
fn get_field_uniform_names(&self) -> &[FieldUniformName];
fn get_field_infos(&self) -> &[FieldInfo];
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>>;
fn get_uniform_texture(&self, name: &str) -> Option<Handle<Texture>>;
fn get_shader_defs(&self) -> Option<Vec<String>>;
@ -39,7 +38,7 @@ pub enum FieldBindType {
}
pub struct UniformInfoIter<'a, 'b, T: AsUniforms> {
pub field_uniform_names: &'a [FieldUniformName],
pub field_infos: &'a [FieldInfo],
pub uniforms: &'b T,
pub index: usize,
pub add_sampler: bool,
@ -49,9 +48,9 @@ impl<'a, 'b, T> UniformInfoIter<'a, 'b, T>
where
T: AsUniforms,
{
pub fn new(field_uniform_names: &'a [FieldUniformName], uniforms: &'b T) -> Self {
pub fn new(field_infos: &'a [FieldInfo], uniforms: &'b T) -> Self {
UniformInfoIter {
field_uniform_names,
field_infos,
uniforms,
index: 0,
add_sampler: false,
@ -68,19 +67,19 @@ where
if self.add_sampler {
self.add_sampler = false;
Some(UniformInfo {
name: self.field_uniform_names[self.index - 1].sampler,
name: self.field_infos[self.index - 1].sampler_name,
bind_type: BindType::Sampler,
})
} else {
if self.index == self.field_uniform_names.len() {
if self.index == self.field_infos.len() {
None
} else {
let index = self.index;
self.index += 1;
let ref field_uniform_name = self.field_uniform_names[index];
let ref field_info = self.field_infos[index];
let bind_type = self
.uniforms
.get_field_bind_type(field_uniform_name.field)
.get_field_bind_type(field_info.name)
.unwrap();
Some(match bind_type {
FieldBindType::Uniform => UniformInfo {
@ -88,7 +87,7 @@ where
dynamic: false,
properties: Vec::new(),
},
name: field_uniform_name.uniform,
name: field_info.uniform_name,
},
FieldBindType::Texture => {
self.add_sampler = true;
@ -97,7 +96,7 @@ where
dimension: TextureViewDimension::D2,
multisampled: false,
},
name: field_uniform_name.texture,
name: field_info.texture_name,
}
}
})
@ -106,11 +105,12 @@ where
}
}
pub struct FieldUniformName {
pub field: &'static str,
pub uniform: &'static str,
pub texture: &'static str,
pub sampler: &'static str,
pub struct FieldInfo {
pub name: &'static str,
pub uniform_name: &'static str,
pub texture_name: &'static str,
pub sampler_name: &'static str,
pub is_vertex_buffer_member: bool,
}
pub trait AsFieldBindType {

View file

@ -1,23 +1,24 @@
use crate::{
asset::Handle,
render::{
shader::{AsUniforms, FieldBindType, FieldUniformName},
shader::{AsUniforms, FieldBindType, FieldInfo},
texture::Texture,
},
};
use zerocopy::AsBytes;
const LOCAL_TO_WORLD_FIELD_UNIFORM_NAMES: &[FieldUniformName] = &[FieldUniformName {
field: "object",
uniform: "Object",
texture: "",
sampler: "",
const LOCAL_TO_WORLD_FIELD_INFOS: &[FieldInfo] = &[FieldInfo {
name: "object",
uniform_name: "Object",
texture_name: "",
sampler_name: "",
is_vertex_buffer_member: false,
}];
impl AsUniforms for bevy_transform::prelude::LocalToWorld {
fn get_field_uniform_names(&self) -> &[FieldUniformName] {
LOCAL_TO_WORLD_FIELD_UNIFORM_NAMES
fn get_field_infos(&self) -> &[FieldInfo] {
LOCAL_TO_WORLD_FIELD_INFOS
}
fn get_uniform_bytes(&self, name: &str) -> Option<Vec<u8>> {