La sintassi di GLSL è molto simile al C. La definizione delle delle variabili ha una sintassi identica, ma con alcune importanti differenze di utilizzo:
GLSL definisce tre tipi di dato fondamentali:
float reale; // numero a virgola mobile bool booleano; // variabile booleana (vero o falso) int intero; // intero
Anche i vettori, fino a 4 elementi, sono tipi predefiniti, perché sono operandi elementari su quasi tutte le GPU.
vec2 duefloat; // vettore di due float (x e y) vec3 trefloat; // vettore di tre float (xyz o rgb) vec4 quattrofloat;// vettore di quattro float (xyz con w o rgb con alpha)
Per ottenere vettori non di float, si premette l'iniziale del tipo desiderato al nome del vettore:
ivec2 dueint; // vettore di due interi ivec3 treint; // vettore di tre interi ivec4 quattroint; // vettore di quattro interi bvec2 duebool; // vettore di due bool bvec3 trebool; // vettore di tre bool bvec4 quattrobool;// vettore di quattro bool
È ancora possibile definire array di variabili come in C, ma non potranno essere usati come operandi al pari dei vettori:
float a[4]; // array di 4 float vec2 b[2]; // array di due vettori di 2 float
Alcune matrici sono tipi predefiniti. In GLSL 1.2.0, solo le matrici quadrate di float, fino a lato 4.
mat2 m2; // matrice di 2x2 float mat3 m3; // matrice di 3x3 float mat4 m4; // matrice di 4x4 float
Inoltre, sono definiti alcuni tipi di dato che servono ad accedere alle texture:
sampler1D tex1; // texture monodimensionale sampler2D tex2; // texture bidimensionale sampler3D tex3; // texture tridimensionale samplerCube texCube; // cube map sampler1DShadow shadow1; // shadow map 1D sampler2DShadow shadow2; // shadow map 2D
Le variabili possono essere definite e inizializzate durante la creazione come in C.
La prima differenza è che non esiste il typecast automatico delle variabili. Questo significa che le seguenti istruzioni sono illegali in GLSL:
float tre = 3; int due = 2.0; float sei = tre * due;
Si deve scrivere, invece:
float tre = 3.0; int due = 2; float sei = tre * float(due);
Come si può vedere, il typecast non avviene con il tipico stile del C ((tipo)variabile), ma con una sintassi più simile a un costruttore del C++ (tipo(parametri)).
I costruttori sono anche l'unico modo per definire vettori costanti da assegnare ai tipi di dato vettoriali. In questo caso, un costruttore accetta più di un parametro. Ad esempio:
vec4 v = vec4(1.0,2.0,3.0,4.0); // crea e inizializza il vettore con i valori 1, 2, 3, 4 ivec3 interi = vec3(3,2,1); // crea e inizializza il vettore con i valori 3, 2, 1
Infine, i costruttori permettono di convertire un tipo di dato vettoriale in un altro.
vec3 reali = vec3(interi); // converte tre interi in tre reali v = vec4(reali,1.0); // il vettore "reali" dà i primi 3 elementi, 1.0 è il quarto. vec2 col1 = vec2(1.0,-1.0); // prima colonna vec2 col2 = vec2(-1.0,1.0); // seconda colonna mat2 matrice = mat2(col1,col2); // creazione di una matrice a partire dalle due colonne mat2 matrice2 = mat2(2.0,1.0,0.0,3.0); /* Le matrici GLSL sono divise per colonne (column-major order). La matrice creata è: 2.0 0.0 1.0 3.0 */
Per accedere agli elementi di un vettore è ancora possibile usare la normale notazione con le parentesi quadre:
vec4 vettore = vec4(-1.0,0.0,1.0,3.0); float secondo = vettore[1]; // seleziona il secondo elemento del vettore vec2 duevettori[2]; duevettori[0] = vec2(2.0,-2.0); duevettori[1] = vec2(-1.0,4.0); float elemento = duevettori[0][1]; // seleziona il secondo elemento del primo vettore
Tuttavia, se il vettore è stato dichiarato come tipo di dato fondamentale, è consentito l'accesso alle componenti (o a sottogruppi di componenenti) di quel vettore per nome. Un vettore può essere scomposto nelle coordinate (xyzw) o nelle componenti cromatiche (rgba). Le due notazioni sono sinonimi, ma possono rendere più chiaro l'uso che si sta facendo di quella variabile.
vec4 v = vec4(1.0,2.0,3.0,4.0); float primo = v.x; // estrae il primo elemento v.w = 1.0; // imposta il quarto elemento (w) a 1 vec2 vecxy = v.xy; // seleziona i primi due elementi vec3 color = v.rgb; // seleziona i primi tre elementi vec3 reversecolor; reversecolor = v.bgr; // seleziona i primi tre elementi, ma in ordine inverso vec4 riordina = v.barg; // estrae tutti i componenti, ma in ordine diverso dall'originale (blue, alpha, red, green)
GLSL permette la definizione di tipi di dato personalizzato tramite strutture, esattamente come in C:
struct Luce { vec4 colore; vec3 posizione; }; Luce luce; luce.colore = vec4(0.0,0.0,1.0,1.0); vec3 pos = luce.posizione;
Copyright © 2011 Riccardo Monica
Eccetto ove espressamente indicato altrimenti, il contenuto di questa pagina è disponibile secondo la licenza Creative Commons Attribuzione - Condividi allo stesso modo 3.0.