1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gsk.GLShader;
26 
27 private import glib.Bytes;
28 private import glib.ConstructionException;
29 private import glib.ErrorG;
30 private import glib.GException;
31 private import glib.Str;
32 private import glib.c.functions;
33 private import gobject.ObjectG;
34 private import graphene.Vec2;
35 private import graphene.Vec3;
36 private import graphene.Vec4;
37 private import gsk.Renderer;
38 private import gsk.c.functions;
39 public  import gsk.c.types;
40 
41 
42 /**
43  * A `GskGLShader` is a snippet of GLSL that is meant to run in the
44  * fragment shader of the rendering pipeline.
45  * 
46  * A fragment shader gets the coordinates being rendered as input and
47  * produces the pixel values for that particular pixel. Additionally,
48  * the shader can declare a set of other input arguments, called
49  * uniforms (as they are uniform over all the calls to your shader in
50  * each instance of use). A shader can also receive up to 4
51  * textures that it can use as input when producing the pixel data.
52  * 
53  * `GskGLShader` is usually used with gtk_snapshot_push_gl_shader()
54  * to produce a [class@Gsk.GLShaderNode] in the rendering hierarchy,
55  * and then its input textures are constructed by rendering the child
56  * nodes to textures before rendering the shader node itself. (You can
57  * pass texture nodes as children if you want to directly use a texture
58  * as input).
59  * 
60  * The actual shader code is GLSL code that gets combined with
61  * some other code into the fragment shader. Since the exact
62  * capabilities of the GPU driver differs between different OpenGL
63  * drivers and hardware, GTK adds some defines that you can use
64  * to ensure your GLSL code runs on as many drivers as it can.
65  * 
66  * If the OpenGL driver is GLES, then the shader language version
67  * is set to 100, and GSK_GLES will be defined in the shader.
68  * 
69  * Otherwise, if the OpenGL driver does not support the 3.2 core profile,
70  * then the shader will run with language version 110 for GL2 and 130 for GL3,
71  * and GSK_LEGACY will be defined in the shader.
72  * 
73  * If the OpenGL driver supports the 3.2 code profile, it will be used,
74  * the shader language version is set to 150, and GSK_GL3 will be defined
75  * in the shader.
76  * 
77  * The main function the shader must implement is:
78  * 
79  * ```glsl
80  * void mainImage(out vec4 fragColor,
81  * in vec2 fragCoord,
82  * in vec2 resolution,
83  * in vec2 uv)
84  * ```
85  * 
86  * Where the input @fragCoord is the coordinate of the pixel we're
87  * currently rendering, relative to the boundary rectangle that was
88  * specified in the `GskGLShaderNode`, and @resolution is the width and
89  * height of that rectangle. This is in the typical GTK coordinate
90  * system with the origin in the top left. @uv contains the u and v
91  * coordinates that can be used to index a texture at the
92  * corresponding point. These coordinates are in the [0..1]x[0..1]
93  * region, with 0, 0 being in the lower left corder (which is typical
94  * for OpenGL).
95  * 
96  * The output @fragColor should be a RGBA color (with
97  * premultiplied alpha) that will be used as the output for the
98  * specified pixel location. Note that this output will be
99  * automatically clipped to the clip region of the glshader node.
100  * 
101  * In addition to the function arguments the shader can define
102  * up to 4 uniforms for textures which must be called u_textureN
103  * (i.e. u_texture1 to u_texture4) as well as any custom uniforms
104  * you want of types int, uint, bool, float, vec2, vec3 or vec4.
105  * 
106  * All textures sources contain premultiplied alpha colors, but if some
107  * there are outer sources of colors there is a gsk_premultiply() helper
108  * to compute premultiplication when needed.
109  * 
110  * Note that GTK parses the uniform declarations, so each uniform has to
111  * be on a line by itself with no other code, like so:
112  * 
113  * ```glsl
114  * uniform float u_time;
115  * uniform vec3 u_color;
116  * uniform sampler2D u_texture1;
117  * uniform sampler2D u_texture2;
118  * ```
119  * 
120  * GTK uses the the "gsk" namespace in the symbols it uses in the
121  * shader, so your code should not use any symbols with the prefix gsk
122  * or GSK. There are some helper functions declared that you can use:
123  * 
124  * ```glsl
125  * vec4 GskTexture(sampler2D sampler, vec2 texCoords);
126  * ```
127  * 
128  * This samples a texture (e.g. u_texture1) at the specified
129  * coordinates, and containes some helper ifdefs to ensure that
130  * it works on all OpenGL versions.
131  * 
132  * You can compile the shader yourself using [method@Gsk.GLShader.compile],
133  * otherwise the GSK renderer will do it when it handling the glshader
134  * node. If errors occurs, the returned @error will include the glsl
135  * sources, so you can see what GSK was passing to the compiler. You
136  * can also set GSK_DEBUG=shaders in the environment to see the sources
137  * and other relevant information about all shaders that GSK is handling.
138  * 
139  * # An example shader
140  * 
141  * ```glsl
142  * uniform float position;
143  * uniform sampler2D u_texture1;
144  * uniform sampler2D u_texture2;
145  * 
146  * void mainImage(out vec4 fragColor,
147  * in vec2 fragCoord,
148  * in vec2 resolution,
149  * in vec2 uv) {
150  * vec4 source1 = GskTexture(u_texture1, uv);
151  * vec4 source2 = GskTexture(u_texture2, uv);
152  * 
153  * fragColor = position * source1 + (1.0 - position) * source2;
154  * }
155  * ```
156  */
157 public class GLShader : ObjectG
158 {
159 	/** the main Gtk struct */
160 	protected GskGLShader* gskGLShader;
161 
162 	/** Get the main Gtk struct */
163 	public GskGLShader* getGLShaderStruct(bool transferOwnership = false)
164 	{
165 		if (transferOwnership)
166 			ownedRef = false;
167 		return gskGLShader;
168 	}
169 
170 	/** the main Gtk struct as a void* */
171 	protected override void* getStruct()
172 	{
173 		return cast(void*)gskGLShader;
174 	}
175 
176 	/**
177 	 * Sets our main struct and passes it to the parent class.
178 	 */
179 	public this (GskGLShader* gskGLShader, bool ownedRef = false)
180 	{
181 		this.gskGLShader = gskGLShader;
182 		super(cast(GObject*)gskGLShader, ownedRef);
183 	}
184 
185 
186 	/** */
187 	public static GType getType()
188 	{
189 		return gsk_gl_shader_get_type();
190 	}
191 
192 	/**
193 	 * Creates a `GskGLShader` that will render pixels using the specified code.
194 	 *
195 	 * Params:
196 	 *     sourcecode = GLSL sourcecode for the shader, as a `GBytes`
197 	 *
198 	 * Returns: A new `GskGLShader`
199 	 *
200 	 * Throws: ConstructionException GTK+ fails to create the object.
201 	 */
202 	public this(Bytes sourcecode)
203 	{
204 		auto __p = gsk_gl_shader_new_from_bytes((sourcecode is null) ? null : sourcecode.getBytesStruct());
205 
206 		if(__p is null)
207 		{
208 			throw new ConstructionException("null returned by new_from_bytes");
209 		}
210 
211 		this(cast(GskGLShader*) __p, true);
212 	}
213 
214 	/**
215 	 * Creates a `GskGLShader` that will render pixels using the specified code.
216 	 *
217 	 * Params:
218 	 *     resourcePath = path to a resource that contains the GLSL sourcecode for
219 	 *         the shader
220 	 *
221 	 * Returns: A new `GskGLShader`
222 	 *
223 	 * Throws: ConstructionException GTK+ fails to create the object.
224 	 */
225 	public this(string resourcePath)
226 	{
227 		auto __p = gsk_gl_shader_new_from_resource(Str.toStringz(resourcePath));
228 
229 		if(__p is null)
230 		{
231 			throw new ConstructionException("null returned by new_from_resource");
232 		}
233 
234 		this(cast(GskGLShader*) __p, true);
235 	}
236 
237 	/**
238 	 * Tries to compile the @shader for the given @renderer.
239 	 *
240 	 * If there is a problem, this function returns %FALSE and reports
241 	 * an error. You should use this function before relying on the shader
242 	 * for rendering and use a fallback with a simpler shader or without
243 	 * shaders if it fails.
244 	 *
245 	 * Note that this will modify the rendering state (for example
246 	 * change the current GL context) and requires the renderer to be
247 	 * set up. This means that the widget has to be realized. Commonly you
248 	 * want to call this from the realize signal of a widget, or during
249 	 * widget snapshot.
250 	 *
251 	 * Params:
252 	 *     renderer = a `GskRenderer`
253 	 *
254 	 * Returns: %TRUE on success, %FALSE if an error occurred
255 	 *
256 	 * Throws: GException on failure.
257 	 */
258 	public bool compile(Renderer renderer)
259 	{
260 		GError* err = null;
261 
262 		auto __p = gsk_gl_shader_compile(gskGLShader, (renderer is null) ? null : renderer.getRendererStruct(), &err) != 0;
263 
264 		if (err !is null)
265 		{
266 			throw new GException( new ErrorG(err) );
267 		}
268 
269 		return __p;
270 	}
271 
272 	/**
273 	 * Looks for a uniform by the name @name, and returns the index
274 	 * of the uniform, or -1 if it was not found.
275 	 *
276 	 * Params:
277 	 *     name = uniform name
278 	 *
279 	 * Returns: The index of the uniform, or -1
280 	 */
281 	public int findUniformByName(string name)
282 	{
283 		return gsk_gl_shader_find_uniform_by_name(gskGLShader, Str.toStringz(name));
284 	}
285 
286 	/**
287 	 * Formats the uniform data as needed for feeding the named uniforms
288 	 * values into the shader.
289 	 *
290 	 * The argument list is a list of pairs of names, and values for the
291 	 * types that match the declared uniforms (i.e. double/int/guint/gboolean
292 	 * for primitive values and `graphene_vecN_t *` for vecN uniforms).
293 	 *
294 	 * It is an error to pass a uniform name that is not declared by the shader.
295 	 *
296 	 * Any uniforms of the shader that are not included in the argument list
297 	 * are zero-initialized.
298 	 *
299 	 * Params:
300 	 *     uniforms = name-Value pairs for the uniforms of @shader, ending
301 	 *         with a %NULL name
302 	 *
303 	 * Returns: A newly allocated block of data which can be
304 	 *     passed to [ctor@Gsk.GLShaderNode.new].
305 	 */
306 	public Bytes formatArgsVa(void* uniforms)
307 	{
308 		auto __p = gsk_gl_shader_format_args_va(gskGLShader, uniforms);
309 
310 		if(__p is null)
311 		{
312 			return null;
313 		}
314 
315 		return new Bytes(cast(GBytes*) __p, true);
316 	}
317 
318 	/**
319 	 * Gets the value of the uniform @idx in the @args block.
320 	 *
321 	 * The uniform must be of bool type.
322 	 *
323 	 * Params:
324 	 *     args = uniform arguments
325 	 *     idx = index of the uniform
326 	 *
327 	 * Returns: The value
328 	 */
329 	public bool getArgBool(Bytes args, int idx)
330 	{
331 		return gsk_gl_shader_get_arg_bool(gskGLShader, (args is null) ? null : args.getBytesStruct(), idx) != 0;
332 	}
333 
334 	/**
335 	 * Gets the value of the uniform @idx in the @args block.
336 	 *
337 	 * The uniform must be of float type.
338 	 *
339 	 * Params:
340 	 *     args = uniform arguments
341 	 *     idx = index of the uniform
342 	 *
343 	 * Returns: The value
344 	 */
345 	public float getArgFloat(Bytes args, int idx)
346 	{
347 		return gsk_gl_shader_get_arg_float(gskGLShader, (args is null) ? null : args.getBytesStruct(), idx);
348 	}
349 
350 	/**
351 	 * Gets the value of the uniform @idx in the @args block.
352 	 *
353 	 * The uniform must be of int type.
354 	 *
355 	 * Params:
356 	 *     args = uniform arguments
357 	 *     idx = index of the uniform
358 	 *
359 	 * Returns: The value
360 	 */
361 	public int getArgInt(Bytes args, int idx)
362 	{
363 		return gsk_gl_shader_get_arg_int(gskGLShader, (args is null) ? null : args.getBytesStruct(), idx);
364 	}
365 
366 	/**
367 	 * Gets the value of the uniform @idx in the @args block.
368 	 *
369 	 * The uniform must be of uint type.
370 	 *
371 	 * Params:
372 	 *     args = uniform arguments
373 	 *     idx = index of the uniform
374 	 *
375 	 * Returns: The value
376 	 */
377 	public uint getArgUint(Bytes args, int idx)
378 	{
379 		return gsk_gl_shader_get_arg_uint(gskGLShader, (args is null) ? null : args.getBytesStruct(), idx);
380 	}
381 
382 	/**
383 	 * Gets the value of the uniform @idx in the @args block.
384 	 *
385 	 * The uniform must be of vec2 type.
386 	 *
387 	 * Params:
388 	 *     args = uniform arguments
389 	 *     idx = index of the uniform
390 	 *     outValue = location to store the uniform value in
391 	 */
392 	public void getArgVec2(Bytes args, int idx, Vec2 outValue)
393 	{
394 		gsk_gl_shader_get_arg_vec2(gskGLShader, (args is null) ? null : args.getBytesStruct(), idx, (outValue is null) ? null : outValue.getVec2Struct());
395 	}
396 
397 	/**
398 	 * Gets the value of the uniform @idx in the @args block.
399 	 *
400 	 * The uniform must be of vec3 type.
401 	 *
402 	 * Params:
403 	 *     args = uniform arguments
404 	 *     idx = index of the uniform
405 	 *     outValue = location to store the uniform value in
406 	 */
407 	public void getArgVec3(Bytes args, int idx, Vec3 outValue)
408 	{
409 		gsk_gl_shader_get_arg_vec3(gskGLShader, (args is null) ? null : args.getBytesStruct(), idx, (outValue is null) ? null : outValue.getVec3Struct());
410 	}
411 
412 	/**
413 	 * Gets the value of the uniform @idx in the @args block.
414 	 *
415 	 * The uniform must be of vec4 type.
416 	 *
417 	 * Params:
418 	 *     args = uniform arguments
419 	 *     idx = index of the uniform
420 	 *     outValue = location to store set the uniform value in
421 	 */
422 	public void getArgVec4(Bytes args, int idx, Vec4 outValue)
423 	{
424 		gsk_gl_shader_get_arg_vec4(gskGLShader, (args is null) ? null : args.getBytesStruct(), idx, (outValue is null) ? null : outValue.getVec4Struct());
425 	}
426 
427 	/**
428 	 * Get the size of the data block used to specify arguments for this shader.
429 	 *
430 	 * Returns: The size of the data block
431 	 */
432 	public size_t getArgsSize()
433 	{
434 		return gsk_gl_shader_get_args_size(gskGLShader);
435 	}
436 
437 	/**
438 	 * Returns the number of textures that the shader requires.
439 	 *
440 	 * This can be used to check that the a passed shader works
441 	 * in your usecase. It is determined by looking at the highest
442 	 * u_textureN value that the shader defines.
443 	 *
444 	 * Returns: The number of texture inputs required by @shader
445 	 */
446 	public int getNTextures()
447 	{
448 		return gsk_gl_shader_get_n_textures(gskGLShader);
449 	}
450 
451 	/**
452 	 * Get the number of declared uniforms for this shader.
453 	 *
454 	 * Returns: The number of declared uniforms
455 	 */
456 	public int getNUniforms()
457 	{
458 		return gsk_gl_shader_get_n_uniforms(gskGLShader);
459 	}
460 
461 	/**
462 	 * Gets the resource path for the GLSL sourcecode being used
463 	 * to render this shader.
464 	 *
465 	 * Returns: The resource path for the shader,
466 	 *     or %NULL if none.
467 	 */
468 	public string getResource()
469 	{
470 		return Str.toString(gsk_gl_shader_get_resource(gskGLShader));
471 	}
472 
473 	/**
474 	 * Gets the GLSL sourcecode being used to render this shader.
475 	 *
476 	 * Returns: The source code for the shader
477 	 */
478 	public Bytes getSource()
479 	{
480 		auto __p = gsk_gl_shader_get_source(gskGLShader);
481 
482 		if(__p is null)
483 		{
484 			return null;
485 		}
486 
487 		return new Bytes(cast(GBytes*) __p);
488 	}
489 
490 	/**
491 	 * Get the name of the declared uniform for this shader at index @idx.
492 	 *
493 	 * Params:
494 	 *     idx = index of the uniform
495 	 *
496 	 * Returns: The name of the declared uniform
497 	 */
498 	public string getUniformName(int idx)
499 	{
500 		return Str.toString(gsk_gl_shader_get_uniform_name(gskGLShader, idx));
501 	}
502 
503 	/**
504 	 * Get the offset into the data block where data for this uniforms is stored.
505 	 *
506 	 * Params:
507 	 *     idx = index of the uniform
508 	 *
509 	 * Returns: The data offset
510 	 */
511 	public int getUniformOffset(int idx)
512 	{
513 		return gsk_gl_shader_get_uniform_offset(gskGLShader, idx);
514 	}
515 
516 	/**
517 	 * Get the type of the declared uniform for this shader at index @idx.
518 	 *
519 	 * Params:
520 	 *     idx = index of the uniform
521 	 *
522 	 * Returns: The type of the declared uniform
523 	 */
524 	public GskGLUniformType getUniformType(int idx)
525 	{
526 		return gsk_gl_shader_get_uniform_type(gskGLShader, idx);
527 	}
528 }