38
1 Programmazione grafica: l’Interazione Daniele Marini

1 Programmazione grafica: lInterazione Daniele Marini

Embed Size (px)

Citation preview

Page 1: 1 Programmazione grafica: lInterazione Daniele Marini

1

Programmazione grafica: l’Interazione

Daniele Marini

Page 2: 1 Programmazione grafica: lInterazione Daniele Marini

2

Generalità

• L’interazione dipende dalle caratteristiche dei dispositivi fisici e del sistema operativo

• OpenGL si appoggia sul window manager (X-Window, Microsoft Windows, Mac, ..)

• Per interfacciare OpenGL al window manager faremo uso di GLUT, indipendente dallo specifico WM

Page 3: 1 Programmazione grafica: lInterazione Daniele Marini

3

Dispositivi di input

Dispositivi logici e dispositivi fisici: analogo al rapporto indotto da funzioni come: printf, scanf, getchar, putchar: si puo’ leggere o scrivere su file, stampante, display, tastiera ecc.

Nella grafica è più complesso: non sono solo caratteri!

Page 4: 1 Programmazione grafica: lInterazione Daniele Marini

4

Dispositivi di input

• Dispositivi di puntamento: per indicare una posizione su uno schermo, comprende bottoni per inviare interrupt o segnali

• Mouse

• Trackball

• Tablet

• Light pen

• Joystick

• Spaceball

• Tastiera: invia caratteri

Page 5: 1 Programmazione grafica: lInterazione Daniele Marini

5

Mouse/trackball

• Non trasmettono posizione ma velocità

• I due valori rilevati dal movimento della sferetta sono incrementi relativi, posti in relazione all’intervallo di tempo danno luogo al calcolo di una velocità, la cui integrazione restituisce una posizione relativaposizione relativa

• Permette di ottenere movimenti lenti o veloci del cursore

Page 6: 1 Programmazione grafica: lInterazione Daniele Marini

6

tablet

• Fornisce posizione assoluta

• La posizione viene rilevata con interazione elettromagnetica della punta di una penna speciale con una maglia di fili annegati nella superficie

• Touch screen ha funzioni analoghe

Page 7: 1 Programmazione grafica: lInterazione Daniele Marini

7

lightpen

• Un sensore ottico rileva la presenza di luce dal display, invia un interrupt all’host, che ricava la posizione conoscendo l’istante di rilevazione dell’interrupt e il tempo di scansione della figura; identifica l’oggetto grafico indicato conoscendo l’intera struttura dati e il modo di attraversamento della struttura

• Limiti dovuti alla complessità e alla soglia di illuminazione: se punta lo sfondo non rileva luce!

Page 8: 1 Programmazione grafica: lInterazione Daniele Marini

8

Joystick

• Anche il joystick rileva velocità, che vengono integrate per calcolare posizioni relative

• Può avere componenti meccaniche che simulano effetti di resistenza con stimolazione “cinestesica”

Page 9: 1 Programmazione grafica: lInterazione Daniele Marini

9

Spaceball

• Dotata di sensori di pressione, ha sei gradi di libertà ed è adatta ad input 3D:

• Front-back left-right top-bottom

• Rotazioni su tre assi

Page 10: 1 Programmazione grafica: lInterazione Daniele Marini

10

Dispositivi logici - classificazione GKS e PHIGS

• Secondo lo standard GKS e PHIGS sei logical devices:• String - es. tastiera• Locator - fornisce coordinate mondo (WC) es. mouse con conversione da SC (ccordinate schermo) a WC• Pick - restituice l’identificatore di un oggetto• Choice - seleziona una opzione• Dial - input analogico (potenziometri)• Stroke - array di locazioni

Page 11: 1 Programmazione grafica: lInterazione Daniele Marini

11

Logical devices - OpenGL

• string - supportata dal Window Manager (WM), OGL non distingue tra dispositivo fisico e logico (tastiera)• locator - OGL converte da SC a WC con dati da mouse ecc.• Pick - OGL usa il processo selectionselection• choice - OGL usa widgets ((gadget: congegno, dispositivo; gadget: congegno, dispositivo;

aggeggio, arnese)aggeggio, arnese) del WM (menu, scrollbar, bottoni ecc.)• dial - OGL usa widgets del WM (sliders)• stroke - OGL simula l’invio di sequenze di valori attivando e terminando lo stream ad es. col bottone del mouse

