About all my projects
Gnome::Gsk4::GLShader

Gnome::Gsk4::GLShader

Description

A Gnome::Gsk4::GLShader is a snippet of GLSL that is meant to run in the fragment shader of the rendering pipeline.

A fragment shader gets the coordinates being rendered as input and produces the pixel values for that particular pixel. Additionally, the shader can declare a set of other input arguments, called uniforms (as they are uniform over all the calls to your shader in each instance of use). A shader can also receive up to 4 textures that it can use as input when producing the pixel data.

Gnome::Gsk4::GLShader is usually used with gtk_snapshot_push_gl_shader() to produce a Gnome::Gsk4::GLShaderNode in the rendering hierarchy, and then its input textures are constructed by rendering the child nodes to textures before rendering the shader node itself. (You can pass texture nodes as children if you want to directly use a texture as input).

The actual shader code is GLSL code that gets combined with some other code into the fragment shader. Since the exact capabilities of the GPU driver differs between different OpenGL drivers and hardware, GTK adds some defines that you can use to ensure your GLSL code runs on as many drivers as it can.

If the OpenGL driver is GLES, then the shader language version is set to 100, and GSK_GLES will be defined in the shader.

Otherwise, if the OpenGL driver does not support the 3.2 core profile, then the shader will run with language version 110 for GL2 and 130 for GL3, and GSK_LEGACY will be defined in the shader.

If the OpenGL driver supports the 3.2 code profile, it will be used, the shader language version is set to 150, and GSK_GL3 will be defined in the shader.

The main function the shader must implement is:

Where the input $fragCoord is the coordinate of the pixel we're currently rendering, relative to the boundary rectangle that was specified in the Gnome::Gsk4::GLShaderNode, and $resolution is the width and height of that rectangle. This is in the typical GTK coordinate system with the origin in the top left. $uv contains the u and v coordinates that can be used to index a texture at the corresponding point. These coordinates are in the [0..1]x[0..1] region, with 0, 0 being in the lower left corder (which is typical for OpenGL).

The output $fragColor should be a RGBA color (with premultiplied alpha) that will be used as the output for the specified pixel location. Note that this output will be automatically clipped to the clip region of the glshader node.

In addition to the function arguments the shader can define up to 4 uniforms for textures which must be called u_textureN (i.e. u_texture1 to u_texture4) as well as any custom uniforms you want of types int, uint, bool, float, vec2, vec3 or vec4.

All textures sources contain premultiplied alpha colors, but if some there are outer sources of colors there is a gsk_premultiply() helper to compute premultiplication when needed.

Note that GTK parses the uniform declarations, so each uniform has to be on a line by itself with no other code, like so:

GTK uses the "gsk" namespace in the symbols it uses in the shader, so your code should not use any symbols with the prefix gsk or GSK. There are some helper functions declared that you can use:

This samples a texture (e.g. u_texture1) at the specified coordinates, and containes some helper ifdefs to ensure that it works on all OpenGL versions.

You can compile the shader yourself using .compile(), otherwise the GSK renderer will do it when it handling the glshader node. If errors occurs, the returned $error will include the glsl sources, so you can see what GSK was passing to the compiler. You can also set GSK_DEBUG=shaders in the environment to see the sources and other relevant information about all shaders that GSK is handling.

An example shader

Class initialization

new

:native-object

Create an object using a native object from elsewhere. See also Gnome::N::TopLevelSupportClass.

multi method new ( N-Object :$native-object! )

new-from-bytes

Creates a Gnome::Gsk4::GLShader that will render pixels using the specified code.

method new-from-bytes ( N-Object $sourcecode --> Gnome::Gsk4::GLShader \)
  • $sourcecode; GLSL sourcecode for the shader, as a Gnome::Glib::N-Bytes

new-from-resource

Creates a Gnome::Gsk4::GLShader that will render pixels using the specified code.

method new-from-resource ( Str $resource-path --> Gnome::Gsk4::GLShader \)
  • $resource-path; path to a resource that contains the GLSL sourcecode for the shader.

Methods

compile

Tries to compile the $shader for the given $renderer.

If there is a problem, this function returns False and reports an error. You should use this function before relying on the shader for rendering and use a fallback with a simpler shader or without shaders if it fails.

Note that this will modify the rendering state (for example change the current GL context) and requires the renderer to be set up. This means that the widget has to be realized. Commonly you want to call this from the realize signal of a widget, or during widget snapshot.

method compile ( N-Object() $renderer, CArray[N-Error] $err --> Bool )
  • $renderer; a Gnome::Gsk4::Renderer.

  • $err; Error object. When defined, an error can be returned when there is one. Use Pointer when you want to ignore the error. .

Return value; True on success, False if an error occurred.

find-uniform-by-name

Looks for a uniform by the name $name, and returns the index of the uniform, or -1 if it was not found.

