AsUniforms provide VertexBufferDescriptor. Initial macro work

This commit is contained in:
Carter Anderson 2020-03-17 18:25:27 -07:00
parent 28fb0fdfc8
commit d9663d740b
14 changed files with 233 additions and 94 deletions

10
.vscode/settings.json vendored
View File

@ -1,10 +1,18 @@
{ {
"cSpell.words": [ "cSpell.words": [
"Bitmask",
"MSAA",
"Wgpu", "Wgpu",
"Zunstable",
"bools", "bools",
"chunkset", "chunkset",
"chunksets", "chunksets",
"eprintln",
"hashset",
"multizip", "multizip",
"passthrough" "passthrough",
"rspirv",
"rustc",
"spirv"
] ]
} }

View File

@ -8,7 +8,6 @@ edition = "2018"
default = ["wgpu"] default = ["wgpu"]
[dependencies] [dependencies]
# Modified to use std::any::type_name instead of std::any::TypeId
legion = { path = "bevy_legion", features = ["serialize"] } legion = { path = "bevy_legion", features = ["serialize"] }
wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "a7b0d5ae5bc0934439ef559ed145e93f0117c39a", optional = true } wgpu = { git = "https://github.com/gfx-rs/wgpu-rs.git", rev = "a7b0d5ae5bc0934439ef559ed145e93f0117c39a", optional = true }
bitflags = "1.0" bitflags = "1.0"
@ -27,10 +26,11 @@ type-uuid = "0.1"
shaderc = "0.6" shaderc = "0.6"
libloading = "0.5.2" libloading = "0.5.2"
png = "0.16.0" png = "0.16.0"
# rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "baa469eae2932271174593eb066894d7a7a38439" }
spirv-reflect = "0.2.3" spirv-reflect = "0.2.3"
bevy_derive = { path = "bevy_derive" } bevy_derive = { path = "bevy_derive" }
bevy_transform = { path = "bevy_transform" } bevy_transform = { path = "bevy_transform" }
# TODO: replace once_cell with std equivalent if/when this lands: https://github.com/rust-lang/rfcs/pull/2788
once_cell = "1.3.1"
[profile.release] [profile.release]
debug = true debug = true

View File

