Interazione utente-programma

Slides:



Advertisements
Presentazioni simili
INFORMATICA Altre Istruzioni di I/O
Advertisements

Esercitazioni If nidificati
1 Introduzione ai calcolatori Parte II Software di base.
Introduzione al linguaggio C
© 2007 SEI-Società Editrice Internazionale, Apogeo Unità F2 Selezione.
Iterazione A. Ferrari.
Interazione con lutente I menu. Menu La forma più semplice di interazione con lutente è il menu che fornisce una serie di opzioni tra le quali lutente.
Selezione - approfondimento
1 Informatica Generale Susanna Pelagatti Ricevimento: Mercoledì ore presso Dipartimento di Informatica, Via Buonarroti,
GLUT & OpenGL Ing. Tommaso Coviello Politecnico di Bari
Un nuovo tipo di dati Gli array.
Giuseppe Fabio Fortugno.
Programmazione Procedurale in Linguaggio C++
JavaScript Laboratorio di Applicazioni Informatiche II mod. A.
Caratteri e stringhe di caratteri
Argomenti dalla linea dei comandi Gli argomenti possono essere passati a qualsiasi funzione di un programma, compresa la main(), direttamente dalla linea.
Laboratorio di Linguaggi lezione XI: I/O Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea.
Introduzione agli stream e alle classi
I Thread.
INFORMATICA Altre Istruzioni di I/O. © Piero Demichelis 2 Funzioni di I/O Per la lettura e la scrittura da videoterminale il C prevede numerose istruzioni.
9) If e else. Lab.Calc.I AA2002/03 - cap.92 espressione.
Istruzioni di selezione (If/else/switch)
Sistemi Operativi GESTIONE DEI PROCESSI.
A.A. 2010/2011Ambienti di Programmazione per il Software di Base1 (Es. – 6) Ambienti di Programmazione per il Software di Base Le Stringhe in C Input.
1 LINUX: struttura generale The layers of a UNIX system. User Interface.
Strutture di controllo nel C
Strutture di controllo in C -- Flow Chart --
SOFTWARE I componenti fisici del calcolatore (unità centrale e periferiche) costituiscono il cosiddetto Hardware (alla lettera, ferramenta). La struttura.
I File.
Espressioni condizionali
1 Programmazione grafica: lInterazione Daniele Marini.
L' ARCHITETTURA DI VON NEUMANN
PROGRAMMARE IN C Un ambiente di sviluppo `e un software che serve per scrivere ed eseguire programmi. Generalmente integra almeno 3 funzionalita’: Editor:
Corso di informatica Athena – Periti Informatici
Parte 1 Introduzione alla Teoria dei Circuiti
In molti casi è utile assegnare a degli identificatori dei valori che restino costanti durante tutto il programma e che non possano essere cambiati nemmeno.
void binario(int n); …………………
Creazione progetto in C++/DEV
Unità Didattica 3 Linguaggio C
Passaggio di parametri per indirizzo
Utilizzo di Vettori e Funzioni a.s. 2012/13. Pagine Web Anche nelle pagine Web (linguaggio JavaScript) vengono utilizzati Vettori e Funzioni. Le Funzioni.
Sviluppare un programma in C che, dato un array da 100 elementi interi caricato con numeri casuali compresi tra [10,100], sia in grado di cercare il valore.
Corso JAVA Lezione n° 12 Istituto Statale di Istruzione Superiore “F. Enriques”
Introduzione al C Davide Gadia.
Primitive grafiche e interazione Daniele Marini Corso Di Programmazione Grafica e Laboratorio.
Corso di Programmazione Grafica e Laboratorio Daniele Marini
1 Programmazione grafica: l’Interazione Daniele Marini.
Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni – BCOR Ingegneria Elettronica – BELR Introduzione al C Esercitazione 5 D. Bloisi, A.
Complessità ciclomatica
I processi.
Dal problema all’ algoritmo
Lezione 23 Riccardo Sama' Copyright  Riccardo Sama' Lavorare con gli strumenti.
Introduzione a Javascript
INTERFACCE Schede elettroniche che permettono al calcolatore di comunicare con le periferiche, che possono essere progettate e costruite in modo molto.
Corso di Algoritmi e Strutture Dati APPUNTI SUL LINGUAGGIO C
Capitolo 6 Iterazione Lucidi relativi al volume: Java – Guida alla programmazione James Cohoon, Jack Davidson Copyright © The McGraw-Hill Companies.
Università di Torino – Facoltà di Scienze MFN Corso di Studi in Informatica Programmazione I - corso B a.a prof. Viviana Bono Blocco 7 – Array.
Tecnologie Informatiche ed Elettroniche per le Produzioni Animali
Fabio Scotti – Università degli Studi – Laboratorio di programmazione per la sicurezza 1 Lezione 13 e 14 GESTIONE DEI FILE A) Nozioni sulla gestione dei.
CORSO DI PROGRAMMAZIONE II
1 Il linguaggio C Precisazioni sull’esperienza in laboratorio.
Il software Componente del computer costituita dai: –programmi di base per la gestione del sistema –programmi applicativi per l’uso del sistema Queste.
1 Input/Output. 2 Livelli del sottosistema di I/O Hardware Gestori delle interruzioni Driver dei dispositivi Software di sistema indipendente dal dispositivo.
Operatori di incremento e decremento
1 Input/Output. 2 Livelli del sottosistema di I/O Hardware Gestori delle interruzioni Driver dei dispositivi Software di sistema indipendente dal dispositivo.
Linguaggio C: Le basi Stefano Cagnoni e Monica Mordonini
Programmazione dei Calcolatori Elettronici
1 Informatica di Base Facoltà di Lingue e Letterature Straniere Corso di laurea in Relazioni Pubbliche.
Le modalità attraverso le quali gli utenti interagiscono con il computer A cura di Eleonora Bilotta.
Appunti su formati numerici. Tipi numerici Il C dispone di due tipi numerici: tipi interi e tipi reali; I tipi reali sono anche detti floating, ovvero.
Transcript della presentazione:

Interazione utente-programma (dal punto di vista dell'OpenGL)

elementi di interazione uomo->macchina: dal punto di vista astratto possiamo elencare: LOCATOR specifica un punto (x,y) su schermo (ad es click del mouse) STROKE specifica un insieme di punti (traccia del mouse, oppure una serie di click del mouse) STRING una stringa di caratteri ("edit object") VALUATOR un valore scalare (uno slider..) CHOICE scelta in un menu' PICK selezione di una componente di un'immagine strutturata...

i componenti elencati fanno spesso parte di un sistema grafico (es XWindows, la Borland Builder Visual Class Lib, Java..., ecc); dal punto di vista dell'esecuzione del programma, abbiamo varie situazioni: un programma puo' decidere quando ha bisogno di dati (request mode), e i dati devono essere forniti al momento della richiesta es. tipico in/out stile "console" unix o msdos : printf("inserisci un intero"); scanf("%d", &dato); oppure cout<<"inserisci dato"; cin>>dato; ... il programma su scanf oppure su cin>> si ferma e aspetta il dato; l'istruzione di lettura e' sincronizzata con l'immissione del dato;

schema a eventi: il programma esegue costantemente un ciclo di attesa di evento, ovvero il programma lavora indipendentemente dal dispositivo che genera i dati: quando il dato serve al programma esso lo preleva (sample mode, campionamento) da una memoria comune, che e' la coda degli eventi (di vario genere) se la coda eventi e' vuota e il programma e' in attesa ("idle") l'OpenGL prevede la possibilita' di far fare al programma qualcosa "se non c'e' null'altro da fare allora fai questo" ancora, "event mode": dall' ingresso (uno dei ..) viene generato un dato che va inserito in una coda di eventi; appena possibile, il progr.(sistema OpenGL) esamina la coda di eventi e in base al tipo di evento e al dato associato esegue quanto richiesto; l'OpenGL prevede questo come specifica normale di funzionamento:

int main (int argc, char **argv) { myOpenWindow( argc, argv ); /* GLUT init */ myInitProj( ); /* init projection matrix */ glutKeyboardFunc( myKeyboard ); /*<<<<<< */ glutSpecialFunc ( myArrowkeys ); /*<<<<<< */ glutReshapeFunc ( myReshape ); /*if reshape*/ glutDisplayFunc ( myDisplay ); /* chiamata da glutPostRedisplay() */ glutMainLoop( ); return (0); } /* main() */ /*le procedure glutEventFunct(myProc) hanno parametro di tipo indirizzo di procedura, e myKeyboard, myArrowkeys, myReshape, sono procedure (che scrivo io) da eseguire in risposta agli eventi specificati:

procedura da eseguire se si preme un tasto, notificata dal main al sistema OpenGL glut prima di eseguire il glutMainLoop(); con la glutKeyboardFunc( myKeyboard ): void myKeyboard( unsigned char key, int x, int y) { switch (key) { case 'b': case 'B': /* cambia stato */ blend_colors = ! blend_colors; break; case 27 : /*ESC key-default Unix exit*/ case 'q': case 'Q': exit(0); } glutPostRedisplay(); /*ridisegna appena possib*/ } /* myKeyboardPP() */

vediamo alcuni problemi associati all'ingresso dati

questo e' il caso piu' semplice: una situazione molto frequente si verifica quando abbiamo un dispositivo di puntamento (es. un mouse) che viene usato per selezionare un oggetto: abbiamo il problema della distanza tra il punto PCM "posizione corrente del mouse" (marcato sullo schermo da una freccia) e un altro punto P(di un oggetto da selezionare) questo e' il caso piu' semplice: test di "vicinanza" equivale al test di "distanza tra due punti minore di una soglia LIMITE" : vicino = | P - PCM | < LIMITE P PCM

dist = sqrt( dx*dx + dy*dy ) se i due punti sono pensati come estremi distanza tra due punti P1(x1,y1) P2(x2,y2) se dx=x2-x1 e dy = y2-y1 allora dist = sqrt( dx*dx + dy*dy ) se i due punti sono pensati come estremi di un vettore allora dist = lunghezza del vettore P1 dist dy dx P2

double dist ( double x1, double y1, double x2, double y2) { /* distanza tra due punti, buon vecchio Pitagora */ return sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) ); } /* dist */

a) test di punto vicino / non vicino ad un lato oppure un altro esempio di test di vicinanza e' il test di un punto (posizione del mouse) vicino ad un poligono (es un rettangolo); in tal caso il test puo' essere visto in due modi: a) test di punto vicino / non vicino ad un lato oppure b) test di punto esterno / interno ad un poligono vediamo il problema di punto vicino ad un lato, ovvero il problema di punto vicino ad un segmento: P s1 s2

seguono alcuni richiami di geometria: punto, vettore, prodotto scalare, retta, proiezione di vettore su retta, distanza punto retta segue poi un cenno sul test di punto esterno / interno ad un poligono

vettore = definito da due punti: VP = P2 - P1 ha una lunghezza | VP | == | P2-P1 | == dist(P2,P1) == sqrt( dx*dx + dy*dy ) un orientamento rispetto il sistema di riferimento = angolo rispetto asse x P2 angolo P1

vettore = due punti = VP = P2 - P1 vettore=somma di due vettori S = VP1+VP2=(x1+x2,y1+y2) prodotto scalare: x = VP1 . VP2 = |VP1| * | VP2 | * cos(a) se uno dei due (ad es.VP1) e' unitario, il prodotto scalare e' | VP2 | * cos(a) = pr ed e' la proiezione di VP2 su VP1 se entrambi sono unitari, il prodotto scalare e' cos(a), con a angolo tra i due vettori ... da cui cos(a) = (VP1.VP2)/(|VP1| * | VP2 |) (useremo in seguito!) P2 S VP1 a P1 VP2 VP2 a pr VP1

(x-x1)/(x2-x1)=(y-y1)/(y2-y1) retta: si definisce in molti modi: y=mx+b (y-y1)=m(x-x1) x/a + y/b = 1 (con m = -b/a) x = ax * t, y = ay * t (parametrico) (x-x1)/(x2-x1)=(y-y1)/(y2-y1) P1(x1,y1) y=b P2(x2,y2) x=a

retta individuata con due punti, P1 e P2, equazione (r = P2-P1) P = (P2-P1)*k = r * k con (x-x1) (x2-x1) -------- = --------- (y-y1) (y2-y1) (y-y1) = (x-x1)/(x2-x1)*(y2-y1) y= m * x + dy dove m = (y2-y1)/(x2-x1) e dy = (y1*x2-x1*y2)/(x2-x1) P2 r P1 P

distanza punto P -- retta P1-P2 punto P -- segmento P1-P2 P P2 d r P1

DISTANZA PUNTO P - RETTA (P1,P2) ( retta data dai due punti P1,P2 = dal vettore r (dx,dy) ) un vettore perpendicolare alla linea e' (scambia dx,dy e cambia segno per una componente): v = ( (y2-y1), -(x2-x1) ) allora la distanza punto P e retta e' data dal prodotto scalare del vettore v normale alla retta e del vettore t = P1-P che unisce P e P1, ((x1-x),(y1-y)), quindi dist = |v . r| |(x1-x)*(y2-y1)- (y1-y)*(x2-x1)| dist = ---------------------------------- sqrt((x2-x1)^2+(y2-y1)^2) P2 P v dy t r P1 dx r v

double distanza_P0_retta12 (int x0, int y0, int x1, int y1, int x2, int y2) { /*distanza di un punto P0 da una retta def.da r=P1-P2, distanza calcolata come prodotto scalare del vettore P1-P0 e del vettore v normale alla retta (a r), definita da (x1,y1) a (x2, y2), il punto e'(x0,y0) */ double lung; double vx,vy; /* v */ /* vettore normalizzato (lung==1) perpendicolare */ lung = dist(x1,y1, x2,y2); if (lung==0.0) return -999.0; /* nulla da fare...*/ /* componenti del vettore perpendicolare a P1-P2 */ vx = -(y2-y1)/lung; vy = (x2-x1)/lung; /*proiezione di P0-P1 su v perpendicolare a r e norm*/ vldis = fabs( vx*(x0-x1) + vy*(y0-y1) ); return vldis; } /* distanza_P0_retta12 */

peraltro si noti che per stabilire la vicinanza di un punto ad un lato di un poligono non e' sufficiente stabilire che il punto e' vicino alla retta che passa per il lato: p3 tutti e tre i punti p1,p2,p3 sono vicini alla retta che passa per il lato A-B, nel senso che la distanza punto-retta e' piccola per p1,p2,p3; ma solo il punto p2 e' vicino al lato; si dovra' quindi tenere anche conto della posizione rispetto il segmento A-B p2 p1 B A

calcolo la proiezione con segno del vettore A-> pk , sul segm. vediamo meglio: calcolo la proiezione con segno del vettore A-> pk , sul segm. A-B, data dal prodotto scalare di r (unitario) (A-B)/|A-B| per A-> pk si avra' per i tre punti : ( p1-A ) . r < zero, zero < ( p2-A) . r < lungh(A-B), ( p3-A) . r > lungh(A-B) e quindi p2 e' vicino al lato A-B, p1 e p3 non lo sono; dist=linedist( x,y, xa,ya,xb,yb ); onsegm=vertonseg( if( (d<limit) && (onsegment) ) { allora..e'.vicino..} p3 p2 r p1 B A

double vlineproj (int x0, int y0, int x1, int y1, int x2, int y2) { /* calcola la proiezione del vettore P1-P0 sulla retta definita dai due punti P1 P2, con segno; usata poi in vertonseg qui sotto */ double vlpro, lung; double rx,ry; /* r = (P2- P1),unitario */ lung = dist(x1,y1,x2,y2); if (lung==0.0) return -999.0; rx=(x2-x1)/lung; ry=(y2-y1)/lung; vlpro=rx*(x0-x1)+ry*(y0-y1); return vlpro ; } /* vlineproj */ bool vertonseg(int x0, int y0, int x1, int y1, int x2, int y2) { /* vale true 1 se la proiezione di t sta sul segmento */ double prz, lung; lung = dist(x1,y1,x2,y2); if (lung==0.0) return -999.0; prz = vlineproj(x0,y0,x1,y1,x2,y2) ; if (prz >=0 && l<=lung) return 1; else return 0; } /* vertonseg */

nella figura a fianco il cursore (quadratino verde) e' posizionato vicino al segmento diagonale a destra, il programma riconosce (con un controllo di vicinanza del cursore a tutti i segmenti dell' immagine) quale segmento e' vicino al cursore, e questo appare evidenziato piu' chiaro,

cenno sul test di punto esterno / interno ad un poligono Pinterno Pesterno

appartenenza di un punto ad un poligono: test di punto P dentro/fuori di un poligono: esistono vari metodi per poligoni generali, es: regola dell' attraversamento pari/dispari : dato P, scelgo punto Q lontano dal poligono, poi conto quante volte si attra- versa un lato del poligono percorrendo tutti i punti da P a Q: P e' dentro se dispari, fuori se pari: in figura sopra, da A (oppure B) a Q sono due (o 4)attraversamenti -> A e B sono fuori, da C a S (oppure T) sono uno (o 3) attraversamenti -> C e' dentro S Q A T C B Q

un altro metodo: test di punto P dentro/fuori regola dell'attraversamento orientato: si conta quante volte un seg- mento P-Q (Q lontano) viene attraversato dai lati orientati del poligono, contando +1 se il lato attraversa P-Q da dest a sinistra, e -1 se viceversa; alla fine, se il conto e' non zero, allora P sta dentro altrimenti sta fuori; A D C P Q B

un altro problema da notare: test di vicinanza - ma in che coordinate? quando muovo il mouse, spesso il sistema fornisce al programma le coordinate schermo della posizione corrente del mouse; se si vuole ottenere le coordinate del "mondo utente" o "mondo oggetto" allora si deve fare a ritroso la trasformazione che normalmente viene fatta dalle coordinate oggetto alle coordinate schermo: model -> object world -> viewport (almeno 2 matrici di trasformazione, "MODEL_VIEW" e "PROJECTION", la seconda e' predisposta ad es. dalle procedure di inizializzazione...

... glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, MyWidth, 0.0, MyHeight ); // <<<<<<< glViewport(0, 0, MyWidth,MyHeight); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef(MyBariX,MyBariY,0.0); // <<<<<<< glRotatef(MyAlfa, 0.0, 0.0, 1.0); // <<<<<<< glTranslatef(-MyBariX,-MyBariY,0.0); glTranslatef(MyBariX,MyBariY,0.0); glScalef( MyScala, MyScala, 1.0); // <<<<<<< glTranslatef(-(MyBariX),-(MyBariY),0.0); drawMyObject(); le coordinate (x,y) dell'oggetto sono sempre trasformate attraverso la pipeline di visualizzazione in coordinate schermo... ad es. (0.2,0.01) in un mondo 0.0..1.0, oppure (5700.0,-4000.0) in un mondo (-10000.. +10000)

viceversa, se voglio poi nel programma eseguire un test di vicinanza, devo ri-passare da coordinate viewport del mouse a coordinate del mondo oggetto correnti: ... getRealXY ( MyPassMousePosX, MyPassMousePosY, X, Y ); if( dist(X,Y, MyBariX,MyBariY) < D_NEAR ) { we are near } /* coord.viewport myX,myY => coord.oggetto myXREAL,myYREAL */ void getRealXY(int myX,int myY, int& myXREAL,int& myYREAL) { GLint viewport[4]; GLdouble mvmatrix[16], projmatrix[16]; GLdouble wx,wy,wz; /* current window coordin. to current my object coord */ glGetIntegerv (GL_VIEWPORT, viewport); glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix); glGetDoublev (GL_PROJECTION_MATRIX, projmatrix); gluUnProject ( (GLdouble) myX, (GLdouble) myY, 0.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz ); myXREAL = (GLint) wx; /* un-project== un-transform */ myYREAL = (GLint) wy; } /* getRealXY */

Riempimento (filling): un procedimento intuitivo e': void fillR4(int x,int y, tcol bordo, tcol fillcolore){ tcol corrente = getPixel(x,y); /* colore del pix corrente */ if( corrente != colorebordo && corrente != fillcolore ) { setPixel(x,y); /* allora setColore/fillcolore; poi vedi vicini: */ fillR4(x+1, y, bordo, fillcolore ); /* destra */ fillR4(x-1, y, bordo, fillcolore ); /* sinistra */ fillR4(x, y+1, bordo, fillcolore ); /* su */ fillR4(x, y-1, bordo, fillcolore ); /* giu' */ } /* if */ } /* fillR4 */ procedimento ricorsivo per visita dei 4 pixel adiacenti (ma costa molta memoria per lo stack); meglio: procedere per linee orizzontali verso sin e verso dest, e poi procedere alle due linee sopra/sotto, e ripetere separatamente per le due linee

esempio di uso di procedura di fill (a fianco un es.di esecuzione, partendo dai punti A e B) /*fillColor =1,interiorColor=0 */ void FloodFill4 (int x, int y) { if( x<0 || /* controlla */ y<0 || /* se out! */ x>=RasterSizeX || y>=RasterSizeY ) return; /*check se colore interno*/ if( getPixel( x,y ) == 0 ) { DrawMode = DRAW_OR; setPixel( x,y, 1 ); FloodFill4 ( x+1, y ); FloodFill4 ( x-1, y ); FloodFill4 ( x, y-1); FloodFill4 ( x, y+1); } /* if */ } /* FloodFill4 */ A B

A) PIU' FINESTRE: il sistema glut permette di avere piu' finestre; esse sono create con la glutCreateWindow, che fornisce in uscita l'identificatore (un numero intero da 1 in poi) ad ogni finestra sono associate delle proc di gestione evento: ... myWinID1=glutCreateWindow("OGL5E_WWW_111"); glutSetWindow(myWinID1); myCurrentWin = myWinID1; glutDisplayFunc ( myDisplay1 ); myWinID2 = glutCreateWindow("OGL5E_WWW_222"); glutSetWindow(myWinID2); myCurrentWin = myWinID2; glutDisplayFunc ( myDisplay2 ); ... poi posso attivare la prima finestra: myCurrentWin = myWinID1; /* NOTA !! glutSetWindow(myWinID1);

piu' finestre ... void myOpen2Windows( int argc, char* argv[ ] ) { glutInit(&argc, argv); /*GLUT initialization here comune :*/ glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); /* for the first window: */ glutInitWindowPosition( Xwp1, Ywp1 ); glutInitWindowSize( Xww1, Ywh1 ); myWinID1 = glutCreateWindow("EGD4_D uno"); /* NOTA IL N.RO FINESTRA myWinID1 */ glutSetWindow(myWinID1); myCurrentWin = myWinID1; glutDisplayFunc ( myDis1 ); ... glutReshapeFunc ( myRes1 ); glutKeyboardFunc( myKeyb1 ); /* now the second window: */ glutInitWindowPosition( Xwp2, Xwp2 ); glutInitWindowSize( Xww2, Ywh2 ); myWinID2 = glutCreateWindow("EGD_4D due "); glutSetWindow(myWinID2); myCurrentWin = myWinID2; glutDisplayFunc ( myDis2 ); glutReshapeFunc ( myRes2 ); glutKeyboardFunc ( myKeyb2 ); glutSetWindow(myWinID1); myCurrentWin = myWinID1; } /* myOpenWindow */

piu' finestre ... void myOpen2Windows( int argc, char* argv[ ] ) { glutInit(&argc, argv); /* parte comune */ glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); /* W1 */ glutInitWindowPosition( ... ); glutInitWindowSize( ... ); myWinID1=glutCreateWindow("Titolo"); glutSetWindow(myWinID1); myCurrentWin = myWinID1; glutDisplayFunc ( myD1 ); glutReshapeFunc ( myR1 ); glutKeyboardFunc ( myK ); /* W2 */ myWinID2 = glutCreateWindow("OGL5E_WWW_222"); glutSetWindow(myWinID2); myCurrentWin = myWinID2; glutDisplayFunc ( myD2 ); glutReshapeFunc ( myR2 ); glutKeyboardFunc ( myK ); /* NOTA : cambia finestra attiva: */ glutSetWindow(myWinID1); myCurrentWin = myWinID1; } /* myOpenWindow */

piu' finestre in figura lo schermo dopo la creazione di due finestre, la seconda finestra e' attiva

piu' finestre in figura lo schermo dopo la creazione di due finestre, qui e' attiva la prima finestra:

piu' finestre void myKeyboard(unsigned char key, int x, int y) { switch (key) { case '1': glutSetWindow( myWinID1 ); glutPopWindow(); break; case '2': glutSetWindow( myWinID2 ); case '3': if (myWinID3==0) myMakeNewWin(); glutSetWindow( myWinID3 ); case 'k': if( myWinID3 !=0 ) { glutDestroyWindow(myWinID3); myWinID3 = 0; } break; } } // switch e myKeyboard ...

piu' finestre la terza finestra e' creata dopo, procedura tipo: void myMakeNewWin() { glutInitWindowPosition( 50,300 ); glutInitWindowSize( 400,400 ); myWinID3 = glutCreateWindow("EGD4_D tre "); myCurrentWin = myWinID3; glutDisplayFunc ( myDisplay3 ); glutReshapeFunc ( myReshape3 ); glutKeyboardFunc ( myKeyboard ); glutSetWindow(myWinID3); glutPopWindow(); } // myMakeNewWin

piu' finestre in figura dopo la creazione della terza finestra

piu' finestre durante l'esecuzione si puo' cambiare posizione e dimensione della finestra; qui, con il tasto spazio, si agisce sulla win 2: void myKeyboard(unsigned char key, int x, int y) { switch (key) { .... case ' ': if( myWinID2 !=0 ) { /* se esiste la finestra 2 ...*/ Xmaxw2=300+rand()%200; Ymaxw2=200+rand()%200; Xpos_win2= rand()%500; Ypos_win2= rand()%400; glutSetWindow( myWinID2 ); glutPopWindow(); glutPositionWindow(Xpos_win2, Ypos_win2); glutReshapeWindow(Xmax_win2, Ymax_win2); glViewport( 0, 0, Xmax_win2, Ymax_win2 ); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D( ... ); /* y=0 on bottom */ } } } // myKeyboard

piu' viewport void myDisplay3(void) { float x1,y1,x2,y2,dx,dy,r,g,b; // in una finestra si possono int k; int wid, hi; // avere due viewport (o piu'): wid = glutGet(GLUT_WINDOW_WIDTH); hi = glutGet(GLUT_WINDOW_HEIGHT); myClear(); /* clear current window (all!) * / glViewport(0, 0, wid/2, hi); /* left half window !! * / glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D( 0.0, 1.0 /* x1,x2 */ , 0.0, 1.0 ); /* y=0 on bottom */ myTriFull(-0.1, 1.1, 1.1, 0.9, 0.5, -0.1, 0, 1, 1 ); /* cyano */ glViewport(wid/2, 0, wid, hi); /* right half window */ gluOrtho2D( 0.0, 1.0, 0.0, 1.0 ); /* y=0 on bottom * / myTriFull(-0.1, 0.1, 1.1, -0.1, 0.5, 1.2, 1, 0,1 ); /*magenta*/ glFlush(); } /* myDisplay3 * /

terza finestra con due viewport glViewport(0, 0, wid/2, hi); /* left half window !! * / disegna in viewport a sinistra ... glViewport(wid/2, 0, wid, hi); /* right half window */ disegna in viewport a destra ...

piu' finestre, piu' viewport, ...

FINE EGD15_interaz2D