Preamble

In the following, it is assumed that the developer is familiar with OpenGL concepts and Shading Language.


General Principles for Effects Development

In order to understand how the effects work, it is necessary to understand the layer structure of YoupiPaint


A layer consists of a set of tiles (512x512 pixels) assembled with a border covering of a width of 6 pixels. The visible surface of each tile is therefore 500x500 pixels.


The drawings of the tiles are OpenGL textures plated on the rectangle occupied by the tile. When performing a brush stroke or other drawing operation, YoupiPaint creates the tiles as needed and updates the textures associated with the tiles.


- la structure des tuiles du calque -


An effect is an OpenGL fragment shader. This shader is used to display the tile texture of the current layer. The previews of the effects are displayed in real time. When the effect is applied, the tile textures are updated.

General Principles for the Development of Brush Engines

As for effects brush engines are OpenGL fragment shaders.


A brush stroke consists of a set of more or less spaced buffers. These buffers are drawn dynamically or represented by a texture in the case where the brush is associated with a texture. The fragment shader  performs this drawing.

Inputs provided by the application to the shaders

A stamp or a tile are delimited by a quadruple point. In addition to the coordinates of the points YoupiPaint provide inputs as uniform variables:


The transformation matrices (projection, view, model)

The general parameters of the application such as the coordinates and size of the paper

The texture coordinates of the tiles for the effects, the texture coordinates of the stamps for the brushes

The identifiers of the textures of the current layer, of the layer under the current layer

The texture identifier used as a mask for the selection areas

The specific parameters defined by the shader developer

For the brushes, the dynamic parameters of the brush, calculated just before the execution of the shader, such as radius, hardness, flow and many others.

What the shader should calculate

Like any fragment shader, effects and brush engines must calculate the color of the fragment and update the predefined variable f_color.


All colors are pre-multiplied and must be rendered in the pre-multiplied f-color variable.


As a reminder, if r, g, b are the red, green, blue components of a color and alpha its transparency, the corresponding pre-multiplied color is the quadruplet


(r*alpha, g*alpha, b*alpha, alpha)