Upload
tore-monaco
View
214
Download
0
Embed Size (px)
Citation preview
3 Dprospettive
non parallele
grafica in tre dimensioni :
visualizzazione su schermo (2D)
di un "mondo" ovvero una "scena" di
un insieme di oggetti a 3 dimensioni
in questa parte sono presentati cenni su :
passaggio da 3 D a 2 D :
le proiezioni prospettiche
ricorda : Fondam. di grafica tridimensionale interattiva di R.Scateni,P.Cignoni, C.Montani,R.Scopigno, McGrawHill It, 2005;
proiezioni geometriche piane
abbiamo visto le proiezioni parallele : ortografiche piante e alzati, assonometriche isometriche, dimetriche, trimetriche oblique cavaliera cabinet altre
vediamo ora le proiezioni prospettiche: a 1 punto di fuga, a 2 punti di fuga, a 3 punti di fuga
centro di vista o punto di riferimentodella prospettiva
piano di proiezione
oggetto (segmento)da rappresentare
proiezioni prospettiche a 1, 2 o 3 punti di fuga:
le linee parallele dello spazio oggetti che NON sono parallele al piano di proiezione convergono nel piano di proiezione verso un punto di fuga; (le linee parallele al piano di proiezione rimangono parallele al piano di proiezione)
possono esserci infiniti punti di fuga,
interessano in particolare i punti di fuga delle linee parallele ad uno degli assi (tre direzioni al max);
vediamo ora lerappresentazioni prospettiche:
rappresentazione a due punti di fuga, molto usata ...
il disegno di oggetti in prospettiva fa parte dell'insegnamento nelle scuole secondarie da molti anni (veniva insegnato nel 1890 a TS sia nei licei come nelle scuole professionali per artigiani)
prospettiva a 2 punti di fuga, due esempi
prospettiva a 2 punti di fuga, ancora un esempiohttp://www.artekjara.it/Manuale/disegno/prospettiva_angolare.shtml
vediamo ora le
rappresentazioni prospettiche:
a 1 punto di fuga, a 2 punti di fuga, a 3 punti di fuga ...
la rappresentazione prospettica e' disponibile in Open GL , vedremo le
tre procedure OpenGL per la definizione di una rappresentazione prospettica:
glFrustum (left, right, bottom, top, near, far);
gluPerspective( angle, aspect, znear, zfar); gluLookAt( x0,y0,z0, xref,yref,zref, upx,upy,upz);
prospettiva a un punto di fuga
un punto di fuga centrato:
un punto di fuga non centrato
prospettiva a un punto di fuga, due esempi:
prospettiva
a un puntodi fuga
prospettiva - 1653, palazzo Spada, di Francesco Castelli detto il
Borromini
http://www.galleriaborghese.it/spada/it/prospett.htm
se il piano di proiezione e' perpendicolare all' asse z (non interseca altri assi) allora abbiamo un punto di fuga, e le linee parallele agli assi x e y rimangono parallele
x
y
z
*) in generale *) piano proiezioneperpendicolare a asse z
piano di proiezione perpendicolare all' asse z (non interseca altri assi) : abbiamo un punto di fuga, le linee parallele agli assi x e y rimangono parallele
in figura una vista prospettica di un cubo (a "fil di ferro") con un punto di fuga: il piano di proiezione e' orto-gonale all' asse z, le linee // agli assi x e y rimangono tali
... dal rinascimento in poi, la proiezione prospettica o prospettiva a due punti di fuga
e' normalmente utilizzata nel disegno tecnico (e non) grazie al realismo e alla "piacevolezza" della scena;
prospettiva a due punti di fuga, che abbiamo gia' visto - qui una ripetizione:
x
z
y
se il piano di proiezione e' perpendicolare all' asse y ("verticale") e interseca gli assi x ("orizzontale") e z ("verso l'osservatore"), abbiamo due punti di fuga, e solo le linee verticali (parallele all'asse y) rimangono parallele (rimangono verticali) :
infine,
se il piano di proiezione interseca tutti e tre gli assi (la normale al piano di proiezione non e' parallela ad alcun piano di coordinate dell' oggetto)
allora abbiamo una prospettiva con tre punti di fuga:
prospettiva a tre punti di fuga
PF1PF2
PF3
la proiezione prospettica a tre punti di fuga, dove anche le linee verticali convergono - in basso (come in fig. a destra) oppure in alto, e' poco usata ...
La prospettiva con 3 punti di fuga aggiunge poco al realismo della scena, e "distorce la scena" si usa poco (effetti speciali in film di animazione digitale)
per passare dal mondo di coordinate (x,y,z) di un oggetto della scena 3D al mondo coordinate (x,y) nel piano di proiezione nella rappresentazione prospetticasi usa una matrice di trasformazione prospettica:
P2D = MTP x P3D
P2D = il punto in 2D e' dato dal prodotto matriciale (coord.omogenee) di MTP per il P3D = punto in 3D
vediamo...
trasformazione prospettica :
P(x,y,z)
Pp(xp,yp,zp)x
z
y
d
P(x,y,z)
z
y
d
yp
P(x,y,z) punto dell'oggetto,Pp(xp,yp,zp) su piano prospettico,dai triangoli simili (sin. sotto) ho:yp/d = y/z e xp/d = x/z da cui xp=x*d/z, yp=y*d/z, zp=d da cui la trasformazione matriciale 1 0 0 0 0 1 0 0 Mpro 0 0 1 0 0 0 1/d 0
infatti dal prodotto Mpro* P con P(x,y,z,w) righeper colonne si ha P=(x,y,z,z/d)se ora divido per w=z/d, e quindi(x/w,y/w,z/w)=(x/(z/d),y/(z/d),z/(z/d))riottengo quanto sopra: (xp,yp,zp)=(x*d/z,y*d/z,z*d/z)
Pp(xp,yp,zp) y
matrice di trasformazione prospettica generale: nel caso generale avremo (Hearn Baker ecc) : 1 0 -dx/dy zp*dx/dz 0 1 -dy/dz zp*dy/dzMgen 0 0 -zp/(Q*dz) zp
2/(Q*dz)+zp
0 0 -1/(Q*dz) zp2/(Q*dz)+1
dove P e' il punto da proiettare, Pp e' la proiezione di P sul piano di proiezione (perpendicolare all'asse z e situato a distanza zp dall'origine), centro di proiezione non vincolato
P(x,y,z)
Pp(xp,yp,zp)
z
x oppure y
(0,0,zp)
(dx,dy,dz)
Q
CP
vediamo i limiti dello spazio visualizzato:
inevitabilmente solo una parte della scena del mondo degli oggetti puo' essere visualizzata, e quindi si deve specificare i limiti di questo spazio:gli oggetti che stanno fuori tale spazio non vengono visualizzati, sono tagliati
termine tecnico, clipping
clip 2 |klɪp| verb ( clipped |klɪpt|, clipping |ˌklɪpɪŋ|) [ trans. ]1 cut short or trim (hair, wool, nails, or vegetation) with shears or scissors : clipping the hedge. trim or remove the hair or wool of (an animal) : clip your horse. ( clip something off) cut off a thing or part of a thing with shears or scissors : he clipped off a piece of wire | figurative she clipped nearly two seconds off the old record. cut (a section) from a newspaper or magazine : a photograph clipped from a magazine.speak (words) in a quick, precise, staccato manner : “Yes?” The word was clipped short | [as adj. ] ( clipped) cold, clipped tones. Computing process (an image) so as to remove the parts outside a certain area. Electronics truncate the amplitude of (a signal) above or below predetermined levels.2 strike briskly or with a glancing blow : the steamroller clipped some parked cars | branches clipped his face. [ trans. ] strike or kick (something, esp. a ball) briskly in a specified direction : he clipped a right-field double.3 informal swindle or rob (someone) : in all the years he ran the place, he was clipped only three times.4 [ intrans. ] informal move quickly in a specified direction : we clip down the track.
frustum |ˌfrəstəm| |ˌfrʌstəm|noun ( pl. -ta |-tə| |ˌfrəstə| |-tə|or -tums |ˌfrəstəmz|) Geometry the portion of a cone or pyramid that remains after its upper part has been cut off by a plane parallel to its base, or that is intercepted between two such planes.
ORIGIN mid 17th cent.: from Latin, ‘piece cut off.’
specifico il volume di visualizzazione con: Pvista (PRP) e finestra di visualizzazione ,separatamente i limiti per l'asse z (near/far)
oppure specifico il volume di visualizzazione dando: Pvista (PRP) , angolo di visualizzazione (entrambe le cose in OpenGL) - e separatamente i limiti per l'asse z (near/far)
ricorda l' orientamento dei tre sistemi di assi:dell'oggetto, del piano di proiezione, dell'osservatore (punto di vista)
nella prospettiva ortogonale la posizione del punto di vista sull'asse z non ha importanza, sono importanti solo i limiti di visualizzazione [ se sbagliati, non vedo nulla <:-( ]
clipping asse z: quello che sta fuori dei limiti per l'asse z viene tagliato, cioe' quello che sta prima di znear o dopo zfar; qui esempio di eliminazione dovuta al cambio di zfar (da 2 a 0.3) :
qui visualizzati 4 cubetti messi sui vertici di un cubo (progr. EGD3D_01XORTHO), a inizio di myDisplay e' chiamata la glOrtho( xmin, xmax, ymin, ymax, znear, zfar );
con xmin=-2,xmax=2,..,znear =-2, zfar = 2; ... si cambiano i limiti z con left_arrow ( znear=znear*0.75; zfar=zfar*0.75; )
clipping asse z: quello che sta fuori dei limiti per l'asse z (se z esce da [znear..zfar] ) viene tagliato. In figura e' usata la prospettiva parallela (glOrto), dove il frustum e' un parallelepipedo (xmin..zfar).
qui visualizzati 4 cubetti messi sui vertici di un cubo (progr. EGD3D_01XORTHO), a inizio di myDisplay e' chiamata la glOrtho( xmin, xmax, ymin, ymax, znear, zfar );
con xmin=-2,xmax=2,..,znear =-2, zfar = 2; poi si cambiano i limiti znear,zfar (usato zn=zn*0.75; zf=zf*0.75); il frustum si accorcia nel senso delle z, e le parti fuori sono eliminate
Per definire la visione prospettica in OpenGL si usano le
procedure glFrustum e gluPerspective: glFrustum(left,right, bottom,top, near,far) definisce la prospettiva con il volume di vista, una
piramide tronca detta appunto "frustum"; nota: left, right,
bottom, top sono coordinate, near,far sono distanze dal punto di
vista
x
y
z
3 D - geometria, prospettive, OpenGL 3D
3 D - geometria, prospettive, OpenGL 3Dil volume di vista (dove sono gli oggetti che saranno visualizzati)e' un parallelepipedo (vista ortogonale) oppure una piramide tronca (prospettiva) detta "frustum" - in OGL il piano di vista e' sempre il piano z=znear.
in OGL il piano di vista e' sempre il piano z=znear,l'osservatore sta nell'origine e guarda verso le z<0
z
y
x
asse z, con z<0
il piano di vista e' il piano z=znear.
glFrustum (left, right, bottom, top, near, far)
3 D - geometria, prospettive, OpenGL 3Dnella prospettiva non ortogonale il frustum e' una piramide troncanota: znear e zfarDEVONO essere positivi NON nulliad es. 0.01--100.01.0--2.0 ecc, e TUTTE le z degli oggetti sono in tale intervallo
void myDisplay() { // prospettiva definita con frustum : glClearColor( 0.1, 0.1, 0.3, 1.0f ); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_B...BIT); glMatrixMode( GL_PROJECTION); glLoadIdentity(); glFrustum(-1.1,1.1, -1.1,1.1, 2.0, 100.0 ); // xmin, xmax, ymin,ymax znear,zfar glPushMatrix(); glLineWidth(3.0); glTranslatef( 0, 0, -4.0 ); glColor4f( 0.2, 0.2, 1.0, 0.5); glutWireCube(2.0); glRotatef( +10.0, 1.0, 0.0, 0.0); glColor4f( 1.0, 0.2, 0.2, 0.5); glutWireCube(2.0); glPopMatrix(); myLines(); glFlush();} // myDis
void myDisplay(){ // prospettiva definita con frustum : glClearColor( 0.1, 0.1, 0.3, 1.0f ); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_B...BIT); glMatrixMode( GL_PROJECTION); glLoadIdentity(); glFrustum(-1.1,1.1, -1.1,1.1, 2.0, 100.0 ); // xmin, xmax, ymin,ymax znear,zfar glPushMatrix(); glLineWidth(3.0); glTranslatef( 0, 0, -4.0 ); glColor4f( 0.2, 0.2, 1.0, 0.5); glutWireCube(2.0); glRotatef( +10.0, 1.0, 0.0, 0.0); glColor4f( 1.0, 0.2, 0.2, 0.5); glutWireCube(2.0); glPopMatrix(); myLines(); glFlush();} // myDis
nota il primo cubo blu centrato, il secondo rossoinclinato in avanti (ruota attorno asse x di 10 gradi)
void myDisplay(){ ... glFrustum(-1.1,1.1, -1.1,1.1, 2,100); // znear, zfar glPushMatrix(); .. glPopMatrix(); myLines(); glFlush();} /* myDisplay */
void myLines(){ float x=-0.5,z,r=1,g=0,b=1; while(x<=0.5){ glLineWidth(2); z= -1; while(z>=-100) { glBegin(GL_LINES); glColor3f(r,g,b); glVertex3f(x, -0.5, z ); glVertex3f(x, -0.5, z -1.0 ); glEnd(); z -= 2; g += 0.1; b -= 0.1; } x +=1.0; r=0; } /* while x,z */ ...
nota in mezzo due tratti orizzontali (a y=-0.5), uno a sinistra (x=-0.5) e uno dest (x=0.5), tratteggio adistanza di z=z-2;
void myDisplay(){ ... glFrustum(-1.1,1.1, -1.1,1.1, 2,100); glPushMatrix(); .. glPopMatrix(); myLines(); glFlush();} /* display */void myLines(){ float x=-0.5,z,r=1,g=0,b=1; ...
glColor3f( 1, 1, 1 ); glBegin(GL_LINES); glVertex3f(-1,0, -4); glVertex3f( 1,0, -4); // hor glVertex3f(0,-1, -4); glVertex3f( 0,1, -4); // ver glEnd(); } // myLines
infine due segmenti bianchi, in posizione z = -4, e con vertici in (-1,0) -- (1,0) (orizzontale)(0,-1) -- (0,1) (verticale)
il resto:#if defined __APPLE__#include <GLUT/glut.h> #else #include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #endiffloat wi=500,he=500;void myOpenWin(int n,char*a[ ]){ glutInit( n, a ); glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE ); glutInitWindowPosition(40,40); glutInitWindowSize(wi, he); glutCreateWindow( "FRU");} /* myOpenWin */
void myInit ( ) { wi = glutGet( GLUT_WINDOW_WIDTH); he = glutGet( GLUT_WINDOW_HEIGHT); glViewport(0,0,wi,he);} /* Init */
int main ( int n, char * a[]) { myOpenWin( n, a ); myInit(); glutDisplayFunc( myDisplay); glutMainLoop( ); return 0;} /* main */
nel main:...glMatrixMode( GL_PROJECTION); glLoadIdentity();
glFrustum(-1,1, -1,1, 1.5,20);...// limiti x y z nella Display:glMatrixMode(GL_MODELVIEW);glLoadIdentity(); glPushMatrix(); glTranslatef( tx, ty, tz );glRotatef(ang, 1.0,1.0,1.0); // rotate ang degrees around // the vector (1,1,1) */ glScalef ( 1.0, 2.0, 1.0 );// cube elongated upward DrawCube();
nota: i lati NON si mantengono paralleli!(prog. OGL3D_2FRUSTUM)
gluPerspective
la libreria OpenGL offre un secondo modo per specificare una prospettiva, forse un piu' intuitivo: vengono specificati i parametri
= apertura angolare dell' "obiettivo" ("fovy" (*)
= rapporto dx/dy (1 quadrato, w/h >1 orizzontale ...) = limiti z della scena: troncato quello che sta prima (o addiritura dietro l'osservatore) oppure dopo (troppo lontano verso le z negative)
gluPerspective ( double fovy, double aspect, double znear, double zfar );
-------------------------------------
(*) nota "fovy" = Field Of Viewing Angle
gluPerspective
per specificare una prospettiva si puo' anche dare:
= apertura angolare dell' "obiettivo" ("fovy" (*)
= rapporto tra dx e dy (1 se quadrato, w/h >1 se orizzontale ...) = limiti della scena (troncare quello che sta prima (o addiritura dietro l'osservatore) oppure dopo (troppo lontano verso le z negative)
gluPerspective( double fovy, double aspect, double znear, double zfar);
esempio: fovy 45.0 (gradi) aspect 1.6 (w/h) znear 0.5 zfar 100.0
gluPerspective( 45.0, 1.6, 0.5, 100.0 );
-------------------------------------
(*) nota "fovy" = Field Of Viewing Angle
la libr. OpenGL prevede la possibilita' di specificare direttamente un tipo di prospettiva come dai parametri nella figura sopra gluPerspective( db fovy, db aspect, db znear, db zfar);db sta per double, fovy angolo apertura (asse y) (15 gradi=tele, 60 gradi=grandang)w/h e' l'aspect ratio , znear e zfar sono i limiti delle distanze dal viewpoint agli oggetti lungo l'asse z negativo, in genere positivi
/* 3D_3PERSP_Cube perspective view truncated pyramid = frustum: (* ------------------object---------- top | ------------------------------ bottom | | | eye near limit zf far limit == distance viewpoint zn between viewpoint and object ==origin (0,0,0)we look down negative z axis, positive z toward usobject is clipped if nearer than frustum "near", zn, or farther than frustum "far"; zf or out of left/right, top/bottom limitswith glPerspective( angle, aspect, znear, zfar) we specify fovy=viewangle, aspect=width/height, near, far; the viewangle gives the viewing volume angle; in this example the object is sized 1, with vertex coordinates (-0.5,-0.5,-0.5) (-0.5,0,0),(0,-0.5,0),..(0.5,0.5, 0.5)and is moved (MODELVIEW, then translate) to position (0,0,-10), viewpoint is in (0,0,0) and the viewing volume is given with: gluPerspective( viewang, 1.0, zn, zf );fovy=viewangle, 1.0=aspect=width/height, zn,zf= znear, zfar where viewang = 45.0 and znear= 0.5, zfar = 100.0;
di seguito e'riportata parte del testo del progr.ma 3D_3PERSPdove e' anche illustrato un modo per definire un oggetto:vengono definiti separatamente tutti i vertici (un cubo ha otto vertici), (X e' una costante, qui vale 0.5) GLfloat vdata[8][3]= /*sono 8 punti che def il cubo*/{
{X,X, X}, {X,-X, X}, {-X,-X, X}, {-X,X, X},{X,X,-X}, {X,-X,-X}, {-X,-X,-X}, {-X,X,-X}
poi le facce (ogni faccia del cubo ha 4 vertici, e sono scelti tra i vertici elencati del cubo),
GLint tindices[6][4] = { /* vertici delle 6 facce */ {1,2,3,4}, /* top*/ {5,8,7,6}, /*bottom*/
... }
si definisce una faccia in modo che osservando la faccia dall'esterno i vertici vengono elencati in senso antiorario (vedremo in seguito per il problema delle faccie nascoste)
/* DEFINIZIONE E DISEGNO DEL CUBO: */const GLdouble X= 0.5; /* size of half edge *//* upper face vert. 1,2,3,4 clockwise, lower face 5,6,7,8 */GLint kk[6]={0,1,2,3,4,5}; /* order of faces drawing */static GLfloat vdata[8][3]= /*sono 8 punti che def il cubo*/{
{X,X, X}, {X,-X, X}, {-X,-X, X}, {-X,X, X},{X,X,-X}, {X,-X,-X}, {-X,-X,-X}, {-X,X,-X} };
/* how to link vertices to make a RECT: the first (top) rect *//* is made from vertices 1,2,3,4; bottom rect is 5,8,7,6, etc*/static GLint tindices[6][4] = {
{1,2,3,4}, /* top*/ {5,8,7,6}, /*bottom*/ {1,5,6,2}, /* front*/ {4,3,7,8}, /*rear*/{2,6,7,3}, /* left side*/ {1,4,8,5} /*right side*/
}; /* end tindices */ ...void DrawCube(){ GLint i,ii; for (i=0; i<6; i++) { glBegin(GL_POLYGON); ii=kk[i]; /* gives the order */ glVertex3fv( &vdata[ tindices[ii][0]-1 ] [0]); glVertex3fv( &vdata[ tindices[ii][1]-1 ] [0]); glVertex3fv( &vdata[ tindices[ii][2]-1 ] [0]); glVertex3fv( &vdata[ tindices[ii][3]-1 ] [0]); glEnd(); } /* for i */} /* DrawCube */
3 D - geometria, prospettive, OpenGL 3D
esempio di un risultato prodotto dal programma
OGL3D_3PERSP
una terza possibilita' di specifica di una prospettiva
abbiamo visto due modi per definire la visione prospettica di una scena: glFrustum ( left, right, bottom, top, near, far)
e gluPerspective( fovy, aspect, znear, zfar);entrambe le procedure pero' sono meno intuitive rispetto l'idea di dire: metto la telecamera montata in una certa posizione, diretta verso un certo punto e orientata in un certo angolo rispetto la verticale - allora in analogia alla macchina fotografica per ottenere la specifica di una prospettiva : posso dire DOVE sta la macchina, e dove sta l' oggetto da visualizzare, e come e' orientata la macchina fotografica - puo' essere inclinata (non verticale = parallela all'asse y)in aggiunta a glFrustum e gluPerspective abbiamo :
gluLookAt( eyePosX, eyePosY, eyePosZ, lookAtX, lookAtY, lookAtZ, upX, upY, upZ );
l'openGL ha una procedura per specificare con una procedura la posizione del punto di vista, degli oggetti e del versore "v_alto": { segue una gluPerspective(), glOrtho() and glFrustum() }
gluLookAt( x0,y0,z0, xref,yref,zref, vax,vay,vaz); P0=viewpoint Pref=origine o riferim. oggetti,valto=direzionedove sta l'alto
gluLookAt e' una procedura per specificare con una chiamata la posizione del punto di vista e del versore "v_alto": in figura, il punto di vista e' spostato rispetto l'oggetto, e ruotato ("up vector" <> asse y)
gluLookAt( x0,y0,z0, xref,yref,zref, vax,vay,vaz);con P0=(0,0,0)origine oggettiPref=viewpointvalto=direzionedove sta l'alto
gluPerspective e gluLookAtesempio uso gluLookAt (da Nate Robins, projection tutorial)http://www.xmission.com/~nate/tutors.html
in figura l'angolo di apertura e' 88 gradi(grandangolo)rapporto x/y e' 1,znear, zfar 1 e 10il punto di vista e'nel punto (0,0,2)(indicato a sinistra congli assi in rosso)l'orientamento della"macchina fotografica"e' in alto
gluPerspective e gluLookAtesempio uso gluLookAt (da Nate Robins, projection tutorial)
cambia fovy e Lookat:
in figura l'angolo di apertura e' 18 gradi(teleobiettivo)rapporto x/y e' 1,znear, zfar 1 e 10il punto di vista e'nel punto (0,0.5, 2.6 )all'altezza del viso,il centro "dove si guarda"e' all'altezza 0.7 (viso),orientamento macchina fotografica e' in alto
glOrtho e gluLookAtesempio uso gluLookAt (Nate Robins, projection)
qui e' usata la glOrtho, con frustum "stretto", si ritaglia solo il viso;cambia anche il punto di vista, e' nel punto (0.2, 1.1, 4.2) sopra la testa (il viso si vede dall'alto), il centro dove si guardae' all' altezza 0.7 (viso),orientamento macchina fotografica e' in alto
Un esempio di uso di gluLookAt: posso visualizzare la stessa scena da due punti di vista diversi in due finestre diverse:la display e' la stessa, cambia la prospettiva ovvero posso usare due punti di vista diversi con la gluLookAt :
gluLookAt( eyePosX, eyePosY, eyePosZ, lookAtX, lookAtY, lookAtZ, upX, upY, upZ )
(eyePosX, eyePosY, eyePosZ) posizione dell'occhio (lookAtX, lookAtY, lookAtZ) posizione dell'oggetto a cui guardo(upX, upY, upZ) orientamento della mia testa nella figura seguente abbiamo vp1 = Eye1 x,y,z = 2.90 1.60 -3.00 nota eyey=1.6 vp1 = Obj x,y,z = 0.00 0.00 -6.00 cioe' vista dall'alto vp1 = UP vec xyz= -0.60 1.00 -0.20 vp2 = Eye1 x,y,z = -0.80 -1.50 -3.90 nota eyey= -1.5 vp2 = Obj x,y,z = 0.00 0.00 -6.00 cioe' vista dal basso vp2 = UP vec xyz = 0.00 1.00 0.40
vista tre cubetti unitari con due viewport diversi, e con valori di gluLookAt diversi; dati: posiz occhio, posiz.oggetto, versore vertic vp1 = Eye1 x,y,z = 2.90 1.60 -3.00 nota eyey=1.6 vp1 = Obj x,y,z = 0.00 0.00 -6.00 cioe' vista dall'alto vp1 = UP vec xyz= -0.60 1.00 -0.20 vp2 = Eye1 x,y,z = -0.80 -1.50 -3.90 nota eyey= -1.5 vp2 = Obj x,y,z = 0.00 0.00 -6.00 cioe' vista dal basso vp2 = UP vec xyz = 0.00 1.00 0.40
esempio con due finestre, stessa scena, con due viste diverse:(programma di Michael Toffolon, 12 nov 2008, EGD3D06X2dueFinestreToffolon.cpp)
void myOpenWin ( int argc, char * argv[] ) {glutInit(&argc, argv); glutInitDisplayMode( ... );
glutInitWindowPosition(px,py); glutInitWindowSize( Wx,Wy );myWinID1=glutCreateWindow("Prima"); // inizial. 1.a finestraglutSetWindow(myWinID1); myCurrentWin = myWinID1; gluLookAt(eX1,eY1,eZ1,lX1,lY1,lZ1,uX1,uY1,uZ1); // punto di glutDisplayFunc(myDispl1); // vista, punta in direzione ...glutReshapeFunc(myResh1); glutKeyboardFunc( myKeyb ); myInitPersp(); myInitData();
glutInitWindowPosition(px+Wx, py);// inizializzo 2.a finestramyWinID2=glutCreateWindow("Seconda");glutSetWindow(myWinID2); myCurrentWin = myWinID2;gluLookAt(eX2,eY2,eZ2,lX2,lY2,lZ2,uX2,uY2,uZ2); // 2.o punto glutDisplayFunc( myDispl1 ); // di vista, punta in direzione ...glutReshapeFunc(myResh1); glutKeyboardFunc( myKeyb ); myInitPersp();myInitData();} // myOpenWin
void myInitPersp(){ // se tasto aggiorno parametri prospettiva int w=glutGet(GLUT_WINDOW_WIDTH); int h=glutGet(GLUT_WINDOW_HEIGHT); glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(apertura, aspetto, vicino, lontano); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // e verifico in che finestra sono: se cambiata aggiorno lo stato.. if(glutGetWindow()==myWinID1){ if(myWinID1!=myCurrentWin){ tx2=tx;..y..z..; rotx2=rotx; ..y..z ; tx=tx1;..y..z..; rotx=rotx1;..y..z..; myCurrentWin=myWinID1; } // if myWin.. gluLookAt(eX1,eY1,eZ1,lX1,lY1,lZ1,uX1,uY1,uZ1); }else{ if(myWinID2!=myCurrentWin){ tx1=tx;..y..z..; rotx1=rotx;..y..z..; tx=tx2;..y..z..;rotx=rotx2;..y..z..; myCurrentWin=myWinID2; } gluLookAt(eX2,eY2,eZ2,lX2,lY2,lZ2,uX2,uY2,uZ2);} glutPostRedisplay(); } // myInitPersp, chiamata anche in:void myKeyboard(..){ .. myInitPersp(); glutPostRedisplay();}
orientamento dei poligoni e visualizzazione dei poligoni
ancora tre argomenti per la visualizzazione di oggetti in 3D
in EGD3D_07DisplayListCuboAnima
sono usate alcune possibilita' dell' OpenGL:
glPolygonMode e orientamento dei poligoni
culling
display list
orientamento dei poligoni e visualizzazione dei poligoni
ancora tre argomenti per la visualizzazione di oggetti in 3D
nota: l' orientamento dei poligoni deve essere consistente,in EGD3D_07DisplayListCuboAnima e' usata specifica della modalita' di tracciamento di una faccia (un poligono) a seconda se la faccia e' orientata in avanti o verso dietro; attenzione:un poligono e' orientato, nel senso che il verso di percorrenza dei vertici definisce un orientamento; in OpenGL si assume orientamento positivo quello antiorario: default: glFrontFace(GL_CCW); le facce con orientamento anti-orario (counter-clock-wise) si assumono volte verso l'osservatore, e quindi sono visibili (si puo'cambiare: se chiamo glFrontFace(GL_CW); allora le facce con orientamento orario (clock-wise) si assumono volte verso l'osservatore
orientamento dei poligoni e visualizzazione dei poligoninel programma EGD3D_07DisplayListCuboAnima e' usata una variabile DisplayMode per controllare il tipo di visualizzazione, 1 lines 2 fill 3 fill and linesswitch(DisplayMode) {case 1: glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break; case2:glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); break;case 3: glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glPolygonMode(GL_BACK, GL_FILL); // facce piene glPolygonMode(GL_FRONT,GL_LINE);//solo bordi //c'e'anche glPolygonMode( GL_FRONT, GL_POINTS); break;} // switch
orientamento dei poligoni e visualizzazione dei poligoni
inoltre in EGD3D_07DisplayListCuboAnima
e' usato il "culling"
o selezione faccie da far vedere se culling e' attivo NON sono mostrate le facce nascoste, cioe' orientate via dall'osservatore) glCullFace(GL_BACK); if(doCulling) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
orientamento dei poligoni e visualizzazione dei poligoni
in EGD3D_07DisplayListCuboAnima e' usata la display list:procedure usate per definire un oggetto a partire da vertici: CubeListId = glGenLists(1); // numero identificazione display list glNewList( CubeListId, GL_COMPILE ); //inizia costruire lista glPushMatrix(); //- salva matrice trasformaz.corrente glPushAttrib(GL_CURRENT_BIT); // salva colore,traslazione.. glColor3f(0.8, 0.2,0.2); glBegin(GL_POLYGON);
glColor3f(0.2, 0.2, 0.8); glVertex2f(0.0, 1.0); glColor3f(1.0, 0.5, 0.5); glVertex2f(-3.0, 7.0); glEnd(); glTranslatef(2.0,0.0,0.0);
... glPopAttrib(); glPopMatrix(); // ripristina glEndList();
orientamento dei poligoni e visualizzazione dei poligoni
CubeListId = glGenLists(1); glNewList( CubeListId, GL_COMPILE ); // inizia costruire lista glPushMatrix(); glPushAttrib(GL_CURRENT_BIT); // salva stato ... glBegin(GL_POLYGON); glPopAttrib(); glPopMatrix(); - ripristinaglEndList();
in seguito per disegnare l'oggetto nella myDisplay: ... glCallList(CubeListId);
display lists: danno un esecuzione piu' efficiente del codice, i comandi OpenGL tra glNewList(..) e glEndList() sono interpretati e memorizzati, e l'esecuzione successiva e' piu' veloce; es:#define myList 1void faiC(){ GLint i; GLfloat co,se; glNewList(myList,GL_COMPILE); glBegin(GL_POLYGON); for(i=0; i<100; i++) { co=cos(i*2*M_PI/100.0); se=sin(i*2*M_PI/100.0); glVertex2f(co,se); } // for i glEnd(); glEndList();
in seguito si esegue la display list con il semplice richiamo:
glCallList( myList);(vedere list.cesempi red-book)
e con la slide seguente,che e' solo l'indice dei programmi demo,
abbiamo finito
questa prima parte della grafica 3D,
con la presentazione delle possibilita' date
in OpenGL
in 3D per la resa prospettica di una scena
3D programmi, parte EGD_07_3D1 : 1 EGD3D_01ORTHO 11 EGD3D_01X1ORTHO (9 O 4 CUBI, ANIMAZ) 12 EGD3D_01X2ORTanim (Vers.di A.SORIO) 2 EGD3D_02XORTHO (SCELTA OGGETTO) 3 EGD3D_03FRUSTUM 31 EGD3D_03X1FRUSTUM 4 EGD3D_04PERSPcubeDef 5 EGD3D_05DisplayListCubo 6 EGD3D_06LookAt scelta oggetto, LookAt 61 EGD3D_06X1LookAt9cubi.cpp piu'oggetti 62 EGD3D_06X2LookAtDue - due viewport 63 EGD3D_06X3LookAtDue - due window 7 EGD3D_07DisplayListCuboAnima 8 EGD3D_08PerspAnima3P3CUBI