SOLUZIONI DELL'ESEMPIO DI SCRITTO DI INTERFACCE GRAFICHE - A.A. 1998-99 ----------------------------------------------------------------------- DOMANDE DI TEORIA Sulla parte interfacce 1) Vedere pacchetto di dispense intitolato "Il desktop e la sua metafora" 2) Vedere pacchetto di dispense intitolato "Sistemi a finestre"; In OpenGL/XForms il problema e' gestito lasciando al programmatore che scrive l'interfaccia la responsabilita' di associare alla canvas OpenGL un handler per l'evento X "Expose", contenente le istruzioni OpenGL necessarie per ritracciare la scena. Sulla parte grafica 1) Vedere pacchetti di dispense intitolato "Introduzione alla computer graphics" e "La libreria grafica OpenGL" 2) Vedere pacchetti di fotocopie di lucidi intitolato "Trasformazioni geometriche bidimensionali" e "Trasformazioni geometriche tredimensionali" ESERCIZI 1) - La prima istanza del cubo e' soggetta nell'ordine ad una scalatura di fattori (1,1,10) sui tre assi, che lo porta ad essere un parallelepidedo con angoli (0,0,0)-(1,1,10) e poi ad una traslazione con vettore di traslazione (2,2,0). - La seconda istanza del cubo e' soggetta nell'ordine ad una scalatura di fattori (5,5,1), che lo porta ad essere un parallelepidedo con angoli (0,0,0)-(5,5,1) e poi ad una traslazione con vettore di traslazione (0,0,10). - La scena mostra due parallelepipedi con facce parallele ai piani coordinati, uno di diagonale (2,2,0)-(3,3,10) e l'altro di diagonale (0,0,10)- (5,5,11). - Se eliminassimo glPushMatrix e glPopMatrix, la seconda istanza del cubo sarebbe sottoposta anche alle trasformazioni della prima, cioe' subirebbe nell'ordine le trasformazioni: scalatura con fattori (5,5,1), traslazione di vettore (0,0,10), scalatura con fattori (1,1,10), traslazione di vettore (2,2,0). [Osservazione facoltativa: Notare che entrambe le scalature tengono ferma l'origine, ma nella prima l'origine e' uno dei vertici dell'oggetto, mentre nella seconda l'origine e' un punto esterno all'oggetto, quindi come effetto collaterale della scalatura l'oggetto viene anche spostato aumentando di 10 volte la sua distanza dall'origine lungo l'asse z.] - per dare a ciascun cubo un colore diverso, si inserisce una chiamata a glColor (con i parametri del colore voluto) immediatamente prima di ciascuna delle due chiamate a glCallList. [Variante facoltativa: ciascuna delle due coppie di comandi glColor+glCallList puo' essere fatta precedere da una chiamata a glPushAttrib e seguire da una chiamata a glPopAttrib; in tal modo, dopo aver disegnata la seconda istanza del cubo, il colore corrente (col quale saranno disegnate eventuali primitive seguenti) e' di nuovo quello che era presente prima di disegnare i due parallelepipedi.] - Il mio tavolo ha gambe a base quadrata di lato 1x1 unita', alte 4 unita', il piano del tavolo e' quadrato di lato 6x6 unita' ed e' spesso 1 unita'. Il tavolo e' posizionato in modo tale che il suo bounding box abbia diagonale (0,0,0)-(6,6,5) [La descrizione del tavolo deve preferibilmente essere corredata da una figura esplicativa; la figura puo' sostituire la descrizione se tutte le misure sono riportate in modo chiaro] Costruisco il tavolo posizionando 5 istanze del cubo nel modo seguente: glPushMatrix(); glTranslate(0,0,4); glScalef(6,6,1); glCallList(cubo); /* piano del tavolo */ glPopMatrix(); glPushMatrix(); glScalef(1,1,4); glCallList(cubo); /* prima gamba */ glPopMatrix(); glPushMatrix(); glTranslate(5,0,0); glScalef(1,1,4); glCallList(cubo); /* seconda gamba */ glPopMatrix(); glPushMatrix(); glTranslate(0,5,0); glScalef(1,1,4); glCallList(cubo); /* terza gamba */ glPopMatrix(); glPushMatrix(); glTranslate(5,5,0); glScalef(1,1,4); glCallList(cubo); /* quarta gamba */ glPopMatrix(); 2) - L'interfaccia realizzata e' costituita da una finestra di 200x320 pixel, contenente uno slider verticale ed un box. I valori estremi dello slider sono -1 e +1, ed il cursore e' posizionato inizialmente sul valore 0.5. L'etichetta del box e' la stringa "--". [E' necessaria una figura, che qui non viene riportata] - Quando l'utente muove col mouse il cursore dello slider, il suo valore attuale viene stampato su standard output. - Utilizzo il box gia' presente nbella form. Memorizzo tale box in una variabile globale mybox di tipo FL_OBJECT * affinche' sia visibile all'interno della callback dello slider. Semplicemente sostituisco l'istruzione obj = fl_add_box(...); con mybox = fl_add_box(...); Modifico la callback dello slider sostituendo la printf con la seguente istruzione: fl_set_object_label(mybox,); - Inserisco due variabili globali FL_OBJECT *sli1, *sli2; per i due slider. Il primo slider e' lo "slider1" gia' presente, il secondo slider e' anch'esso verticale, posizionato a destra del primo [Nota: e' gradita figura]. Il valore iniziale del secondo slider sara' -0.5 (l'opposto di quello del primo). I due slider condivideranno la stessa callback con diverso parametro "user_data". La definizione della form cambia in: form = fl_bgn_form(...); sli1 = fl_add_slider(FL_VERT_SLIDER,30,50,40,180,"slider1"); sli1 = fl_add_slider(FL_VERT_SLIDER,90,50,40,180,"slider2"); fl_set_slider_bounds(sli1,-1.0,1.0); fl_set_slider_bounds(sli2,-1.0,1.0); fl_set_slider_value(sli1,0.5); fl_set_slider_value(sli1,-0.5); fl_set_object_callback(sli1,slidercallback,1); fl_set_object_callback(sli2,slidercallback,2); obj = fl_add_box(FL_DOWN_BOX,30,260,40,30,""); fl_set_object_label(obj,"--"); fl_end_form(); La funzione slidercallback cambia in: float v = fl_get_slider_value(ob); if (user_data==1) /* callback slider1 */ fl_set_slider_value(sli2,-v); else /* callback slider2 */ fl_set_slider_value(sli1,-v); [Nota: non e' necessario scrivere per esteso i parametri numerici delle fl_add_... (come ho fatto qui), e' sufficiente un disegno ben preciso che mostri bene la collocazione dell'oggetto in questione]