Tutorial 6

Control instruments and alpha blending

In this tutorial things start getting complicated. We will be changing alpha values through the use of a global control instrument. This means that we will have one instrument which will produce no visible output, but will generate a variable that will be available for all other instruments. When you want to modify several instruments simultaneously you will need to use a global variable which will usually be controlled by a 'control' instrument. Control instrument should have a lower number that the instruments it will be controlling. The reason for this is a little complicated for this tutorial, so just try to practice this when you use control instruments.

When using alpha values, a new concept called alpha blending must be introduced. Alpha blending is the process of mixing colours according to the alpha values of the source (SRC) object and the destination (DST) object. The source object is the one created latest in the rendering chain, either because it has a greater number in GLinsert or because it was created later. The pixel colour is defined by the function:

C = Csrc * F src + Cdst * Fdst

Where C is the original colour and F refers to the blending function used. For example when:

glBlendFunc $GL_SRC_ALPHA,$GL_ONE_MINUS_SRC_ALPHA

is used the function will be:

C = Csrc * α src + Cdst * (1- αsrc)

In this case the colour of the foreground object (src) is multiplied by its alpha value, and the colour of the destination objext is multiplied by (1-src alpha). So the back colour is strong when the foreground object is more transparent. Remember that an alpha value of 1 means opaque and a value of 0 means transparent.

Grasping this takes a while and requires experimentation, so play a lot with this tutorial, and make up your own examples to understand it.

Let's start the tutorial.

<CsoundSynthesizer>
<CsOptions>
-+Y
</CsOptions>
<CsInstruments>

#include "OpenGL.h"

sr=100
kr =100
ksmps=1
nchnls=1

GLfps 30
GLpanel "OpenGL panel", 512, 512
GLpanel_end
FLrun




glMatrixMode $GL_PROJECTION
glLoadIdentity
gluPerspective 60,0.1,100
glMatrixMode $GL_MODELVIEW
;We will add two lines to our usual headers. These will enable alpha blending and define the way this blending is done.
;First we use the instruction glEnable, which is used to 'enable' gl functions. It can have many different values,
;but right now we will only use $GL_BLEND to enable alpha blending.
glEnable $GL_BLEND
;The blend function is defined by glBlendFunc, which has two values. The first defines the factor by which
;the source colour will be modified. The second defines the factor by which the destination colour will be modified.
;You can think of alpha blending as a sum of both colours each modified by the value indicated by the blending function.
;The value $GL_SRC_ALPHA,$GL_ONE_MINUS_SRC_ALPHA should be thought of as a default,
;and unless you want a special effect, you should use this values.
glBlendFunc $GL_SRC_ALPHA,$GL_ONE_MINUS_SRC_ALPHA

GLinsert_i $GL_NOT_VALID

glClear $GL_COLOR_BUFFER_BIT + $GL_DEPTH_BUFFER_BIT
GLinsert_i 1.1

gisine ftgen 1,0,1024,10,1

;Here we define our control instrument. Notice the comment that accompanies the instrument. In Csound
;anything after a semi-colon is discarded, it is useful to comment complicated scores to find your way.
instr 1 ;control instrument
gkalpha linseg 0,10,1,10,1,10,0
;Here we define a global k-rate value. Remember a variable starting with g means global. A k-rate variable
;is one that can be updated every control cycle. There are kr (as in the header here kr = 100) control cycles in a second.
;Control signals don't normally need to be as accurate as audio signals, that's why in csound we have k-rate variables,
;which saves processing power. The opcode linseg defines the variable gkalpha as a function made up
;of line segments. If you check the manual it'll tell you that the first parameter is the initial value, then they come
;by pairs of duration and ending value. In this case we will have 3 line segments, starting at 0 and rising
;for 10 seconds to 1, then staying there for 10 seconds, and finally going down to 0 over 10 seconds.
;This command starts when the instrument is called, which in our case is second 0.
;This is all that the control instrument will do.
endin

instr 2
;Now instrument 2, which will do the drawing.
ired = p4
igreen = p5
iblue = p6
iy = p7
;As we've done before we assign th p-fields to i-rate variables, to give them a clearer name.
glLoadIdentity
talpha = t (gkalpha)
;Since graphics opcodes can only work with t-rate and i-rate variables (any other type produces an error and stops
;compilation), we use the function t( ) to convert the global k-rate variable gkalpha to the local t-rate variable talpha.
tmove GLoscil 2,360,1
;We use the variable tmove to hold the result of an oscillator, this time fixed, with an amplitude of 2, completing
;a cycle every 360 frame and oscillating according to f-table 1, which is again a pure sine wave.
glTranslate tmove,iy,-6
;We now do a variable translation, moving tmove units along the x-axis, and displacing the fixed values iy
;and -6 on the other axis.
glColor ired,igreen,iblue,talpha
;The colour of our object is determined in the score's instrument call, and the alpha value is modified according
;to the global control instrument defined above. I've chosen to use a control instrument so that all alpha values,
;no matter when the instrument ends or starts, are the same.
glBegin $GL_QUADS
glVertex3 0,0,0
glVertex3 1,0,0
glVertex3 1,1,0
glVertex3 0,1,0
glEnd
GLinsert 1.5
;We draw a square as usual, and our instrument is done.
endin



</CsInstruments>
<CsScore>

i 1 0 30
;We must call our control instument, for the whole duration that we want it to be active. In this case it is 30 seconds.

i 2 2 28 1 0 0 1
i 2 3 27 0 1 0 0.8
i 2 4 26 0 0 1 0.6
i 2 5 25 1 0 1 0.4
i 2 6 24 0 1 1 0.2
i 2 7 23 1 1 0 0
i 2 8 22 1 1 1 -0.2
i 2 9 21 1 1 0 -0.4
i 2 10 20 0 1 1 -0.6
i 2 11 19 1 0 1 -0.8
i 2 12 18 0 0 1 -1
i 2 13 17 0 1 0 -1.2
i 2 14 16 1 0 0 -1.4
;Now we call 13 instances of the instrument, each with a different colour and y-position. Notice it is only the fact
;that they start at different times, that creates the whirly movement.

</CsScore>
</CsoundSynthesizer>

That's it for tutorial 6. Remember as always to experiment with values, and changing things around. It's the only way to learn.
Notice how the control instrument 'binds' objects together, by letting them all share values, even if they start at different times or have different durations.
Notice also how the change in alpha can be though of as a change in transparency. Also be aware that the behavior of alpha values, is completely dependent of the blending function used. Some very interesting results can be achieved from a dull scene by just changing the alpha blending characteristic. The values that can go in either parameter of glBlendFunc are:

$GL_SRC_ALPHA

$GL_ONE_MINUS_SRC_ALPHA

$GL_DST_ALPHA

$GL_ONE_MINUS_DST_ALPHA

$GL_ONE

$GL_ZERO


Back to OpenGL Tutorials Index