Documente Academic
Documente Profesional
Documente Cultură
Lucrarea Nr. 1
BIBLIOTECI GRAFICE
Pentru programarea aplicaiilor grafice complexe se pot utiliza mai multe biblioteci i interfee
grafice, precum i sisteme de dezvoltare de programe (toolkit-uri), care permit proiectantului s
reutilizeze un numr mare de funcii grafice deja implementate i s-i concentreze eforturile asupra
aplicaiei nsi. Dat fiind c majoritatea acestor biblioteci sunt foarte iefine sau disponibile gratis pe
Internet i pot fi folosite ntr-un numr mare de platforme hardware i software, cunoaterea i
utilizarea lor este deosebit de important i util.
Dintre bibliotecile grafice existente, biblioteca OpenGL, scris n limbajul C, este una dintre
cele mai utilizate, datorit faptului c implementeaz un mare numr de funcii grafice de baz pentru
crearea apliciilor grafice tridimensionale, asigurnd o interfa independent de platforma hardware.
n redarea obiectelor tridimensionale, biblioteca OpenGL folosete un numr redus de
primitive geometrice (puncte, linii, poligoane), iar modele complexe ale obiectelor i scenelor
tridimensionale se pot dezvolta particularizat pentru fiecare aplicaie, pe baza acestor primitive. Dat
fiind c OpenGL prevede un set puternic, dar de nivel sczut, de comenzi de redare a obiectelor, mai
sunt folosite i alte biblioteci de nivel mai nalt care utilizeaz aceste comenzi i preiau o parte din
sarcinile de programare grafic. Astfel de biblioteci sunt:
Biblioteca de funcii utilitare GLU (OpenGL Utility Library) permite definirea sistemelor
de vizualizare, redarea suprafeelor curbe i alte funcii grafice.
Pentru fiecare sistem Windows exist o extensie a bibliotecii OpenGL care asigur
interfaa cu sistemul respectiv: pentru Microsoft Windows, extensia WGL, pentru sisteme
care folosesc X Window, extensia GLX, pentru sisteme IMB OS/2, extensia PGL.
Biblioteca de dezvoltare GLUT (OpenGL Utility Toolkit) este un sistem de dezvoltare
independent de platform, care ascunde dificultile interfeelor de aplicaii Windows,
punnd la dispoziie funcii pentru crearea i iniializarea ferestrelor i pentru execuia
programelor grafice bazate pe biblioteca OpenGL.
Toate funciile bibliotecii OpenGL ncep cu prefixul gl, funciile GLU ncep cu prefixul glu,
iar funciile GLUT ncep cu prefixul glut.
nainte de a prezenta caracteristicile bibliotecii OpenGL, se vor preciza conveniile de
reprezentare a coordonatelor punctelor n spaiul tridimensional i al culorilor.
Sisteme de referin tridimensionale. Pentru crearea i redarea scenelor tridimensionale este
necesar ca obiectele s fie poziionate ntr-un sistem de referin tridimensional. Exist mai multe
posibiliti de a specifica poziia unei mulimi de puncte (vrfuri) prin care este reprezentat un obiect
n spaiul tridimensional: coordonate cilindrice, coordonate sferice, coordonate carteziene. Dintre
aceste sisteme de referin, cel mai utilizat n aplicaiile grafice este sistemul de coordonate cartezian.
Sistemul de coordonate cartezian n care sunt definite toate obiectele scenei virtuale se
numete sistem de referin universal (world coordinate system- WCS).
Un sistem de coordonate cartezian se definete prin originea O i trei axe perpendiculare, Ox,
Oy i Oz, orientate dup regula minii drepte sau dup regula minii stngi. ntr-un sistem orientat
dup regula minii drepte, dac se rotete mna dreapt n jurul axei z de la axa x pozitiv spre axa y
pozitiv, orientarea degetului mare este n direcia z pozitiv. ntr-un sistem orientat dup regula minii
stngi, rotirea de la axa x pozitiv spre axa y pozitiv, cu orientarea degetului mare n direcia z
pozitiv, se obine folosind mna stng. Diferite sisteme de grafic tridimensional folosesc convenii
diferite pentru definirea sistemelor de referin, ceea ce conduce la confuzii, dac nu se precizeaz
convenia folosit. n acest text, pentru sistemul de referin universal se folosete convenia de sistem
de coordonate drept. n grafica tridimensional se mai folosesc i alte sisteme de referin, care permit
descrierea operaiilor de transformri geometrice i care vor fi precizate pe parcurs.
1.1
Biblioteca OpenGL definete propriile tipuri de date, cele mai multe corespunznd tipurilor de
date fundamentale ale limbajului C. De exemplu, n gl.h sunt definite urmtoarele tipuri:
typedef
typedef
typedef
typedef
typedef
typedef
typedef
typedef
typedef
De asemenea, n fiierul header ale bibliotecii OpenGL (gl.h) sunt definite mai multe
constante simbolice, care reprezint diferite stri, variabile sau valori de selecie a opiunilor OpenGL.
Aceste constante sunt toate scrise cu majuscule i sunt precedate de prefixul GL_. De exemplu,
constantele simbolice care definesc valorile TRUE i FALSE i cele care selecteaz tipul unei primitive
grafice sunt:
/* Boolean */
#define GL_TRUE
#define GL_FALSE
1
0
/* BeginMode */
#define GL_POINTS
#define GL_LINES
#define GL_TRIANGLES
#define GL_POLYGON
0x0000
0x0001
0x0004
0x0009
memorat n locaia corespunztoare unui pixel este distana acestuia fa de punctul de observare
(adncimea pixelului). La generarea unui nou pixel cu aceeai adres, se compar adncimea noului
pixel cu adncimea memorat n bufferul de adncime, i noul pixel nlocuiete vechiul pixel (l
ascunde) dac este mai apropiat de punctul de observare. Bufferul de adncime se mai numete i
Z-buffer, de la coordonata z, care reprezint adncimea n sistemul de referin ecran 3D.
Operaiile de baz. OpenGL deseneaz primitive geometrice (puncte, linii i poligoane) n
diferite moduri selectabile. O primitiv este definit printr-unul sau mai multe vrfuri (vertices). Un
vrf definete un punct, captul unei linii sau vrful unui poligon. Fiecare vrf are asociat un set de
date: coordonate, culoare, normal, coordonate de textur.
Aceste date sunt prelucrate n ordine i n acelai mod pentru toate primitivele geometrice.
Modul n care este executat secvena de operaii pentru redarea primitivelor geometrice depinde de
starea bibliotecii OpenGL, stare care este definit prin mai multe variabile de stare ale acesteia
(parametri). Numrul de variabile de stare ale bibliotecii este destul de mare, descrierea lor poate fi
gsit n manualul de referin (OpenGL Reference Manual), iar pe parcursul expunerii vor fi
prezentate numai cele mai importante dintre acestea.
La iniializare, fiecare variabil de stare este setat la o valoare implicit. O stare o dat setat
i menine valoarea neschimbat pn la o nou setare. Variabilele de stare au denumiri date sub
form de constante simbolice care pot fi folosite pentru aflarea valorilor acestora. Cteva exemple de
stri definite prin constante simbolice n fiierul gl.h sunt:
#define
#define
#define
#define
GL_CURRENT_COLOR
GL_CURRENT_NORMAL
GL_MODELVIEW_MATRIX
GL_PROJECTION_MATRIX
0x0B00
0x0B02
0x0BA6
0x0BA7
Variabilele de stare OpenGL sunt de dou categorii: variabile de tip binar i variabile definite
prin diferite structuri de date.
Variabile de tip binar pot avea una din dou stri: starea activ (enabled) sau starea inactiv
(disabled). Setarea la starea activ se realizeaz prin apelul funciei
void glEnable(GLenum param);
la o valoare dat prin trei componente: rou (red), verde (green), albastru (blue).
Fiind o bibliotec dezvoltat n limbajul C, fr posibilitatea de suprancrcare a funciilor,
selecia unei funcii apelate cu diferite tipuri de argumente de apel este realizat prin modificarea
(printr-un sufix) a numelui funciei. De exemplu, funcia de setare a culorii curente are mai multe
variante, dup tipul i numrul argumentelor: glColor3f(), glColor4d(), etc. n continuare,
n aceast lucrare se noteaz generic cu # sufixul dintr-o familie de funcii (de exemplu,
glColor#()).
Primitive geometrice. Funciile OpenGL execut secvena de operaii grafice asupra fiecrei
primitive geometrice, definit prin tipul acesteia i o list de vrfuri. Coordonatele unui vrf al unei
primitive sunt transmise ctre OpenGL prin apelul unei funcii glVertex#(). Aceasta are mai
multe variante, dup numrul i tipul argumentelor. Iat, de exemplu, numai cteva din prototipurile
funciilor glVertex#():
void
void
void
void
Vrfurile pot fi specificate n plan, n spaiu sau n coordonate omogene, folosind apelul
funciei corespunztoare.
O primitiv geometric se definete printr-o list de vrfuri (care dau descrierea geometric a
primitivei) i printr-unul din tipurile prestabilite, care indic topologia, adic modul n care sunt
conectate vrfurile ntre ele. Fiecare vrf este specificat prin intermediul unei funcii glVertex, iar
lista de vrfuri este delimitat ntre funciile glBegin(GLenum mode) i glEnd(). Aceeai list
de vrfuri (v0, v1, v2,.vn1) poate fi tratat ca puncte izolate, linii, poligon, etc, n funcie de tipul
primitivei, care este transmis prin argumentul mode al funciei glBegin() (GL_POINTS,
GL_LINES, GL_POLYGON, etc).
De exemplu, desenarea unei primitive geometrice (un patrulater) n spaiul tridimensional se
realizeaz n OpenGL prin secvena de apeluri de funcii:
glBegin(GL_POLYGON);
glVertex3d(-1.0, 1.0,
glVertex3d( 1.0, 1.0,
glVertex3d( 1.0,-1.0,
glVertex3d(-1.0,-1.0,
glEnd();
0.0);
0.0);
0.0);
0.0);
intrare (index) componentele corespunztoare R,G,B,A ale culorii. n modul de culori indexate nu se
pot efectua unele dintre prelucrrile grafice importante (cum sunt umbrirea, anti-aliasing, ceaa).
Modelul de culori indexate este folosit n principal n aplicaii de proiectare grafic (CAD), n care
este necesar un numr mic de culori i nu se folosesc umbrirea, ceaa, etc. n aplicaiile de realitate
virtual nu se poate folosi modelul de culori indexate i de aceea n continuare nu vor mai fi prezentate
comenzile sau opiunile care se refer la acest model i toate descrierile consider numai modelul
RGBA.
Culoarea care se atribuie unui pixel dintr-o primitiv geometric depinde de mai multe
condiii, putnd fi o culoare constant a primitivei, o culoare calculat prin interpolare ntre culorile
vrfurilor primitivei, sau o culoare calculat n funcie de iluminare, anti-aliasing i texturare.
Presupunnd pentru moment culoarea constant a unei primitive, aceasta se obine prin setarea unei
variabile de stare a bibliotecii, variabila de culoare curent (GL_CURRENT_COLOR). Culoarea curent
se seteaz folosind una din funciile glColor#(), care are mai multe variante, n funcie de tipul i
numrul argumentelor. De exemplu, dou din prototipurile acestei funcii definite n fiierul gl.h sunt:
void glColor3f(GLfloat r, GLfloat g, GLfloat b);
void glColor4d(GLdouble r, GLdouble g, GLdouble b, GLdouble a);
Culoarea se poate specifica prin trei sau patru valori, care corespund componentelor rou (r),
verde (g), albastru (b), respectiv transparen (a) ca a patra component pentru funciile cu 4
argumente.
1.2
funcie fr argumente care nu returneaz nici o valoare. Funcia Display (a aplicaiei) este apelat
oridecte ori este necesar desenarea ferestrei: la iniializare, la modificarea dimensiunilor ferestrei,
sau la apelul explicit al funciei gluPostRedisplay().
Funcia void
glutReshapeFunc(void(*Reshape)(int
w,
int
h))
nregistreaz funcia callback Reshape() care este apelat oridecte ori se modific dimensiunea
ferestrei de afiare. Argumentul este un pointer la funcia cu numele Reshape cu dou argumente de
tip ntreg i care nu returneaz nici o valoare. n aceast funcie, programul de aplicaie trebuie s
refac transformarea fereastr-poart, dat fiind c fereastra de afiare i-a modificat dimensiunile.
Funcia glutKeyboardFunc(void(*Keyboard)(unsigned int key, int x,
int y) nregistreaz funcia callback Keyboard() care este apelat atunci cnd se acioneaz o
tast. Parametrul key este codul tastei, iar x i y sunt coordonatele (relativ la fereastra de afiare) a
mouse-ului n momentul acionrii tastei.
Funcia glutMouseFunc(void(*Mouse)(unsigned int button, int
state, int x, int y) nregistreaz funcia callback Mousecare este apelat atunci cnd este
apsat sau eliberat un buton al mouse-ului. Parametrul button este codul butonului (poate avea una
din constantele GLUT_LEFT_BUTTON,
GLUT_MIDDLE_BUTTON
sau
GLUT_RIGHT
_BUTTON). Parametrul state indic apsarea (GLUT_DOWN) sau eliberarea (GLUT_UP) al unui
buton al mouse-ului. Parametrii x i y sunt coordonatele relativ la fereastra de afiare a mouse-ului n
momentul evenimentului. Funcia glutMotionFunc(void(*Motion)(int x, int y)
nregistreaz funcia callback Motion care este apelat la micarea mouse-ului.
Execuia unui program folosind toolkit-ul GLUT se lanseaz prin apelul funciei
glutMainLoop(), dup ce au fost efectuate toate iniializrile i nregistrrile funciilor callback.
Aceast bucl de execuie poate fi oprit prin nchiderea ferestrei aplicaiei.
Generarea obiectelor tridimensionale. Multe programe folosesc modele simple de obiecte
tridimensionale pentru a ilustra diferite aspecte ale prelucrrilor grafice. GLUT conine cteva funcii
care redau astfel de obiecte tridimensionale n modul wireframe sau cu suprafee pline (filled). Fiecare
obiect este reprezentat ntr-un sistem de referin local, dimensiunea lui poate fi transmis ca argument
al funciei, iar poziionarea i orientarea n scen se face n programul de aplicaie. Exemple de astfel
de funcii:
void glutWireCube(GLdouble size);
void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
Programele GLUT au un mod specific de organizare, care provine din felul n care sunt
definite i apelate funcii callback. Acest mod va fi prezentat la primul exemplu de program OpenGLGLUT i va fi reluat apoi i n alte exemple.
Exemplu:
Pentru crearea unui program grafic bazat pe biblioteca GLUT n sistemele Windows se
poate folosi mediul Microsoft Visual Studio. Se creeaz un proiect de tipul Win32 Console
Application i se selecteaz opiunea "An empty project".
Programul dorit se scrie ntr-unul sau mai multe fiiere care se insereaz n proiectul creat. De
exemplu, programul GLUT care deseneaz un ptrat rou n spaiul tridimensional, va conine fiierul
surs:
// Program HelloGlut.cpp
#include <GL/glut.h>
// Pozitionare obiecte scena
float Xs = 0.0f, Ys = 0.0f, Zs = 0.0f;
float angleXs = 0.0f, angleYs = 0.0f, angleZs = 0.0f;
// Pozitionare observator
float Xv = 0.0f, Yv = 0.0f, Zv = 5.0f;
float angleXv = 0.0f, angleYv = 0.0f, angleZv = 0.0f;
// Mouse
bool pressed = false;
int mouse_x;
int mouse_y;
// Functia de initializare a starii OpenGL
void Init(){
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // culoare stergere
glClearDepth(1.0f);
//adancimea maxima Z buffer
glEnable(GL_DEPTH_TEST);
// validare Z buffer
}
void DrawRectangle(){
glBegin(GL_POLYGON);
glVertex3d(-1.0, 1.0, 0.0);
glVertex3d( 1.0, 1.0, 0.0);
glVertex3d( 1.0,-1.0, 0.0);
glVertex3d(-1.0,-1.0, 0.0);
glEnd();
}
// Functia callback de desenare
void Display(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
// Transformarea de observare
glRotatef(-angleZv, 0.0,0.0,1.0);
glRotatef(-angleXv, 1.0,0.0,0.0);
glRotatef(-angleYv, 0.0,1.0,0.0);
glTranslatef(-Xv, -Yv, -Zv);
// se initializeaza Zv = 5;
// Transformare de modelare (pozitionare) obiecte din scena
glTranslatef(Xs,Ys,Zs);
glRotatef(angleYs, 0.0,1.0,0.0);
glRotatef(angleXs, 1.0,0.0,0.0);
glRotatef(angleZs, 0.0,0.0,1.0);
glColor3d(1.0, 0.0, 0.0);
// culoare curenta
DrawRectangle();
glPopMatrix();
glFinish();
glutSwapBuffers();
// comutare buffer
}
// Functia CALLBACK de redimensionare a ferestrei
void Reshape(int w, int h){
h = (h == 0) ? 1 : h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); //selectie stiva PROJECTION
glLoadIdentity();
gluPerspective(45.0f, (GLdouble)w/h, 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW); // selectie stiva MODELVIEW
glLoadIdentity();
}
Observatii
Pentru compilarea i execuia corect a programului, trebuie adugate bibliotecile
OpenGL, GLU i GLUT. Pentru aceasta se folosete comanda Project-Properties si se adaug
bibliotecile opengl32.lib, glu32.lib, glut32.lib, glaux.lib (dupa cum reiese din figura de mai jos).
10
sunt:
Fisierul cod sursa C++ se creaza si se adauga in proiect dupa cum urmeaza:
11
n acest program se pot remarca funciile strict necesare dezvoltrii unui program folosind
biblioteca GLUT . Funcia de iniializare Init()seteaz culoarea de tergere (prin apelul funciei
glClearColor), seteaz valoarea de tergere a buferului de adncime i valideaz testul de
adncime (GL_DEPTH_TEST).
n funcia main() se fac iniializrile bibliotecilor GLUT i OpenGL, se nregistreaz
funciile callback i se apeleaz funcia de execuie n bucl (glutMainLoop()).
Funcia callback de desenare (denumit Display()) este echivalent funciei
DrawScene() din proiectul precedent; n exemplul prezentat ea conine doar partea de desenare a
unui ptrat.
Funcia callback de redimensionare (denumit Reshape()) este echivalent funciei
OnSize() din proiectul precedent. Ea este invocat de aplicaia cadru GLUT atunci cnd se schimb
dimensiunile ferestrei de afiare a imaginii i definete transformarea ferestr-poart
(glViewport()) i transformarea de proiecie perspectiv (gluPerspective(), cu aceeai
parametri ca n proiectul precedent.
Funcia callback de tratare a evenimentelor de tastatura (Keyboard()) permite modificarea
poziiei obiectelor n scen (coordonata Zs) la acionarea tastelor z, Z. Funciile callback de tratare a
evenimentelor de mouse (Mouse() i Motion()) permit rotirea obiectului dup axele x i y.
La execuia programului se afia un ptrat a crui poziie n spaiul tridimensional poate fi
modificat folosind mouse-ul i tastatura.
12
Execiii
1.1.
Studiul culorilor n OpenGL. Modificai culoarea de tergere (prin modificarea
argumentelor funciei glClearColor()) intr-o culoare neutra (gri) i culoarea ptratului desenat
(prin modificarea argumentelor funciei glColor3f()).
1.2.
Modurile de desenare a suprafeelor. Selectarea modului de desenare "plin" se specific
prin funcia glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) care se poate introduce n
funcia de iniializare. Aceasta este setarea implicit a bibliotecii OpenGL. Dac se modific
argumentul GL_FILL n GL_LINE, suprafeele sunt desenate sub forma "cadru de srm"
(wireframe), iar la valoarea GL_POINT se deseneaz numai vrfurile suprafeelor.
De exemplu, la utilizarea GL_LINE
urmatoarea fereastra:
se
va
obtine
la
executia
programului
1.3.
Interpolarea culorilor la desenarea primitivelor geometrice. Pentru interpolarea culorilor
se specific cte o culoare diferit pentru fiecare vrf al primitivei. Pentru obiectul CUBE desenat,
exist deja acest mod de specificare. Pentru obiectul RECTANGLE, modificai funcia
DrawRectangle() astfel:
void DrawRectangle(){
glBegin(GL_POLYGON);
glColor3d(1.0, 0.0, 0.0);
glVertex3d(-1.0, 1.0, 0.0);
glColor3d(0.0, 1.0, 0.0);
glVertex3d( 1.0, 1.0, 0.0);
glColor3d(0.0, 0.0, 1.0);
glVertex3d( 1.0,-1.0, 0.0);
glColor3d(1.0, 1.0, 1.0);
glVertex3d(-1.0,-1.0, 0.0);
glEnd();
}
// rosu
// verde
// albastru
// alb
13
functia
glutSolidTeapot(1.0);
14
la
executia