mod3d_base/traits.rs
1//a Imports
2use crate::{BufferData, BufferDataAccessor, BufferIndexAccessor, Texture, Vertices};
3use crate::{BufferDescriptor, MaterialAspect, MaterialBaseData, ShortIndex};
4
5//a Client traits
6//tt BufferClient
7/// Trait supported by a BufferData client
8///
9/// A buffer client is created first by a buffer as 'none'
10///
11/// The data may be created more than once with the same buffer; the client
12/// is responsible for deduplication within the render context if required
13pub trait BufferClient: Sized + std::fmt::Debug + std::default::Default + Clone {
14 /// Format for display; this can be used in indented displays for
15 /// hierarchies in objects
16 ///
17 /// The trait itself does not require std::fmt::Display as that is
18 /// not implemented for some simple types (such as ()).
19 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
20 <Self as std::fmt::Debug>::fmt(self, fmt)
21 }
22}
23impl BufferClient for () {}
24
25//tt AccessorClient
26/// Trait supported by a BufferAccessor client
27///
28/// A buffer client is created first by a buffer as 'none'
29///
30/// Before a view is creataed the data will be created at least once
31///
32/// The data may be created more than once with the same buffer; the client
33/// is responsible for dedupliclation within the render context if required
34pub trait AccessorClient: Sized + std::fmt::Debug + std::default::Default + Clone {}
35impl AccessorClient for () {}
36
37//tt DescriptorClient
38/// Trait supported by a BufferDescriptor client
39///
40/// A buffer descriptor client is created first by a buffer as 'none'
41///
42/// Before a descriptor is created the data will be created at least once
43///
44/// The data may be created more than once with the same descriptor; the client
45/// is responsible for dedupliclation within the render context if required
46pub trait DescriptorClient: Sized + std::fmt::Debug + std::default::Default + Clone {}
47impl DescriptorClient for () {}
48
49//tt TextureClient
50/// The trait that must be supported by a client texture
51///
52/// Default is required as the client is made when a texture is made
53/// Clone is required as the client is textures are cloned
54pub trait TextureClient: Sized + std::fmt::Debug + std::default::Default + Clone {}
55impl TextureClient for () {}
56
57//tt MaterialClient
58/// Trait supported by a material client
59///
60/// Default is not required as materials are only created in response
61/// to a crate::Material
62pub trait MaterialClient: Sized + std::fmt::Debug {}
63impl MaterialClient for () {}
64
65//tt VerticesClient
66/// The trait that must be supported by a client vertices
67///
68/// Clone is required as Vertices can be borrowed by more than one object, and an
69/// instantiable object contains the [VerticesClient] for the Vertices
70///
71pub trait VerticesClient: Sized + std::fmt::Debug + std::default::Default + Clone {}
72impl VerticesClient for () {}
73
74//a Renderable
75//tt Renderable
76/// The [Renderable] trait must be implemented by a type that is a
77/// client of the 3D model system. It provides associated types for a
78/// renderable context (this might be a particular shader program
79/// within a OpenGL context, for example), and then its own structures
80/// that are used to hold [BufferData], textures, materials, and sets
81/// of renderable [Vertices].
82pub trait Renderable: Sized {
83 /// The renderer's type that reflects a [BufferData]
84 ///
85 /// A BufferData is a slice of u8 that contains some data
86 /// (indices, vertex data, etc) for an object
87 type Buffer: BufferClient;
88
89 /// The renderer's type that reflects a [BufferDescriptor]
90 ///
91 /// A buffer descriptor is a slice of a BufferData that contains
92 /// multiple records, each of which contains a number of fields
93 /// for different VertexAttr
94 type Descriptor: DescriptorClient;
95
96 /// The renderer's type that reflects a [BufferDataAccessor]
97 ///
98 /// A BufferDataAccessor is a reference to a single entry in a
99 /// BufferDescriptor; hence it might be 'Position' for a vertex,
100 /// from a large array of vertex records in an object
101 type DataAccessor: AccessorClient;
102
103 /// The renderer's type that reflects a [BufferIndexAccessor]
104 ///
105 /// A BufferIndexAccessor represents a slice of a BufferData
106 /// containing indices for accessing an array of vertex records
107 /// for rendering a primitive in an object
108 type IndexAccessor: AccessorClient;
109
110 /// The renderer's type that represents a texture; this is
111 /// supplied to material creation, and hence is less a product of
112 /// the renderer and more an input to the 3D model library
113 type Texture: TextureClient;
114
115 /// The renderer's type that reflects a [Material]; this is expected
116 /// to be an extraction of the aspects of a material that the
117 /// renderer pipelines can apply.
118 type Material: MaterialClient;
119
120 /// The renderer's type that reflects a [BufferAccessor] of indices
121 /// and the associated [BufferAccessor]s of attributes supported by a
122 /// particular pipeline within the renderer
123 type Vertices: VerticesClient;
124
125 /// Initialize a buffer data client - it will have been created using default()
126 ///
127 /// This is invoked by the base library only when the client
128 /// invoked 'create_client' for a data buffer
129 fn init_buffer_data_client(
130 &mut self,
131 client: &mut Self::Buffer,
132 buffer_data: &BufferData<Self>,
133 );
134
135 /// Initialize a buffer descriptor client - it will have been created using default()
136 fn init_buffer_desc_client(
137 &mut self,
138 client: &mut Self::Descriptor,
139 buffer_desc: &BufferDescriptor<Self>,
140 );
141
142 /// Initialize the client of an index accessor of a buffer data
143 fn init_index_accessor_client(
144 &mut self,
145 client: &mut Self::IndexAccessor,
146 buffer_view: &BufferIndexAccessor<Self>,
147 );
148
149 /// Initialize the client of a data accessor of a buffer data
150 fn init_data_accessor_client(
151 &mut self,
152 client: &mut Self::DataAccessor,
153 buffer_view: &BufferDataAccessor<Self>,
154 );
155
156 /// Create a client
157 fn create_vertices_client(&mut self, vertices: &Vertices<Self>) -> Self::Vertices;
158
159 /// Create a client
160 fn create_texture_client(&mut self, texture: &Texture<Self>) -> Self::Texture;
161
162 /// Create a client
163 fn create_material_client<M>(
164 &mut self,
165 object: &crate::Object<M, Self>,
166 material: &M,
167 ) -> Self::Material
168 where
169 M: Material;
170
171 /// Create a client for a reason - reason 0 is reserved
172 /// Can we lose this?
173 fn init_material_client<M: Material>(&mut self, client: &mut Self::Material, material: &M);
174 // Destroy a client given a reason - reason 0 implies all
175 // fn drop_material_client(&mut self, material: &dyn Material<Self>, render_context: &mut Self::Context);
176}
177
178//tt Material
179/// A [Material] provides means to access the data for a material, be
180/// it simple of full PBR. A fragment shader may require some aspects
181/// of a material to be provided to it for rendering, and this API
182/// allows that information to be gathered from any kind of material
183pub trait Material: std::fmt::Debug {
184 // Invoked when an 3D model object is made renderable
185 // fn create_renderable(&self, _render_context: &mut R::Context) {}
186
187 /// Borrow the basic data of a material - color and base
188 /// metallic/roughness, for example
189 fn base_data(&self) -> &MaterialBaseData;
190 /// Get the index into the Textures array for a specific aspect
191 fn texture(&self, _aspect: MaterialAspect) -> ShortIndex {
192 ShortIndex::none()
193 }
194}