Skip to content

About OpenGL and GLSL

Peter Nagy edited this page Apr 21, 2020 · 10 revisions

Introduction

bzzzbz uses OpenGL ES 2.0 to render 2D vector graphics.

Documentation is provided by Khronos Group at the appropriate reference pages. OpenGL ES is used to create a windowing context and perform related tasks while the graphics are created solely by using fragment shaders written in GLSL, a C-style shading language developed for OpenGL. Introductory resources for OpenGL (ES) 2.0 and GLSL can be found here.

Custom shaders ("visuals") can be used for which The Book of Shaders provides an extensive (though incomplete) introduction. A useful tool to sketch shaders is GLSL Sandbox. To implement this in bzzzbz the shader source code must be saved as *.glsl using the following template:

/*this is automatically added to the shader src in shader_utils.cpp but must be changed to reflect the OpenGL version used */
#version 100 // for OpenGL ES 2.0
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif  


/*uniforms should be listed here. All uniforms must be 'active' and directly influence the output gl_FragColor() 
and must be bound in the OpenGL code */
uniform float H; //Screen height
uniform float W; //Screen width
//uniforms used by **bzzzbz**: 3 potentiometer controls and an fft frame with 513 bins.
uniform float A; 
uniform float B;
uniform float C;
uniform float fft[513];
 
void main( void ) {
    //normalise pixel positions to screen resolution so values are in the range [0.0 1.0]
    float X = gl_FragCoord.x/W;
    float Y = gl_FragCoord.y/H;
    //not necessary but useful to create; by default GLSL Sandbox uses a similar "position" variable
    float pos = vec2(X,Y);
    //initialise output variable, conventionally called "color"
    float color = 0.0;
    
    /***write operations here and do not forget to use all the uniforms!***/

    //output variable with RGBA channels
    gl_FragColor = vec4( color, color, color, 1.0 );
}

Useful tips about GLSL

  • for loops are allowed, but only with static indexing; a large number of iterations can lead to performance issues (see example ex_audio_slow) and signifies the differences of GPU and CPU programming "logic"
  • recursion is forbidden
  • uniforms must be active; they must affect the output and multiplying by 0.0 to avoid this is not allowed, instead it is suggested that the binding is changed
  • arrays (?)
  • pointers do not exist
  • screen dimensions can in some cases affect the render.