Page 12: 1 Programmazione grafica: lInterazione Daniele Marini

12

Misura e trigger

• L’input di un dispositivi fisico è caratterizzato da misuramisura e triggertrigger– Misura: è il valore restituito dal dispositivo– Trigger: è un input fisico con cui l’utente invia un

segnale al sistema• String: measure = caratteri battuti, trigger = CR

• Locator: measure = posizione, trigger = click su bottone

• Si può anche considerare un valore di stato (il cursore è fuori dalla window …)

Page 13: 1 Programmazione grafica: lInterazione Daniele Marini

13

Modi di input

• Request mode– La misura viene ritornata al sistema quando il

trigger viene attivatorequest_locator(device_id, &measure)

• Sample mode– Input immediato, non c’è triggersample_locator(device_id, &measure)

Page 14: 1 Programmazione grafica: lInterazione Daniele Marini

14

• Request mode - tipico di programmi non grafici, es. input da tastiera con scanf– Oppure per posizionare il cursore in WM e selezionare con click

• Sample mode e request mode non sono adatti ad applicazioni in cui l’utente determina il flusso del programma, è piuttosto il programma che guida l’utente (es. scelte di menu, word processing)

• In un simulatore di volo possono esserci input da moltissimi dispositivi

Page 15: 1 Programmazione grafica: lInterazione Daniele Marini

15

Event mode• Permette di trattare situazioni complesse

• In ogni istante ogni dispositivo può generare un evento

• Le measures del dispositivo, con identificatore associato, sono poste in una coda di eventi (event queue) indipendentemente da ciò che sta eseguendo il programma - il programma esamina la coda e decide che fare, se la coda è vuota resta idle

Page 16: 1 Programmazione grafica: lInterazione Daniele Marini

16

Event mode

• Alternativamente si associa a ogni tipo di evento una callbackcallback

• L’approccio con callback è il più usato nei sistemi di WM e in OGL, e si presta a situazioni client-server

Page 17: 1 Programmazione grafica: lInterazione Daniele Marini

17

Client-server• Servizi distribuiti in LAN (printer, file, graphics, ..)• Un programma applicativo OGL e’ un processo client

che usa un graphics server, i due processi possono risiedere sul medesimo sistema o essere distribuiti

Page 18: 1 Programmazione grafica: lInterazione Daniele Marini

18

Display List

• Per poter gestire eventi e interazione è necessario tener traccia della struttura dati grafica generata dal programma e modificata dalla interazione

È più difficile cancellare che disegnare!

Page 19: 1 Programmazione grafica: lInterazione Daniele Marini

19

Display list - origini

• Origine nei sistemi grafici pre-workstation• Registrare in una memoria dedicata (display memorydisplay memory) del

display processor le istruzioni a basso livello (nella forma di diplay filediplay file o display listdisplay list) per generare il disegno sul monitor

• Si distingueva tra monitor a memoria (storage) e monitor refresh (raster)

• Negli storage la DL poteva essere rimossa, nei refresh la DL doveva venire attraversata a ≈ 50 Hz

Page 20: 1 Programmazione grafica: lInterazione Daniele Marini

20

Display list - client server

• Oggi il display processor è un server grafico e il programma applicativo può essere in esecuzione su un client

• Il bottleneck non è tra host e DP, ma tra server e client - due modalità di display:

• Modo immediato (immediate modeimmediate mode)- la primitiva grafica viene spedita al server al momento in cui è definita, e non se ne conserva memoria; per ridisegnarla il programma deve eseguire nuovamente l’istruzione che genera la primitiva

• Modo differito (retained moderetained mode)

Page 21: 1 Programmazione grafica: lInterazione Daniele Marini

21

Display list - client server • Modo differito (retained moderetained mode) - la descrizione della

primitiva viene posta in una display list che risiede nel server grafico, la DL viene attraversata su richiesta del client per ridisegnare la figura

