# Shader routines

These functions are declared in the main Allegro header file:

~~~~c
 #include <allegro5/allegro.h>
~~~~

## API: ALLEGRO_SHADER

An [ALLEGRO_SHADER] is a program that runs on the GPU.
It combines both a vertex and a pixel shader.
(In OpenGL terms, an [ALLEGRO_SHADER] is actually a *program*
which has one or more *shaders* attached. This can be confusing.)

The source code for the underlying vertex or pixel shader can be provided
either as GLSL or HLSL, depending on the value of [ALLEGRO_SHADER_PLATFORM]
used when creating it.

Since: 5.1.0

## API: ALLEGRO_SHADER_TYPE

Used with [al_attach_shader_source] and [al_attach_shader_source_file] to
specify how to interpret the attached source.

ALLEGRO_VERTEX_SHADER
:   A vertex shader is executed for each vertex it is
    used with. The program will output exactly one vertex at a time.
   
    When Allegro's graphics are being used then in addition to all vertices of
    primitives from the primitives addon, each drawn bitmap also consists of
    four vertices.

ALLEGRO_PIXEL_SHADER
:   A pixel shader is executed for each pixel it is used
    with. The program will output exactly one pixel at a time - either in the
    backbuffer or in the current target bitmap.
   
    With Allegro's builtin graphics this means the shader is for example called
    for each destination pixel of the output of an [al_draw_bitmap] call.
   
    A more accurate term for pixel shader would be fragment shader since one
    final pixel in the target bitmap is not necessarily composed of only a
    single output but of multiple fragments (for example when multi-sampling is
    being used).

Since: 5.1.0

## API: ALLEGRO_SHADER_PLATFORM

The underlying platform which the [ALLEGRO_SHADER] is built on top of,
which dictates the language used to program the shader.

* ALLEGRO_SHADER_AUTO - Pick a platform automatically given the
  current display flags.
* ALLEGRO_SHADER_GLSL - OpenGL Shading Language
* ALLEGRO_SHADER_HLSL - High Level Shader Language (for Direct3D)
* ALLEGRO_SHADER_AUTO_MINIMAL - Like ALLEGRO_SHADER_AUTO, but pick a
  more minimal implementation that supports only basic alpha blending.
* ALLEGRO_SHADER_GLSL_MINIMAL - Minimal GLSL shader.
* ALLEGRO_SHADER_HLSL_MINIMAL - Minimal HLSL shader.
* ALLEGRO_SHADER_HLSL_SM_3_0 - HLSL shader using shader model 3_0.

Since: 5.1.0

## API: al_create_shader

Create a shader object.

The platform argument is one of the [ALLEGRO_SHADER_PLATFORM] values,
and specifies the type of shader object to create, and which language is
used to program the shader.

The shader platform must be compatible with the type of display that you will
use the shader with.  For example, you cannot create and use a HLSL shader on
an OpenGL display, nor a GLSL shader on a Direct3D display.

The ALLEGRO_SHADER_AUTO value automatically chooses the appropriate platform
for the display currently targeted by the calling thread; there must be such a
display.  It will create a GLSL shader for an OpenGL display, and a HLSL shader
for a Direct3D display.

Returns the shader object on success. Otherwise, returns NULL.

Since: 5.1.0

See also: [al_attach_shader_source], [al_attach_shader_source_file],
[al_build_shader], [al_use_shader], [al_destroy_shader],
[al_get_shader_platform]

## API: al_attach_shader_source

Attaches the shader's source code to the shader object and compiles it. Passing
NULL deletes the underlying (OpenGL or DirectX) shader. See also
[al_attach_shader_source_file] if you prefer to obtain your shader source from
an external file.

If you do not use ALLEGRO_PROGRAMMABLE_PIPELINE Allegro's graphics functions
will not use any shader specific functions themselves. In case of a system
with no fixed function pipeline (like OpenGL ES 2 or OpenGL 3 or 4) this means
Allegro's drawing functions cannot be used.

TODO: Is ALLEGRO_PROGRAMMABLE_PIPELINE set automatically in this case?

When ALLEGRO_PROGRAMMABLE_PIPELINE is used the following shader uniforms
are provided by Allegro and can be accessed in your shaders:

al_projview_matrix
:   matrix for Allegro's orthographic projection multiplied by the
    [al_use_transform] matrix.  The type is `mat4` in GLSL, and `float4x4` in
    HLSL.

al_use_tex
:   whether or not to use the bound texture. The type is `bool` in
    both GLSL and HLSL.

