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 }