• Vantaggi: » minor traffico di rete» Il client sfrutta le performance grafiche del server» Si tiene memoria della figura per successive modifiche e

interazione

• Svantaggi:» Costo di memoria

Page 22: 1 Programmazione grafica: lInterazione Daniele Marini

22

OGL e Display list

Creazione:glNewList, glEndList

#define BOX 1 /* definisce un quadrato, attribuisce il nome BOX e il numero 1 */glNewList(BOX, GL_COMPILE);

glBegin(GL_POLYGON);glColor3f(1.0, 0.0, 0.0);glVertex2f(-1.0, -1.0);glVertex2f(1.0, -1.0);glVertex2f(1.0, 1.0);glVertex2f(-1.0, 1.0);

glEnd();glEndList;

Page 23: 1 Programmazione grafica: lInterazione Daniele Marini

23

GL_COMPILE flag - indica al sistema di inviare la display list al server ma di non visualizzare la struttura BOX

GL_COMPILE_AND_EXECUTE il display è immediato

Per disegnare la struttura si esegue la funzione:

glCallList(BOX);

Cambiando attributi alla struttura o modificando i parametri di window, viewport, o di proiezione ed eseguendo la glCallList la figura viene disegnata modificata

Page 24: 1 Programmazione grafica: lInterazione Daniele Marini

24

La display list viene usata in modo massiccio per programmi di modellazione geometrica, per trasformare la geometria degli oggetti si usano matrici, attributi e trasformazioni possono essere nidificate con una gestione a stack:

glPushAttrib(GL_ALL_ATTRIB_BITS);glPushMatrix();

e recuperati con:glPopAttrib();glPopMatrix();

Si possono gestire più liste contemporaneamente:glGenLists(number); permette di creare liste con identificatori consecutivi, restituendo il primo intero di number disponibile, sono consecutivi corrispondenti a label non ancora usate;glCallLists permette di eseguire, visualizzandole contemporaneamente, tutte le liste definite (es. gestione del testo con display list, paragrafo 3.4.2 Angel - pag.99-102)

Page 25: 1 Programmazione grafica: lInterazione Daniele Marini

25

Programmazione dell’interazione event driven

• Uso del puntatore• Terminazione programma• Resize della finestra• Gestione della finestra• Menu • Picking

Page 26: 1 Programmazione grafica: lInterazione Daniele Marini

26

Uso puntatore

• Il puntatore può essere usato per la terminazione del programma; distinguiamo tra– move eventmove event: il mouse viene mosso col bottone premuto– passive move eventpassive move event: mosso con bottone alzato

Dopo un move event la “measure” del device (posizione del mouse) è resa disponibile

– mouse eventmouse event - un bottone del mouse è premuto o rilasciato (il bottone mantenuto premuto non genera eventi, è la transizione che conta!)

Page 27: 1 Programmazione grafica: lInterazione Daniele Marini

27

Terminazione programma

glutMouseFunction(mouse_callback_func);

void mouse_callback_func(int button, int state, int x, int y,);

int x, int y;

{

if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)

exit();

}

Altri bottoni o uno stato differente del mouse non provocano nulla, non ci sono callback registrateregistrate col WM

Page 28: 1 Programmazione grafica: lInterazione Daniele Marini

28

main

int main(int argc, char **argv){

glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLLUT_RGB);glutCreateWindow(“square”);myinit();glutReshapeFunc(myReshape);glutMouseFunc(mouse);glutDisplayFunc(display);glutMainLoop();

}

Reshape è invocato quando la finestra viene modificata dall’utenteOgni programma deve avere una display callback, anche vuota:

void display() {}

Page 29: 1 Programmazione grafica: lInterazione Daniele Marini

29

Disegnare un rettangolo al click del mouse

void mouse(int button, int state, int x, int y);{

if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN) drawSquare(x,y);

if(button==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN) exit();

}

La drawSquare si limita a disegnare, gli attributi del disegno vanno definiti altrove, nell’esempio in myinit

Page 30: 1 Programmazione grafica: lInterazione Daniele Marini

30

myinit

/* globals */

Glsizei wh = 500, ww = 500; /* dim finestra iniziale */Glfloat size = 3.0; /* metà del lato del quadrato */

