Laboratorio di Grafica Interattiva A.A. 2003-4

Esercizio 3

Argomento

Zoom e pan in OpenGL.

Files

Nessun file nuovo. Si parte da quelli dell'esercitazione precedente.

Esercitazione guidata

Prima tappa

Aggiungete al menu' pop-up della work area un sotto-menu' per selezionare una primitiva tra quelle presenti (indicandole con numeri da 1 a 5) oppure nessuna primitiva. La primitiva selezionata viene evidenziata, per es. disegnando dei quadratini attorno ai suoi vertici.

Fate in modo che i comandi di cambio degli attributi (spessore di linea, colore ecc.) agiscano solo sulla primitiva selezionata, mentre le altre mantengono inalterati gli attributi che avevano in precedenza.

Ognuna delle 5 primitive deve avere proprie variabili che tengano memoria dei suoi valori degli attributi. Queste variabili vanno aggiunte alla classe C++ che mantiene le informazioni sulla primitiva. Il costruttore assegna agli attributi valori di default, che l'utente potra' cambiare.

Usate glPushAttrib e glPopAttrib per avere un cambio temporaneo dell'attributo mentre si sta disegnando una primitiva:

Seconda tappa

Aggiungete la possibilita' di eseguire le seguenti operazioni sulla scena visualizzata in work area:

Per adesso l'utente invoca zoom battendo la sequenza di tasti "z+" o "z-" ed invoca pan usando i tasti freccia.

Le coordinate del mondo vengono scalate e traslate.
Siccome siamo in 2D, possiamo fare questo agendo indifferentemente sulla trasformazione di vista o su quella di proiezione:

Terza tappa

Aggiungete la possibilita' di eseguire operazioni di zoom e pan che interessano solo la primitiva selezionata e ne cambiano la dimensione / posizione rispetto al resto della scena.
Zoom e pan implementati per l'intera scena vanno mantenuti.

Se una primitiva e' selezionata, allora i prossimi comandi di zoom e pan immessi dall'utente agiscono su di essa. Altrimenti agiscono sull'intera scena.

Ognuna delle 5 primitive deve avere proprie variabili che tengano memoria del fattore di scala e del vettore di traslazione. Queste variabili vanno aggiunte alla classe C++ che mantiene le informazioni sulla primitiva. Il costruttore ne inizializza opportunamente i valori.

Pensiamo la scena disegnata nella work area come fatta da piu' oggetti:

Nella versione attuale gli oggetti (primitve ed assi) sono gia' definiti nello stesso sistema di coordinate. Le coordinate di modellazione di ciascuno di essi coincidono con le coordinate del mondo. La trasformazione di modellazione che li porta nel mondo e' la trasformazione identica.

Nella nuova versione la trasformazione di modellazione che agisce su ciascuna primitiva e' una scalatatura (zoom) e/o una traslazione (pan).
La scalatura deve avvenire tenendo fermo il baricentro della primitiva. Dopo la scalatura interviene la traslazione.

Per fare una scalatura che tenga fermo il baricentro, prima trasliamo per portare il baricentro nell'origine, poi scaliamo (il baricentro resta fermo), poi eseguiamo la traslazione inversa per riportare il baricentro (ora nell'origine) alla sua posizione originaria,

Ricordate che in OpenGL le trasformazioni vanno scritte in ordine inverso a quello in cui vogliamo che siano eseguite.
E ricordate di usare glPushMatrix e glPopMatrix per cambiare la matrice modelview solo temporaneamente mentre si sta disegnando una primitiva.