pub struct VertexBuffer { /* private fields */ }
Expand description
Vertex buffer with dynamic layout. It is used to store multiple vertices of a single type, that implements VertexTrait
.
Different vertex types used to for efficient memory usage. For example, you could have a simple vertex with only position
expressed as Vector3 and it will be enough for simple cases, when only position is required. However, if you want to draw
a mesh with skeletal animation, that also supports texturing, lighting, you need to provide a lot more data (bone indices,
bone weights, normals, tangents, texture coordinates).
§Examples
#[derive(Copy, Clone)]
#[repr(C)]
struct MyVertex {
position: Vector3<f32>,
}
impl VertexTrait for MyVertex {
fn layout() -> &'static [VertexAttributeDescriptor] {
&[VertexAttributeDescriptor {
usage: VertexAttributeUsage::Position,
data_type: VertexAttributeDataType::F32,
size: 3,
divisor: 0,
shader_location: 0,
normalized: false
}]
}
}
fn create_triangle_vertex_buffer() -> VertexBuffer {
VertexBuffer::new(
3,
vec![
MyVertex {
position: Vector3::new(0.0, 0.0, 0.0),
},
MyVertex {
position: Vector3::new(0.0, 1.0, 0.0),
},
MyVertex {
position: Vector3::new(1.0, 1.0, 0.0),
},
],
)
.unwrap()
}
This example creates a simple vertex buffer that contains a single triangle with custom vertex format. The most important
part here is VertexTrait::layout
implementation - it describes each “attribute” of your vertex, if your layout does not
match the actual content of the vertex (in terms of size in bytes), then vertex buffer cannot be created and VertexBuffer::new
will return None
.
The second, but not least important is #[repr(C)]
attribute - it is mandatory for every vertex type, it forbids fields
reordering of you vertex structure and guarantees that they will have the same layout in memory as their declaration order.
§Limitations
Vertex size cannot be more than 256 bytes, this limitation shouldn’t be a problem because almost every GPU supports up to 16 vertex attributes with 16 bytes of size each, which gives exactly 256 bytes.
Implementations§
Source§impl VertexBuffer
impl VertexBuffer
pub const DENSE_LAYOUT: &'static str = "dense_layout"
pub const SPARSE_LAYOUT: &'static str = "sparse_layout"
pub const VERTEX_SIZE: &'static str = "vertex_size"
pub const VERTEX_COUNT: &'static str = "vertex_count"
pub const DATA: &'static str = "data"
pub const LAYOUT_HASH: &'static str = "layout_hash"
pub const MODIFICATIONS_COUNTER: &'static str = "modifications_counter"
Source§impl VertexBuffer
impl VertexBuffer
Sourcepub fn new<T>(
vertex_count: usize,
data: Vec<T>,
) -> Result<Self, ValidationError>where
T: VertexTrait,
pub fn new<T>(
vertex_count: usize,
data: Vec<T>,
) -> Result<Self, ValidationError>where
T: VertexTrait,
Creates new vertex buffer from provided data and with the given layout of the vertex type T
.
Sourcepub fn new_with_layout(
layout: &[VertexAttributeDescriptor],
vertex_count: usize,
bytes: BytesStorage,
) -> Result<Self, ValidationError>
pub fn new_with_layout( layout: &[VertexAttributeDescriptor], vertex_count: usize, bytes: BytesStorage, ) -> Result<Self, ValidationError>
Creates new vertex buffer from the given layout, vertex count and bytes storage.
Sourcepub fn clone_empty(&self, capacity: usize) -> Self
pub fn clone_empty(&self, capacity: usize) -> Self
Creates a new empty vertex buffer with the same layout and vertex size, but with an empty inner buffer of the specified capacity.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if buffer does not contain any vertex, false - otherwise.
Sourcepub fn modifications_count(&self) -> u64
pub fn modifications_count(&self) -> u64
Returns the total amount of times the buffer was modified.
Sourcepub fn content_hash(&self) -> u64
pub fn content_hash(&self) -> u64
Calculates inner data hash.
Sourcepub fn layout_hash(&self) -> u64
pub fn layout_hash(&self) -> u64
Returns hash of vertex buffer layout. Cached value is guaranteed to be in actual state. The hash could be used to check if the layout has changed.
Sourcepub fn modify(&mut self) -> VertexBufferRefMut<'_>
pub fn modify(&mut self) -> VertexBufferRefMut<'_>
Provides mutable access to content of the buffer.
§Performance
This method returns special structure which has custom destructor that calculates hash of the data once modification is over. You must hold this structure as long as possible while modifying contents of the buffer. Do not even try to do this:
use fyrox_impl::{
scene::mesh::buffer::{VertexBuffer, VertexWriteTrait, VertexAttributeUsage},
core::algebra::Vector3
};
fn do_something(buffer: &mut VertexBuffer) {
for i in 0..buffer.vertex_count() {
buffer
.modify() // Doing this in a loop will cause HUGE performance issues!
.get_mut(i as usize)
.unwrap()
.write_3_f32(VertexAttributeUsage::Position, Vector3::<f32>::default())
.unwrap();
}
}
Instead do this:
use fyrox_impl::{
scene::mesh::buffer::{VertexBuffer, VertexWriteTrait, VertexAttributeUsage},
core::algebra::Vector3
};
fn do_something(buffer: &mut VertexBuffer) {
let mut buffer_modifier = buffer.modify();
for mut vertex in buffer_modifier.iter_mut() {
vertex
.write_3_f32(VertexAttributeUsage::Position, Vector3::<f32>::default())
.unwrap();
}
}
Why do we even need such complications? It is used for lazy hash calculation which is used for automatic upload of contents to GPU in case if content has changed.
Sourcepub fn has_attribute(&self, usage: VertexAttributeUsage) -> bool
pub fn has_attribute(&self, usage: VertexAttributeUsage) -> bool
Checks if an attribute of usage
exists.
Sourcepub fn layout(&self) -> &[VertexAttribute]
pub fn layout(&self) -> &[VertexAttribute]
Returns vertex buffer layout.
Sourcepub fn layout_descriptor(
&self,
) -> impl Iterator<Item = VertexAttributeDescriptor> + '_
pub fn layout_descriptor( &self, ) -> impl Iterator<Item = VertexAttributeDescriptor> + '_
Returns vertex buffer layout.
Sourcepub fn cast_data_ref<T>(&self) -> Result<&[T], ValidationError>where
T: VertexTrait,
pub fn cast_data_ref<T>(&self) -> Result<&[T], ValidationError>where
T: VertexTrait,
Tries to cast internal data buffer to a slice of given type. It may fail if size of type is not equal with claimed size (which is set by the layout).
Sourcepub fn iter(&self) -> impl Iterator<Item = VertexViewRef<'_>> + '_
pub fn iter(&self) -> impl Iterator<Item = VertexViewRef<'_>> + '_
Creates iterator that emits read accessors for vertices.
Sourcepub fn get(&self, n: usize) -> Option<VertexViewRef<'_>>
pub fn get(&self, n: usize) -> Option<VertexViewRef<'_>>
Returns a read accessor of n-th vertex.
Sourcepub fn vertex_count(&self) -> u32
pub fn vertex_count(&self) -> u32
Returns exact amount of vertices in the buffer.
Sourcepub fn vertex_size(&self) -> u8
pub fn vertex_size(&self) -> u8
Return vertex size of the buffer.
Sourcepub fn find_free_shader_location(&self) -> u8
pub fn find_free_shader_location(&self) -> u8
Finds free location for an attribute in the layout.
Sourcepub fn attribute_view<T>(
&self,
usage: VertexAttributeUsage,
) -> Option<AttributeViewRef<'_, T>>where
T: Copy,
pub fn attribute_view<T>(
&self,
usage: VertexAttributeUsage,
) -> Option<AttributeViewRef<'_, T>>where
T: Copy,
Tries to find an attribute with the given usage
and if it exists, returns its “view”, that
allows you to fetch data like in ordinary array.
Sourcepub fn attribute_view_mut<T: Copy>(
&mut self,
usage: VertexAttributeUsage,
) -> Option<AttributeViewRefMut<'_, T>>
pub fn attribute_view_mut<T: Copy>( &mut self, usage: VertexAttributeUsage, ) -> Option<AttributeViewRefMut<'_, T>>
Tries to find an attribute with the given usage
and if it exists, returns its “view”, that
allows you to fetch data like in ordinary array.
Trait Implementations§
Source§impl Clone for VertexBuffer
impl Clone for VertexBuffer
Source§fn clone(&self) -> VertexBuffer
fn clone(&self) -> VertexBuffer
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl Debug for VertexBuffer
impl Debug for VertexBuffer
Source§impl Default for VertexBuffer
impl Default for VertexBuffer
Source§fn default() -> VertexBuffer
fn default() -> VertexBuffer
Source§impl Reflect for VertexBufferwhere
Self: 'static,
Vec<VertexAttribute>: Reflect,
[Option<VertexAttribute>; 22]: Reflect,
u8: Reflect,
u32: Reflect,
BytesStorage: Reflect,
u64: Reflect,
impl Reflect for VertexBufferwhere
Self: 'static,
Vec<VertexAttribute>: Reflect,
[Option<VertexAttribute>; 22]: Reflect,
u8: Reflect,
u32: Reflect,
BytesStorage: Reflect,
u64: Reflect,
fn source_path() -> &'static str
fn type_name(&self) -> &'static str
fn doc(&self) -> &'static str
Source§fn assembly_name(&self) -> &'static str
fn assembly_name(&self) -> &'static str
#[derive(Reflect)]
) to ensure that this method will return correct assembly
name. In other words - there’s no guarantee, that any implementation other than proc-macro
will return a correct name of the assembly. Alternatively, you can use env!("CARGO_PKG_NAME")
as an implementation.Source§fn type_assembly_name() -> &'static str
fn type_assembly_name() -> &'static str
#[derive(Reflect)]
) to ensure that this method will return correct assembly
name. In other words - there’s no guarantee, that any implementation other than proc-macro
will return a correct name of the assembly. Alternatively, you can use env!("CARGO_PKG_NAME")
as an implementation.fn fields_info(&self, func: &mut dyn FnMut(&[FieldInfo<'_, '_>]))
fn into_any(self: Box<Self>) -> Box<dyn Any>
fn set( &mut self, value: Box<dyn Reflect>, ) -> Result<Box<dyn Reflect>, Box<dyn Reflect>>
fn as_any(&self, func: &mut dyn FnMut(&dyn Any))
fn as_any_mut(&mut self, func: &mut dyn FnMut(&mut dyn Any))
fn as_reflect(&self, func: &mut dyn FnMut(&dyn Reflect))
fn as_reflect_mut(&mut self, func: &mut dyn FnMut(&mut dyn Reflect))
fn fields(&self, func: &mut dyn FnMut(&[&dyn Reflect]))
fn fields_mut(&mut self, func: &mut dyn FnMut(&mut [&mut dyn Reflect]))
fn field(&self, name: &str, func: &mut dyn FnMut(Option<&dyn Reflect>))
fn field_mut( &mut self, name: &str, func: &mut dyn FnMut(Option<&mut dyn Reflect>), )
Source§fn set_field(
&mut self,
field: &str,
value: Box<dyn Reflect>,
func: &mut dyn FnMut(Result<Box<dyn Reflect>, Box<dyn Reflect>>),
)
fn set_field( &mut self, field: &str, value: Box<dyn Reflect>, func: &mut dyn FnMut(Result<Box<dyn Reflect>, Box<dyn Reflect>>), )
#[reflect(setter = ..)]
or falls back to
Reflect::field_mut
fn as_array(&self, func: &mut dyn FnMut(Option<&(dyn ReflectArray + 'static)>))
fn as_array_mut( &mut self, func: &mut dyn FnMut(Option<&mut (dyn ReflectArray + 'static)>), )
fn as_list(&self, func: &mut dyn FnMut(Option<&(dyn ReflectList + 'static)>))
fn as_list_mut( &mut self, func: &mut dyn FnMut(Option<&mut (dyn ReflectList + 'static)>), )
fn as_inheritable_variable( &self, func: &mut dyn FnMut(Option<&(dyn ReflectInheritableVariable + 'static)>), )
fn as_inheritable_variable_mut( &mut self, func: &mut dyn FnMut(Option<&mut (dyn ReflectInheritableVariable + 'static)>), )
fn as_hash_map( &self, func: &mut dyn FnMut(Option<&(dyn ReflectHashMap + 'static)>), )
fn as_hash_map_mut( &mut self, func: &mut dyn FnMut(Option<&mut (dyn ReflectHashMap + 'static)>), )
Source§impl Visit for VertexBufferwhere
Vec<VertexAttribute>: Visit,
[Option<VertexAttribute>; 22]: Visit,
u8: Visit,
u32: Visit,
BytesStorage: Visit,
u64: Visit,
impl Visit for VertexBufferwhere
Vec<VertexAttribute>: Visit,
[Option<VertexAttribute>; 22]: Visit,
u8: Visit,
u32: Visit,
BytesStorage: Visit,
u64: Visit,
Source§fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult
fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult
Auto Trait Implementations§
impl Freeze for VertexBuffer
impl RefUnwindSafe for VertexBuffer
impl Send for VertexBuffer
impl Sync for VertexBuffer
impl Unpin for VertexBuffer
impl UnwindSafe for VertexBuffer
Blanket Implementations§
Source§impl<T> AsyncTaskResult for T
impl<T> AsyncTaskResult for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Any
. Could be used to downcast a trait object
to a particular type.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
Any
. Could be used to downcast a trait object
to a particular type.fn into_any(self: Box<T>) -> Box<dyn Any>
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> FieldValue for Twhere
T: 'static,
impl<T> FieldValue for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<R, P> ReadPrimitive<R> for P
impl<R, P> ReadPrimitive<R> for P
Source§fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
fn read_from_little_endian(read: &mut R) -> Result<Self, Error>
ReadEndian::read_from_little_endian()
.Source§impl<T> ReflectBase for Twhere
T: Reflect,
impl<T> ReflectBase for Twhere
T: Reflect,
fn as_any_raw(&self) -> &(dyn Any + 'static)
fn as_any_raw_mut(&mut self) -> &mut (dyn Any + 'static)
Source§impl<T> ResolvePath for Twhere
T: Reflect,
impl<T> ResolvePath for Twhere
T: Reflect,
fn resolve_path<'p>( &self, path: &'p str, func: &mut dyn FnMut(Result<&(dyn Reflect + 'static), ReflectPathError<'p>>), )
fn resolve_path_mut<'p>( &mut self, path: &'p str, func: &mut dyn FnMut(Result<&mut (dyn Reflect + 'static), ReflectPathError<'p>>), )
fn get_resolve_path<'p, T>(
&self,
path: &'p str,
func: &mut dyn FnMut(Result<&T, ReflectPathError<'p>>),
)where
T: Reflect,
fn get_resolve_path_mut<'p, T>(
&mut self,
path: &'p str,
func: &mut dyn FnMut(Result<&mut T, ReflectPathError<'p>>),
)where
T: Reflect,
Source§impl<T> ScriptMessagePayload for T
impl<T> ScriptMessagePayload for T
Source§fn as_any_ref(&self) -> &(dyn Any + 'static)
fn as_any_ref(&self) -> &(dyn Any + 'static)
self
as &dyn Any
Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
self
as &dyn Any
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.