al_tex
:   the texture if one is bound. The type is `sampler2D` in GLSL and
    `texture` in HLSL.

al_use_tex_matrix
:   whether or not to use a texture matrix (used by the primitives addon).
    The type is `bool` in both GLSL and HLSL.

al_tex_matrix
:   the texture matrix (used by the primitives addon). Your shader should
    multiply the texture coordinates by this matrix. The type is `mat4` in
    GLSL, and `float4x4` in HLSL.

With GLSL alpha testing is done in the shader and uses these additional
uniforms:

al_alpha_test
:   Whether to do any alpha testing. If false, the shader should render the
    pixel, otherwise it should interpret the values of `al_alpha_func` and
    `al_alpha_test_val`.

al_alpha_func
:   The alpha testing function used. One of the [ALLEGRO_RENDER_FUNCTION]
    values. The default is ALLEGRO_RENDER_ALWAYS which means all pixels
    (even completely transparent ones) are rendered. The type is `int`.
    See [ALLEGRO_RENDER_STATE].

al_alpha_test_val
:   If alpha testing is not ALLEGRO_RENDER_NEVER or ALLEGRO_RENDER_ALWAYS
    the alpha value to compare to for alpha testing. The type is `float`.

For GLSL shaders the vertex attributes are passed using the following variables:

al_pos
:   vertex position attribute. Type is `vec4`.

al_texcoord
:   vertex texture coordinate attribute. Type is `vec2`.

al_color
:   vertex color attribute. Type is `vec4`.

al_user_attr_0
:   The vertex attribute declared as ALLEGRO_PRIM_USER_ATTR

al_user_attr_1, ..., al_user_attr_9
:   The vertex attribute declared as ALLEGRO_PRIM_USER_ATTR + X where X is an integer from 1 to 9


For HLSL shaders the vertex attributes are passed using the following semantics:

POSITION0
:   vertex position attribute. Type is `float4`.

TEXCOORD0
:   vertex texture coordinate attribute. Type is `float2`.

TEXCOORD1
:   vertex color attribute. Type is `float4`.

Also, each shader variable has a corresponding macro name that can be used when
defining the shaders using string literals. Don't use these macros with the
other shader functions as that will lead to undefined behavior.

* ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX for "al_projview_matrix"
* ALLEGRO_SHADER_VAR_POS for "al_pos"
* ALLEGRO_SHADER_VAR_COLOR for "al_color"
* ALLEGRO_SHADER_VAR_TEXCOORD for "al_texcoord"
* ALLEGRO_SHADER_VAR_USE_TEX for "al_use_tex"
* ALLEGRO_SHADER_VAR_TEX for "al_tex"
* ALLEGRO_SHADER_VAR_USE_TEX_MATRIX for "al_use_tex_matrix"
* ALLEGRO_SHADER_VAR_TEX_MATRIX for "al_tex_matrix"
* ALLEGRO_SHADER_VAR_ALPHA_FUNCTION for "al_alpha_func"
* ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE for "al_alpha_test_val"

Examine the output of [al_get_default_shader_source] for an example of how to
use the above uniforms and attributes.

Returns true on success and false on error, in which case the error log is
updated. The error log can be retrieved with [al_get_shader_log].

Since: 5.1.0

See also: [al_attach_shader_source_file], [al_build_shader],
[al_get_default_shader_source], [al_get_shader_log], [ALLEGRO_PRIM_ATTR]

## API: al_attach_shader_source_file

Like [al_attach_shader_source] but reads the source code for the shader from
the named file.

Returns true on success and false on error, in which case the error log is
updated. The error log can be retrieved with [al_get_shader_log].

Since: 5.1.0

See also: [al_attach_shader_source], [al_build_shader], [al_get_shader_log]

## API: al_build_shader

This is required before the shader can be used with [al_use_shader]. It should
be called after successfully attaching the pixel and/or vertex shaders with
[al_attach_shader_source] or [al_attach_shader_source_file].

Returns true on success and false on error, in which case the error log is
updated. The error log can be retrieved with [al_get_shader_log].

> *Note:* If you are using the ALLEGRO_PROGRAMMABLE_PIPELINE flag, then you
must specify both a pixel and a vertex shader sources for anything to be
rendered.

Since: 5.1.6

See also: [al_use_shader], [al_get_shader_log]

## API: al_get_shader_log

Return a read-only string containing the information log for a shader program.
The log is updated by certain functions, such as [al_attach_shader_source]
or [al_build_shader] when there is an error.

This function never returns NULL.

Since: 5.1.0

See also: [al_attach_shader_source], [al_attach_shader_source_file],
[al_build_shader]

