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}