Introduction

Examples

Advanced use

GPGPU

Documentation

Installation

Downloads

Browse source

Forums

Tracker

Wiki

Blog







Off-screen rendering

The GLGraphics library includes a renderer that can be used as an off-screen drawing surface. This allows to generate multiple independent canvases on the same Processing sketch, and then blend them together, or apply post-processing filters on them. An off-screen surface is created as follows:
size(640, 480, GLConstants.GLGRAPHICS);

glg1 = new GLGraphicsOffScreen(640, 480, this);
glg2 = new GLGraphicsOffScreen(200, 200, this);
glg3 = new GLGraphicsOffScreen(160, 120, this);

All the drawing functions of the OpenGL renderer are available for use in the off-screen mode, since GLGraphicsOffScreen is a descendant of PGraphicsOpenGL. GLGraphicsOffScreen contains an instance GLTexture, which is the destination of the render operations. This texture can be retrieved with the  getTexture() function:
glg1.beginDraw();
glg1.fill(230, 50, 20, 255);
glg1.rect(0, 0, 640, 480);
glg1.endDraw();

image(glg1.getTexture(), 0, 0);

Texture grids


The filters allow to map the input texture(s) on a rectangular grid. The coordinates of the vertices of this grid can be altered in the vertex stage of the shader, to achieve arbitrary deformations in the output texture.




The grid is specified in the xml file for the filter, for example:
<filter name="pulsating emboss">
<description>Dynamic emboss effect on pulsating grid</description>
<vertex>PulseGrid.glsl</vertex>
<fragment>DynEmboss.glsl</fragment>
<textures input="1" output="1"></textures>
<grid>
<resolution nx="10" ny="10"></resolution>
</grid>
</filter>
The <grid> tag is used to define the rectangular grid the input texture is applied onto. With <resolution nx="10" ny="10"></resolution> you just specify the number of points on the grid, along the x and y directions. In this case, the grid has 10×10 points.

Filter parameters

The operation of the filter can be controlled with parameters passed when applying the filter. These parameters correspond to uniform variables defined inside the shader. There are some conventions to name the uniform variables inside the shaders, for the filter to be able of recognizing those uniforms and link them to the parameters that can be passed from Processing.

The naming conventions are the following:
  • the name of the source/input texture units should be “src_tex_unit” + n, where n = 0, 1, 2, etc. I.e., the first texture unit should be named src_tex_unit0, the second src_tex_unit1, and so on.
  • The offset of the source textures is identified by “src_tex_offset” + n, with n = 0, 1, 2, etc. The offset is, in other words, the inverse of the width and height of the texture, and represents the step size to move from one texel to the next.
  • At least one src_tex_unit0 uniform should be defined in the fragment shader, since a filter needs at least one source texture to operate on.
Then you can define the following optional uniforms to pass general parameters into the shader:
  • timing_data (of type vec2): the first component of this vector is the frameCount and the second is millis() at the time the shader program is executed. This allows to pass timing information into the shader.
  • par_int1, par_int2, par_int3 and par_int4 (of type int): these float uniforms can be used to pass integer numbers into the shader.
  • par_flt1, par_flt2, par_flt3 and par_flt4 (of type float): these float uniforms can be used to pass float numbers into the shader.
  • par_vec21, par_vec22 and par_vec23 (of type vec2) to pass a 2d vector into the shader.
  • par_vec31, par_vec32 and par_vec33 (of type vec3) to pass a 3d vector into the shader.
  • par_vec41, par_vec42 and par_vec43 (of type vec4) to pass a 4d vector into the shader.
  • par_mat2 (of type mat2), to pass a 2×2 matrix into the shader.
  • par_mat3 (of type mat3), to pass a 3×3 matrix into the shader.
  • par_mat4 (of type mat4), to pass a 4×4 matrix into the shader.
These uniforms don’t need to be defined inside the shader, and also the shader can have other uniforms with different names. However, the advantage of having the uniforms listed here is that they are handled automatically inside the filter class. In order to set the value of these uniforms from Processing, you use the GLTextureFilterParams object, inside which you have the parInt1, parInt2... variables. So, if the glsl shader that defines the filter has the float uniform par_flt1, you can set its value with the following code:
GLTextureFilterParams params = new GLTextureFilterParams();
params.parFlt1 = map(mouseX, 20, 640, 1, 30);
tex0.filter(pixelate, tex1, params);