350 likes | 419 Vues
Lezione 5: prepariamoci ad implementare. Università dell’Insubria Facoltà di Scienze MFN di Varese Corso di Laurea in Informatica Anno Accademico 200 5 /0 6. Computer Graphics. Marco Tarini. Ambiente di sviluppo. Chiaramente va bene come qualunque altro.
E N D
Lezione 5: prepariamoci ad implementare Università dell’Insubria Facoltà di Scienze MFN di Varese Corso di Laurea in Informatica Anno Accademico 2005/06 Computer Graphics Marco Tarini
Ambiente di sviluppo • Chiaramente va bene come qualunque altro. • Leggero (9 MB), simpatico e free software (GNU GPL) • Progetti in C e C++ • Include compilatore Mingw/GCC • Ha un un buon package downloader e manager che permette di istallare facilmente le librerie che usiamo (OpenGL, SDL...) e della ducumentazione • "tools" -> "check for update/pakages" • Funziona • Per info, sull'uso, potete scaricare la lez 1 del corso di lab linguaggi: http://vcg.isti.cnr.it/~tarini/?51 M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 2/40
Simple DirectMedia Layer • cross-platform multimedia library • GNU LGPL • fornisce accesso (a livello abb basso) a • audio, • keyboard, mouse, joystick, • windowing • 3D hardware via OpenGL • 2D video framebuffer. • gira su: Linux, Windows, BeOS, MacOS X ... • completato di librerie "figlie" per vari scopo (e.g. SDL_png per file png) • C++ • http://www.libsdl.org M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 3/40
Struttura programma non va bene per applicazioni interattive ! • Struttura classica dei programmi a linea di comando: main() { init(); do_my_beautiful_algorithm(); exit(); } M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 4/40
Struttura programma • eventi tipo: • mouse, tastiera... • sistema di finistre • reshape, minimizzazione... • generati dall'applicazione stessa • o da thread differenti • Sistema a eventi • "a callback" (o "a message handlers" ecc) main() { init(); while (true) { get_event() ; process_event(); } } M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 5/40
La minima applicazione SDL: headers #ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include <windows.h> #endif #include <GL/gl.h> #include <GL/glu.h> #include <stdlib.h> #include <SDL.h> M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 6/40
La minima applicazione SDL: main int main(int argc, char **argv) { SDL_Init(SDL_INIT_VIDEO); SDL_SetVideoMode(640, 480, 0, SDL_OPENGL); int done = 0; while ( ! done ) /* Loop, drawing and checking events */ { myDrawGLScene();/* Questa poi la vediamo */ SDL_Event event; SDL_WaitEvent(&event); switch(event.type) { case SDL_QUIT : done = 1; break ; case SDL_KEYDOWN : if ( event.key.keysym.sym == SDLK_ESCAPE ) done = 1; break; } } SDL_Quit(); return 1; } M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 7/40
Meglio: • Ridisegna la scena troppe volte • Gestiamo anche l’evento “necessita’ di ridisegnare” • Nel ciclo degli eventi: case SDL_VIDEOEXPOSE : myDrawGLScene(); break; • E togliamo il myDrawGLScene dal ciclo degli eventi M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 8/40
La minima applicazione SDL: la parte che disegna void DrawGLScene() { glClear(GL_COLOR_BUFFER_BIT); /* disegna tutto */ glFinish(); /* aspetta che sia tutto finito */ SDL_GL_SwapBuffers();/* questa fra un sec */ } M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 9/40
Double buffering set-up set-up rasterizer segmenti rasterizer punti • Piccolo trucco utile alle applicazioni interattive • nascondere il frame buffer mentre viene riempito frame buffer A [ pronto ] al video Vertici proiettati (punti in R2) frammenti (candidati pixels) computazioniper frammento set-up rasterizer triangoli A frame buffer B [ in costruzione ] M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 10/40
Double buffering set-up set-up rasterizer segmenti rasterizer punti • Piccolo trucco utile alle applicazioni interattive • nascondere il frame buffer mentre viene riempito frame buffer A [ in costruzione ] Vertici proiettati (punti in R2) frammenti (candidati pixels) computazioniper frammento set-up rasterizer triangoli B frame buffer B [ pronto ] al video M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 11/40
Riassunto puntate precedenti 1/3 set-up set-up rasterizer punti rasterizer segmenti v1 v0 v2 Z pixel finali (nello screen-buffer) Vertici proiettati (punti in R2) frammenti (candidati pixels) set-up rasterizer triangoli computazioniper vertice computazioniper frammento Vertici (punti in R3) ora di qui sappiamo tutto y v1 v0 v2 x z M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 12/40
Struttura Applicazione OpenGL+SDL OpenGL Application OpenGL SDL Operative SystemGraphical User Interface API OpenGL API Graphics Hardware Driver Graphics Hardware M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 13/40
Non lo studiamo qui, ma esiste • Direct3D • Parte di DirectX • Microsoft • Stessi scopi di OpenGL • un API per usare lo stesso hardware • dtruttura non dissimile • L'alternativa piu' comune a OpenGL M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 14/40
Specifiche ver 2.0 • Open Graphic Language • Libreria C • Cross platform • Qualche centinaio di routines • www.opengl.org • specifiche M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 15/40
Storia ARB ... • inizialmente sviluppato da Silicon Graphics • ora:OpenGL Architecture Review Board • mantiene e aggiorna le specifiche • versione attuale: 2.0 • una compagnia, un voto • ci sono anche le estensioni private • Soprattutto e M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 16/40
Vicini di casa • OpenGL e’ il layer di base • GLU (GL utilites) • insieme di funzioni di utility costruite sopra OpenGL, piu’comode da usare • esempio void gluLookAt(eyex,eyey,eyez, cx,cy,cz, upx, upy, upz); • GLUT e’ il Toolkit di interfaccia con il SO • Wgl e GLx sono i sottoinsiemi di OpenGL che dipendono dal SO M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 17/40
Syntax • Tutte le funzioni di Opengl si chiamano: glSomethingXXX • Dove XXX specifica (numero) il tipo dei parametri: • esempio: glColor3f(float, float, float); glColor3fv( float*); f: float d: double ... v: vettore • Non e’ C++… M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 18/40
Syntax • Ma anche: glColor3b, glColor3d, glColor3f, glColor3i, glColor3s, glColor3ub, glColor3ui, glColor3us, glColor4b, glColor4d, glColor4f, glColor4i, glColor4s, glColor4ub, glColor4ui, glColor4us, glColor3bv, glColor3dv, glColor3fv, glColor3iv, glColor3sv, glColor3ubv, glColor3uiv, glColor3usv, glColor4bv, glColor4dv, glColor4fv, glColor4iv, glColor4sv, glColor4ubv, glColor4uiv, glColor4usv M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 19/40
Basato sullo stato • Una state machine • ad esempio • current color • posizione luci • matrici fanno parte dello stato corrente • Molti comandi OpenGL non fanno nulla • se non cambiare lo stato M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 20/40
Basato sullo stato • Stato comprende 2 matrici (e due stacks) • Model-View • Projection • Una di queste e’ sempre la matrice di lavoro • la matrice corrente • I comandi che modificano matrici lavorano su questa matrice M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 21/40
Matrici • Nota: assume che siano memorizzate per colonne • detto anche in column major order M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 22/40
Matrici • Per cambiare quale é la matrice di lavoro: glMatrixMode(***); GL_MODELVIEW GL_PROJECTION • Per rimpiazzare la matrice di lavoro • glLoadIdentity(); • glLoadMatrixf( float* m ); • Tutti gli altri comandi modificano (moltiplicano per un altra matrice) la matrice corrente. M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 23/40
Matrici in gradi asse di rotazione passante per l'origine • Rotazioni • glRotatef(angle,ax,ay,az); • Traslazioni • glTranslatef(dx,dy,dz); • Scalature (non uniformi) • glScalef(ax,ay,az); • Generica • glMultMatrixf(float f*); M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 24/40
Matrici centro. La direzione e' (c – eye) • Vista: void gluLookAt(eyex,eyey,eyez, cx,cy,cz, upx, upy, upz); M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 25/40
Matrici • Operazione sullo Stack: glPushMatrix() glPopMatrix() M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 26/40
Matrici di proiezione • Matrici di proiezione: glOrtho2D(left, right, bottom top); void gluPerspective( fovy, aspect, zNear, zFar); in gradi M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 27/40
Viewport • Per settare il viewport: glViewPort(int x, int y, int w, int h); reminder: il rapporto fra w e h deve essere lo stesso specificato nella matrice di proiezione! M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 28/40
Evento Window Reshape • Succede all'inizio • e ogni volta che l'utente cambia dimensioni alla finestra • devo permettere all'utente di farlo, durantel'inizializzazione: • gestione dell'evento: (devo fare di nuovo il set up del video) SDL_SetVideoMode(640,480,0, SDL_OPENGL | SDL_RESIZABLE) • ... • case SDL_VIDEORESIZE : SDL_SetVideoMode(event.resize.w,event.resize.h, 0, SDL_OPENGL |SDL_RESIZABLE); myReshapeFunc(event.resize.w,event.resize.h); M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 29/40
Adattare la camera alla finestra:proiezione ortografica void myReshapeFunc(GLsizei w, GLsizei h) { glMatrixMode (GL_PROJECTION); glLoadIdentity (); float ratio=(float)h/(float)w; glOrtho2D(-1,1,-ratio,ratio); glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_MODELVIEW); } M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 30/40
Ricordare sempre:OpenGL = state machine manipolazioni di stato (es. settare la matrice) primitive qui stato di OpenGL tutto il pipeline (proiezione, setup, rasterizzazione...) pixels M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 31/40
Come si "sparano" i triangoli nel pipeline primo triangolo secondo triangolo terzo triangolo glBegin (GL_TRIANGLES); glVertex3d(x1,y1,z1); glVertex3d(x2,y2,z2); glVertex3d(x3,y3,z3); glVertex3d(x4,y4,z4); glVertex3d(x5,y5,z5); glVertex3d(x6,y6,z6); glVertex3d(x7,y7,z7); glVertex3d(x8,y8,z8); glVertex3d(x9,y9,z9); ... glEnd(); M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 32/40
Come si "sparano" i triangoli nel pipeline coordinata w=1 sottointesa! coordinata z =0 sottointesa! glVertex3d(x,y,z); oppureglVertex3f(x,y,z); oppureglVertex3i(x,y,z); oppureglVertex2d(x,y); oppureglVertex4d(x,y,z,w); oppureglVertex4dv(vett); oppure... M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 33/40
Non solo glBegin (GL_TRIANGLES); linea finale quando si fa la glEnd() M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 34/40
Non solo glBegin (GL_TRIANGLES); Le specifiche OpenGL non prescrivono quale diagonale usare (quindi dipende dall'implementazione quanti triangoli rasterizzati per quanti vertici proiettati ? M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 0 5 / 0 6 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a - 35/40