@ -4,7 +4,7 @@ use darling::FromMeta;
use inflector::Inflector; use inflector::Inflector;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use quote::{format_ident, quote}; use quote::{format_ident, quote};
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields}; use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Field, Fields, Type};
#[proc_macro_derive(EntityArchetype)] #[proc_macro_derive(EntityArchetype)]
pub fn derive_entity_archetype(input: TokenStream) -> TokenStream { pub fn derive_entity_archetype(input: TokenStream) -> TokenStream {
@ -45,7 +45,7 @@ struct UniformAttributeArgs {
#[proc_macro_derive(Uniforms, attributes(uniform))] #[proc_macro_derive(Uniforms, attributes(uniform))]
pub fn derive_uniforms(input: TokenStream) -> TokenStream { pub fn derive_uniforms(input: TokenStream) -> TokenStream {
const UNIFORM_ATTRIBUTE_NAME: &'static str = "uniform"; static UNIFORM_ATTRIBUTE_NAME: &'static str = "uniform";
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 {
@ -85,6 +85,10 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
}) })
.map(|(f, _attr)| *f) .map(|(f, _attr)| *f)
.collect::<Vec<&Field>>(); .collect::<Vec<&Field>>();
let active_uniform_field_types = active_uniform_fields
.iter()
.map(|f| &f.ty)
.collect::<Vec<&Type>>();
let shader_def_fields = uniform_fields let shader_def_fields = uniform_fields
.iter() .iter()
@ -109,8 +113,10 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
}); });
let struct_name = &ast.ident; let struct_name = &ast.ident;
let struct_name_string = struct_name.to_string();
let struct_name_screaming_snake = struct_name.to_string().to_screaming_snake_case(); let struct_name_screaming_snake = struct_name.to_string().to_screaming_snake_case();
let field_infos_ident = format_ident!("{}_FIELD_INFO", struct_name_screaming_snake); let field_infos_ident = format_ident!("{}_FIELD_INFO", struct_name_screaming_snake);
let vertex_buffer_descriptor_ident = format_ident!("{}_VERTEX_BUFFER_DESCRIPTOR", struct_name_screaming_snake);
let active_uniform_field_names = active_uniform_fields.iter().map(|field| { let active_uniform_field_names = active_uniform_fields.iter().map(|field| {
&field.ident &field.ident
@ -158,10 +164,25 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
}); });
TokenStream::from(quote! { TokenStream::from(quote! {
const #field_infos_ident: &[bevy::render::shader::FieldInfo] = &[ static #field_infos_ident: &[bevy::render::shader::FieldInfo] = &[
#(#field_infos,)* #(#field_infos,)*
]; ];
static #vertex_buffer_descriptor_ident: bevy::once_cell::sync::Lazy<bevy::render::pipeline::VertexBufferDescriptor> =
bevy::once_cell::sync::Lazy::new(|| {
use bevy::render::pipeline::AsVertexFormats;
// let vertex_formats = vec![
// #(#active_uniform_field_types::as_vertex_formats(),)*
// ];
bevy::render::pipeline::VertexBufferDescriptor {
attributes: Vec::new(),
name: #struct_name_string.to_string(),
step_mode: bevy::render::pipeline::InputStepMode::Instance,
stride: 0,
}
});
impl bevy::render::shader::AsUniforms for #struct_name { impl bevy::render::shader::AsUniforms for #struct_name {
// TODO: max this an iterator that feeds on field_uniform_names_ident // TODO: max this an iterator that feeds on field_uniform_names_ident
fn get_field_infos(&self) -> &[bevy::render::shader::FieldInfo] { fn get_field_infos(&self) -> &[bevy::render::shader::FieldInfo] {
@ -213,6 +234,10 @@ pub fn derive_uniforms(input: TokenStream) -> TokenStream {
.map(|(f, shader_def)| format!("{}_{}{}", #struct_name_screaming_snake, f, shader_def.unwrap())) .map(|(f, shader_def)| format!("{}_{}{}", #struct_name_screaming_snake, f, shader_def.unwrap()))
.collect::<Vec<String>>()) .collect::<Vec<String>>())
} }
fn get_vertex_buffer_descriptor() -> Option<&'static bevy::render::pipeline::VertexBufferDescriptor> {
Some(&#vertex_buffer_descriptor_ident)
}
} }
}) })
} }

View File

@ -13,3 +13,4 @@ pub mod diagnostics;
pub use bevy_transform as transform; pub use bevy_transform as transform;
pub use glam as math; pub use glam as math;
pub use legion; pub use legion;
pub use once_cell;

View File

@ -4,6 +4,7 @@ mod pipeline;
mod pipeline_layout; mod pipeline_layout;
pub mod pipelines; pub mod pipelines;
mod vertex_buffer_descriptor; mod vertex_buffer_descriptor;
mod vertex_format;
pub mod state_descriptors; pub mod state_descriptors;
pub use bind_group::*; pub use bind_group::*;
@ -11,3 +12,4 @@ pub use binding::*;
pub use pipeline::*; pub use pipeline::*;
pub use pipeline_layout::*; pub use pipeline_layout::*;
pub use vertex_buffer_descriptor::*; pub use vertex_buffer_descriptor::*;
pub use vertex_format::*;

View File

