LA LIBRERIA GRAFICA OPENGL

libreria grafica:

Note storiche

Prime librerie grafiche erano bidimensionali.

Modello concettuale alla base: modello del pen plotter.

Un pen plotter produce immagini muovendo la penna sul foglio in due direzioni ortogonali. La penna puo' essere alzata (e allora non scrive mentre la muovo) o abbassata (e allora scrive) per creare l'immagine desiderata.

Esempi: LOGO, GKS, PostScript.

In questi sistemi grafici si hanno due funzioni primitive:

Esempio:

MOVETO(0,0)
LINETO(1,0)
LINETO(1,1)
LINETO(0,1)
LINETO(0,0)

Tali sistemi vanno bene per applicazioni specifiche (descrizione del layout di una pagina: PostScript). Diventano complessi quando si voglia disegnare un oggetto tridimensionale.

Nota: grafica 2D e' la grafica di X Window (in Xlib).

OPEN GL (Open Graphics Library)

Interfaccia software verso l'hardware grafico che consiste di un insieme di diverse centinaia di funzioni e procedure.

Progettata per rendering in tempo reale e sviluppata (GL) per Silicon Graphics.

Funzionamento di OpenGL:

Primitive di output sono visualizzate su frame buffer sulla base di alcuni attributi (ved. dopo).

Le funzioni della libreria si dividono in: Le funzioni OpenGL iniziano con "gl" e sono contenute nella libreria GL.

Organizzazione della libreria per sistema X:

Una organizzazione simile vale per l'ambiente Microsoft Windows.

Primitive geometriche

Libreria di base (GL) contiene un insieme ristretto di primitive geometriche. Libreria GLU contiene un insieme piu' ricco composto a partire dalle primitive semplici di GL.

Le primitive geometriche si costruiscono tramite vertici.

