3D
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 :
orientamento del sistema degli assi in 3 D
trasformazioni geometriche in 3 D
passaggio da 3 D a 2 D : le proiezioni
cenni di storia della prospettiva
cenno sulla struttura dell' OpenGL (gl,glu,glut),
tipi di prospettive (parallele, prospettiche)
3 D - geometria, prospettive, OpenGL 3D
mondo
oggetto,
coordinate
xw,yw,zw
(world coord)
mondo
del centro
vista,
coordinate
xv,yv,zv
(viewing pnt)
il passaggio dal piano 2D (visto finora) al 3D presenta subito
un'ambiguita' che comporta una scelta di orientamento:
in 2D, l'orientamento degli assi ( coordinate x,y) e' sempre (*)
* asse delle ascisse x orientato a destra, e
* asse delle ordinate y orientato verso l'alto,
nel caso dello spazio 3D sono usato due sistemi di riferimento
in entrambi gli assi x e y sono orientati come usuale
(colleghiamo l'asse x con il pollice e l'asse y con l'indice),
per l'asse z abbiamo:
* sistema destrorso abbiamo l'asse z orientato verso fuori
(mano destra: asse x=pollice, asse y= indice, asse z=medio)
(verso l'osservatore)
* sistema sinistrorso: l'asse z e' orientato verso dentro
(mano sinistra : asse x=pollice, asse y=indice, asse z=medio)
(via dall'osservatore)
graficamente...
(*) o quasi
y
y
z
x
x
z
sistema destrorso regola della mano destra:
x=pollice, y=indice, z=medio
(esce dallo schermo) in grafica e' il piu' usato,
l' OGL usa questo
sistema sinistrorso regola della mano sinistra:
x=pollice, y=indice, z=medio
(entra nello schermo)
meno usato
trasformazioni geometriche
ricorda le
trasformazioni geometriche in 2D:
coordinate (x,y),
trasformazioni:
scalatura:
fattore di scala: Sx, Sy
rotazione:
angolo:
Θ
traslazione: posizione:
x, y
inclinazione o scorrimento dei piani (shear),
e altro,
riflessione ecc
trasformazioni geometriche
trasformazioni geometriche in 2D:
coordinate (x,y),
il OpenGL usa coordinate omogenee (x,y,h)
trasformazioni:
scalatura: fattore di scala: 2 parametri Sx, Sy
rotazione: angolo:
1 parametro Θ
traslazione: posizione: 2 parametri x, y
la rotazione si intende sempre attorno l'asse z perpendicolare al piano
x,y
L'OpenGL prevede apposite funzioni per posizionare
le matrici di trasformazione - dati i parametri
essenziali riportati sopra
trasformazioni in 2D: coordinate omogenee (x,y,h)
// ricordiamo la trafila per trasformazione in 2D
// per disegnare una parte in posizione voluta:
glMatrixMode(GL_MODELVIEW); // seleziona quale matrice
glPushMatrix(); glLoadIdentity(); // azzera; segue:
glTranslatef(xt, yt, 0.0);
//rotaz attorno punto(x,y): 1)trasl 2)rotaz 3)traslIndiet
glTranslatef(MyBariX, MyBariY, 0.0);
glRotatef(MyAlfa, 0.0, 0.0, 1.0);
glTranslatef(-MyBariX,-MyBariY,0.0);
//scala attorno punto(x,y): 1)trasl 2)scala 3)traslIndiet
glTranslatef(MyBariX,MyBariY,0.0);
glScalef( MyScala, MyScala, 1.0);
glTranslatef(-MyBariX,-MyBariY,0.0);
MyRect( 0.5, 0.5, 0.5 ); // disegna qualcosa
glPopMatrix(); //elimina trasformaz.da ultima push
// fine trasforma e disegna una parte
trasformazioni in 3D: coordinate omogenee (x,y,h)
3 D - geometria:
anche in 3D per le trasformazioni geometriche
conviene passare dalle coordinate cartesiane
(x,y,z) alle coordinate omogenee (x,y,z,h), e le
trasformazioni di traslazione (posizione) e scala
sono espresse dalle matrici di trasformazione:
trasla o riposiziona ha 3 parametri: dx, dy, dz
glTranslatef (dx,dy,dz);
1
0
0
0
0
1
0
0
0
0
1
0
sx 0
0 sy
0 0
0 0
dx
dy
dz
1
la scala ha 3 parametri:
0
0
sz
0
0
0
0
1
Sx, Sy, Sz
glScalef( MyScala, MyScala, 1.0);
trasformazioni in 3D: coordinate omogenee (x,y,h)
3 D - geometria:
anche in 3D per le trasformazioni geometriche
conviene passare dalle coordinate cartesiane
(x,y,z) alle coordinate omogenee (x,y,z,h),
la trasformazione di rotazione ha 4 parametri
glRotatef(MyAlfa, dirx, diry, dirz);
( oppure si puo' definire con tre rotazioni attorno
i tre assi x, y, z, di angoli ... Θ, Φ, Ψ )
ma .. richiede delle precisazioni ...
trasformazioni in 3D: coordinate omogenee (x,y,h)
per specificare una rotazione nello spazio
dobbiamo specificare un asse di
rotazione V, e in relazione all' asse di
rotazione definiremo l' angolo di rotazione
OpenGL prevede la procedura di
rotaz.generica :
glRotatef(ang,Vx,Vy,Vz);
(*)
(*)
y
z
rotazione
attorno asse z,
sistema destro
MA nota: Vx,Vy,Vz e' una direzione,
il punto di riferimento dell' asse e' l' origine !!
e una rotazione generica ??
x
trasformazioni in 3D: coordinate omogenee (x,y,h)
OpenGL prevede la procedura di rotazione
glRotatef(ang,Vx,Vy,Vz);
(*)
V - asse di rotazione,
ang = angolo di rotazione
Verso rotazione: una rotazione attorno
un asse V si intende positiva se e' in
verso antiorario quando si guardi
l'origine dell'asse V da una posizione
generica del semiasse positivo:
se mi metto su asse z (sist. destrorso, asse z
in fuori) sul punto
(0,0,1) del semiasse z
positivo, allora una rotazione positiva ruotera'
il piano x,y in verso antiorario
y
z
x
rotazione positiva antioraria
attorno asse z,
sistema destro
accanto alle trasformazioni di posizione e scala ,
che abbiamo visto c'e'
la trasformazione di rotazione attorno un asse
ad es. attorno l'asse z
glRotatef(a, 0,0,1);
che equivale alla matrice a sinistra:
cos(a) -sin(a)
sin(a) cos(a)
0
0
0
0
0
0
1
0
0
0
0
1
accanto alle trasformazioni di posizione e scala ,
che abbiamo visto, c'e' la trasformazione di
rotazione attorno un asse
ad es. attorno l'asse z : glRotatef(a, 0,0,1);
che equivale alla matrice:
cos(a) -sin(a)
sin(a) cos(a)
0
0
0
0
0
0
1
0
0
0
0
1
Una rotazione attorno asse x e':
1
0
0
0 cos(a) -sin(a)
0 sin(a) cos(a)
0
0
0
0
0
0
1
ed e' data per esempio dalla
glRotatef(a, 1,0,0);
trasformazioni in 3D: rotazione generica:
0) rotazione generica di angolo a attorno ad un vettore v e
un punto p (generici) ,
v
y
y
la trasformazione sara'
v
composta come segue:
a
1) traslazione del punto
p
generico p nell'origine,
x
p
x
affinche' l' asse di rotaz
z
z 2)
passi per l'origine;
1)
2) rotazione di v attorno
asse y finche' l'asse di
y
y
rotaz v giace in piano y,z,
v
3) rotaz1 attorno asse x
finche' l'asse di rotaz v
a
p=(0,0,0)
coincide con l'asse z;
p
x
x
z
4) rotaz2 attorno z (che
z=v a
4)
3)
ora coincide con v) dell'
angolo voluto a,
trasformazioni in 3D: rotazione generica:
e una rotazione generica di un oggetto (qui "
")
di un angolo a
attorno ad un vettore v
v
y
asse che passa per
un punto p (generico)
a
p
?
z
nota: a,vx,vy,vz,px,py,pz
7 parametri ...
x
1)
rotazione generica attorno ad vettore v e punto p generici:
la trasformazione sara' composta (come gia' visto per il 2D,
ma qui i passi sono di piu' !!) come segue (ripeto i primi passi):
1) traslazione del punto generico p nell'origine, per fare in
modo che l' asse di rotazione passi per l'origine;
2) rotazione di v attorno all'asse y finche' l'asse di rotazione v
non giace nel piano y,z, e poi
3) attorno all'asse x fino a far coincidere l'asse di rotazione v
con l'asse z; ora siamo in una situazione nota:
4) infine si ruota attorno l'asse z dell' angolo voluto a,
e poi si rifanno i passi 1,2,3 a ritroso,
5) rotazione inversa di 3): il vettore v torna nel piano yz
6) rotazione inversa di 2): il vettore v torna com'era, ma in orig
7) traslazione inversa di 1): il vettore v torna al punto p
... e siamo a posto ;-)
(7 trasformazioni!!)
proiezione 3D -> 2D
il passaggio
dal mondo 3D
della scena composta da diversi oggetti
al mondo 2D
dello schermo dove si visualizza la scena
implica vari sistemi di riferimento di coordinate
trasformazioni in 2D: tre sistemi di riferimento
nel caso 2D abbiamo tre sistemi di coordinate nel mondo degli
oggetti 1) coordinate oggetto per il riferimento dei singoli elementi
costitutivi dell' oggetto [ad es una mano rispetto il corpo]
2) coordinate riferimento dell' oggetto nel mondo della scena
(trasformazione da coordinate della parte (dell'oggetto) alle
coordinate della scena (mondo "utente") [ad es il corpo
rispetto il centro stanza]
3) coordinate del dispositivo di visualizzazione
(trasformazione window -> viewport->schermo )
trasformazioni in 3D: sei sistemi di riferimento
nel caso 3D per il passaggio dal mondo oggetti al mondo del
dispositivo di visualizzazione dobbiamo considerare piu'
passaggi:
coordinate mondo oggetti
coordinate punto di vista
** proiezione (da 3D a 2D)
coordinate piano di proiezione
2D
passaggio finestra utente -> viewport
coordinate dispositivo di visualizzazione
la proiezione di un oggetto 3D su un piano di
proiezione 2D e' definita da
un insieme di rette di proiezione ("proiettori") che hanno tutte
un' origine comune nel punto "centro di proiezione" e
congiungono il centro di proiezione con tutti i punti dell'
oggetto; il centro di proiezione = punto di vista, dove
immagino l'occhio dell'osservatore); e da
un piano di proiezione
centro di proiezione
oggetto
da rappresentare
raggi proiettori
piano di proiezione
la proiezione di un oggetto 3D su un piano di proiezione 2D e'
data dall' intersezione dei proiettori con il piano di proiezione;
i proiettori = un insieme di rette di proiezione che hanno tutte
un' origine comune nel punto "centro di proiezione"
(punto di vista, dove possiamo immaginare l'occhio
dell'osservatore) e passano per tutti i punti dell' oggetto;
centro di proiezione
oggetto
da rappresentare
proiettori
piano di proiezione
Si noti che in generale una proiezione puo' essere definita da
"proiettori curve" (non rette) che passano tutte per il centro
di proiezione e intersecano una superficie di proiezione (non
piana) [altre applicazioni, in particolare, cartografia]
3 D - geometria, prospettive, OpenGL 3D
P0
Pv
Pw
oggetto
piano di proiezione
punto di vista
un'osservazione banale:
ben noto (oggi): oggetti a distanza diversa dal punto di vista
appaiono di grandezza diversa sul piano di proiezione, e
questo e' uno degli effetti visivi di lontananza (spesso usato)
prima della prospettiva ?
prima della prospettiva il disegnatore non si poneva il problema
della rappresentazione realistica di una scena:
la scena "raccontava"
una storia, con finalita' e tecniche molto diverse di oggi ...
la prospettiva appare solo 550 anni fa ...
vediamo in circa 10 slide l' evoluzione del disegno
PRIMA della prospettiva
dalle figure rupestri di 20000 anni fa (paleolitico)
agli affreschi Egiziani (4000 anni fa)
alle immagini murali e dei vasi greci (2500 anni fa)
(le immagini migliori su legno sono tutte andate perse),
agli affreschi delle tombe greche (il tuffatore),
alle iconografie bizantine (Ravenna)
e romaniche (1200 anni fa)
e gotiche (800 anni fa)
fino a Giotto compreso (700 anni fa) ...
Pitture rupestri grotte di Lascaux (Pirenei, Francia) e dintorni
Pitture risalenti al paleolitico 30.000 - 15.000 anni fa;
dopo piu' di
10.000 anni
(quante generazioni a 1015 anni per generazione?)
Nefertari Merytmut
circa 1290-1255 BC,
prima moglie di
Ramses nell' atto di
preghiera
(circa il periodo in cui i
fenici svilupparono
l'alfabeto, ripreso vari
secoli dopo dai greci)
Immagine dal " Libro delle preghiere dei morti "
della tomba di Hunefer, circa 2000 b.c.
dopo circa
1500 anni
(quante generazioni a 10-15 anni
per generazione?)
alcune immagini greche
di circa 500 anni prima di Cristo:
tavoletta votiva con scena di sacificio alla grazia/nimfa Carithes,
530 b.c., pittura su legno, trovata in una grotta a Pitsa, Corinto
due scene murali dalla
tomba di Paestum (vicino
Eboli), cultura greca, 480
b.c.
sopra: "symposium" o
convivio,
sotto: "il tuffatore"
circa 1400 anni dopo ...
Mosaico Bizantino 900 d.c. chiesa di Hagia Sophia Costantinopoli
sopra: discussione tra i dotti
Rabanus, Alcuinus (Ealhwine) e
Otgar, corte di Carlomagno, circa
820 d.c.
a destra: illustrazione da libro di
epoca Carolingia
circa 820 d.c.
Giotto di
Bondone
(circa 1300)
La strage degli
innocenti,
Capella degli
Scrovegni,
Padova
Mappa della citta'
di Costantinopoli,
1422,
disegno di cartografo
fiorentino
(32 anni prima della
conquista da parte
dei Turchi)
nell'ambiente ricco dell' inizio rinascimento
(anche se la richezza era limitata a pochi)
dell' Italia, Olanda, Germania di fine medio evo
nascono esigenze nuove,
e nascono risposte nuove...
Duerer, 1525 : lezione di prospettiva: disegno di un liuto !
la visualizzazione prospettica risale al rinascimento, il pittore
tedesco Duerer l'ha imparato nei suoi viaggi in Italia (Venezia)
Donato Bramante, attorno al 1500, a Roma
Pf
nota il palazzo a destra, disegnato in prospettiva a un punto
di fuga situato circa in mezzo alla scena
Donato Bramante :
Donato di Angelo di Pascuccio, detto il Bramante (Monte
Adrualdo 1444 - Roma 1514) famoso pittore e architetto italiano.
Nato a Monte Adrualdo (Urbino), si formò artisticamente nella
sua città natale ma iniziò ben presto a viaggiare e a lavorare a
Mantova, Milano e Roma.
Fu influenzato (prospettiva, classicità) da Leon Battista Alberti,
Andrea Mantegna e Melozzo da Forlì. L'influsso di quest'ultimo si
manifesta in particolare nelle opere milanesi. Lo studio di
Vitruvio, degli antichi edifici classici e le discussioni con
Leonardo, lo indirizzarono verso l'impiego di forme architettoniche possenti e classiche - esempio la sua Prospettiva di città
ideale, un manifesto della nuova architettura milanese
rinascimentale. Bramante è riuscito a ricreare un edificio che
abbia tutte le caratteristiche classiche.
Di Donato Bramante era anche affermato pittore “illusionista”,
ossia creatore di prospettive e d’architetture fittizie, segue es.:
L'abside della chiesa San Satiro
abside della chiesa di
Santa Maria presso
San Satiro a Milano,
illusione pittorica di
un grande spazio
dietro l'altare - che
non c'e' in realta' :
dietro l'altare vi sono
90 cm di spazio...
vedi slide seguente
ma
ritorniamo ora alla
prospettiva
per quanto ci riguarda
nella visualizzazione di scene 3D
con il sistema
OpenGL
rivediamo alcune cose ...
l' OpenGL consente la definizione di vari tipi di prospettive
con alcune procedure di libreria;
ricordiamo che l' OpenGL e' un sistema formato da piu'
livelli di librerie:
+ insieme base libreria GL di procedure con prefisso gl
+ la libreria GLU (OpenGL Utility Lib)
+ le librerie di interfaccia per diversi sistemi operativi,
ciascuna con procedure di gestione di finestre, menu,
eventi ecc come previsto nei diversi S.O.,
+ la libreria GLUT (OpenGL Utility Toolkit)
l'OpenGL
insieme base con prefisso gl
= un insieme di primitive base per la visualizzazione di
oggetti 3D su uno schermo 2D
es... glBegin(); glBlend();..
sono tutte procedure,funzioni,tipi,cost., con prefisso gl
[c'e gia' nel Borland Builder 4 !! ]
poi c'e' l'insieme con prefisso glu:
* libreria GLU (OpenGL Utility Lib) = procedure di
specifica di proiezioni, resa di poligoni e superfici nello
spazio, e altro; tutte le procedure hanno un nome che
inizia con glu (prefisso)
(es: gluLookAt(...) gluPerspective(..), ecc )
inoltre ...
alcune proc di OpenGL base, prefisso gl:
glBegin(..), glEnd(), glBitmap(..), glBlend(..), glCallList(..),
glClear(..), glClip(..), glColor*(..), glCopy(..), ... glRect*(..),
glTex(..), .. glTranslate*(..), glVertex*(..), glViewport(..),
..glWindowPos*(..), dove * sta per 2f,3f,4f,2i,..
in particolare, tutte le glSet.. e glGet.. per gestire le variabili di
stato dell'OpenGL, (circa 200 procedure)
* proc di GLU(OpenGL UtilityLib) prefisso glu:
gluBeginCurve(..), .. gluLookAt(...), gluNewQuadric(..),
gluNurbs(..), gluPerspective(..), ..gluSphere(..),
gluTessNormal(..), gluUnProject(..)..
(circa 50 procedure),
l'OpenGL:
1) procedure di base con prefisso
gl;
2) libreria GLU (OpenGL Utility Lib),
procedure prefisso glu
3) alle parti 1 e 2 manca l'interfaccia grafica tra S.O. e
utente: ma queste sono MOLTO diverse nei vari sistemi, e
quindi esistono (esistevano)
delle librerie per l'uso dell' interfaccia grafica dei sistemi
operativi piu' diffusi: prefisso glX per X-Window,
prefisso wgl per MS Windows pref. agl per l'Apple OS9,
non riportiamo nulla ...
per il nostro corso ci limiteremo ad una particolare
interfaccia ...
OpenGL:
1) libreria gl: procedure di base con prefisso gl;
2) libr. GLU (OpenGL Utility Lib), procedure prefisso glu
3) librer. per l'uso dell' interfaccia grafica di DIVERSI sist.
operativi: prefissi glX per Unix X, wgl per MS Windows,
agl per l'Apple OS9, infine:
4) GLUT: nel Mark Kilgard scrisse una libreria
SEMPLIFICATA di interfaccia SO-utente (per il Unix XWindow system) che ebbe subito successo e fu portata su
altri sistemi, come MSWindows dove continua a funzionare
(+ o - ;-)
GLUT = OpenGL Utility Toolkit: le procedure di questa
libreria hanno il prefisso glut, ad es: glutMainLoop();
* libreria GLUT(OpenGL Utility Toolkit) con prefisso glut :
glutCreateWindow(..), glutDisplayFunc(..), glutIdleFunc(..), ..
glutMainLoop(..), glutSolidCone(..), .. glutWireTorus(..),..
(circa 30 procedure)
nella prospettiva interessano la posizione e
l'orientamento del piano di proiezione rispetto il
centro di proiezione e rispetto gli oggetti che
vogliamo rappresentare :
centro di proiezione
N
proiettori
piano di proiezione
asse z spazio oggetti
normale al piano di
proiezione
orientamento del piano di vista e del vettore normale N
posizioni del piano di proiezione sull'asse z
posizioni del piano di proiezione sull'asse z
distz
distz
y
x
z
nota orientam. asse z;
qui l'oggetto sta dalla
parte delle z negative
posizioni del piano di
proiezione rispetto l'asse
oggetto-centro proiezione
3 D - prospettiva parallela
distz
distz
y
x
z
prospettiva parallela: la posizione del piano di
proiezione rispetto l'asse oggetto-centro proiezione
non e' rilevante (il punto di vista sta all'infinito)
definiz del vettore normale al piano di vista
il punto Pref
viene scelto
di solito come
origine del
mondo degli
oggetti
fig. da
D.Hearn
e M.P.Baker
"Comp.Graph
with OpenGL
Pearson
Prentice Hall
3.rd ed.,2004
posizioni di riferimento per l' OpenGL 3D
Nel caso dell' OpenGL
il punto di vista default
sta all'origine,
l'oggetto sta nell'origine
(reference point - in qualche
caso sta in (0,0,-1),
il piano di vista sta nell'
origine - il tutto va benissimo
per le prospettive paralelle
OpenGL 3D: posizione oggetto / centro prosp.
oggetto
camera
per la visualizzazione (specie se prospettica) di un oggetto 3D
conviene separare il centro di vista (il punto dove sta la camera
o l'occhio) dall'oggetto o spostando la camera (sinistra) o spostando l'oggetto (destra)
che ha ora le z negative
proiezioni geometriche piane (*)
proiezioni
geometriche
piane
(*) Fondam. di grafica tridimensionale interattiva
di R.Scateni,P.Cignoni, C.Montani,R.Scopigno,
McGrawHill It, 2005;
proiezioni geometriche piane (*)
parallele (vediamo prima queste) - e sono:
ortografiche
piante e alzati,
assonometriche
isometriche, dimetriche, trimetriche
oblique
cavaliera cabinet altre
prospettiche: e sono:
a 1 punto di fuga,
a 2 punti di fuga,
a 3 punti di fuga
proiezione ortogonale o parallela:
il punto di vista sta all'infinito,
i raggi di proiezione sono paralleli.
non c' e'
" distanza " tra :
- piano proiezione,
- punto vista,
- oggetto:
quindi
l'asse z e le
distanze z sono
" irrilevanti "
proiezione parallela:
il punto di vista sta all'infinito,
i raggi di proiezione sono paralleli,
non c' e' "distanza" tra piano proiezione, punto vista,
oggetto: l'asse z e' "irrilevante".
se la direzione di proiezione e
la normale al piano di proiezione coincidono
allora abbiamo le proiezioni parallele ortografiche le piu'comuni nel disegno tecnico: il piano di proiezione
e' perpendicolare ad uno degli assi cartesiani,
l' asse e' la direzione di proiezione;
abbiamo:
vista frontale, vista laterale e pianta (vista dall'alto)
3 D- prospettiva ortografica (o ortogonale)
pianta
laterale
frontale
proiezioni parallele ortografiche
punto di vista all'infinito,
raggi di proiezione
paralleli agli assi:
vista frontale, laterale e
dall'alto (pianta).
Si usano perche' dal
disegno si possono rilevare
le distanze e le dimensioni
dell'oggetto;
ma la resa 3D e' modesta,
le tre prospettive non
danno l'idea immediata di
come e' fatto l'oggetto in
3D (infatti, in figura..)
se nella proiezione parallela ortografica la
direzione di proiezione NON coincide con
alcuno degli assi cartesiani abbiamo le
proiezioni assonometriche:
Le prospettive assonometriche (isometrica dove la direzione di
proiezione forma angoli uguali con i tre assi di proiezione,
dimetrica se due angoli tra direzione di proiezione e assi
vartesiani sono uguali, in generale e' trimetrica) si ottengono
dalle ortografiche con direzione parallela all'asse z ruotando
l'oggetto opportunamente.
PROIEZIONI OBLIQUE:
la direzione di proiezione forma un angolo obliquo con il piano di
proiezione; l'oggetto rappresentato conserva l'informazione
della natura 3D (a differenza della proiez.ortografica
fronte/fianco/pianta), ma appare deformato
(*)
in figura, prospettiva parallela
d
(o)
d
d
obliqua (non ortografica) Cavaliera,
gli spigoli laterali (*) hanno la stessa
lunghezza dei frontali (o), angolo 30o
3 D - geometria, prospettive, OpenGL 3D
in generale una prospettiva parallela (ortho) puo' essere
obliqua, come qui in figura,
o come nella figura seguente ..
3 D - geometria, prospettive, OpenGL 3D
PROIEZIONI OBLIQUE:
la direzione di proiezione forma un angolo obliquo con il piano
di proiezione; l'oggetto rappresentato conserva l'informazione
della natura 3D (a differenza della proiez.ortografica
fronte/fianco/pianta), ma appare deformato
un rimedio e' l'accorciamento dei segmenti laterali (paralleli
all'asse z che e' rivolto verso l'osservatore), nella
proiezione cabinet
la lunghezza delle linee laterali si riduce a meta':
d
d
d/2
l'OpenGL non prevede le
prospettive obliqui come
"predefinite", anche se e'
possibile definire la matrice
di trasformazione anche per
tale prospettiva
3 D - prospettiva orto in OpenGL:
glOrtho(xwinmin,xwinmax,ywinmin,ywinmax,distnear,distfar)
3 D - geometria, prospettive, OpenGL 3D
glOrtho (xwinmin,xwinmax,
ywinmin,ywinmax,
distnear,distfar)
nota: asse z verso chi
guarda, assi x e y nel piano
di vista (z=near)
nota: la procedura ortho e la procedura ortho2D sono
"quasi" le stesse, nel senso che l'asse z e' quasi
irrilevante; cambia il volume di visualizzazione, che nel
caso della ortho ha una dimensione sull'asse z da
specificare, gli oggetti fuori tale spazio saranno eliminati
(clipping)
ortho2D assume znear 1 e zfar -1,
per cui tutti gli oggetti in 2D con z=0
sono dentro il volume di visualizzazione.
3 D - geometria, prospettive, OpenGL 3D
glOrtho
(xwinmin,xwinmax, ywinmin,ywinmax, distnear,distfar);
attenzione:
l'asse z e' orientato verso chi guarda,
siamo su punto con z zero
e stiamo guardando verso l'asse z negativo;
gli oggetti sono di solito messi lungo l'asse z negativo;
gli ultimi due parametri specificano due distanze (positive!) per i
piani di clipping vicino e lontano
da cui ho la posizione per gli oggetti; ad es. con znear=10 e zfar=50
(distanza da chi guarda min e max) allora l'oggetto (che sta lungo
l'asse z negativo), deve essere nella posizione tra -10 e -50.
se non specifico nulla, si assume il volume unitario, come nella figura
seguente:
glOrtho(xwinmin,xwinmax,ywinmin,ywinmax, distnear,distfar)
prospettiva parallela in OpenGL:
glMatrixMode( GL_PROJECTION); glLoadIdentity();
segue la specifica del tipo di proiezione e dei limiti dello spazio degli
oggetti visualizzati, con piano di proiezione z==0, e con gli oggetti nell'
origine:
glOrtho(-2.0,2.0, -2.0,2.0, -2.0,2.0);
//
xmin,xmx, ymin,ymx, znear,zfar
poi, in Display:
nota:
i lati si mantengono
paralleli!
(prog. EGD3D_01ORTHO)
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(dx,dy,dz);
glRotatef(ang,1.0,1.0,1.0);
/*rotate ang degrees (/360)
around vector 1,1,1*/
glScalef( 1.0, 1.0, 1.0);
DrawCube();
provare l'uso e leggere con cura
il programma OGL3D_1ORTHO
QuickTime™ and a
TIFF (Uncompressed) decompressor
are needed to see this picture.
QuickTime™ and a
TIFF (Uncompressed) decompressor
are needed to see this picture.
in figura,
visualizzazione con proiezione parallela (orthographic) con
oggetto (cubo) ruotato in due modi diversi
ancora un'
immagine in
prospettiva
ortografica,
programma
EGD3D_1ORTHO,
con angoli di
rotazione
ax=-10,
ay=-10,
az=0
QuickTime™ and a
TIFF (Uncompressed) decompressor
are needed to see this picture.
segue ora una breve
presentazione del
programma
EGD3D_01ORTHO
dal programma EGD3D_01ORTHO
void DrawCube(){ /* asse x a destra, asse y in alto,
asse z in fuori verso l'osservatore
4------3 asse x a destra,
/ | . / | asse y in alto,
6------7 .| asse z in fuori,
| 1---|--2 verso l'osservatore
| / . | / piano con z=0.5 e'
5------8 1-5-8-2 */
//per disegnare le linee verdi da z<0 a z>0 1-5, 2-8, 4-6, 3-7
glLineWidth(3.0); glColor3f(0.0,1.0,0.0);
glBegin(GL_LINES);
glVertex3f(-0.5,-0.5,-0.5 ); glVertex3f(-0.5,-0.5,+0.5 );//1-5
glVertex3f(+0.5,-0.5,-0.5 ); glVertex3f(+0.5,-0.5,+0.5 );//2-8
glVertex3f(-0.5,+0.5,-0.5 ); glVertex3f(-0.5,+0.5,+0.5 );//4-6
glVertex3f(+0.5,+0.5,-0.5 ); glVertex3f(+0.5,+0.5,+0.5 );//3-7
glEnd(); ...
dal programma EGD3D_01ORTHO
void DrawCube(){ /* asse x a destra, asse y in alto,
asse z in fuori verso l'osservatore
4------3 asse x a destra,
/ | . / | asse y in alto,
6------7 .| asse z in fuori,
| 1---|--2 verso l'osservatore
| / . | / piano con z=0.5 e'
5------8 1-5-8-2
*/
//disegna le linee blu della faccia dietro (z<0) punti 1,2,3,4
glColor3f(0.0, 0.0, 1.0); /* linee blu */
glBegin(GL_LINE_LOOP); /* 1-2-3-4 blu back face */
glVertex3f(-0.5, -0.5, -0.5 ); glVertex3f(+0.5, -0.5, -0.5 );
glVertex3f(+0.5, +0.5, -0.5 ); glVertex3f(-0.5, +0.5, -0.5 );
glEnd();
dal programma EGD3D_01ORTHO
void DrawCube(){ /* asse x a destra, asse y in alto,
asse z in fuori verso l'osservatore
4------3 asse x a destra,
/ | . / | asse y in alto,
6------7 .| asse z in fuori,
| 1---|--2 verso l'osservatore
| / . | / piano con z=0.5 e'
5------8 1-5-8-2
*/
//disegna linee gialle faccia davanti (z>0) punti 5,6,7,8
glColor3f(1.0, 1.0, 0.0); /* giallo z=0.5, */
glBegin(GL_LINE_LOOP); /* 5-6-7-8 yellow front face */
glVertex3f(-0.5, -0.5, +0.5 ); glVertex3f(-0.5, +0.5, +0.5 );
glVertex3f(+0.5, +0.5, +0.5 ); glVertex3f(+0.5, -0.5, +0.5 );
glEnd();
dal programma EGD3D_01ORTHO
void DrawCube(){ /* asse x a destra, asse y in alto,
asse z in fuori verso l'osservatore
4------3 asse x a destra,
/ | . / | asse y in alto,
6------7 .| asse z in fuori,
| 1---|--2 verso l'osservatore
| / . | / piano con z=0.5 e'
5------8 1-5-8-2
*/
// lo stesso disegno si ottiene con la procedura di libreria:
glLineWidth(5.0);
glColor3f(1.0,1.0,1.0); /* bianco */
glutWireCube(1.0); /* lato lungo 1, centro in origine */
// a faccie piene (rettangoli), proc di libr:
glutSolidCube(1.0); // o, stesso disegno con GL_POLY:
/*
4-------3
not wire .
/|
/|
disegna 4 poligoni
.
6------7 .|
attenzione all'ordine e
.
| 1--- |-- 2 al verso di orientamento
.
| /
|/
dei poligoni
. 5-------8
*/
glEnable(GL_BLEND); glBlendFunc( .., ...); // usa alfa
glColor4f(0.4,0.4,0.4, alf); /* grigio */
glBegin(GL_POLYGON);
/* 1-2-5-8 bottom y=-0.5 */
glVertex3f(-0.5, -0.5, -0.5 ); glVertex3f(+0.5, -0.5, -0.5 );
glVertex3f(+0.5, -0.5, +0.5 ); glVertex3f(-0.5, -0.5, +0.5 );
glEnd();
glBegin(GL_POLYGON);
/* 6-7-3-4 top y= +0.5 */
glVertex3f(-0.5, +0.5, +0.5 ); glVertex3f(+0.5, +0.5, +0.5 );
glVertex3f(+0.5, +0.5, -0.5 ); glVertex3f(-0.5, +0.5, -0.5 );
glEnd();
... ecc per le altre facce
void myPerspectiveSet(){ inizializzazioni per uso della prospettiva
glMatrixMode( GL_PROJECTION); glLoadIdentity();
/* 4x4 projection matrix for openGL hw */
glOrtho( xmin, xmax, ymin, ymax, znear, zfar );
/* usa prospettiva parallela */
} /* myPerspectiveSet */
void myGLInit ( ) {
myWiWi=glutGet(GLUT_WINDOW_WIDTH); myWiHe=glutGet..
glViewport(0,0,myWiWi, myWiHe);
myPerspectiveSet();
glMatrixMode( GL_MODELVIEW); glLoadIdentity();
} /* myInitGL */
void myReshape ( int w, int h ) {
myWiWi=w; myWiHe= h; glViewport( 0, 0, w, h );
PerspectiveSet();
glMatrixMode( GL_MODELVIEW); glLoadIdentity();
glutPostRedisplay();
} /* myReshape */
// la procedura che disegna ha la struttura:
void myDisplay() { // start display
glClearColor( 0.1, 0.1, 0.3, 1.0f );
glClear( GL_COLOR_BUFFER_BIT );
myPerspectiveSet(); /* esegue glOrtho( xmin, xmax, ... zfar);*/
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* unita' */
glPushMatrix(); /* fai una copia, cambia la copia della matr. */
/* - non accumulare la trasformaz.che segue */
glTranslatef( tx, ty, tz ); /* inizia con tx=ty=tz=0.0 */
glRotatef( angx, 1.0, 0.0, 0.0); /* ruota di angx attorno asse x
*/
glRotatef( angy, 0.0, 1.0, 0.0); /* attorno asse y */
glRotatef( angz, 0.0, 0.0, 1.0 ); /* attorno asse z */
glScalef( 1.5, 1.5, 1.5 ); /* ingrandisci il cubo, e' -0.5..+0.5 */
myDrawCube(); /* fa il disegno del cubo */
glPopMatrix(); /* elimina tutte le trasformazioni fatte dal push
*/
glFlush();
/* fai passare da scheda grafica su schermo */
/* e il programma ha la struttura come segue */
int main (int argc, char * argv[]) {
SpiegaFig();
SpiegaTasti();
myOpenWin( argc, argv ); myDataInit(); myInit( );
glutDisplayFunc( myDisplay);
glutReshapeFunc( myReshape );
glutKeyboardFunc( myKeyboard );
glutSpecialFunc( myArrow_keys );
glutMainLoop( ); return 0; /* ma non si ritorna qui */
} /* main */
void myOpenWin(int argc, char * argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE );
glutInitWindowPosition(WinX0, WinY0);
glutInitWindowSize( WinSizex, WinSizey );
glutCreateWindow( "<OGL3D_01ORTHO>");
} /* OpenWinPlease */
Scarica

EGD21_3Dproiez1Orto