@ -58,7 +58,7 @@ pub struct PipelineDescriptor {
pub sample_mask: u32, pub sample_mask: u32,
/// When enabled, produces another sample mask per pixel based on the alpha output value, that /// When enabled, produces another sample mask per pixel based on the alpha output value, that
/// is ANDed with the sample_mask and the primitive coverage to restrict the set of samples /// is AND-ed with the sample_mask and the primitive coverage to restrict the set of samples
/// affected by a primitive. /// affected by a primitive.
/// The implicit mask produced for alpha of zero is guaranteed to be zero, and for alpha of one /// The implicit mask produced for alpha of zero is guaranteed to be zero, and for alpha of one
/// is guaranteed to be all 1-s. /// is guaranteed to be all 1-s.

View File

@ -1,3 +1,5 @@
use super::VertexFormat;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub struct VertexBufferDescriptor { pub struct VertexBufferDescriptor {
pub name: String, pub name: String,
@ -6,77 +8,6 @@ pub struct VertexBufferDescriptor {
pub attributes: Vec<VertexAttributeDescriptor>, pub attributes: Vec<VertexAttributeDescriptor>,
} }
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum VertexFormat {
Uchar2 = 1,
Uchar4 = 3,
Char2 = 5,
Char4 = 7,
Uchar2Norm = 9,
Uchar4Norm = 11,
Char2Norm = 14,
Char4Norm = 16,
Ushort2 = 18,
Ushort4 = 20,
Short2 = 22,
Short4 = 24,
Ushort2Norm = 26,
Ushort4Norm = 28,
Short2Norm = 30,
Short4Norm = 32,
Half2 = 34,
Half4 = 36,
Float = 37,
Float2 = 38,
Float3 = 39,
Float4 = 40,
Uint = 41,
Uint2 = 42,
Uint3 = 43,
Uint4 = 44,
Int = 45,
Int2 = 46,
Int3 = 47,
Int4 = 48,
}
impl VertexFormat {
pub fn get_size(&self) -> u64 {
match *self {
VertexFormat::Uchar2 => 2,
VertexFormat::Uchar4 => 4,
VertexFormat::Char2 => 2,
VertexFormat::Char4 => 4,
VertexFormat::Uchar2Norm => 2,
VertexFormat::Uchar4Norm => 4,
VertexFormat::Char2Norm => 2,
VertexFormat::Char4Norm => 4,
VertexFormat::Ushort2 => 2 * 2,
VertexFormat::Ushort4 => 2 * 4,
VertexFormat::Short2 => 2 * 2,
VertexFormat::Short4 => 2 * 4,
VertexFormat::Ushort2Norm => 2 * 2,
VertexFormat::Ushort4Norm => 2 * 4,
VertexFormat::Short2Norm => 2 * 2,
VertexFormat::Short4Norm => 2 * 4,
VertexFormat::Half2 => 2 * 2,
VertexFormat::Half4 => 2 * 4,
VertexFormat::Float => 4,
VertexFormat::Float2 => 4 * 2,
VertexFormat::Float3 => 4 * 3,
VertexFormat::Float4 => 4 * 4,
VertexFormat::Uint => 4,
VertexFormat::Uint2 => 4 * 2,
VertexFormat::Uint3 => 4 * 3,
VertexFormat::Uint4 => 4 * 4,
VertexFormat::Int => 4,
VertexFormat::Int2 => 4 * 2,
VertexFormat::Int3 => 4 * 3,
VertexFormat::Int4 => 4 * 4,
}
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum InputStepMode { pub enum InputStepMode {
Vertex = 0, Vertex = 0,

View File

@ -0,0 +1,111 @@
use crate::math::{Vec2, Vec3, Vec4, Mat4};
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum VertexFormat {
Uchar2 = 1,
Uchar4 = 3,
Char2 = 5,
Char4 = 7,
Uchar2Norm = 9,
Uchar4Norm = 11,
Char2Norm = 14,
Char4Norm = 16,
Ushort2 = 18,
Ushort4 = 20,
Short2 = 22,
Short4 = 24,
Ushort2Norm = 26,
Ushort4Norm = 28,
Short2Norm = 30,
Short4Norm = 32,
Half2 = 34,
Half4 = 36,
Float = 37,
Float2 = 38,
Float3 = 39,
Float4 = 40,
Uint = 41,
Uint2 = 42,
Uint3 = 43,
Uint4 = 44,
Int = 45,
Int2 = 46,
Int3 = 47,
Int4 = 48,
}
impl VertexFormat {
pub fn get_size(&self) -> u64 {
match *self {
VertexFormat::Uchar2 => 2,
VertexFormat::Uchar4 => 4,
VertexFormat::Char2 => 2,
VertexFormat::Char4 => 4,
VertexFormat::Uchar2Norm => 2,
VertexFormat::Uchar4Norm => 4,
VertexFormat::Char2Norm => 2,
VertexFormat::Char4Norm => 4,
VertexFormat::Ushort2 => 2 * 2,
VertexFormat::Ushort4 => 2 * 4,
VertexFormat::Short2 => 2 * 2,
VertexFormat::Short4 => 2 * 4,
VertexFormat::Ushort2Norm => 2 * 2,
VertexFormat::Ushort4Norm => 2 * 4,
VertexFormat::Short2Norm => 2 * 2,
VertexFormat::Short4Norm => 2 * 4,
VertexFormat::Half2 => 2 * 2,
VertexFormat::Half4 => 2 * 4,
VertexFormat::Float => 4,
VertexFormat::Float2 => 4 * 2,
VertexFormat::Float3 => 4 * 3,
VertexFormat::Float4 => 4 * 4,
VertexFormat::Uint => 4,
VertexFormat::Uint2 => 4 * 2,
VertexFormat::Uint3 => 4 * 3,
VertexFormat::Uint4 => 4 * 4,
VertexFormat::Int => 4,
VertexFormat::Int2 => 4 * 2,
VertexFormat::Int3 => 4 * 3,
VertexFormat::Int4 => 4 * 4,
}
}
}
pub trait AsVertexFormats {
fn as_vertex_formats() -> &'static [VertexFormat];
}
impl AsVertexFormats for f32 {
fn as_vertex_formats() -> &'static [VertexFormat] {
&[VertexFormat::Float]
}
}
impl AsVertexFormats for Vec2 {
fn as_vertex_formats() -> &'static [VertexFormat] {
&[VertexFormat::Float2]
}
}
impl AsVertexFormats for Vec3 {
fn as_vertex_formats() -> &'static [VertexFormat] {
&[VertexFormat::Float3]
}
}
impl AsVertexFormats for Vec4 {
fn as_vertex_formats() -> &'static [VertexFormat] {
&[VertexFormat::Float4]
}
}
impl AsVertexFormats for Mat4 {
fn as_vertex_formats() -> &'static [VertexFormat] {
&[
VertexFormat::Float4,
VertexFormat::Float4,
VertexFormat::Float4,
VertexFormat::Float4,
]
}
}

View File

@ -346,11 +346,18 @@ where
); );
renderer.copy_buffer_to_buffer(mapped_buffer_resource, 0, resource, 0, size); renderer.copy_buffer_to_buffer(mapped_buffer_resource, 0, resource, 0, size);
// TODO: uncomment this to free resource?
renderer.remove_buffer(mapped_buffer_resource); renderer.remove_buffer(mapped_buffer_resource);
} }
} }
fn initialize_vertex_buffer_descriptor(&self, renderer: &mut dyn Renderer) {
let vertex_buffer_descriptor = T::get_vertex_buffer_descriptor();
if let Some(vertex_buffer_descriptor) = vertex_buffer_descriptor {
if let None = renderer.get_vertex_buffer_descriptor(&vertex_buffer_descriptor.name) {
renderer.set_vertex_buffer_descriptor(vertex_buffer_descriptor.clone());
}
}
}
} }
impl<T> ResourceProvider for UniformResourceProvider<T> impl<T> ResourceProvider for UniformResourceProvider<T>
@ -367,12 +374,14 @@ where
} }
fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) { fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) {
let query = <(Read<T>, Read<Renderable>)>::query(); self.initialize_vertex_buffer_descriptor(renderer);
// TODO: this breaks down in multiple ways: // TODO: this breaks down in multiple ways:
// (SOLVED 1) resource_info will be set after the first run so this won't update. // (SOLVED 1) resource_info will be set after the first run so this won't update.
// (2) if we create new buffers, the old bind groups will be invalid // (2) if we create new buffers, the old bind groups will be invalid
// reset all uniform buffer info counts // reset all uniform buffer info counts
let query = <(Read<T>, Read<Renderable>)>::query();
for (_name, (resource, count, _entities)) in self.uniform_buffer_info_resources.iter_mut() { for (_name, (resource, count, _entities)) in self.uniform_buffer_info_resources.iter_mut() {
renderer renderer
.get_dynamic_uniform_buffer_info_mut(resource.unwrap()) .get_dynamic_uniform_buffer_info_mut(resource.unwrap())

View File

@ -84,7 +84,7 @@ fn try_compiling_shader_with_macros(
.unwrap(); .unwrap();
let shader = shader_storage.get(shader_handle).unwrap(); let shader = shader_storage.get(shader_handle).unwrap();
// don't produce new shader if the input source is already spriv // don't produce new shader if the input source is already spirv
if let ShaderSource::Spirv(_) = shader.source { if let ShaderSource::Spirv(_) = shader.source {
return None; return None;
} }
@ -203,7 +203,7 @@ pub fn update_shader_assignments(
macroed_pipeline_handle macroed_pipeline_handle
}; };
// TODO: this will break down if pipeline layout changes. fix this with "autolayout" // TODO: this will break down if pipeline layout changes. fix this with "auto-layout"
if let None = shader_pipeline_assignments.assignments.get(&final_handle) { if let None = shader_pipeline_assignments.assignments.get(&final_handle) {
shader_pipeline_assignments shader_pipeline_assignments
.assignments .assignments

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
legion::prelude::*, legion::prelude::*,
render::{ render::{
pipeline::PipelineDescriptor, pipeline::{VertexBufferDescriptor, PipelineDescriptor},
render_graph::RenderGraph, render_graph::RenderGraph,
render_resource::{BufferUsage, RenderResource, RenderResources, ResourceInfo}, render_resource::{BufferUsage, RenderResource, RenderResources, ResourceInfo},
shader::DynamicUniformBufferInfo, shader::DynamicUniformBufferInfo,
@ -105,6 +105,8 @@ pub trait Renderer {
entity: Entity, entity: Entity,
pipeline_descriptor: &PipelineDescriptor, pipeline_descriptor: &PipelineDescriptor,
); );
fn set_vertex_buffer_descriptor(&mut self, vertex_buffer_descriptor: VertexBufferDescriptor);
fn get_vertex_buffer_descriptor(&self, name: &str) -> Option<&VertexBufferDescriptor>;
} }
pub trait RenderPass { pub trait RenderPass {

View File

@ -7,9 +7,7 @@ use crate::{
PassDescriptor, RenderPassColorAttachmentDescriptor, PassDescriptor, RenderPassColorAttachmentDescriptor,
RenderPassDepthStencilAttachmentDescriptor, RenderPassDepthStencilAttachmentDescriptor,
}, },
pipeline::{ pipeline::{BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType, VertexBufferDescriptor},
BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType,
},
render_graph::RenderGraph, render_graph::RenderGraph,
render_resource::{ render_resource::{
resource_name, BufferUsage, RenderResource, RenderResources, ResourceInfo, resource_name, BufferUsage, RenderResource, RenderResources, ResourceInfo,
@ -29,6 +27,7 @@ pub struct WgpuRenderer {
pub encoder: Option<wgpu::CommandEncoder>, pub encoder: Option<wgpu::CommandEncoder>,
pub swap_chain_descriptor: wgpu::SwapChainDescriptor, pub swap_chain_descriptor: wgpu::SwapChainDescriptor,
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>, pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
pub vertex_buffer_descriptors: HashMap<String, VertexBufferDescriptor>,
pub wgpu_resources: WgpuResources, pub wgpu_resources: WgpuResources,
} }
@ -65,6 +64,7 @@ impl WgpuRenderer {
swap_chain_descriptor, swap_chain_descriptor,
wgpu_resources: WgpuResources::new(), wgpu_resources: WgpuResources::new(),
render_pipelines: HashMap::new(), render_pipelines: HashMap::new(),
vertex_buffer_descriptors: HashMap::new(),
} }
} }
@ -124,8 +124,6 @@ impl WgpuRenderer {
} }
let layout = pipeline_descriptor.get_layout_mut().unwrap(); let layout = pipeline_descriptor.get_layout_mut().unwrap();
// println!("{:#?}", layout);
// println!();
// setup new bind group layouts // setup new bind group layouts
for bind_group in layout.bind_groups.iter_mut() { for bind_group in layout.bind_groups.iter_mut() {
@ -714,4 +712,16 @@ impl Renderer for WgpuRenderer {
} }
} }
} }
fn set_vertex_buffer_descriptor(
&mut self,
vertex_buffer_descriptor: VertexBufferDescriptor,
) {
self.vertex_buffer_descriptors.insert(vertex_buffer_descriptor.name.to_string(), vertex_buffer_descriptor);
}
fn get_vertex_buffer_descriptor(
&self,
name: &str
) -> Option<&VertexBufferDescriptor> {
self.vertex_buffer_descriptors.get(name)
}
} }