method find-uniform-by-name ( Str $name --> Int )
  • $name; uniform name.

Return value; The index of the uniform, or -1.

format-args This function is not yet available

Formats the uniform data as needed for feeding the named uniforms values into the shader.

The argument list is a list of pairs of names, and values for the types that match the declared uniforms (i.e. double/int/guint/gboolean for primitive values and graphene_vecN_t *` for vecN uniforms).

Any uniforms of the shader that are not included in the argument list are zero-initialized.

method format-args ( … --> N-Object )
  • …; …. Note that each argument must be specified as a type followed by its value!

Return value; A newly allocated block of data which can be passed to .newglshader() in class Gnome::Gsk4::GLShaderNode..

format-args-va This function is not yet available

Formats the uniform data as needed for feeding the named uniforms values into the shader.

The argument list is a list of pairs of names, and values for the types that match the declared uniforms (i.e. double/int/guint/gboolean for primitive values and graphene_vecN_t *` for vecN uniforms).

It is an error to pass a uniform name that is not declared by the shader.

Any uniforms of the shader that are not included in the argument list are zero-initialized.

method format-args-va ( … --> N-Object )
  • uniforms; name-Value pairs for the uniforms of $shader, ending with a undefined name. Note that each argument must be specified as a type followed by its value!

Return value; A newly allocated block of data which can be passed to .newglshader() in class Gnome::Gsk4::GLShaderNode..

get-arg-bool

Gets the value of the uniform $idx in the $args block.

The uniform must be of bool type.

method get-arg-bool ( N-Object $args, Int() $idx --> Bool )
  • $args; uniform arguments

  • $idx; index of the uniform.

Return value; The value.

get-arg-float

Gets the value of the uniform $idx in the $args block.

The uniform must be of float type.

method get-arg-float ( N-Object $args, Int() $idx --> Num )
  • $args; uniform arguments

  • $idx; index of the uniform.

Return value; The value.

get-arg-int

Gets the value of the uniform $idx in the $args block.

The uniform must be of int type.

method get-arg-int ( N-Object $args, Int() $idx --> Int )
  • $args; uniform arguments

  • $idx; index of the uniform.

Return value; The value.

get-arg-uint

Gets the value of the uniform $idx in the $args block.

The uniform must be of uint type.

method get-arg-uint ( N-Object $args, Int() $idx --> UInt )
  • $args; uniform arguments

  • $idx; index of the uniform.

Return value; The value.

get-arg-vec2

Gets the value of the uniform $idx in the $args block.

The uniform must be of vec2 type.

method get-arg-vec2 ( N-Object $args, Int() $idx, N-Object $out-value )
  • $args; uniform arguments

  • $idx; index of the uniform.

  • $out-value; location to store the uniform value in

get-arg-vec3

Gets the value of the uniform $idx in the $args block.

The uniform must be of vec3 type.

method get-arg-vec3 ( N-Object $args, Int() $idx, N-Object $out-value )
  • $args; uniform arguments

  • $idx; index of the uniform.

  • $out-value; location to store the uniform value in

get-arg-vec4

Gets the value of the uniform $idx in the $args block.

The uniform must be of vec4 type.

method get-arg-vec4 ( N-Object $args, Int() $idx, N-Object $out-value )
  • $args; uniform arguments

  • $idx; index of the uniform.

  • $out-value; location to store set the uniform value in

get-args-size

Get the size of the data block used to specify arguments for this shader.

method get-args-size (--> Int )

Return value; The size of the data block.

get-n-textures

Returns the number of textures that the shader requires.

This can be used to check that the a passed shader works in your usecase. It is determined by looking at the highest u_textureN value that the shader defines.

method get-n-textures (--> Int )

Return value; The number of texture inputs required by $shader.

get-n-uniforms

Get the number of declared uniforms for this shader.

method get-n-uniforms (--> Int )

Return value; The number of declared uniforms.

get-resource

Gets the resource path for the GLSL sourcecode being used to render this shader.

method get-resource (--> Str )

Return value; The resource path for the shader.

get-source

Gets the GLSL sourcecode being used to render this shader.

method get-source (--> N-Object )

Return value; The source code for the shader.

get-uniform-name

Get the name of the declared uniform for this shader at index $idx.

method get-uniform-name ( Int() $idx --> Str )
  • $idx; index of the uniform.

Return value; The name of the declared uniform.

get-uniform-offset

Get the offset into the data block where data for this uniforms is stored.

method get-uniform-offset ( Int() $idx --> Int )
  • $idx; index of the uniform.

Return value; The data offset.

get-uniform-type

Get the type of the declared uniform for this shader at index $idx.

method get-uniform-type ( Int() $idx --> GskGLUniformType )
  • $idx; index of the uniform.

Return value; The type of the declared uniform.