## API: al_get_shader_platform

Returns the platform the shader was created with (either
ALLEGRO_SHADER_HLSL or ALLEGRO_SHADER_GLSL).

Since: 5.1.6

See also: [al_create_shader]

## API: al_use_shader

Uses the shader for subsequent drawing operations on the current target
bitmap.  Pass NULL to stop using any shader on the current target bitmap.

Returns true on success. Otherwise returns false, e.g. because the shader
is incompatible with the target bitmap.

Since: 5.1.6

See also: [al_destroy_shader], [al_set_shader_sampler], [al_set_shader_matrix],
[al_set_shader_int], [al_set_shader_float], [al_set_shader_bool],
[al_set_shader_int_vector], [al_set_shader_float_vector]

## API: al_destroy_shader

Destroy a shader.  Any bitmaps which currently use the shader will implicitly
stop using the shader.  In multi-threaded programs, be careful that no such
bitmaps are being accessed by other threads at the time.

As a convenience, if the target bitmap of the calling thread is using the
shader then the shader is implicitly unused before being destroyed.

This function does nothing if the shader argument is NULL.

Since: 5.1.0

See also: [al_create_shader]

## API: al_set_shader_sampler

Sets a texture sampler uniform and texture unit of the current target bitmap's
shader. The given bitmap must be a video bitmap.

Different samplers should use different units. The bitmap passed to Allegro's
drawing functions uses the 0th unit, so if you're planning on using the
`al_tex` variable in your pixel shader as well as another sampler, set the
other sampler to use a unit different from 0. With the primitives addon, it is
possible to free up the 0th unit by passing `NULL` as the texture argument to
the relevant drawing functions. In this case, you may set a sampler to use the
0th unit and thus not use `al_tex` (the `al_use_tex` variable will be set to
`false`).

Returns true on success. Otherwise returns false, e.g. if the uniform by that
name does not exist in the shader.

Since: 5.1.0

See also: [al_use_shader]

## API: al_set_shader_matrix

Sets a matrix uniform of the current target bitmap's shader.

Returns true on success. Otherwise returns false, e.g. if the uniform by that
name does not exist in the shader.

Since: 5.1.0

See also: [al_use_shader]

## API: al_set_shader_int

Sets an integer uniform of the current target bitmap's shader.

Returns true on success. Otherwise returns false, e.g. if the uniform by that
name does not exist in the shader.

Since: 5.1.0

See also: [al_use_shader]

## API: al_set_shader_float

Sets a float uniform of the target bitmap's shader.

Returns true on success. Otherwise returns false, e.g. if the uniform by that
name does not exist in the shader.

Since: 5.1.0

See also: [al_use_shader]

## API: al_set_shader_bool

Sets a boolean uniform of the target bitmap's shader.

Returns true on success. Otherwise returns false, e.g. if the uniform by that
name does not exist in the shader.

Since: 5.1.6

See also: [al_use_shader]

## API: al_set_shader_int_vector

Sets an integer vector array uniform of the current target bitmap's shader. The
'num_components' parameter can take one of the values 1, 2, 3 or 4. If it is 1
then an array of 'num_elems' integer elements is added. Otherwise each added
array element is assumed to be a vector with 2, 3 or 4 components in it.

For example, if you have a GLSL uniform declared as `uniform ivec3 flowers[4]`
or an HLSL uniform declared as `uniform int3 flowers[4]`, then you'd use this
function from your code like so:

~~~~c
int flowers[4][3] =
{
   {1, 2, 3},
   {4, 5, 6},
   {7, 8, 9},
   {2, 5, 7}
};

al_set_shader_int_vector("flowers", 3, (int*)flowers, 4);
~~~~

Returns true on success. Otherwise returns false, e.g. if the uniform by that
name does not exist in the shader.

Since: 5.1.0

See also: [al_set_shader_float_vector], [al_use_shader]

## API: al_set_shader_float_vector

Same as [al_set_shader_int_vector] except all values are float instead of int.

Since: 5.1.0

See also: [al_set_shader_int_vector], [al_use_shader]

## API: al_get_default_shader_source

Returns a string containing the source code to Allegro's default vertex or pixel
shader appropriate for the passed platform. The ALLEGRO_SHADER_AUTO value means
GLSL is used if OpenGL is being used otherwise HLSL. ALLEGRO_SHADER_AUTO
requires that there is a current display set on the calling thread. This
function can return NULL if Allegro was built without support for shaders of the
selected platform.

Since: 5.1.6

See also: [al_attach_shader_source]