View File

@ -3,7 +3,7 @@ use crate::{
core::GetBytes, core::GetBytes,
render::{ render::{
color::ColorSource, color::ColorSource,
pipeline::BindType, pipeline::{VertexBufferDescriptor, BindType},
texture::{Texture, TextureViewDimension}, texture::{Texture, TextureViewDimension},
}, },
}; };
@ -17,6 +17,7 @@ pub trait AsUniforms {
fn get_shader_defs(&self) -> Option<Vec<String>>; fn get_shader_defs(&self) -> Option<Vec<String>>;
fn get_field_bind_type(&self, name: &str) -> Option<FieldBindType>; fn get_field_bind_type(&self, name: &str) -> Option<FieldBindType>;
fn get_uniform_bytes_ref(&self, name: &str) -> Option<&[u8]>; fn get_uniform_bytes_ref(&self, name: &str) -> Option<&[u8]>;
fn get_vertex_buffer_descriptor() -> Option<&'static VertexBufferDescriptor>;
} }
pub trait ShaderDefSuffixProvider { pub trait ShaderDefSuffixProvider {

View File

@ -1,14 +1,17 @@
use crate::{ use crate::{
asset::Handle, asset::Handle,
render::{ render::{
pipeline::{
InputStepMode, VertexAttributeDescriptor, VertexBufferDescriptor, VertexFormat,
},
shader::{AsUniforms, FieldBindType, FieldInfo}, shader::{AsUniforms, FieldBindType, FieldInfo},
texture::Texture, texture::Texture,
}, },
}; };
use once_cell::sync::Lazy;
use zerocopy::AsBytes; use zerocopy::AsBytes;
const LOCAL_TO_WORLD_FIELD_INFOS: &[FieldInfo] = &[FieldInfo { static LOCAL_TO_WORLD_FIELD_INFOS: &[FieldInfo] = &[FieldInfo {
name: "object", name: "object",
uniform_name: "Object", uniform_name: "Object",
texture_name: "", texture_name: "",
@ -16,6 +19,38 @@ const LOCAL_TO_WORLD_FIELD_INFOS: &[FieldInfo] = &[FieldInfo {
is_instanceable: true, is_instanceable: true,
}]; }];
static VERTEX_BUFFER_DESCRIPTOR: Lazy<VertexBufferDescriptor> = Lazy::new(|| VertexBufferDescriptor {
attributes: vec![
VertexAttributeDescriptor {
name: "I_Object_Matrix_0".to_string(),
format: VertexFormat::Float4,
offset: 0,
shader_location: 0,
},
VertexAttributeDescriptor {
name: "I_Object_Matrix_1".to_string(),
format: VertexFormat::Float4,
offset: 16,
shader_location: 0,
},
VertexAttributeDescriptor {
name: "I_Object_Matrix_2".to_string(),
format: VertexFormat::Float4,
offset: 32,
shader_location: 0,
},
VertexAttributeDescriptor {
name: "I_Object_Matrix_3".to_string(),
format: VertexFormat::Float4,
offset: 48,
shader_location: 0,
},
],
name: "Object".to_string(),
step_mode: InputStepMode::Instance,
stride: 64,
});
impl AsUniforms for bevy_transform::prelude::LocalToWorld { impl AsUniforms for bevy_transform::prelude::LocalToWorld {
fn get_field_infos(&self) -> &[FieldInfo] { fn get_field_infos(&self) -> &[FieldInfo] {
LOCAL_TO_WORLD_FIELD_INFOS LOCAL_TO_WORLD_FIELD_INFOS
@ -47,4 +82,8 @@ impl AsUniforms for bevy_transform::prelude::LocalToWorld {
_ => None, _ => None,
} }
} }
fn get_vertex_buffer_descriptor() -> Option<&'static VertexBufferDescriptor> {
Some(&VERTEX_BUFFER_DESCRIPTOR)
}
} }