cogl/auto/
attribute.rs

1use crate::{AttributeBuffer, AttributeType, Context, Object};
2
3use glib::translate::*;
4use std::fmt;
5
6glib_wrapper! {
7    pub struct Attribute(Object<ffi::CoglAttribute, AttributeClass>) @extends Object;
8
9    match fn {
10        get_type => || ffi::cogl_attribute_get_gtype(),
11    }
12}
13
14impl Attribute {
15    /// Describes the layout for a list of vertex attribute values (For
16    /// example, a list of texture coordinates or colors).
17    ///
18    /// The `name` is used to access the attribute inside a GLSL vertex
19    /// shader and there are some special names you should use if they are
20    /// applicable:
21    ///  `<itemizedlist>`
22    ///  `<listitem>`"cogl_position_in" (used for vertex positions)`</listitem>`
23    ///  `<listitem>`"cogl_color_in" (used for vertex colors)`</listitem>`
24    ///  `<listitem>`"cogl_tex_coord0_in", "cogl_tex_coord1", ...
25    /// (used for vertex texture coordinates)`</listitem>`
26    ///  `<listitem>`"cogl_normal_in" (used for vertex normals)`</listitem>`
27    ///  `<listitem>`"cogl_point_size_in" (used to set the size of points
28    ///  per-vertex. Note this can only be used if
29    ///  `COGL_FEATURE_ID_POINT_SIZE_ATTRIBUTE` is advertised and
30    ///  `Pipeline::set_per_vertex_point_size` is called on the pipeline.
31    ///  `</listitem>`
32    ///  `</itemizedlist>`
33    ///
34    /// The attribute values corresponding to different vertices can either
35    /// be tightly packed or interleaved with other attribute values. For
36    /// example it's common to define a structure for a single vertex like:
37    ///
38    /// ```text
39    /// typedef struct
40    /// {
41    ///   float x, y, z; /<!-- -->* position attribute *<!-- -->/
42    ///   float s, t; /<!-- -->* texture coordinate attribute *<!-- -->/
43    /// } MyVertex;
44    /// ```
45    ///
46    /// And then create an array of vertex data something like:
47    ///
48    /// ```text
49    /// MyVertex vertices[100] = { .... }
50    /// ```
51    ///
52    /// In this case, to describe either the position or texture coordinate
53    /// attribute you have to move `<literal>`sizeof (MyVertex)`</literal>` bytes to
54    /// move from one vertex to the next. This is called the attribute
55    /// `stride`. If you weren't interleving attributes and you instead had
56    /// a packed array of float x, y pairs then the attribute stride would
57    /// be `<literal>`(2 * sizeof (float))`</literal>`. So the `stride` is the number of
58    /// bytes to move to find the attribute value of the next vertex.
59    ///
60    /// Normally a list of attributes starts at the beginning of an array.
61    /// So for the `<literal>`MyVertex`</literal>` example above the `offset` is the
62    /// offset inside the `<literal>`MyVertex`</literal>` structure to the first
63    /// component of the attribute. For the texture coordinate attribute
64    /// the offset would be `<literal>`offsetof (MyVertex, s)`</literal>` or instead of
65    /// using the offsetof macro you could use `<literal>`sizeof (float) *
66    /// 3`</literal>`. If you've divided your `array` into blocks of non-interleved
67    /// attributes then you will need to calculate the `offset` as the number of
68    /// bytes in blocks preceding the attribute you're describing.
69    ///
70    /// An attribute often has more than one component. For example a color
71    /// is often comprised of 4 red, green, blue and alpha `components`, and a
72    /// position may be comprised of 2 x and y `components`. You should aim
73    /// to keep the number of components to a minimum as more components
74    /// means more data needs to be mapped into the GPU which can be a
75    /// bottlneck when dealing with a large number of vertices.
76    ///
77    /// Finally you need to specify the component data type. Here you
78    /// should aim to use the smallest type that meets your precision
79    /// requirements. Again the larger the type then more data needs to be
80    /// mapped into the GPU which can be a bottlneck when dealing with
81    /// a large number of vertices.
82    /// ## `attribute_buffer`
83    /// The `AttributeBuffer` containing the actual
84    ///  attribute data
85    /// ## `name`
86    /// The name of the attribute (used to reference it from GLSL)
87    /// ## `stride`
88    /// The number of bytes to jump to get to the next attribute
89    ///  value for the next vertex. (Usually
90    ///  `<literal>`sizeof (MyVertex)`</literal>`)
91    /// ## `offset`
92    /// The byte offset from the start of `attribute_buffer` for
93    ///  the first attribute value. (Usually
94    ///  `<literal>`offsetof (MyVertex, component0)`</literal>`
95    /// ## `components`
96    /// The number of components (e.g. 4 for an rgba color or
97    ///  3 for and (x,y,z) position)
98    /// ## `type_`
99    /// FIXME
100    ///
101    /// # Returns
102    ///
103    /// A newly allocated `Attribute`
104    ///  describing the layout for a list of attribute values
105    ///  stored in `array`.
106    pub fn new(
107        attribute_buffer: &AttributeBuffer,
108        name: &str,
109        stride: usize,
110        offset: usize,
111        components: i32,
112        type_: AttributeType,
113    ) -> Attribute {
114        unsafe {
115            from_glib_full(ffi::cogl_attribute_new(
116                attribute_buffer.to_glib_none().0,
117                name.to_glib_none().0,
118                stride,
119                offset,
120                components,
121                type_.to_glib(),
122            ))
123        }
124    }
125
126    /// Creates a new, single component, attribute whose value remains
127    /// constant across all the vertices of a primitive without needing to
128    /// duplicate the value for each vertex.
129    ///
130    /// The constant `value` is a single precision floating point scalar
131    /// which should have a corresponding declaration in GLSL code like:
132    ///
133    /// [|
134    /// attribute float name;
135    /// |]
136    /// ## `context`
137    /// A `Context`
138    /// ## `name`
139    /// The name of the attribute (used to reference it from GLSL)
140    /// ## `value`
141    /// The constant value for the attribute
142    ///
143    /// # Returns
144    ///
145    /// A newly allocated `Attribute`
146    ///  representing the given constant `value`.
147    pub fn new_const_1f(context: &Context, name: &str, value: f32) -> Attribute {
148        unsafe {
149            from_glib_full(ffi::cogl_attribute_new_const_1f(
150                context.to_glib_none().0,
151                name.to_glib_none().0,
152                value,
153            ))
154        }
155    }
156
157    /// Creates a new, 2 component, attribute whose value remains
158    /// constant across all the vertices of a primitive without needing to
159    /// duplicate the value for each vertex.
160    ///
161    /// The constants (`component0`, `component1`) represent a 2 component
162    /// float vector which should have a corresponding declaration in GLSL
163    /// code like:
164    ///
165    /// [|
166    /// attribute vec2 name;
167    /// |]
168    /// ## `context`
169    /// A `Context`
170    /// ## `name`
171    /// The name of the attribute (used to reference it from GLSL)
172    /// ## `component0`
173    /// The first component of a 2 component vector
174    /// ## `component1`
175    /// The second component of a 2 component vector
176    ///
177    /// # Returns
178    ///
179    /// A newly allocated `Attribute`
180    ///  representing the given constant vector.
181    pub fn new_const_2f(
182        context: &Context,
183        name: &str,
184        component0: f32,
185        component1: f32,
186    ) -> Attribute {
187        unsafe {
188            from_glib_full(ffi::cogl_attribute_new_const_2f(
189                context.to_glib_none().0,
190                name.to_glib_none().0,
191                component0,
192                component1,
193            ))
194        }
195    }
196
197    /// Creates a new, 2 component, attribute whose value remains
198    /// constant across all the vertices of a primitive without needing to
199    /// duplicate the value for each vertex.
200    ///
201    /// The constants (value[0], value[1]) represent a 2 component float
202    /// vector which should have a corresponding declaration in GLSL code
203    /// like:
204    ///
205    /// [|
206    /// attribute vec2 name;
207    /// |]
208    /// ## `context`
209    /// A `Context`
210    /// ## `name`
211    /// The name of the attribute (used to reference it from GLSL)
212    /// ## `value`
213    /// A pointer to a 2 component float vector
214    ///
215    /// # Returns
216    ///
217    /// A newly allocated `Attribute`
218    ///  representing the given constant vector.
219    pub fn new_const_2fv(context: &Context, name: &str, value: &[f32; 2]) -> Attribute {
220        unsafe {
221            from_glib_full(ffi::cogl_attribute_new_const_2fv(
222                context.to_glib_none().0,
223                name.to_glib_none().0,
224                value.as_ptr(),
225            ))
226        }
227    }
228
229    /// Creates a new matrix attribute whose value remains constant
230    /// across all the vertices of a primitive without needing to duplicate
231    /// the value for each vertex.
232    ///
233    /// `matrix2x2` represent a square 2 by 2 matrix specified in
234    /// column-major order (each pair of consecutive numbers represents a
235    /// column) which should have a corresponding declaration in GLSL code
236    /// like:
237    ///
238    /// [|
239    /// attribute mat2 name;
240    /// |]
241    ///
242    /// If `transpose` is `true` then all matrix components are rotated
243    /// around the diagonal of the matrix such that the first column
244    /// becomes the first row and the second column becomes the second row.
245    /// ## `context`
246    /// A `Context`
247    /// ## `name`
248    /// The name of the attribute (used to reference it from GLSL)
249    /// ## `matrix2x2`
250    /// A pointer to a 2 by 2 matrix
251    /// ## `transpose`
252    /// Whether the matrix should be transposed on upload or
253    ///  not
254    ///
255    /// # Returns
256    ///
257    /// A newly allocated `Attribute`
258    ///  representing the given constant matrix.
259    pub fn new_const_2x2fv(
260        context: &Context,
261        name: &str,
262        matrix2x2: &[f32; 4],
263        transpose: bool,
264    ) -> Attribute {
265        unsafe {
266            from_glib_full(ffi::cogl_attribute_new_const_2x2fv(
267                context.to_glib_none().0,
268                name.to_glib_none().0,
269                matrix2x2.as_ptr(),
270                transpose as i32,
271            ))
272        }
273    }
274
275    /// Creates a new, 3 component, attribute whose value remains
276    /// constant across all the vertices of a primitive without needing to
277    /// duplicate the value for each vertex.
278    ///
279    /// The constants (`component0`, `component1`, `component2`) represent a 3
280    /// component float vector which should have a corresponding
281    /// declaration in GLSL code like:
282    ///
283    /// [|
284    /// attribute vec3 name;
285    /// |]
286    ///
287    /// unless the built in name "cogl_normal_in" is being used where no
288    /// explicit GLSL declaration need be made.
289    /// ## `context`
290    /// A `Context`
291    /// ## `name`
292    /// The name of the attribute (used to reference it from GLSL)
293    /// ## `component0`
294    /// The first component of a 3 component vector
295    /// ## `component1`
296    /// The second component of a 3 component vector
297    /// ## `component2`
298    /// The third component of a 3 component vector
299    ///
300    /// # Returns
301    ///
302    /// A newly allocated `Attribute`
303    ///  representing the given constant vector.
304    pub fn new_const_3f(
305        context: &Context,
306        name: &str,
307        component0: f32,
308        component1: f32,
309        component2: f32,
310    ) -> Attribute {
311        unsafe {
312            from_glib_full(ffi::cogl_attribute_new_const_3f(
313                context.to_glib_none().0,
314                name.to_glib_none().0,
315                component0,
316                component1,
317                component2,
318            ))
319        }
320    }
321
322    /// Creates a new, 3 component, attribute whose value remains
323    /// constant across all the vertices of a primitive without needing to
324    /// duplicate the value for each vertex.
325    ///
326    /// The constants (value[0], value[1], value[2]) represent a 3
327    /// component float vector which should have a corresponding
328    /// declaration in GLSL code like:
329    ///
330    /// [|
331    /// attribute vec3 name;
332    /// |]
333    ///
334    /// unless the built in name "cogl_normal_in" is being used where no
335    /// explicit GLSL declaration need be made.
336    /// ## `context`
337    /// A `Context`
338    /// ## `name`
339    /// The name of the attribute (used to reference it from GLSL)
340    /// ## `value`
341    /// A pointer to a 3 component float vector
342    ///
343    /// # Returns
344    ///
345    /// A newly allocated `Attribute`
346    ///  representing the given constant vector.
347    pub fn new_const_3fv(context: &Context, name: &str, value: &[f32; 3]) -> Attribute {
348        unsafe {
349            from_glib_full(ffi::cogl_attribute_new_const_3fv(
350                context.to_glib_none().0,
351                name.to_glib_none().0,
352                value.as_ptr(),
353            ))
354        }
355    }
356
357    /// Creates a new matrix attribute whose value remains constant
358    /// across all the vertices of a primitive without needing to duplicate
359    /// the value for each vertex.
360    ///
361    /// `matrix3x3` represent a square 3 by 3 matrix specified in
362    /// column-major order (each triple of consecutive numbers represents a
363    /// column) which should have a corresponding declaration in GLSL code
364    /// like:
365    ///
366    /// [|
367    /// attribute mat3 name;
368    /// |]
369    ///
370    /// If `transpose` is `true` then all matrix components are rotated
371    /// around the diagonal of the matrix such that the first column
372    /// becomes the first row and the second column becomes the second row
373    /// etc.
374    /// ## `context`
375    /// A `Context`
376    /// ## `name`
377    /// The name of the attribute (used to reference it from GLSL)
378    /// ## `matrix3x3`
379    /// A pointer to a 3 by 3 matrix
380    /// ## `transpose`
381    /// Whether the matrix should be transposed on upload or
382    ///  not
383    ///
384    /// # Returns
385    ///
386    /// A newly allocated `Attribute`
387    ///  representing the given constant matrix.
388    pub fn new_const_3x3fv(
389        context: &Context,
390        name: &str,
391        matrix3x3: &[f32; 9],
392        transpose: bool,
393    ) -> Attribute {
394        unsafe {
395            from_glib_full(ffi::cogl_attribute_new_const_3x3fv(
396                context.to_glib_none().0,
397                name.to_glib_none().0,
398                matrix3x3.as_ptr(),
399                transpose as i32,
400            ))
401        }
402    }
403
404    /// Creates a new, 4 component, attribute whose value remains
405    /// constant across all the vertices of a primitive without needing to
406    /// duplicate the value for each vertex.
407    ///
408    /// The constants (`component0`, `component1`, `component2`, `constant3`)
409    /// represent a 4 component float vector which should have a
410    /// corresponding declaration in GLSL code like:
411    ///
412    /// [|
413    /// attribute vec4 name;
414    /// |]
415    ///
416    /// unless one of the built in names "cogl_color_in",
417    /// "cogl_tex_coord0_in or "cogl_tex_coord1_in" etc is being used where
418    /// no explicit GLSL declaration need be made.
419    /// ## `context`
420    /// A `Context`
421    /// ## `name`
422    /// The name of the attribute (used to reference it from GLSL)
423    /// ## `component0`
424    /// The first component of a 4 component vector
425    /// ## `component1`
426    /// The second component of a 4 component vector
427    /// ## `component2`
428    /// The third component of a 4 component vector
429    /// ## `component3`
430    /// The fourth component of a 4 component vector
431    ///
432    /// # Returns
433    ///
434    /// A newly allocated `Attribute`
435    ///  representing the given constant vector.
436    pub fn new_const_4f(
437        context: &Context,
438        name: &str,
439        component0: f32,
440        component1: f32,
441        component2: f32,
442        component3: f32,
443    ) -> Attribute {
444        unsafe {
445            from_glib_full(ffi::cogl_attribute_new_const_4f(
446                context.to_glib_none().0,
447                name.to_glib_none().0,
448                component0,
449                component1,
450                component2,
451                component3,
452            ))
453        }
454    }
455
456    /// Creates a new, 4 component, attribute whose value remains
457    /// constant across all the vertices of a primitive without needing to
458    /// duplicate the value for each vertex.
459    ///
460    /// The constants (value[0], value[1], value[2], value[3]) represent a
461    /// 4 component float vector which should have a corresponding
462    /// declaration in GLSL code like:
463    ///
464    /// [|
465    /// attribute vec4 name;
466    /// |]
467    ///
468    /// unless one of the built in names "cogl_color_in",
469    /// "cogl_tex_coord0_in or "cogl_tex_coord1_in" etc is being used where
470    /// no explicit GLSL declaration need be made.
471    /// ## `context`
472    /// A `Context`
473    /// ## `name`
474    /// The name of the attribute (used to reference it from GLSL)
475    /// ## `value`
476    /// A pointer to a 4 component float vector
477    ///
478    /// # Returns
479    ///
480    /// A newly allocated `Attribute`
481    ///  representing the given constant vector.
482    pub fn new_const_4fv(context: &Context, name: &str, value: &[f32; 4]) -> Attribute {
483        unsafe {
484            from_glib_full(ffi::cogl_attribute_new_const_4fv(
485                context.to_glib_none().0,
486                name.to_glib_none().0,
487                value.as_ptr(),
488            ))
489        }
490    }
491
492    /// Creates a new matrix attribute whose value remains constant
493    /// across all the vertices of a primitive without needing to duplicate
494    /// the value for each vertex.
495    ///
496    /// `matrix4x4` represent a square 4 by 4 matrix specified in
497    /// column-major order (each 4-tuple of consecutive numbers represents a
498    /// column) which should have a corresponding declaration in GLSL code
499    /// like:
500    ///
501    /// [|
502    /// attribute mat4 name;
503    /// |]
504    ///
505    /// If `transpose` is `true` then all matrix components are rotated
506    /// around the diagonal of the matrix such that the first column
507    /// becomes the first row and the second column becomes the second row
508    /// etc.
509    /// ## `context`
510    /// A `Context`
511    /// ## `name`
512    /// The name of the attribute (used to reference it from GLSL)
513    /// ## `matrix4x4`
514    /// A pointer to a 4 by 4 matrix
515    /// ## `transpose`
516    /// Whether the matrix should be transposed on upload or
517    ///  not
518    ///
519    /// # Returns
520    ///
521    /// A newly allocated `Attribute`
522    ///  representing the given constant matrix.
523    pub fn new_const_4x4fv(
524        context: &Context,
525        name: &str,
526        matrix4x4: &[f32; 16],
527        transpose: bool,
528    ) -> Attribute {
529        unsafe {
530            from_glib_full(ffi::cogl_attribute_new_const_4x4fv(
531                context.to_glib_none().0,
532                name.to_glib_none().0,
533                matrix4x4.as_ptr(),
534                transpose as i32,
535            ))
536        }
537    }
538
539    ///
540    /// # Returns
541    ///
542    /// the `AttributeBuffer` that was
543    ///  set with `Attribute::set_buffer` or `Attribute::new`.
544    pub fn get_buffer(&self) -> Option<AttributeBuffer> {
545        unsafe { from_glib_none(ffi::cogl_attribute_get_buffer(self.to_glib_none().0)) }
546    }
547
548    ///
549    /// # Returns
550    ///
551    /// the value of the normalized property set with
552    /// `Attribute::set_normalized`.
553    pub fn get_normalized(&self) -> bool {
554        unsafe { ffi::cogl_attribute_get_normalized(self.to_glib_none().0) == crate::TRUE }
555    }
556
557    /// Sets a new `AttributeBuffer` for the attribute.
558    /// ## `attribute_buffer`
559    /// A `AttributeBuffer`
560    pub fn set_buffer(&self, attribute_buffer: &AttributeBuffer) {
561        unsafe {
562            ffi::cogl_attribute_set_buffer(
563                self.to_glib_none().0,
564                attribute_buffer.to_glib_none().0,
565            );
566        }
567    }
568
569    /// Sets whether fixed point attribute types are mapped to the range
570    /// 0→1. For example when this property is TRUE and a
571    /// `AttributeType::UnsignedByte` type is used then the value 255
572    /// will be mapped to 1.0.
573    ///
574    /// The default value of this property depends on the name of the
575    /// attribute. For the builtin properties cogl_color_in and
576    /// cogl_normal_in it will default to TRUE and for all other names it
577    /// will default to FALSE.
578    /// ## `normalized`
579    /// The new value for the normalized property.
580    pub fn set_normalized(&self, normalized: bool) {
581        unsafe {
582            ffi::cogl_attribute_set_normalized(self.to_glib_none().0, normalized as i32);
583        }
584    }
585}
586
587impl fmt::Display for Attribute {
588    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
589        write!(f, "Attribute")
590    }
591}