OpenGL distingue fra 3 diversi tipi di luce:
- Ambiente: si tratta della luce proveniente da ogni direzione della scena che rimbalzando tra gli oggetti non consente il calcolo della direzione, quindi si trova nell’ambiente con la stessa intensità.
- Diffusa: il raggio di luce proviene da una fonte luminosa e va a colpire un oggetto che assorbe o riflette più o meno questo raggio che va quindi a colorare l’oggetto in base alla sua natura.
- Speculare: si tratta della parte di luce riflessa dagli oggetti in metallo o che hanno comunque una superficie lucida, determina i riflessi.
Gli oggetti in presenza di fonti di luce non hanno il loro colore iniziale, ma questo cambierà in base ai raggi che li colpiranno. Un oggetto di colore rosso, ad esempio, se viene illuminato da una luce bianca sarà rosso, mentre se viene illuminato da una luce verde risulterà nero. Oltre ai colori dati dalle luci, possiamo assegnare ad ogni oggetto un colore di emissione che consente di creare, ad esempio, una lampadina accesa oppure un neon. Occorre dire che assegnare una luce di emissione ad un oggetto non lo rende una fonte di luce, ma viene colorato come se fosse illuminato dall’interno. Per altre informazioni sui raggi luminosi vi consiglio di leggere questo articolo, sempre su questo blog.
Per attivare l’illuminazione in OpenGL si utilizza la funzione glEnable(GL_LIGHTING) e per disattivarla si utilizza glDisable(). Abbiamo a disposizione otto luci ( GL_LIGHTX ) che è possibile gestire tramite la funzione glLightfv( luce, parametro, vettore ) per parametri vettoriali e glLightf( luce, parametro, valore ) per parametri non vettoriali. Ad esempio per ottenere un faretto alogeno dobbiamo utilizzare questo codice:
GLfloat cluce_ambiente[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat cluce_diffusa[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat cluce_speculare[] = { 0.7, 0.7, 0.7, 1.0 }; glLightfv(GL_LIGHT0, GL_AMBIENT, cluce_ambiente); glLightfv(GL_LIGHT0, GL_DIFFUSE, cluce_diffusa); glLightfv(GL_LIGHT0, GL_SPECULAR, cluce_speculare);
Da dire che la posizione della luce è influenzata dalla matrice di trasformazione corrente come le coordinate dei vertici degli oggetti, quindi occorre fare attenzione all’ordine. Comunque un oggetto può essere illuminato ed altri no utilizzando le funzioni di abilitazione e disabilitazione della luce nel momento di disegnare l’oggetto stesso.
Altra funzione importante è glLightModel(parametro, valore ) che consente di impostare l’intero comportamento delle luci ed in particolare abbiamo questi parametri:
- GL_LIGHT_MODEL_TWO_SIDE che consente di illuminare tutte le faccie dei poligoni, per default è falso.
- GL_LIGHT_MODEL_LOCAL_VIEWER che consente di calcolare l’angolo dei raggi in maniera più accurata, per default è falso.
- GL_LIGHT_MODEL_AMBIENT per impostare la luce d’ambiente generale.
Le caratteristiche del materiale vengono invece impostate tramite le funzioni glMaterialf(faccia, parametro, valore ) e glMaterialfv(faccia, parametro, vettore ). La faccia può essere quella anteriore ( GL_FRONT ), quella posteriore ( GL_BACK ) oppure entrambe ( GL_FRONT_AND_BACK ). I parametri possono essere:
- GL_AMBIENT per il colore ambiente
- GL_DIFFUSE per il colore di diffusione
- GL_AMBIENT_AND_DIFFUSE per entrambi i colori, molto utile perché negli oggetti reali questi valori sono di solito uguali.
- GL_SPECULAR per il colore speculare
- GL_EMISSION per il colore di emissione
- GL_SHININESS per la durezza, ossia quanto un materiale sia riflettente
L’ultima informazione da sapere per utilizzare le luci sono le normali a tutti i vertici dei nostri oggetti, calcolo che coinvolge anche un po’ di matematica e che tratteremo in una prossima lezione.