
COGL allows creating and manipulating materials used to fill in geometry. Materials may simply be lighting attributes (such as an ambient and diffuse colour) or might represent one or more textures blended together.

Describing GPU blending and texture combining states is rather awkward to do in a concise but also readable fashion. Cogl helps by supporting string based descriptions using a simple syntax.
The following string replaces glBlendFunc[Separate] and glBlendEquation[Separate]:
RGBA = ADD (SRC_COLOR * (SRC_COLOR[A]), DST_COLOR * (1-SRC_COLOR[A]))"
In this case the blend string is actually slightly more verbose than the GL counterpart:
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Though, unless you are familiar with OpenGL or refer to its API documentation you wouldn't know that the default function used by OpenGL is GL_FUNC_ADD nor would you know that the above arguments determine what the source color and destination color will be multiplied by before being adding.
The following string can be used for texture combining:
RGB = REPLACE (PREVIOUS)
A = MODULATE (PREVIOUS, TEXTURE)
In OpenGL terms, it replaces glTexEnv, and the above example is equivalent to this OpenGL code:
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
<channel-mask> = <function-name>(<arg-list>)
You can either use a single statement with an RGBA channel-mask or you can use two statements; one with an A channel-mask and the other with an RGB channel-mask.
A or RGB or RGBA
[A-Za-z_]*
<arg>,<arg> or <arg> or ""
I.e. functions may take 0 or more arguments
<color-source> 1 - <color-source> : Only intended for texture combining <color-source> * ( <factor> ) : Only intended for blending 0 : Only intended for blending
See the blending or texture combining sections for further notes and examples.
<source-name>[<channel-mask>] <source-name>
See the blending or texture combining sections for the list of source-names valid in each context.
If a channel mask is not given then the channel mask of the statement is assumed instead.
0 1 <color-source> 1 - <color-source> SRC_ALPHA_SATURATE
The default value is: (0.2, 0.2, 0.2, 1.0)
The default value is (0.8, 0.8, 0.8, 1.0)
The default value is (0.0, 0.0, 0.0, 1.0)
The default value is 0.0.
The default value is (0.0, 0.0, 0.0, 1.0)
The default is 'always'.
Blending occurs after the alpha test function, and combines fragments with the framebuffer.
Currently the only blend function Cogl exposes is ADD(). So any valid blend statements will be of the form:
<channel-mask> = ADD(SRC_COLOR*(<factor>), DST_COLOR*(<factor>))
Warning: The brackets around blend factors are currently not optional!
This is the list of source-names usable as blend factors:
The color of the in comming fragment
The color of the framebuffer
The constant set via Clutter::Cogl::Material::set_blend_constant()
The source names can be used according to the color-source and factor syntax, so for example "(1-SRC_COLOR[A])" would be a valid factor, as would "(CONSTANT[RGB])".
These can also be used as factors:
Where f = MIN(SRC_COLOR[A], 1 - DST_COLOR[A])
Remember; all color components are normalized to the range [0, 1] before computing the result of blending.
Examples
"RGB = ADD(SRC_COLOR*(SRC_COLOR[A]), DST_COLOR*(1-SRC_COLOR[A]))"
"A = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))"
"RGBA = ADD(SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))"
The default blend string is:
"RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))"
That gives normal alpha-blending when the calculated color for the material is in premultiplied form.
The index values of multiple layers do not have to be consecutive; it is only their relative order that is important.
Note: In the future, we may define other types of material layers, such as purely GLSL based layers.
These are all the functions available for texture combining:
4 x ((arg0[R] - 0.5) * (arg1[R] - 0.5) +
(arg0[G] - 0.5) * (arg1[G] - 0.5) +
(arg0[B] - 0.5) * (arg1[B] - 0.5))
4 x ((arg0[R] - 0.5) * (arg1[R] - 0.5) +
(arg0[G] - 0.5) * (arg1[G] - 0.5) +
(arg0[B] - 0.5) * (arg1[B] - 0.5) +
(arg0[A] - 0.5) * (arg1[A] - 0.5))
The valid source names for texture combining are:
Use the color from the current texture layer
Use the color from the specified texture layer
Use the color from the constant given with Clutter::Cogl::Material::set_layer_constant()
Use the color of the material as set with Clutter::Cogl::Material::set_color()
Either use the texture color from the previous layer, or if this is layer 0, use the color of the material as set with Clutter::Cogl::Material::set_color()
Examples:
This is effectively what the default blending is:
RGBA = MODULATE (PREVIOUS, TEXTURE)
This could be used to cross-fade between two images, using the alpha component of a constant as the interpolator. The constant color is given by calling Clutter::Cogl::Material::set_layer_constant().
RGBA = INTERPOLATE (PREVIOUS, TEXTURE, CONSTANT[A])
Note: You can't give a multiplication factor for arguments as you can with blending.
Currently there is only one type of layer defined, 'texture'; but considering that we may add purely GLSL based layers in the future, you should write code that checks the type first.
Note: In the future, we may support purely GLSL based layers which will likely return undef if you try to get the texture. Considering this, you should call Clutter::Cogl::MaterialLayer::get_type() first, to check it is of type 'texture'.