ux-dx 0.2.1

3D Graphics Primitives for Angular Rust
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
#![allow(
    clippy::too_many_arguments,
    clippy::let_and_return,
    clippy::from_over_into
)]

use super::SnippetHook;
use std::fmt;

// @short_description: Functions for creating and manipulating shader snippets
//
// #Snippets are used to modify or replace parts of a
// #Pipeline using GLSL. GLSL is a programming language supported
// by OpenGL on programmable hardware to provide a more flexible
// description of what should be rendered. A description of GLSL
// itself is outside the scope of this documentation but any good
// OpenGL book should help to describe it.
//
// Unlike in OpenGL, when using GLSL with  it is possible to write
// short snippets to replace small sections of the pipeline instead of
// having to replace the whole of either the vertex or fragment
// pipelines. Of course it is also possible to replace the whole of
// the pipeline if needed.
//
// Each snippet is a standalone chunk of code which would attach to
// the pipeline at a particular point. The code is split into four
// separate strings (all of which are optional):
//
//   declarations
//
// The code in this string will be inserted outside of any fn in
// the global scope of the shader. This can be used to declare
// uniforms, attributes, varyings and functions to be used by the
// snippet.
//
//   pre
//
// The code in this string will be inserted before the hook point.
//
//   post
//
// The code in this string will be inserted after the hook point. This
// can be used to modify the results of the builtin generated code for
// that hook point.
//
//   replace
//
// If present the code in this string will replace the generated code
// for the hook point.
//
//
// All of the strings apart from the declarations string of a pipeline
// are generated in a single fn so they can share variables
// declared from one string in another. The scope of the code is
// limited to each snippet so local variables declared in the snippet
// will not collide with variables declared in another
// snippet. However, code in the 'declarations' string is global to
// the shader so it is the application's responsibility to ensure that
// variables declared here will not collide with those from other
// snippets.
//
// The snippets can be added to a pipeline with
// pipeline_add_snippet() or
// pipeline_add_layer_snippet(). Which fn to use depends on
// which hook the snippet is targetting. The snippets are all
// generated in the order they are added to the pipeline. That is, the
// post strings are executed in the order they are added to the
// pipeline and the pre strings are executed in reverse order. If any
// replace strings are given for a snippet then any other snippets
// with the same hook added before that snippet will be ignored. The
// different hooks are documented under #SnippetHook.
//
// For portability with GLES2, it is recommended not to use the GLSL
// builtin names such as gl_FragColor. Instead there are replacement
// names under the * namespace which can be used instead. These
// are:
//
//   uniform mat4
//         modelview_matrix
//
//    The current modelview matrix. This is equivalent to
//    #gl_ModelViewMatrix.
//
//   uniform mat4
//         projection_matrix
//
//    The current projection matrix. This is equivalent to
//    #gl_ProjectionMatrix.
//
//   uniform mat4
//         modelview_projection_matrix
//
//    The combined modelview and projection matrix. A vertex shader
//    would typically use this to transform the incoming vertex
//    position. The separate modelview and projection matrices are
//    usually only needed for lighting calculations. This is
//    equivalent to #gl_ModelViewProjectionMatrix.
//
//   uniform mat4
//         texture_matrix[]
//
//    An array of matrices for transforming the texture
//    coordinates. This is equivalent to #gl_TextureMatrix.
//
//
// In a vertex shader, the following are also available:
//
//   attribute vec4
//         position_in
//
//    The incoming vertex position. This is equivalent to #gl_Vertex.
//
//   attribute vec4
//         color_in
//
//    The incoming vertex color. This is equivalent to #gl_Color.
//
//   attribute vec4
//         tex_coord_in
//
//    The texture coordinate for layer 0. This is an alternative name
//    for #tex_coord0_in.
//
//   attribute vec4
//         tex_coord0_in
//
//    The texture coordinate for the layer 0. This is equivalent to
//    #gl_MultiTexCoord0. There will also be #tex_coord1_in and
//    so on if more layers are added to the pipeline.
//
//   attribute vec3
//         normal_in
//
//    The normal of the vertex. This is equivalent to #gl_Normal.
//
//   vec4
//         position_out
//
//    The calculated position of the vertex. This must be written to
//    in all vertex shaders. This is equivalent to #gl_Position.
//
//   float
//         point_size_in
//
//    The incoming point size from the point_size_in attribute.
//    This is only available if
//    pipeline_set_per_vertex_point_size() is set on the
//    pipeline.
//
//   float
//         point_size_out
//
//    The calculated size of a point. This is equivalent to #gl_PointSize.
//
//   varying vec4
//         color_out
//
//    The calculated color of a vertex. This is equivalent to #gl_FrontColor.
//
//   varying vec4
//         tex_coord0_out
//
//    The calculated texture coordinate for layer 0 of the pipeline.
//    This is equivalent to #gl_TexCoord[0]. There will also be
//    #tex_coord1_out and so on if more layers are added to the
//    pipeline. In the fragment shader, this varying is called
//    #tex_coord0_in.
//
//
// In a fragment shader, the following are also available:
//
//   varying vec4 color_in
//
//    The calculated color of a vertex. This is equivalent to #gl_FrontColor.
//
//   varying vec4
//              tex_coord0_in
//
//    The texture coordinate for layer 0. This is equivalent to
//    #gl_TexCoord[0]. There will also be #tex_coord1_in and so
//    on if more layers are added to the pipeline.
//
//   vec4 color_out
//
//    The final calculated color of the fragment. All fragment shaders
//    must write to this variable. This is equivalent to
//    #gl_FrontColor.
//
//   float depth_out
//
//    An optional output variable specifying the depth value to use
//    for this fragment. This is equivalent to #gl_FragDepth.
//
//   bool front_facing
//
//    A readonly variable that will be true if the current primitive
//    is front facing. This can be used to implement two-sided
//    coloring algorithms. This is equivalent to #gl_FrontFacing.
//
//   vec2 point_coord
//
//    When rendering points, this will contain a vec2 which represents
//    the position within the point of the current fragment.
//    vec2(0.0,0.0) will be the topleft of the point and vec2(1.0,1.0)
//    will be the bottom right. Note that there is currently a bug in
//     where when rendering to an offscreen buffer these
//    coordinates will be upside-down. The value is undefined when not
//    rendering points. This builtin can only be used if the
//    %FEATURE_ID_POINT_SPRITE feature is available.
//
//
// Here is an example of using a snippet to add a desaturate effect to the
// generated color on a pipeline.
//
// <programlisting>
//   Pipeline *pipeline = pipeline_new ();
//
//   /* Set up the pipeline here, ie by adding a texture or other
//      layers */
//
//   /* Create the snippet. The first string is the declarations which
//      we will use to add a uniform. The second is the 'post' string which
//      will contain the code to perform the desaturation. */
//   Snippet *snippet =
//     snippet_new (SNIPPET_HOOK_FRAGMENT,
//                       "uniform float factor;",
//                       "float gray = dot (vec3 (0.299, 0.587, 0.114), "
//                       "                  color_out.rgb);"
//                       "color_out.rgb = mix (vec3 (gray),"
//                       "                          color_out.rgb,"
//                       "                          factor);");
//
//   /* Add it to the pipeline */
//   pipeline_add_snippet (pipeline, snippet);
//   /* The pipeline keeps a reference to the snippet
//      so we don't need to */
//   object_unref (snippet);
//
//   /* Update the custom uniform on the pipeline */
//   int location = pipeline_get_uniform_location (pipeline, "factor");
//   pipeline_set_uniform_1f (pipeline, location, 0.5f);
//
//   /* Now we can render with the snippet as usual */
//   push_source (pipeline);
//   rectangle (0, 0, 10, 10);
//   pop_source ();
// </programlisting>
pub struct Snippet {
    hook: SnippetHook,