void myinit(void){

glViewport(0,0,ww,wh);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(0.0, (GLdouble) ww , 0.0, (GLdouble) wh , -1.0,

1.0);glMatrixModel(GL_MODELVIEW);glClearColor (0.8, 0.8, 0.8, 1.0);glClear(GL_COLOR_BUFFER_BIT);glFlush();

}

Page 31: 1 Programmazione grafica: lInterazione Daniele Marini

31

Disegno del quadratoL’origine del sistema di riferimento nel WM è in alto a sinistra, con y verso il basso, in OGL è in basso a sinistra con y verso l’alto - bisogna “flippare” la y ritornata dal mouse:

void drawSquare(int x, int y){

y=wh-y; /* flippa y */ glColor3ub( (char) random()%256, (char) random()%256, (char) random()%256); glBegin(GL_POLYGON); glVertex2f(x+size, y+size); glVertex2f(x-size, y+size); glVertex2f(x-size, y-size); glVertex2f(x+size, y-size); glEnd();}

Page 32: 1 Programmazione grafica: lInterazione Daniele Marini

32

Il programma è completo

• Inizializza una finestra, disegna un quadrato di colore casuale nel punto selezionato dal mouse col tasto di sinistra; termina premendo il tasto di mezzo del mouse

• Non ha menu, se la finestra viene modificata (resizeresize) il programma non sa che fare

Page 33: 1 Programmazione grafica: lInterazione Daniele Marini

33

Window events

• Es: resize, che fare?– Ridisegnare tutto?– Che fare se l’aspect ratio cambia?– Si cambiano le dimensioni degli oggetti se la finestra

cambia dimensioni?

• Nell’esempio si ridisegna tutto, mantenendo i rapporti degli oggetti (quadrati restano quadrati) e si applica il clipping

• L’evento di resize restituisce altezza e larghezza della window

Page 34: 1 Programmazione grafica: lInterazione Daniele Marini

34

myReshapevoid myReshape(GLsizei w, GLsizei h){

/* adjust clipping box */

glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();

/* adjust viewport and clear */

glViewport(0,0,w,h); glClearColor (0.8, 0.8, 0.8, 1.0); glClear(GL_COLOR_BUFFER_BIT); display(); glFlush();}

Page 35: 1 Programmazione grafica: lInterazione Daniele Marini

35

Display callback

La glutDisplayFunc(display) viene eseguita quando GLUT determina che la finestra va ridisegnata, certamente alla prima apertura; in questo caso è utile disegnare le parti statiche della finestraLa display callback può essere usata per animazione, quando cambiano parametri nel programmaPer iconizzare una finestra si usa la glutPostDisplay()

Per disabilitare una callback si può settare la sua callback function a NULL

Page 36: 1 Programmazione grafica: lInterazione Daniele Marini

36

Finestre multiple

id=glutCreateWindow(“second window”);

L’intero ritornato permette di attivare la prima o la seconda finestra:

glutSetWindow(id);

Si possono modificare parametri e proprietà della seconda finestra prima di definirla:

glutInitDisplayMode( …);id=glutCreateWindow(“third window”);

Page 37: 1 Programmazione grafica: lInterazione Daniele Marini

37

MenuPull-down e pop-up menus

glutCreateMenu(demo_menu);glutAddMenuEntry(“quit”,1);glutAddMenuEntry(“increase square size”,2);glutAddMenuEntry(“decrease square size”,3);glutAttachMenu(GLUT_RIGHT_BUTTON);

void demo_menu(int id);{

if(id==1) exit();else if (id==2) size = 2*size;else if (id==3) size=size/2;glutPostRedisplay();

}

Page 38: 1 Programmazione grafica: lInterazione Daniele Marini

38

Menu pull-down gerarchici

sub_menu = glutCreateMenu(size_menu);glutAddMenuEntry(“increase square size”,2);glutAddMenuEntry(“decrease square size”,3);glutCreateMenu(top_menu);glutAddMenuEntry(“quit”,1);alutAddSubMenu(“Resize”, sub_menu);glutAttachMenu(GLUT_RIGHT_BUTTON);

Esercizio: scrivere le callback function di: size_menutop_menu