computer graphics marco tarini università dellinsubria facoltà di scienze mfn di varese corso di...
TRANSCRIPT
Computer Graphics
Marco Tarini
Università dell’Insubria
Facoltà di Scienze MFN di Varese
Corso di Laurea in Informatica
Anno Accademico 2005/06
Lezione 5: prepariamoci ad implementare
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
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 - 3/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 - 4/40
Struttura programma
• Struttura classica dei programmi a linea di comando:
main(){
init();do_my_beautiful_algorithm();exit();
}
non va bene per applicazioni
interattive !
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
Struttura programma
• Sistema a eventi– "a callback" (o "a message handlers" ecc)
main(){
init();while (true) {get_event() ;process_event();
}} eventi tipo:
• mouse, tastiera...• sistema di finistre
• reshape, minimizzazione...• generati dall'applicazione stessa• o da thread differenti
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: 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 - 7/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 - 8/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 - 9/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 - 10/40
Double buffering
fram
men
ti(c
andid
ati
pix
els
)
frame buffer A
[ pronto ]
Vert
ici
pro
iett
ati
(punti
in R
2)
rasterizer
triangoli
com
puta
zioni
per
fram
mento
set-up
rasterizer
segmenti
set-up
rasterizer
punti
set-up
• Piccolo trucco utile alle applicazioni interattive– nascondere il frame buffer mentre viene riempito
frame buffer B[ in costruzione ]
al video
A
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
Double buffering
fram
men
ti(c
andid
ati
pix
els
)
frame buffer A[ in costruzione ]
Vert
ici
pro
iett
ati
(punti
in R
2)
rasterizer
triangoli
com
puta
zioni
per
fram
mento
set-up
rasterizer
segmenti
set-up
rasterizer
punti
set-up
• Piccolo trucco utile alle applicazioni interattive– nascondere il frame buffer mentre viene riempito
frame buffer B
[ pronto ]
al video
B
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
fram
men
ti(c
andid
ati
pix
els
)
Riassunto puntate precedenti 1/3V
ert
ici
(punti
in R
3)
pixelfinali
(nello screen-buffer)
Vert
ici
pro
iett
ati
(punti
in R
2)
Z
rasterizer
triangoli
com
puta
zioni
per
fram
mento
x
y
z
v0v1
v2
set-up
v0v1
v2
rasterizer
segmenti
set-up
rasterizer
punti
set-up
com
puta
zioni
per
vert
ice
ora di qui sappiamo tutto
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
Struttura Applicazione OpenGL+SDL
OpenGLOpenGL
OpenGL ApplicationOpenGL Application
Operative SystemGraphical User Interface
API
Operative SystemGraphical User Interface
API
SDLSDL
Graphics Hardware DriverGraphics Hardware Driver
OpenGL API
OpenGL API
Graphics HardwareGraphics 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 - 14/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 - 15/40
• Open Graphic Language• Libreria C
– Cross platform– Qualche centinaio di routines
• www.opengl.org– specifiche
Specifiche
ver 2.0
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
• 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
Storia
ARB
...
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
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 - 18/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: floatd: 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 - 19/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 - 20/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 - 21/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 - 22/40
Matrici
• Nota: assume che siano memorizzate per colonne – detto anche in column major order
151173
141062
13951
12840
aaaa
aaaa
aaaa
aaaa
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
• Per cambiare quale é la matrice di lavoro:glMatrixMode(***);GL_MODELVIEWGL_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 - 24/40
Matrici
• Rotazioni– glRotatef(angle,ax,ay,az);
• Traslazioni– glTranslatef(dx,dy,dz);
• Scalature (non uniformi)
– glScalef(ax,ay,az);
• Generica– glMultMatrixf(float f*);
in gradi
asse di rotazionepassante per l'origine
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
• Vista:void gluLookAt(eyex,eyey,eyez, cx,cy,cz, upx, upy, upz);
centro. La direzionee' (c – eye)
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
• Operazione sullo Stack:
glPushMatrix()
glPopMatrix()
Matrici
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
• Matrici di proiezione:
glOrtho2D(left, right, bottom top);
void gluPerspective(fovy,aspect,zNear,zFar);
Matrici di proiezione
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 - 28/40
• 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!
Viewport
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
Evento Window Reshape
• Succede all'inizio– e ogni volta che l'utente
cambia dimensioni alla finestra– devo permettere all'utente di farlo, durante
l'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 - 30/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 - 31/40
Ricordare sempre:OpenGL = state machine
primitivequi
pixels
tutto il pipeline (proiezione, setup, rasterizzazione...)
stato di OpenGL
manipolazioni di stato(es. settare la 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 - 32/40
Come si "sparano" i triangoli nel pipeline
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();
primo triangolo
secondo triangolo
terzo triangolo
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
Come si "sparano" i triangoli nel pipeline
glVertex3d(x,y,z);
oppure glVertex3f(x,y,z);oppure glVertex3i(x,y,z);oppure glVertex2d(x,y);oppure glVertex4d(x,y,z,w);oppure glVertex4dv(vett);oppure...
coordinata z =0sottointesa!
coordinata w=1sottointesa!
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);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 - 35/40
Non solo glBegin (GL_TRIANGLES);quanti triangoli
rasterizzati per quanti vertici
proiettati ?
Le specifiche OpenGL non
prescrivono quale diagonale usare
(quindi dipende dall'implementazione