Una primitva e' specificata da

  • tipo della primitiva
  • lista di vertici I vertici sono l'informazione geometrica, il tipo della primitiva determina come questi vertici devono essere connessi per formare la primitiva. Ciascun vertice e' specificato dandone le coordinate in un sistema di riferimento locale alla primitiva.

    Tipi di primitive

    Nota sui poligoni in OpenGL

    Un poligono e' un sottoinsieme del piano connesso, chiuso, limitato, la cui frontiera e' una catena chiusa di segmenti di retta.

    OpenGL tratta solo poligoni semplici e convessi.

    Un poligono e' detto semplice se i suoi lati si intersecano al piu' nei vertici estremi.

    Teorema di Jordan: una curva semplice e chiusa divide il piano in due sottoinsiemi, l'interno e l'esterno ===> per un poligono semplice l'interno e' ben definito.

    Un poligono e' detto convesso se dati due punti interni qualunque P1 e P2 il segmento P1P2 e' interno al poligono.

    In un poligono i lati sono gli stessi che avrei con GL_LINE_LOOP.

    Oggetti curvi

    Con le primitive viste prima si possono creare oggetti a facce piane definiti mediante vertici. Oggetti curvi si possono realizzare

    Testo

    Due forme: STROKE e RASTER.

    Attributi delle primitive geometriche

    Distinzione fra il tipo di una primitiva e come la primitiva viene visualizzata.

    Esempi: colore, spessore di una linea, pattern usato per riempire un poligono.

    Aspetto della primitive geometriche dipende dal valore corrente di alcuni attributi al momento della visualizzazione. OpenGL ha uno stato corrente che contiene i valori degli attributi che andranno a influenzare l'aspetto delle primitive che saranno tracciate. Attributi sono specificati da variabili di stato e impostati tramite comandi.

    Esempi:

    Nello spazio un poligono ha due facce (front e back), posso assegnare una modalita' di visualizzazione diversa nelle due facce.
  • Per tutte le primitive: colore, materiale (determina la reazione della primitiva alla luce)... Questi attributi possono essere specificati vertice-per-vertice all'interno di una stessa primitiva.

    Nota sugli attributi vertice-per-vertice

    Se i vari vertici di una primitiva hanno valori diversi di un attributo, il valore in un punto interno alla primitiva viene interpolato ed assume un valore ottenuto come media dei valori nei vertici, pesata rispetto alla distanza del punti dai vertici.

    Esempio: un segmento con un vertice rosso e uno giallo assumera' al suo interno toni di arancio degradanti dal rosso verso il giallo.

    Una primitva e' specificata da

  • tipo della primitiva
  • lista di vertici ed attributi vertice-per-vertice I valori degli attributi che agiscono sulle primitive nel loro complesso (point size, line width, poligon mode) vanno assegnati al di fuori (e prima)della primitiva. Prima, in modo che al momento in cui si incontra la primitiva i valori siano quelli voluti.

    Attributi come parte dello stato corrente

    Una volta che e' stato impostato un certo valore per un attributo, questo influisce su tutte le primitive che seguono fino a che il valore non viene cambiato. Esempio: se si imposta il colore rosso, si continua a disegnare in rosso finche' lo stato non cambia. Le primitive precedenti non sono influenzate.

    Anche gli attributi vertice-per-vertice possono essere assegnati fuori.

    Esiste il modo di cambiare temporaneamente il valore di un attributo e poi ripristinare lo stato precedente. Esempio: spezzone di codice che cambia il colore corrente in rosso, disegna qualcosa in rosso e poi ripristina il colore precedente qualunque esso sia.

    Colore

    Il colore in computer graphics e' basato sulla teoria dei tre colori.

    Usando un modello di colore additivo, si considerano tre colori primari che sono mischiati per formare il colore desiderato.

    Modello R G B

    Un colore C e' definito da C = T1 R + T2 G + T3 B dove
    R = red, G = green, B = blue
    e Ti = intensita' di colore.

    Possiamo vedere un colore come un punto nel cubo dei colori:

    Tutti i colori sulla diagonale = toni di grigio.

    Per definire un colore si specificano le componenti di R, G e B come numeri fra 0.0 e 1.0, dove

    Esempio: la terna (1.0,0.0,0.0) denota il rosso, (1.0,1.0,0.0) il giallo.

    Evoluzione (che vedremo): modello a 4 colori (RGBA).

    A e' detto alpha channel. Il valore di ha e' detto opacita' o trasparenza:

    Un oggetto opaco non ha passare la luce, un oggetto trasparente fa passare tutta la luce.

    Alternativa per il colore

    Supponiamo che la profondita' del frame buffer sia 3k bit per pixel. Posso specificare 2^k rossi, 2^k verdi, 2^k blu, e per combinazione si ottengono 2^(3k) colori diversi. Questi colori sono "distribuiti uniformemente" sulla gamma di colori possibili. Supponiamo che un'applicazione usi solo una certa sotto-gamma di colori (es: un tramonto usa colori con molto rosso, qualche verde, poco blu), ma su quella gamma voglia una precisione maggiore di quella offerta dai k bit di profondita' che sono disponibili per ogni colore. Il colore puo' essere specificato come un indice in una "tavolozza" messa a disposizione dal window management system. I bit di profondita' vengono interpretati come indici nella tabella (detta look-up table) e non come valori di colore RGB. Con 3k bit per il colore, posso indirizzare una tabella di 2^(3k) colori diversi, scelti a seconda delle mie necessita' (invece che uniformemente distribuiti per componenti R,G e B). Importante nel caso il frame buffer abbia una profondita' limitata.

    La lookup table del colore

    Supponiamo che la profondita' del frame buffer sia k bit per pixel (attenzione qui k non e' quello di prima!). Ogni valore (indice) e' un intero fra 0 e 2^k -1. la look-up table ha 2^k campi. Ciascun campo contiene la specifica di un colore in formato RGB.

    Supponiamo di poter visualizzare colori con accuratezza di m bit. Disponiamo di 2^m rossi, 2^m verdi e 2^m blu. Possiamo produrre 2^3m colori diversi sul display. Di questi, 2^k sono scelti per essere messi nella tavolozza e associati agli indici.

    La lookup table ha 2^k righe e 3 colonne ciascuna di m bit. Dimensione totale 3m 2^k bit.

    Esempio: k=8, m=0 ==> 256 righe nella look-up table con possibilita' di scegliere 256 fra 2^24 (= circa 16 mila) colori. In modalita' RGB avremmo bisogno di 24 bit per pixel.

    Inizializzare e modificare il contenuto della look-up table significa interagire con il sistema a finestre.