    // This is set to true the first time the snippet is attached to the
    // pipeline. After that any attempts to modify the snippet will be ignored.
    immutable: bool,

    declarations: String,
    pre: String,
    replace: String,
    post: String,
}

impl Snippet {
    /// Allocates and initializes a new snippet with the given source strings.
    /// ## `hook`
    /// The point in the pipeline that this snippet will wrap around
    ///  or replace.
    /// ## `declarations`
    /// The source code for the declarations for this
    ///  snippet or `None`. See `Snippet::set_declarations`.
    /// ## `post`
    /// The source code to run after the hook point where this
    ///  shader snippet is attached or `None`. See `Snippet::set_post`.
    ///
    /// # Returns
    ///
    /// a pointer to a new `Snippet`
    pub fn new(hook: SnippetHook, declarations: &str, post: &str) -> Snippet {
        // Snippet *snippet = g_slice_new0 (Snippet);

        // _snippet_object_new (snippet);

        // snippet->hook = hook;

        // snippet_set_declarations (snippet, declarations);
        // snippet_set_post (snippet, post);

        // return snippet;
        unimplemented!()
    }

    ///
    /// # Returns
    ///
    /// the source string that was set with
    ///  `Snippet::set_declarations` or `None` if none was set.
    pub fn declarations(&self) -> Option<String> {
        // _RETURN_VAL_IF_FAIL (is_snippet (snippet), NULL);

        // return snippet->declarations;
        unimplemented!()
    }

