Tutorial 7

Vectorial text and linseg

In this tutorial we'll learn how to draw vectorial text (which is text made up of lines) and how to use the csound instruction linseg.

We start everything as usual:

<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
glEnable $GL_BLEND
glBlendFunc $GL_SRC_ALPHA,$GL_DST_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

instr 2
kenv linseg 0,3,1,p3-8,1,5,0
Here I am using the instruction linseg whose result will be output to the k-rate variable kenv. Linseg generates line segments between specified points. We will use these values later to generate a fade in and fade out of the text. The first parameter is the start value, which in this case is 0, which in alpha terms means totally transparent according to our blend function. The next parameter specifies the time it'll take to get to the next value. In this case it'll take 3 seconds to get to a value of 1. An alpha value of 1 means opaque, so we have a fade in from invisible to opaque which takes 3 seconds. The paramters then come in pairs of time and value. We have a time of (p3-8) to stay at a value of 1. Remember that p3 is the total length of the instrument's instance, so what'll happen is that after a rise of 3 seconds to a value of 1, the variable kenv will stay at 1 for (p3-8) seconds. The final values of 5 and 0 indicate that we have a decay lasting 5 seconds, to a value of 0. Notice that the variations of the variable kenv will span all the duration of the instrument instance since we have 3 + (p3-8) + 5 which equals p3 (the complete duration).
ired = p4
irot = p5
iy = p6
As usual, we give p-fields a more understandable name by assigning them to i-rate variables. Notice that this is not necessary, as the linseg instruction above shows, where p3 was used directly as a parameter.
glLoadIdentity
tosc GLoscil 1,120,1
We declare an oscillator to be output to variable tosc, which as usual will oscillate as a sine wave, with a period of 4 seconds (120/30).
glTranslate -1,-1,-3
In this tutorial you should try to fully understand (if you haven't done so before) how the transformations are affecting the objects generated. First we displace our axis towards the lower right hand corner, and 3 units into the screen so we can see our objects.
glRotate irot,0,1,0
Then we rotate our axis around the y-axis irot degrees. To remember how rotation around each axis takes place, you can use your right hand. Use your thumb to point in the positive direction of the axis so that it makes an angle of 90 degrees with the rest of your fingers (eg. For the y-axis, point your thumb upwards). Then curl the rest of your fingers towards your wrist, and this curling will show the positive rotation around the axis. In the case of the y-axis you can see that it is equivalent to the rotation of a turntable.
Notice in the score below that we use angles of 90 and 270, which is like rotating 90 degrees clockwise and 90 counterclockwise.
glTranslate -1,iy, tosc
After the last rotation, we have a displacement. Notice that we make three simultaneous displacements. One on the y-axis through the variable iy, which will mark how high on the screen we see our object. One on the x-axis, which will make our text start at the right. Then we make a variable translation on the z- axis according to the oscillator created above. Notice that when irot is 0, the movement is towards you and back, as expect. When irot is 90 and 270, the movement is left to right because our rotation made the z-axis parallel to our original y-axis. Notice that in one case the text is written from you to the screen and in the other, from the screen to you.
glColor ired,1,0,t (kenv)
Here we define the colour which will depend on the variable ired. Notice that the alpha value is defined as t (kenv) what this expression does is transform the k-rate variable to a t-rate variable so it can be used by the instruction glColor. You would get an error message on compliation if you tried to use kenv directly. Always remember that certain instructions have limitations about which kind of variables they use.
glLineWidth 1
glScale 1/1000,1/1000,1/1000
Vectorial text is drawn too large. That's why we need to scale it a lot.
GLUTprints "www.oocities.org/mantaraya36@CsoundAV Tutorials", $GLUT_STROKE_ROMAN, -150,0,0,0
This last instruction effectively prints the text on the screen. What's printed is everything in quotes. Notice that the character '@' means 'new line'. The next parameter states the font to be used. Since this is vectorial only a few simple fonts can be used, see below for all the options. The next parameter indicates the vertical spacing, or the space between each line of text. A negative nuber here indicates the next line should be placed below. The next three values should state the coordinates (in our relative axis) of the bottom right corner of the first line of text. These three values are apparently not needed in the current version of CsoundAV (0.043).
GLinsert 1.5
endin

</CsInstruments>
<CsScore>

i 2 2 28 1 0 0
i 2 3 27 0.8 0 1
i 2 4 26 0.6 0 2
i 2 5 25 0 270 0
i 2 6 24 0 270 1
i 2 7 23 0 270 2
i 2 8 22 1 90 0
i 2 9 21 1 90 1
i 2 10 20 1 90 2
Notice how we separate by colours the three texts rotated clockwise and the three counterclockwise.

</CsScore>
</CsoundSynthesizer>

This example shows an effective way to draw text on the screen. Since it is vectorial (drawn from lines) it is a bit limited, and doesn't have fonts that are very interesting. It can create a good effect, though when used creatively. In a later tutorial, we'll explore the flashier 3D fonts.The fonts that can currently be used are the following:


$GLUT_STROKE_ROMAN  (vectorial)
$GLUT_STROKE_MONO_ROMAN (vectorial)
Experiment changing the parameter in the instruction GLUTprints. Also notice the great flexibility of the instruction linseg, which creates an envelope which can span the whole of the note, no matter the duration, because it is a function of duration. An envelope is a 'shape' that modifies some parameter. It can be thought of as a form of automation in this case.
Back to OpenGL Tutorials Index