Professional Documents
Culture Documents
OpenGL Tutorijal
OpenGL Tutorijal
Uvod
ta je OpenGL?
OpenGL je API (Application Programming Interface) Softverski interfejs ka grafikom hardveru Sloj izmeu programera i grafikog hardvera Omoguava opis scene na najniem nivou OpenGL je proceduralni interfejs ka hardveru Platformski je nezavisan 1980 IrisGL (Silicon Graphics) 1992 OpenGL verzija 1.0 2001 OpenGL verzija 1.3 2002 OpenGL verzija 1.4 2003 OpenGL verzija 1.5 2006 OpenGL verzija 2.0 2008 OpenGL verzija 3.0
2
Historijat:
Uvod
Specifikacija OpenGL standarda
Specifikaciju pie ARB (Architecture Review Board) lanovi ARB-a su DEC, HP, Intel, IBM, Microsoft...
Implementacija biblioteka
OpenGL biblioteke moe napisati bilo ko Ukoliko biblioteke prou testove mogu se nazvati OpenGL, u suprotnom ne (MESA)
Uvod
Mogunosti
Crtanje linija, trouglova, poligona (3D) Manipulacija slika (2D) Teksture Osvjetljavanje...
OpenGL ne obezbjeuje:
Podrku za opis objekata i scene Podrku za parametrizirani opis povrina (NURBS i sl.) Rad s prozorima Sjenenje... Postoje biblioteke koje ovo obezbjeuju
OpenGL biblioteke
OpenGL gl.h GLU (OpenGL Utility Library) glu.h Transformacija koordinata Osnovni objekti NURBS (Non-Uniform Rational Basis Spline) matematski model za generiranje i predstavljanje krivih i povrina Sastavni dio OpenGL distribucije GLUT (OpenGL Utility Toolkit) glut.h Rutine za rad s prozorima (platformski nezavisne) Nije dio OpenGL distribucije Open Inventor Objekti za rad s modelima Objektno orijentiran Nije dio OpenGL distribucije
6
Svi ovi podaci zajedno se procesiraju Detalji o geometrijskim podacima e biti kasnije objanjeni
9
10
11
12
14
15
Sve OpenGL komande imaju prefiks i sufiks U sluaju procedura poetno slovo svake rijei je veliko
tip poziv procedure konstanta tip podataka Prefiks gl GL_ GL primjer glEnd() GL_POINTS GLfloat
Tipina komanda : glVertex3f(1.0, 2.0, 1.0) prefiks naziv komande broj i tip argumenata (tri argumenta tipa float)
16
Interna predstava
8-bitni cijeli broj 16-bitni cijeli broj 32-bitni cijeli broj 32-bitni broj u pok. taki 64-bitni broj u pok. taki 8-bitni pozitivni cijeli broj 16-bitni pozitivni cijeli broj 32-bitni pozitivni cijeli broj
C tip
char short long float double unsigned char unsigned short unsigned long unsigned int
Sufiks
b s i f d ub us ui
17
18
Prvi primjer
main() { inicijaliziraj_prozor(); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0); glOrtho(-0.5, 1.5, -0.5, 1.4, -1.0, 1.0); glBegin(GL_POLYGON); glVertex2f(0.0, 0.0); glVertex2f(1.0, 0.0); glVertex2f(0.5, 0.866); glEnd(); glFlush(); odrzavaj_prozor_na_ekranu(); }
kd: trougao_neosjencen.c
19
Poetni primjer
inicijaliziraj_prozor() Postavlja sve parametre prozora glClear() isti prozor i postavlja boju pozadine koja je specificirana naredbom glClearColor() glOrtho() Specificira koordinatni sistem u kojem OpenGL crta sliku, kao i nain na koji se slika preslikava na ekran glBegin() / glEnd() Oznaavaju poetak i kraj koda koji e definirati objekt koji se crta poligon u ovom primjeru glVertex3f() Specificira ivice poligona koji e se crtati glFlush() Forsira izvravanje komandi koje su prethodno zadate odrzavaj_prozor_na_ekranu() Iscrtava prozor na ekranu i obrauje sve dogaaje
20
24
GLUT
GLUT OpenGL Utility Toolkit Platformski je nezavisan Glut obezbjeuje sljedee funkcionalnosti:
Vie prozora za OpenGL rendering Obrada dogaaja pomou "callback" funkcija Sofisticirani ulazni ureaji Tajmeri i "idle" rutina Kaskadni pop-up meniji Rutine za generiranje raznih objekata (ajnik, torus...) Podrka za fontove ("bitmap" i "stroke") Razne funkcije za manipuliranje prozorima
}
27
GLUT inicijalizacija
void glutInit(int *argcp, char **argv);
Slui za inicijalizaciju GLUT biblioteke Parametri :
argcp pokaziva na prvi parametar funkcije main() argv pokaziva na drugi parametar funkcije main()
GLUT se moe kontrolisati i pomou parametara iz komandne linije (odatle i parametri funkcije)
28
GLUT inicijalizacija
void glutInitWindowSize(int w, int h);
Inicijalizira veliinu prozora na ekranu Parametri:
w irina prozora h visina prozora
GLUT inicijalizacija
void glutInitDisplayMode(unsigned int mode);
Postavlja inicijalni md prikazivanja Poziva se (po potrebi) za svaki prozor koji se kreira Parametar mode dobija se logikom ILI funkcijom sljedeih bit-maski:
GLUT_RGBA GLUT_RGB GLUT_INDEX GLUT_SINGLE GLUT_DOUBLE GLUT_ACCUM GLUT_ALPHA GLUT_DEPTH GLUT_STENCIL GLUT_MULTISAMPLE GLUT_STEREO GLUT_LUMINANCE RGBA md za boju (podrazumijevano) RGB md za boju indeksirani md za boju prozor s jednim bufferom (podrazumijevano) dvostruko bufferirani prozor prozor s akumulacijskim bufferom prozor s bufferom za alfa komponentu boje prozor s bufferom za dubinu prozor sa stencil bufferom prozor s podrkom za multisampling stereo prozor luminance md za boju (slino indeks modu)
30
GLUT
void glutMainLoop(void);
Poziva se tek nakon to se izvri kompletna inicijalizacija Poziva se najvie jedanput iz jednog programa Zapoinje GLUT petlju za obradu dogaaja Iz nje se pozivaju korisnike rutine za obradu dogaaja Ova rutina se nikada ne zavrava
31
GLUT
void glutSwapBuffers(void);
Vri izmjenu sadraja buffera (buffer swap) na sloju u upotrebi za trenutni prozor. Specifino, glutSwapBuffers podstie sadraje stranjeg buffera sloja u upotrebi trenutnog prozora da postanu sadraji prednjeg buffera. Sadraji stranjeg buffera tada postaju nedefinirani. Auriranje se tipino deava prije za vrijeme vertikalnog retracea monitora, nego neposredno nakon poziva glutSwapBuffers(). Naknadne OpenGL komande mogu biti izdate odmah nakon poziva glutSwapBuffers(), ali se ne izvravaju sve dok izmjena buffera ne bude kompletirana.
32
33
Postoji posebna funkcija za svaki prozor Uvijek se poziva funkcija koja je povezana s prozorom koji je trenutno aktivan
34
39
Greke
U toku rada mogu nastati razne greke OpenGL detektuje jedan dio greaka Kada se greka detektira
OpenGL pamti kd greke koja je nastala Komanda koja je generirala greku se ignorie U sluaju GL_OUT_OF_MEMORY rezultat je nepredvidiv
GLenum glGetError(void);
Vraa kd greke koja se dogodila U sluaju da greke nema, vraa GL_NO_ERROR Resetuje kd greke na GL_NO_ERROR Trebalo bi je pozivati barem jedanput poslije crtanja scene
40
Greke
Greke do kojih moe doi u toku rada su:
Vrijednost
GL_NO_ERROR GL_INVALID_ENUM GL_INVALID_VALUE GL_INVALID_OPERATION GL_STACK_OVERFLOW GL_STAC_UNDERFLOW GL_NO_MEMORY
opis
greka se nije dogodila GLenum argument van opsega numeriki argument van opsega operacija nije dozvoljena u trenutnom stanju operacija bi dovela do prepunjavanja stacka operacija bi dovela do itanja s praznog stacka nema dovoljno memorije da se izvri komanda
41
Greke
Pored ovih postoje i druge greke
37 GLU NURBS greaka (GLU_NURBS_ERROR1 ...) 14 GLU teselator greaka (GLU_TESS_ERROR*)
Bufferi
OpenGL koristi nekoliko buffera u toku rada Ovi bufferi su implementirani u hardveru
naziv Framebuffer z-buffer Opis sprema piksele za ispis na ekran sadri udaljenost svake take na ekranu po z osi sadri providnost svakog piksela slui za antialiasing sprema podatke o boji (RGB md) sprema podatke o boji (u indeksnom modu) ima vie primjena (npr. da onemogui crtanje na odreenom dijelu ekrana)
alpha buffer accumulation buffer color buffer index buffer stencil buffer
43
Bufferi
Pranjenje buffera (izbor vrijednosti za pranjenje) boja (color buffer)
glClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf alpha)
dubina (z-buffer)
glClearDepth(GLclampd depth)
stencil
glClearStencil(GLint s)
akumulacija
glClearAccum(GLclampf r, GLclampf g, GLclampf b, GLclampf alpha)
indeks
glClearIndex(GLfloat index)
44
Bufferi
Pranjenje buffera (postavljanje izabrane vrijednosti)
bufferi se prazne pomou komande glClear(GLint mask) mask je maska koja odreuje koji bufferi se prazne mask se dobija kombinacijom sljedeih vrijednosti:
buffer
color depth stencil accumulation
maska
GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT GL_STENCIL_BUFFER_BIT GL_ACCUM_BUFFER_BIT
Primjer :
glClearColor(0.0, 0.0, 0.0, 0.0); glClearDepth(0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
45
Boja
Opis objekta je nezavisan od boje kojom se crta Svi elementi koji se iscrtavaju imaju trenutnu boju Trenutna boja se moe promijeniti u bilo kojem trenutku Boje se opisuju pomou RGB ili RGBA modela esto se primjenjuje i indeksni md za boju:
Sve vrijednosti boje su upisane u jedan niz Boju piksela odreuje indeks boje u nizu
Primjer (pseudokd): postavi_boju(crvena) nacrtaj objekt(A) postavi_boju(plava) nacrtaj objekt(B) postavi_boju(zelena) postavi boju(crvena) nacrtaj objekt(C)
Boja
Boja se zadaje pomou jedne od sljedeih komandi:
void void void void glColor3{b glColor3{b glColor4{b glColor4{b i i i i f f f f d d d d ub ub ub ub us us us us ui}(TYPE r, TYPE g, Type b) ui}v(TYPE *color) ui}(TYPE r, TYPE g, Type b, TYPE a) ui}v(TYPE *color)
47
Sjenenje
Linije ili ispunjeni poligoni se mogu crtati
Uvijek jednobojno flat shading (konstantno sjenenje) U vie boja smooth shading (Goraudovo sjenenje)
Flat shading
Svi pikseli koji pripadaju poligonu imaju istu boju Boja poligona odreena je bojom prve take koja je zadata (boja ostalih taaka nema uticaja)
Smooth shading
Boja svakog tjemena se uzima u obzir Boje piksela u poligonu se interpoliraju izmeu boja svih tjemena kojima je poligon zadat Dva susjedna piksela imaju neznatno razliitu boju
48
Sjenenje
Smooth shading
OpenGL pokuava da napravi gradijent unutar poligona (gradient fill) U sluaju RGBA boje ovo je pravilno U sluaju indeksiranog moda gradijent se izvodi nad indeksima
Dva susjedna indeksa mogu pokazivati na razliite boje Rjeenje je da se napravi gradijent u nizu boja
49
Boja
Prvi primjer (modificiran) :
glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex2f(0.0, 0.0); glColor3f(0.0, 1.0, 0.0); glVertex2f(1.0, 0.0); glColor3f(0.0, 0.0, 1.0); glVertex2f(0.5, 0.866); glEnd(); GL_SMOOTH kd: trougao_sa_sjencenjem.c
50
GL_FLAT
Nasilno iscrtavanje
Ponekad je potrebno obezbijediti da se scena iscrta prije nego to krenemo s drugim radnim zadatkom Postoje dvije komande za "nasilno" iscrtavanje:
void glFlush(void) void glFinish(void)
glFlush()
Forsira poetak obrade prethodno zadatih komandi Obezbjeuje da se one izvre u konanom vremenu Ne eka da se komande izvre, odmah vraa kontrolu
glFinish()
Kao i glFlush(), samo to eka da se komande izvre
51
Geometrijski primitivi
Osnovni primitivi su take, linije i poligoni Svi primitivi su opisani pomou taaka:
Taka opisuje samu sebe Linija se opisuje pomou krajnjih taaka Poligon se opisuje pomou uglova
Primjer:
[1.0, 0.0, 0.0, 1.0] glVertex2s(1, 0); [4.0, 2.5, 0.3, 1.0] glVertex3d(4.0, 2.5, 0.3); glVertex4f(1.0, 0.8, 0.0, 3.0); [1.0, 0.8, 0.0, 3.0]
Odreuje veliinu take na ekranu size je veliina take u pikselima Postoji maksimalna veliina take Dobija se parametrom GL_POINT_SIZE_RANGE i funkcijom glGetFloatv Bez antialiasinga Veliina take se zaokruuje Taka se crta kao size x size kvadrat na ekranu S antialiasingom Veliina take se ne zaokruuje Taka se crta kao krunica (priblino) Pikseli koji su blii ivici take imaju svjetliju boju radi postizanja glatkoe primitiva
55
glBegin() / glEnd()
glBegin() / glEnd() specificira kd za opis primitiva
Izmeu njih se pomou glVertex*() specificira lista tjemena Tjemena koja se specificiraju izmeu ovih komandi ine jedan primitiv Postoji ogranienje u pogledu komandi koje je mogue upotrijebiti izmeu glBegin i glEnd
Primjer:
glBegin(GL_POLYGON); glVertex2f(0.0, 0.0); glVertex2f(1.0, 0.0); glVertex2f(0.5, 0.866); glEnd();
void glEnd();
glBegin() / glEnd()
void glBegin(GLenum mode); Oznaava poetak sekvence komandi za opis primitiva mode odreuje tip primitiva
Vrijednost GL_POINTS GL_LINES GL_LINE_STRIP GL_LINE_LOOP GL_TRIANGLES GL_TRIANGLE_STRIP GL_TRIANGLE_FAN GL_QUADS GL_QUAD_STRIP GL_POLYGON Znaenje crta pojedinane take parovi taaka se interpretiraju kao pojedinane linije svi segmenti se povezuju u liniju kao i prethodno, samo to se dodaje segment izmeu posljednje i prve take po tri take obrazuju jedan trougao kao i prethodno, samo to jedna taka moe biti tjeme vie trouglova po tri take obrazuju trouglove pri emu nulta taka pripada svakom trouglu po etiri take obrazuju etvorouglove koji se crtaju kao i prethodno, samo to jedna taka moe biti u vie etvorouglova sve take obrazuju jedan poligon
57
glBegin() / glEnd()
58
glBegin() / glEnd()
Komande koje se mogu koristiti unutar glBegin / glEnd
naziv glVertex*() glColor*() glIndex*() glNormal*() glTexCoord*() glEdgeFlag*() glMaterial*() glArrayElement() glEvalCoord*(), glEvalPoint*() glCallList(), glCallLists() namjena postavlja koordinate verteksa postavlja trenutnu boju postavlja trenutni indeks postavlja koordinate vektora normale postavlja koordinate teksture kontrolira crtanje ivica postavlja osobine materijala vraa podatke o takama generira koordinate izvrava prikaznu listu (liste)
59
Linije irina
OpenGL omoguava kontrolu stila i irine linije
void glLineWidth(GLfloat width); Postavlja irinu linije koja se crta Parametar width definira irinu linije u pikselima irina se tretira kao broj taaka po x osi koje linija zauzima (a ne po normali na liniju) irina se interno zaokruuje na cijeli broj prije crtanja Antialiasing
Linija moe imati proizvoljnu irinu (ne zaokruuje se) Ivini pikseli se crtaju s manjim intenzitetom da bi se postigao efekt glatkoe
60
Linije stil
Linije se iscrtavaju sa stilom koji je unaprijed odreen
void glLineStipple(GLint factor, GLushort pattern);
61
Linije stil
Mora se omoguiti upotreba stilova
glEnable(GL_LINE_STIPPLE) omoguuje stilove glDisable(GL_LINE_STIPPLE) iskljuuje upotrebu stilova podrazumijevana vrijednost
62
Linije primjer
glEnable(GL_LINE_STIPPLE); glColor3f(1.0, 0.0, 0.0); glLineWidth(2.0); glLineStipple(1, 0x0101); nacrtaj_liniju(10, 10, 90, 10); glLineStipple(2, 0x0101); nacrtaj_liniju(10, 15, 90, 15); glColor3f(0.0, 1.0, 0.0); glLineWidth(5.0); glLineStipple(1, 0x00FF); nacrtaj_liniju(10, 20, 90, 20); glLineStipple(2, 0x00FF); nacrtaj_liniju(10, 25, 90, 25); glColor3f(0.0, 0.0, 1.0); glLineWidth(10.0); glLineStipple(1, 0x1C47); nacrtaj_liniju(10, 30, 90, 30); glLineStipple(2, 0x1C47); nacrtaj_liniju(10, 35, 90, 35); glDisable(GL_LINE_STIPPLE); glFlush(); void nacrtaj_liniju(float x1, float y1, float x2, float y2) { glBegin(GL_LINES); glVertex2f(x1, y1); glVertex2f(x2, y2); glEnd(); }
kd: linije.c
63
Poligoni
Poligon je oblast ograniena zatvorenom linijom. Mora biti konveksan, ne smije presijecati samog sebe i ne smije imati rupu Primjeri nepravilnih poligona (i kako ih OpenGL crta):
kd: nepravilni_poligoni.c
64
Poligoni pravougaonici
void glRect{s i f d}(x1, y1, x2, y2); void glRect{s i f d}[v](tacka1, tacka2); Crta pravougaonik s jednim tjemenom u (x1, y1), a drugim tjemenom u (x2, y2) Podrazumijeva se da je z = 0 Ova naredba je ekvivalentna sljedeoj sekvenci naredbi glBegin(GL_QUADS); glVertex(x1, y1); glVertex(x2, y2); glVertex(x3, y3); glVertex(y4, y4); glEnd(); (x3, y3) i (x4, y4) se odreuju na osnovu prve dvije take
65
Poligoni ispunjavanje
Poligoni mogu biti ispunjeni zadatom maskom Maska se zadaje kao 32bit x 32bit matrica
Elementi su neoznaeni bajtovi Ukoliko je vrijednost bita 1 onda se crta, u suprotnom ne
66
Poligoni ispunjavanje
Primjer
GLubyte np[] = { 0x00, }; glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_POLYGON_STIPPLE); glPolygonStipple(np); glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex2f(-2.0, -2.0); glColor3f(0.0, 1.0, 0.0); glVertex2f( 2.0, -2.0); glColor3f(0.0, 0.0, 1.0); glVertex2f( 2.0, 2.0); glColor3f(0.0, 1.0, 1.0); glVertex2f(-2.0, 2.0); glEnd(); glDisable(GL_POLYGON_STIPPLE); glFlush();
kd: polygon_stipple.c
67
68
Poligoni
Redoslijed taaka odreuje orijentaciju poligona
Ako su take zadavane u smjeru kretanja kazaljke na satu (CW), poligon je licem naprijed U suprotnom sluaju, poligon je licem unazad (CCW)
void glFrontFace(GLenum face); Odreuje orijentaciju poligona Parametar face GL_CW ako su take zadavane u CW smjeru, poligon je licem naprijed 69 GL_CCW suprotno od prethodnog
Poligoni
glPolygonMode(GL_FRONT, GL_POLYGON); glPolygonMode(GL_BACK, GL_LINE); glBegin(GL_TRIANGLES); glColor3f(1.0, 0.0, 0.0); glVertex2f(-2.0, -2.0); glVertex2f(-0.5, -2.0); glVertex2f(-0.5, 2.0); glColor3f(0.0, 0.0, 1.0); glVertex2f( 2.0, -2.0); glVertex2f( 0.5, -2.0); glVertex2f( 0.5, 2.0); glEnd(); glFlush();
kd: polygon_mode.c
70
Transformacije
Transformiranje 3D modela u 2D sliku
1. Primjenjuju se transformacije za modeliranje scene, za pogled i za projekciju 2. Primjenjuje se neki od algoritama za odsijecanje poligona, tj. u sceni ostaje samo ono to e se vidjeti na ekranu 3. Uspostavlja se korespondencija izmeu taaka koje su ostale poslije 2. koraka i piksela na ekranu (viewport transformacija)
Transformacije se obavljaju preko mnoenja matrica Mogue je putem naredbi promijeniti parametre za svaku transformaciju
71
Transformacije
Prevoenje iz 3D u 2D analogno je fotografiranju Fotografija se dobija u sljedeim koracima
1. Postavimo kameru i uperimo je ka sceni
(transformacija pogleda) 2. Uredimo po elji objekte koji ine scenu (transformacija modela) 3. Izaberemo soiva i podesimo zoom kamere (projekcijska transformacija) 4. Odredimo veliinu slike (viewport)
Transformacija taaka
Transformacija modela mora se u kodu pojaviti prije transformacije pogleda Ostale transformacije mogu se primijeniti bilo kada Redoslijed primjene transformacija (interno)
73
Matrice
Transformacija je definirana pomou 4x4 matrice Primjer
v taka koju transformiramo v' taka nakon transformacije M matrica transformacije
74
Transformacije opte
void glMatrixMode(GLenum mode);
Selektira matricu koja e biti aktivna Parametar mode
GL_MODELVIEW selektira matricu za transformaciju modela i pogleda GL_PROJECTION selektira matricu za projekcijsku transformaciju GL_TEXTURE selektira matricu za teksture
Sve naknadne transformacije modificiraju matricu koja je selektirana pomou ove komande Koja matrica je trenutno izabrana moe se provjeriti preko glGet()s argumentom GL_MATRIXMODE Na poetku rada automatski je selektirana matrica za transformaciju modela i pogleda
75
Transformacije opte
void glLoadIdentity(void);
Postavlja trenutnu matricu na jedininu 4x4 matricu
1 0 M 0 0 0 0 0 1 0 0 0 1 0 0 0 1
Postavlja trenutnu matricu na matricu koja je zadata (M) Primjer (definiranje sopstvene projekcije)
glMatrixMode(GL_PROJECTION); glLoadMatrix(mojaPerspektiva);
76
Transformacije opte
void glMultMatrix{f d}(const TYPE *M);
Mnoi trenutnu matricu sa zadatom matricom Parametar M
4x4 matrica Zadaje se kao niz od 16 vrijednosti (double ili float)
Primjer
C trenutna matrica transformacije M matrica koja je zadata Poslije ove naredbe bie C CM
Mnoenje se uvijek vri s desne strane Redoslijed primjene glMultMatrix (u sluaju vie njih) je bitan (mnoenje matrica nije komutativno)
77
Transformacije opte
C i C++ smjetaju matrice u memoriji po vrstama OpenGL ih pohranjuje po kolonama
GLfloat m[4][4]; m[i][j] i-ta kolona i j-ta vrsta
Ovo bi OpenGL protumaio kao i-tu vrstu i j-tu kolonu Da bi se izbjegla zabuna radite ovako:
GLfloat m[16] = {m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
m0 m M 1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12 m13 m14 m15
78
Transformacije opte
Ponekad je korisno dohvatiti trenutnu matricu
void glGetFloatv(GLenum what, GLfloat *m);
Dohvata matricu proizvoljne transformacije Parametar what
Odreuje koja se matrica trai Kao parametar mode kod glMatrixMode
Parametar m
Pointer na 4x4 matricu U njega e biti upisana matrica
79
Transformacije osnove
Redoslijed transformacija koje se primjenjuju je bitan Ukoliko se transformacije primjenjuju razliitim redoslijedom krajnji efekt nije isti
80
Transformacije osnove
Primjer
glMatrixMode(GL_MODELVIEW); glMultMatrix(P); glMultMatrix(Q); glMultMatrix(R); glBegin(GL_POINTS); glVertex3fv(v); glEnd();
U trenutku crtanja matrica transformacije je PQR Crta se transformirana taka v'=PQRv=P(Q(Rv)) Dakle, prvo se primjenjuje transformacija koja je posljednja zadata
81
Transformacije modela
Transformacije modela mogue je zadati
Preko unaprijed izraunate matrice i glMultMatrix()
Ovo je vrlo komplikovan proces u sluaju vie uzastopnih osnovnih transformacija
Druga varijanta je mnogo bra jer hardver esto posjeduje mogunosti da brzo odradi ove afine transformacije
83
85
x 0 0 0 0 y 0 0 S 0 0 z 0 0 0 0 1
Matrica skaliranja S kojom se mnoi trenutna matrica Primjer
86
kd: trans_primjer.c
87
Transformacije pogleda
Kameru moemo pozicionirati na dva naina
Putem pomjeranja svih objekata u sceni, pri emu je lokacija kamere fiksna (transformacija modela) Putem pomjeranja kamere (transformacija pogleda)
Pomjeranje kamere
Ekvivalentno je pomjeranju svih objekata u suprotnom pravcu Npr. rotacija kamere u smjeru kretanja kazaljke na satu ekvivalentna je rotiranju svih objekata u suprotnom smjeru
Transformacije pogleda
Kamera "gleda" u neku taku
To podrazumijeva da kamera gleda u tom pravcu
89
Transformacija pogleda
Pozicioniranje kamere u 3D prostoru je komplikovano Moe se uprostiti pomou funkcije
void gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble posx, GLdouble posy, GLdouble posz, GLdouble upx, GLdouble upy, GLdouble upz);
90
Transformacija pogleda
Parametri funkcije gluLookAt()
[eyex, eyey, eyez]
Koordinate koje odreuju poloaj kamere
91
Projekcijske transformacije
Definiraju prostor u kojem se scena nalazi
Objekti unutar prostora se crtaju Objekti koji su van prostora se odsijecaju
Mora se izabrati matrica za rad s projekcijama pomou glMatrixMode(GL_PROJECTION); Pomou naknadnih rotacija i translacija mogue je promijeniti orijentaciju prostora za odsijecanje
92
Projekcijske transformacije
void glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far); Postavlja paralelnu projekciju Parametri odreuju prostor za odsijecanje (slika)
93
Projekcijske transformacije
Paralelna projekcija
Prostor za odsijecanje je paralelopiped Bez dodatnih transformacija prostor je paralelan sa z osom Veliina svih objekata je sauvana (tj. ne zavisi od toga koliko su udaljeni od kamere) Uglovi imeu pojedinih ivica su sauvani esto se koristi u inenjerskim aplikacijama (CAD i sl.)
glOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);
Isti efekt kao glOrtho() samo to se podrazumijeva da su sve z koordinate izmeu 1 i 1
94
Projekcijske transformacije
void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
95
Projekcijske transformacije
Perspektiva
Veliina objekata se mijenja Objekti koji su udaljeniji od kamere izgledaju manji Slika se projektuje na vrh piramide koji se nalazi kod kamere Ova projekcija bolje odslikava realnost od paralelne esto se koristi u animacijama i video-igricama Ova projekcija moe biti asimetrina Postoji funkcija gluPerspective koja je intuitivnija za koritenje
96
Projekcijske transformacije
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far);
Postavlja perspektivnu projekciju Projekcija je uvijek simetrina Parametri odreuju prostor za odsijecanje (slika)
97
Projekcijske transformacije
gluPerspective()
Parametri
aspect odnos irine i duine blie ravni (pozitivan broj) fovy ugao koji zauzima piramida po y osi (izmeu 0 i 180 stepeni) near i far odreuju ravni odsijecanja po z osi
Na osnovu ova tri parametra piramida je jednoznano odreena Piramida je paralelna pogledu posmatraa Piramida koja se kreira je simetrina u odnosu na ose (x i y osu)
98
Projekcijske transformacije
Ponekad se objekt ne vidi itav ili se ne vidi u pravoj veliini (iako je kamera dobro postavljena) Potrebno je na osnovu veliine objekta odrediti projekciju (fovy) Za to se moe napisati funkcija u C-u
double fovy(double distance, double size) { double angle; angle = 2.0*atan2(size/2.0, distance); return (180*angle/M_PI); }
99
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glLoadIdentity(); glOrtho(-5, 5, -5, 5, -10, 10); glFrustum(-2, 2, -2, 2, 3.0, 10);
// Centralni cajnik, z = 3.0 glTranslatef(0.0, 0.0, 3.0); glutSolidTeapot(1.0); // Gornji desni cajnik, z = 2.0 glTranslatef(2.0, 2.0, -1.0); glutSolidTeapot(1.0); // Gornji lijevi cajnik, z = 1.0 glTranslatef(-4.0, 0.0, -1.0); glutSolidTeapot(1.0); // Donji lijevi cajnik, z = 0.0 glTranslatef(0.0, -4.0, -1.0); glutSolidTeapot(1.0); // Donji desni cajnik, z = -1 glTranslatef(4.0, 0.0, -1.0); glutSolidTeapot(1.0);
kd: projekcije.c
100
Transformacije viewport
Potrebno je definirati koliki prostor slika zauzima na ekranu (viewport) Cijela scena se crta samo unutar tog prostora Taj prostor je uvijek pravougaonog oblika Njegova veliina je izraena u koordinatama ekrana (unutar prozora) Viewport se zadaje relativno u odnosu na donji lijevi ugao prozora Podrazumijeva se da viewport zauzima cijeli prozor
101
Transformacije viewport
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
Prostor je pravougaonik odreen zadatim parametrima Treba biti paljiv kod definiranja veliine viewporta
gluPerspective(fovy, 1.0, near, far); glViewPort(0, 0, 400, 200);
Transformacije viewport
Primjer iscrtavanja s dva viewporta
int x = 200; int y = 400; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // postavljamo prvi viewport glViewport(0, 0, x, y/2); glutSolidTeapot(1.0); // postavljamo drugi viewport glViewport(0, y/2, x, y/2); glRotatef(45, 1.0, 1.0, 1.0); glutSolidTeapot(1.0);
kd: viewport.c
103
Transformacije dubina
Dubina taaka na ekranu se transformira prilikom viewport transformacije Parametri ove transformacije se mogu promijeniti
void glDepthRange(GLclampd near, GLclampd far);
Transformacije stackovi
OpenGL sprema sve matrice na stackovima Za svaku vrstu transformacije postoji poseban stack Kada primijenimo neku transformaciju, ona modificira samo matricu koja je na vrhu odgovarajueg stacka glLoadMatrix, glMultMatrix i glIdentity imaju uticaj samo na vrh stacka Postoje dvije naredbe za manipulaciju stackom
glPopMatrix() pomjera sve matrice na stacku jedan nivo nanie; matrica na vrhu stacka se duplira glPushMatrix() "skida" matricu s vrha stacka i unitava je; ukoliko je stack imao samo jednu matricu greka Obje naredbe rade s trenutnim stackom
105
Transformacije stackovi
Dubina stacka se moe saznati pomou
glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); glGetIntegerv(GL_PROJECTION_STACK_DEPTH, &depth);