I. Ordinea operatiilor
II. Organizarea programului pentru utilizarea OpenGL
Un program obisnuit în mediul OpenGL începe cu deschiderea unei ferestre grafice, care se adreseaza memoriei grafice a calculatorului si descrie un cadru de imagine pe monitor.
Urmeaza apoi instructiuni pentru alocarea contextului GL care este asociat unei ferestre grafice. Din acest punct, programatorul poate elabora programul propriu-zis, asociat ferestrei respective, proprii mediului OpenGL. Cele mai simple comenzi sunt asociate trasarii unor obiecte geometrice simple, puncte, linii, poligoane, în timp ce altele permit în plus redarea (engl. rendering) acestor primitive împreuna cu aspectul creat de variatiile de culoare si luminozitate determinate de pozitia si caracteristicile sursei de lumina precum si de poxitia observatorului.
Mai exista si apeluri adreste exclusiv memoriei grafice aferente unui cadru de imagine pe monitor, cum ar fi citirea si scrierea unui pixel.
III. Bucla de evenimente (Event Loop)
Programele OpenGL lucreaza într-o bucla de evenimente, de obicei infinita, adica se asteapta o actiune exterioara cum ar fi apasarea unei taste, actiunile mouse-lui, etc.
Redimensionarea scenei are loc la fiecare redimensionare a ferestrei. Afisarea ferestrei are loc la prima desenare sau atunci când fereastra este adusa în planul apropiat.
Comenzile OpenGL folosesc prefixul gl , cuvintele din comanda sunt separate prin semnul _ iar prima litera din cuvânt este o majuscula, de exemplu glBegin(). Similar, constantele sunt definte dupa aceleasi reguli, de exemplu GL_COLOR_BUFFER_BIT. Câteva comenzi OpenGL mai au la sfârsit un numar sau 1-3 litere care semnifica numarul si tipul parametrilor comenzii. Primul caracter indica numarul valorilor tipului indicat care trebuie cotinut în comanda. Al doilea caracter sau pereche de caractere indica tipul argumentelor (întregi sau reale). Ultimul caracter, daca este v indica ca comanda poate sa se refere la un vector în loc de un scalar. De exemplu, în comanda glVertex3fv(), 3 este folosit pentru a indica trei argumente, f este folosit pentru a indica tipul de date real iar v indica tipul vectorial.
Standardizarea acestora este urmatoarea:
Pentru prezentarea generala a comenzilor, aceste specificatii pot fi ignorate iar comanda este scrisa folosind sufixul * în locul lor, cum ar fi glColor*().
V. Primitive în limbajul OpenGL
Programatorului I se ofera urmatoarele primitive (si cuvintele cheie asociate) pentru construirea obiectelor:
Fiecare obiect geometric este descris printr-un set de vârfuri (vertex-uri) si tipurile de primitive care urmeaza sa fie trasate. Tipul primitivei alese determina daca vârfurile sunt conectate sau nu. Observati ca în limbajul POV, sunt definite în plus câteva obiecte uzuale, cum ar fi cilindru,sfera, etc.
Deci, în OpenGL, toate obiectele sunt decrise ca un set de vertexuri ordonate în spatiu Comanda glVertex*() este folosita pentru a defini un vertex. Exemple de folosire:
glVertex2s(1, 2); glVertex3d(0.0, 0.0, 3.1415926535898); glVertex4f(1.3, 2.0, -4.2, 1.0); GLdouble vector[3] = {3.0, 10.0 2033.0}; glVertex3dv(vector);
Toate aceste structuri trebuie incluse între începutul (glBegin()) Si sfârsitul (glEnd()) structurii de reprezentare. Desenarea se face atunci cand este întâlnita instructiunea glBegin(), cu exceptia cazurilor acoperite de lista de afisaj (DisplayList: glEnd()) care vor fi discutate mai jos.
Este important de observat aspectul comenzilor OpenGL care nu sunt executate imediat ce sunt întâlnite. Este necesaracomanda glFlush() pentru a ne asigura de aceasta la sfârsitul secventei de desenare
VI. Schimbarea starii
Atunci când sunt trasate primitivele, fiecare este afectata de variabilele de "stare", cum ar fi: grosimea liniei, culoarea, metoda de hasurare. Unele variabile de stare se refera la aspectul scenei. Acestea pot avea valori implicite (default values) si valori logice (fals: GL_FALSE sau adevarat: GL_TRUE). Alte variabile de stare se refera la o lista definita de Glenum. Unele valori pot fi de tip întreg sau real (GLfloat, GLint, etc.).
Fiecare variabila de stare are o valoare implicita (default value), care poate fi modificata prin program.
Variabilele de stare în OpenGL pot fi activate sau dezactivate cu comenzile glEnable(GLenum capability) si respectiv glDisable(GLenum capability) unde constantele simbolice indica o posibilitate a limbajului.
Valoarea curenta a unei variabile de stare poate fi verificata prin folosirea comenzii glIsEnabled(GLenum capability) care ia valorile GL_TRUE sau GL_FALSE.
Câteva posibilitati ale mediului sunt:
GL_POINT_SMOOTHDaca este activata, functia confera unui punct un aspect neted,altfel marginile acestuia vor fi bine definite (engl. aliased) GL_LINE_SMOOTHSimilar pentru o linie GL_LINE_STIPPLEDaca este activata, functia foloseste aspectul predefinit pentru o linie.
Modurile variabilelor de stare implica comenzi specifice, un exemplu fiind nuanta, data de GL_SHADE_MODEL.
O linie sau un poligon pot fi trasate sau hasurate cu o singura culoare sau cu o paleta de culori, asemanatoare curcubeului (engl. smooth shading, sau Gouraud Shading). Hasurarea dorita se poate efectua cu comanda glShadeModel(GLenum mode) unde mode poate fi GL_SMOOTH pentru hasurare cu paleta sau GL_FLAT pentru hasurare cu o singura culoare.
Valorile variabilelor de stare pot fi aflate si schimbate prin program. Tipic pot fi folosite comenzile urmatoare, în functie de scopul urmarit: glGetBooleanv(), glGetDoublev(), glGetFloatv(), sau glGetIntegerv().
Maniera cea mai obisnuita de schimbare a culorii este folosirea definitiei RGB glColor3f(GLfloat red, GLfloat green, GLfloat blue) unde red, green, si blue sunt valori reale cuprinse între 0 si 1. Valoarea 0.0 corespunde unei contributii minime a culorii de baza folosite iar 1.0 unei contributii maxime.
Negru glColor3f(1.0, 0.0, 0.0) |
Rosu glColor3f(0.0, 1.0, 0.0) |
Verde glColor3f(0.0, 0.0, 1.0) |
Albastru glColor3f(1.0, 1.0, 0.0) |
Galben glColor3f(0.0, 1.0, 1.0) |
Cian glColor3f(1.0, 0.0, 1.0) |
Magenta glColor3f(1.0, 1.0, 1.0) |
Alb glColor3f(0.0, 0.0, 0.0) |
Fisierul tampon trebuie golit de fiecare data când construim o scena, folosind comanda
glClear(GL_COLOR_BUFFER_BIT).Dimensiunea unui punct redat este data de comanda glPointSize(GLfloat size) unde size este dimensiunea în pixeli. Numarul trebuie sa fie mai mare decât 0, iar valoarea implicita este 1.0.
Pentru controlul grosimii unei linii folosim comanda glLineWidth(GLfloat width) unde width este latimea dorita exprimata în pixeli. Latimea trebuie sa fie mai mare eecât 0.0 iar valoarea implicita este 1.0.
Pentru construirea unei linii întrerupte, aspectul este declarat folosind comanda glLineStipple(GLint factor, GLushort pattern) unde pattern este o serie de 16 valori binare, 0 si 1, repetate pentru a codifica aspectul liniei. Valoarea 1 indica penita jos iar valoarea 0 indica penita sus. Aceasta secventa poate fi apoi alterata folosind un factor, care multiplica aceasta serie. Acest factor ia valori cuprinse între 0 si 255.. Variabila de stare GL_LINE_STIPPLE trebuie activata prin apelarea instructiunii glEnable(GL_LINE_STIPPLE).
VII. Construirea scenelor
Intr-o scena 3 dimensionala, obiectele din planul apropiat le pot acoperi pe cele din planul departat. De aceea, pentru o redare realista, trebuie îndepartate din desen suprafetele ascunse. Operatia este efectuata de doua fisiere(sau zi°one de memorie) tampon, pentru adâncime si respectiv pentru testarea adâncimii. La desenare, se asociaza fiecarui pixel o valoare pentru adîncime care este stocata în fisierul tampon de adîncime. Pentru fiecare vertex din scena este efectuat un test de adâncime, pentru a stabili daca nu cumva un vertex deja desenat acopera vertexul curent.
Fisierele tampon de adâncime trebuie activate folosind comanda glEnable(GL_DEPTH_TEST) iar înainte de reprezentarea scenei tamponul de adâncime trebuie golit cu comanda glClear(GL_DEPTH_BUFFER_BIT). Mediul OpenGL traseaza implicit poligoane în care toti pixelii din interior au o anumita culoare, însa poligoanele pot fi trasate si prin folosirea liniilor sau folosind puncte pentru reprezentarea vârfurilor. In OpenGL, un poligon are doua fete care pot avea culori diferite, dupa dorinta, pentru a permite vizualizarea sectiunilor.
Comanda glPolygonMode(GLenum face, GLenum mode) controleaza modul de trasare a fetelor poligonului. Parametrul face poate fi GL_FRONT (fata), GL_BACK(dos), sau GL_FRONT_AND_BACK (ambele); mode poate fi GL_POINT, GL_LINE, sau GL_FILL pentru a indica daca poligonul este reprezentat în puncte, linii sau ca o suprafata colorata. Valoarea implicita este ca mbele fete sunt colorate.
Un poligon colorat poate avea o anumita hasura, data de comanda glPolygonStipple(const GLubyte *mask) unde argumentul mask este un pointer catre o matrice imagine (bitmap) cu dimensiunea 32x32 care este interpretata ca o masca cu valorile 0 si 1. Variabila de stare GL_POLYGON_STIPPLE trebuie activata cu comanda glEnable(GL_POLYGON_STIPPLE).
Comanda glCullFace(GLenum mode) indica poligoanele ce trebuie ignorate din reprezentare, înaintea tribuirii unor coordonate planare pentru trasarea pe ecran. Parametrul mode poate fi parametrizat cu GL_FRONT, GL_BACK, sau GL_FRONT_AND_BACK pentru a indica fata, dosul sau amândoua pentru poligonul în discutie.
VIII. Vizualizarea si modelarea transformarilor
Vizualizarea transformarilor este analoaga cu pozitionarea si orientarea camerei de luat vederi. Modelarea transformarilor este anloaga cu pozitionarea si orientarea obiectelor sa modelului în scena. In OpenGl, vizualizarea trebuie sa preceada modelarea.
Transformarile sunt efectuate prin folosirea matricilor. La orice moment pot fi modificate urmatoarele matrici:
Variabila de stare GL_MATRIX_MODE specifica matricile modificabile. Valoarea implicita este matricea modelului.
Comanda glMatrixMode(GLenum mode) este folosita pentru a schimbavaloarea variabilei de stare GL_MATRIX_MODE.. Valorile posibile ale argumentului de modelare sunt GL_MODELVIEW, GL_PROJECTION, si GL_TEXTURE. La apelarea functiei glMatrixMode() sunt afectate toate comenzile ulterioare pentru transformarea matricii respective. Comanda glLoadIdentity() este folosita pentru a transforma matricea modificabila într-o matrice unitate. Comanda glTranslate(TYPE x, TYPE y, TYPE z) multiplica matricea modificabila curenta cu o matrice care misca obiectul cu valori specificate x, y si z (adica modifica coordonatele locale curente cu valorile x, y si z).
Comanda glRotate(TYPE angle, TYPE x, TYPE y, TYPE z) multiplica matricea modificabila (sistemul de referinta al obiectului) cu o matrice de rotatie în sensul invers acelor de ceasornic în jurul axei care trece prin origine si coordonatele curente x,y,z. Parametrul angle specifica unghiul de rotatie în grade.
Comanda glScale(TYPE x, TYPE y, TYPE z) multiplica matricea modificabila cu o matrice de deformare, care permite micsorarea, marirea sau oglindirea obiectului de-a lungul axelor. Fiecare coordonata x, y, si z a fiecarui punct din obiect este multiplicata cu o valoare corespunzatoare din matricea de transformare.
IX. Transformari asupra planului de vizualizare
Aceste transformari sunt analoage alegerii dimensiunii imaginii. OpenGL ia ca valori implicite dreptunghiul determinat de fereastra programului. Comanda glViewport(GLint x, GLint y, GLsizei width, GLsizei height) este folosita pentru schimbarea dimensiunii dreptunghiului folosit pentru trasare. Parametrii x si y specificacoltul stanga sus al dreptunghiului, iar width si height sunt latimea si respectiv înaltimea acestuia.. Aceasta comanda este folosita în special pentru modificarea scenei în cazul modificarii dimensiunii ferestrei de catre utilizator.
X. Perspectiva
In proiectia de perspectiva, volumul de vizualizare are forma unui trunchi de con (engl. frustum), adica, cu cât un obiect este mai departat de camera de luat vederi, cu atât este mai mic în imagine. Aceasta functie este realizata cu comanda glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far). Argumentele left si right specifica the coordonatele pentru planele de delimitare a perspectivei din stânga si dreapta. Argumentele bottom si top specifica coordonatele planelor de limitare podea si tavan. Argumentele near si far specifica distantele pâna la planele cel mai apropiat si respectiv cel mai îndepartat. Ambele distante trebuie sa fie pozitive.
In proiectia ortografica, volumul de vizualizat are forma unei cutii. Spre deosebire de proiectia ortografica, volumul de vizualizat nu se schimba de la un colt la altul si prin urmare distanta camera-obiect nu schimba dimensiunile aparente ale obiectului în imagine.
Comanda este glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far). Argumentele left si right specifica coordonatele stânga si dreapta ale paralelipipedului de proiectie, iar bottom si top pentru planele podea si respectiv tavan. Argumentele near si far specifica pozitiile planelor apropiat si respectiv îndepartat ale paralelipipedului. Distantele negative sunt situate în spatele observatorului (camerei de luat vederi).
XII. Liste de afisaj (engl. Display Lists)
O lista de afisaj este un grup de comenzi OpenGL care sunt pregatite pentru executie ulterioara. Atunci când invocam lista de afisaj, comenzile prestabilite vor fi executate în ordinea prescrisa
O utilizare comuna este crearea unei liste de afisaj pentru un obiect care urmeaza sa fie desenat de mai multe ori. Daca trebuie calculate doar vertexurile acestuia, timpul de calcul este multa mai mic decât pentru întreaga scena.
Comenzile glNewList(GLuint name, GLenum mode) si glEndList() sunt folosite pentru crearea începutului si respectiv sfârsitului unei astfel de liste. Argumentul mode specifica modul de compilare, care poate fi:
Dupa ce lista a fost creata, ea poate fi executata cu comanda: glCallList(GLuint name).
XIII. Animatia
Animatia în grafica pe calculator este obtinuta prin utilizarea celor doua fisire tampon mentionate mai sus. Prin aceasta avem la dispozitie doua cadre color complete, pregatite pentru afisaj. Intimp ce un cadru este afisat, celalalt este desenat. La sfârsit, cele doua cadre sunt interschimbate si începe reprezentarea noului cadru (3) peste cadrul (1) samd.
OpenGL nu ofera nici o comanda standard pentru interschimbarea fisierelor tampon, aceasta sarcina revenindu-i sistemului de operare. Comanda care specifica modificarea este glFlush().
XIV. Iluminarea scenei
In OpenGL exista doua feluri de surse de lumina: directionala si pozitionala. O sursa directionala este situata la o distanta infinita fata de scena (creaza un fascicul paralel) în timp ce sursa pozitionala este situata aproape sau chiar înauntrul scenei. Sub aspectul eficientei calculului, o sursa pozitionala este mai eficienta decât cea directionala, datorita mai ales numarului mai mic de obiecte întâlnite. Comanda glLightfv() poate fi folosita pentru specificarea pozitiei sursei de lumina si daca ea este directionala sau pozitionala. Se mai pot specificavalorile componentelor de culoare ale sursei, cum ar fi: "ambient color", "diffuse color", "specular color", "emissive color", "shininess". Dupa ce sursele de lumina au fost definite, mai trebuie specificati vectorii normali si proprietatile obiectelor scenei. Vectorii normali ai unui obiect definesc orientarea sa relativ la sursa de lumina. Vectorii normali pot fi specificati pentru fiecare vertex sau aranjament de vertexuri. Comanda folosita este: glNormal(). Componentele de culoare alese pentru sursele de lumina au semnificatii diferite fata de cele ale materialelor. Pentru sursele de lumina, numerele corespund unui procentaj fata de lumina alba. Prin urmare, cea mai stralucitoare sursa are valorile (1.0, 1.0, 1.0). Pentru materiale, numerele corespund reflectivitatii suprafetei vertexurilor. Pentru materiale se foloseste comanda glMaterialfv(), în care se introduc valorile caracteristice materialului.
Comanda glColorMaterial() are scopul scaderii timpului de calcul în cazul schimbarii proprietatilor materialului si trebuie utilizata de fiecare data când se modifica o caracteristica oarecare a materialului. Orice schimbare a culorii curente poate fi facuta prin apelarea functiei glColor() care actualizeaza imediat proprietatea de material specificata de glColorMaterial(). Variabila de stare GL_COLOR_MATERIAL trebuie activata cu comanda glEnable(GL_COLOR_MATERIAL). Activarea iluminarii se face cu comanda glEnable(GL_LIGHTING) si pentru fiecare sursa de lumina din scena se foloseste glEnable(GL_LIGHTi) unde GL_LIGHTi este numarul curent al sursei.