    ///
    /// # Returns
    ///
    /// the hook that was set when `Snippet::new` was
    ///  called.
    pub fn hook(&self) -> SnippetHook {
        // _RETURN_VAL_IF_FAIL (is_snippet (snippet), 0);

        // return snippet->hook;
        unimplemented!()
    }

    ///
    /// # Returns
    ///
    /// the source string that was set with
    ///  `Snippet::set_post` or `None` if none was set.
    pub fn post(&self) -> Option<String> {
        // _RETURN_VAL_IF_FAIL (is_snippet (snippet), NULL);

        // return snippet->post;
        unimplemented!()
    }

    ///
    /// # Returns
    ///
    /// the source string that was set with
    ///  `Snippet::set_pre` or `None` if none was set.
    pub fn pre(&self) -> Option<String> {
        // _RETURN_VAL_IF_FAIL (is_snippet (snippet), NULL);

        // return snippet->pre;
        unimplemented!()
    }

    ///
    /// # Returns
    ///
    /// the source string that was set with
    ///  `Snippet::set_replace` or `None` if none was set.
    pub fn replace(&self) -> Option<String> {
        // _RETURN_VAL_IF_FAIL (is_snippet (snippet), NULL);

        // return snippet->replace;
        unimplemented!()
    }

    /// Sets a source string that will be inserted in the global scope of
    /// the generated shader when this snippet is used on a pipeline. This
    /// string is typically used to declare uniforms, attributes or
    /// functions that will be used by the other parts of the snippets.
    ///
    /// This fn should only be called before the snippet is attached
    /// to its first pipeline. After that the snippet should be considered
    /// immutable.
    /// ## `declarations`
    /// The new source string for the declarations section
    ///  of this snippet.
    pub fn set_declarations(&self, declarations: &str) {
        // _RETURN_IF_FAIL (is_snippet (snippet));

        // if (!_snippet_modify (snippet))
        //     return;

        // g_free (snippet->declarations);
        // snippet->declarations = declarations ? g_strdup (declarations) : NULL;
        unimplemented!()
    }

    /// Sets a source string that will be inserted after the hook point in
    /// the generated shader for the pipeline that this snippet is attached
    /// to. Please see the documentation of each hook point in
    /// `Pipeline` for a description of how this string should be used.
    ///
    /// This fn should only be called before the snippet is attached
    /// to its first pipeline. After that the snippet should be considered
    /// immutable.
    /// ## `post`
    /// The new source string for the post section of this snippet.
    pub fn set_post(&self, post: &str) {
        // _RETURN_IF_FAIL (is_snippet (snippet));

        // if (!_snippet_modify (snippet))
        //   return;

        // g_free (snippet->post);
        // snippet->post = post ? g_strdup (post) : NULL;
        unimplemented!()
    }

    /// Sets a source string that will be inserted before the hook point in
    /// the generated shader for the pipeline that this snippet is attached
    /// to. Please see the documentation of each hook point in
    /// `Pipeline` for a description of how this string should be used.
    ///
    /// This fn should only be called before the snippet is attached
    /// to its first pipeline. After that the snippet should be considered
    /// immutable.
    /// ## `pre`
    /// The new source string for the pre section of this snippet.
    pub fn set_pre(&self, pre: &str) {
        // _RETURN_IF_FAIL (is_snippet (snippet));

        // if (!_snippet_modify (snippet))
        //   return;

        // g_free (snippet->pre);
        // snippet->pre = pre ? g_strdup (pre) : NULL;
        unimplemented!()
    }

    /// Sets a source string that will be used instead of any generated
    /// source code or any previous snippets for this hook point. Please
    /// see the documentation of each hook point in `Pipeline` for a
    /// description of how this string should be used.
    ///
    /// This fn should only be called before the snippet is attached
    /// to its first pipeline. After that the snippet should be considered
    /// immutable.
    /// ## `replace`
    /// The new source string for the replace section of this snippet.
    pub fn set_replace(&self, replace: &str) {
        // _RETURN_IF_FAIL (is_snippet (snippet));

        // if (!_snippet_modify (snippet))
        //     return;

        // g_free (snippet->replace);
        // snippet->replace = replace ? g_strdup (replace) : NULL;
        unimplemented!()
    }
}

impl fmt::Display for Snippet {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Snippet")
    }
}