grafica pe calculator

42
Grafică pe calculator (14.05.2015) – Informatica, anul 1 GpC_C04 1 Utilizarea mouse-ului și tastaturii în programele BGI Exemplu: #include<graphics.h> #include<conio.h> using namespace std; int main() { int x,y; initwindow(640,480); setcolor(BLUE); setbkcolor(WHITE); cleardevice(); char s1[]="Apasati butonul stang al mouse-ului pentru a-i afla coordonatele mouse-ului."; outtextxy(10,5,s1); do{ if (ismouseclick(WM_LBUTTONDOWN) ) //daca s-a apasat butonul stang { getmouseclick(WM_LBUTTONDOWN, x, y); //se preiau coordonatele mouse-ului cand s-a apasat butonul stang char sx[10],sy[4]; strcpy(sx,"000 000"); //text oarecare pentru sters setcolor(WHITE); //culoarea fundalului outtextxy(10,20,sx); //sterg afisarea de dinainte setcolor(BLUE); strcpy(sx,""); itoa(x,sx,10); itoa(y,sy,10); strcat(sx," "); strcat(sx,sy); outtextxy(10,20,sx); //afisam coordonatele mouse-ului } } while(!kbhit()); getch(); closegraph(); } Syntax #include "winbgim.h" bool ismouseclick(int kind); Description: The ismouseclick function is available in the winbgim implementation of BGI graphics. This function returns true if there is an unprocessed mouse event of the specified kind. The argument to ismouseclick is one of these constants from the winbgim.h file: - WM_MOUSEMOVE if you want to detect a mouse movement - WM_LBUTTONDBLCLK ...detect when the left mouse button is double clicked - WM_LBUTTONDOWN ...detect when the left mouse button is clicked down - WM_LBUTTONUP ...detect when the left mouse button is released up - WM_MBUTTONDBLCLK ...detect when the middle mouse button is double clicked - WM_MBUTTONDOWN ...detect when the middle mouse button is clicked down - WM_MBUTTONUP ...detect when the middle mouse button is released up - WM_RBUTTONDBLCLK ...detect when the right mouse button is double clicked - WM_RBUTTONDOWN ...detect when the right mouse button is clicked down

description

grafica

Transcript of grafica pe calculator

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    1

    Utilizarea mouse-ului i tastaturii n programele BGI

    Exemplu: #include #include using namespace std;

    int main() { int x,y; initwindow(640,480); setcolor(BLUE); setbkcolor(WHITE); cleardevice(); char s1[]="Apasati butonul stang al mouse-ului pentru a-i afla coordonatele mouse-ului."; outtextxy(10,5,s1); do{ if (ismouseclick(WM_LBUTTONDOWN) ) //daca s-a apasat butonul stang { getmouseclick(WM_LBUTTONDOWN, x, y); //se preiau coordonatele mouse-ului cand s-a apasat butonul stang char sx[10],sy[4]; strcpy(sx,"000 000"); //text oarecare pentru sters setcolor(WHITE); //culoarea fundalului outtextxy(10,20,sx); //sterg afisarea de dinainte setcolor(BLUE); strcpy(sx,""); itoa(x,sx,10); itoa(y,sy,10); strcat(sx," "); strcat(sx,sy); outtextxy(10,20,sx); //afisam coordonatele mouse-ului } } while(!kbhit()); getch(); closegraph(); }

    Syntax #include "winbgim.h"

    bool ismouseclick(int kind);

    Description:

    The ismouseclick function is available in the winbgim implementation of BGI graphics. This

    function returns true if there is an unprocessed mouse event of the specified kind. The argument

    to ismouseclick is one of these constants from the winbgim.h file:

    - WM_MOUSEMOVE if you want to detect a mouse movement

    - WM_LBUTTONDBLCLK ...detect when the left mouse button is double clicked

    - WM_LBUTTONDOWN ...detect when the left mouse button is clicked down

    - WM_LBUTTONUP ...detect when the left mouse button is released up

    - WM_MBUTTONDBLCLK ...detect when the middle mouse button is double clicked

    - WM_MBUTTONDOWN ...detect when the middle mouse button is clicked down

    - WM_MBUTTONUP ...detect when the middle mouse button is released up

    - WM_RBUTTONDBLCLK ...detect when the right mouse button is double clicked

    - WM_RBUTTONDOWN ...detect when the right mouse button is clicked down

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    2

    - WM_RBUTTONUP ...detect when the right mouse button is released up The middle

    mouse button handlers aren't working on my machine. I haven't yet tracked down the

    reason--it could be a broken mouse or it could be a bug in my programming. A mouse

    event can be processed by calling getmouseclick (which gets the coordinates of the event),

    or by calling clearmouseclick (which processes the event without providing its coordinates).

    Pentru utilizarea tastaturii, folosim funcia getch:

    Syntax #include "winbgim.h"

    int getch(void);

    Description:

    The getch function is available in the winbgim implementation of BGI graphics. You do not need to

    include conio.h; just include winbgim.h. The function reads one character from the keyboard and

    returns its ASCII value (without waiting for a return key). In order to work, the user must click in

    the graphics window (i.e., the Windows focus must be in the graphics window). For special keys,

    the getch function first returns ASCII 0. The next call will then return one of these special keys:

    #define KEY_HOME 71

    #define KEY_UP 72

    #define KEY_PGUP 73

    #define KEY_LEFT 75

    #define KEY_CENTER 76

    #define KEY_RIGHT 77

    #define KEY_END 79

    #define KEY_DOWN 80

    #define KEY_PGDN 81

    #define KEY_INSERT 82

    #define KEY_DELETE 83

    #define KEY_F1 59

    #define KEY_F2 60

    #define KEY_F3 61

    #define KEY_F4 62

    #define KEY_F5 63

    #define KEY_F6 64

    #define KEY_F7 65

    #define KEY_F8 66

    #define KEY_F9 67

    Return Value: The ASCII value of a key that has been pressed.

    Example:

    #include "winbgim.h"

    #include // Provides sprintf

    #include // Provides cout

    void outintxy(int x, int y, int value);

    //doar prototipul functiei, descrierea este dupa main

    int main( ) {

    int i; char c;

    // Initialize the graphics window.

    init_window(400, 300);

    // Convert some numbers to strings and draw them in graphics window:

    outtextxy(10, 10, "Here are some numbers:");

    for (i = 10; i

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    3

    do {

    c = (char) getch( );

    if (c != 0)

    cout

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    4

    Introducere in OpenGl

    Scurt bibliografie:

    1. Rodica Baciu, Programarea aplicaiilor grafice 3D cu OpenGL, Editura Albastr, Cluj-Napoca, 2005.

    2. Specificaii OpenGl (inclusiv Glut), http://www.opengl.org/documentation/specs/ 3. NeHe, Tutorial OpenGl, http://nehe.gamedev.net/ 4. OpenGl Programming Guide (red book), http://www.glprogramming.com/red/ (format html)

    sau http://paginas.fe.up.pt/~jbarbosa/ensino/SG/2005-2006/OpenGL%20Programming%20Guide.pdf (format pdf)

    5. OpenGl Reference Manual (blue book), http://glprogramming.com/blue/ 6. Open Gl Superbible, http://opengl.czweb.org/ewtoc.html

    OpenGL (Open Graphics Library) este o interfa (API = Application Programming Interface) multiplatform, independent de hardware, folosit pentru grafic 3D. Prima versiune, OpenGL 1.0, a aprut n 1992; versiunea OpenGL 4.5 a aprut n 2014.

    OpenGL este disponibil pentru sisteme de operare Windows, Linux i Unix i pentru limbaje de programare ca C, C++, Ada, Fortran i Java.

    Citii mai multe pe site-ul oficial OpenGL http://www.opengl.org/ (de exemplu, http://www.opengl.org/developers/code/tutorials.html).

    Cnd vorbim despre o aplicaie OpenGl, nseamn c este scris ntr-un limbaj de programare (ca C/C++, Java) ce apeleaz una sau mai multe librrii OpenGL.

    API OpenGL

    Un OpenGL API poate conine urmtoarele librrii: Funciile efective ce definesc OpenGL sunt coninute n librria opengl32.dll (de exemplu, n

    :\Windows\System32\) i fiierul header GL/gl.h (de exemplu, n \MinGW Include\GL\). OpenGL utility library (GLU) cu librria glu32.dll (n :\Windows\System32\) i fisierul

    header GL/glu.h (n \MinGW\Include\GL\), conine funcii ce uureaz crearea programelor, ca de exemplu desenarea sferelor, discurilor i cilindrelor, etc.

    Auxiliary (toolkit) library (AUX) este glaux.lib (de exemplu, n \MinGW\Lib\), iar declaraiile acesteia sunt coninute n GL/glaux.h (de exemplu, n \MinGW\Include\GL\).

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    5

    Permite de exemplu scrierea rapid a unui program care folosete OpenGL fr s mai pierdei timpul cu gestiunea ferestrelor etc.

    Folosii biblioteca glut (the OpenGL Utility Toolkit = GLUT) - neinclus n compilatoarele C++, gen CodeBlocks sau Visual C++. Se poate downloada de la adresa https://www.opengl.org/resources/libraries/glut/glut_downloads.php. Aceasta arhiva conine: glut.h, glut32.lib, glut32.dll, readMe.txt.

    Pentru sisteme X Window (UNIX), extensia OpenGL se numete GLX, iar pentru Microsoft Windows se numeste WGL.

    Dac programai cu CodeBlocks, atunci header-ele OpenGL i librriile sunt incluse (n \MinGW\Include\GL\), exceptnd fiierele GLUT care trebuie download-ate i instalate personal.

    Instalare glut: 1. copiai glut.h n directorul \MinGW\Include\GL. l putei pune n acelai director cu fisierul surs, dar vei folosi: #include glut.h 2. copiai glut32.lib n . \MinGW \lib 3. copiai glut32.dll n directorul cu fiierele sistem (\WINDOWS\SYSTEM32)

    n CodeBlocks, pentru o aplicaie OpenGL putei crea un proiect tip Console Application. Nu uitai s adugai n lista bibliotecilor cu care se linkeaz proiectul (meniul Project Build Options eticheta Linker Settings la Link libraries, pe rnd (Add->clic pe Browse ...) din directorul n care avei MinGW instalat, subdirectorul Lib, urmtoarele librrii: libgdi32.lib, glaux.lib, opengl32.lib, etc. Kepp this a relative part? Yes OK OK.).

    Fiind independent de platform, OpenGL prevede cteva tipuri de date proprii; toate ncepnd cu "GL". Pentru a obine o aplicaie portabil este recomandat s le folosii pe acestea i nu altele de aceeai mrime, caracteristice ns sistemului de operare folosit:

    Nume Descriere sufix Glbyte ntreg pe 8 bii b Glshort ntreg pe 16 bii s GLint, Glsizei ntreg pe 32 de bii i GLfloat, GLclampf reprezentare n virgul mobil pe 32 de bii f GLdouble, GLclampd reprezentare n virgul mobila pe 64 de bii d GLubyte, GLboolean ntreg fr semn pe 8 bii Ub Glushort ntreg fr semn pe 16 bii Us GLuint, GLenum, GLbitfield ntreg fr semn pe 32 de bii Ui

    GLsizei se folosete pentru parametri dimensiune ce se reprezint printr-un ntreg. GLclampf este folosit la stabilirea culorii i pentru amplitudinea culorii. GLenum se folosete pentru variabile enumerate. GLbitfield se folosete pentru variabile ce conin cmpuri binare.

    Exist i constante simbolice i care ncep cu "GL_" de exemplu GL_POINTS, GL_POLYGON. De asemenea, comenzile/functiile au prefixul "gl": gl{nume functie}{numar de parametri}{sufix care arata tipul parametrilor}

    {v (daca parametrul este un vector} ( .......) n general, comenzile au sintaxa:

    De exemplu: glVertex3d - primete 3 parametri de tip GLdouble, iar glColor3f - 3 parametri de tip GLfloat

    Totui exist i cteva excepii n care lipsesc numrul i tipul parametrilor (de exemplu glBegin) sau care incep cu un alt prefix (gluLookAt).

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    6

    1. Sistem de coordonate

    OpenGL foloseste un sistem de coordonate dreapta. Intern, OpenGL foloseste coordonate omogene astfel

    c fiecare punct 3D este de fapt reprezentat prin (x, y, z, w); daca w este nenul, acestea corespund punctului euclidian (x/w, y/w, z/w).

    Exemplu de cel mai scurt program OpenGL scris n CodeBlocks:

    #include //functiile librariei AUX pt lucru cu ferestre //#include //headerul pt ferestre necesar in toate programele //#include //headerul functiilor OpenGL -- inclus in glaux.h

    void Initializari(){ glClearColor(0.0f, 0.0f, 1.0f, 1.0f); //stabilirea culorii de sters glClear(GL_COLOR_BUFFER_BIT);//stergerea efectiva a continutului ferestrei glFlush(); //executarea celor doua functii de sus } int main(void) { //functii AUX pentru setarea unei ferestre auxInitDisplayMode(AUX_SINGLE | AUX_RGBA); auxInitPosition(50,50,350,350); //setarea ferestrei auxInitWindow("P0 -- program OpenGL"); //crearea efectiva a ferestrei Initializari(); auxMainLoop(NULL); //mentine fereastra de desenare activa return 0 ; }

    2. Gestiunea ferestrelor folosind libraria AUX

    auxInitPosition(GLint x, GLint y, Glsizei latime, Glsizei inaltime) Dup setarea modului de afiare, se poate preciza locul unde s fie poziionat fereastra i

    dimensiunile acesteia. Parametrii reprezint coordonatele colului stnga-sus al ferestrei ce va fi creat precum i limea i nlimea acesteia toate exprimate n pixeli. Parametrul x reprezint numrul de pixeli de la colul stnga-sus al ferestrei pn la marginea din stnga a ecranului, iar y reprezint numrul de pixeli de la colul stnga-sus al ferestrei pna la marginea de sus a ecranului. Reamintim c o rezolutie VGA standard este de 640480.

    O fereastr n Windows are axele orientate astfel:

    O fereastr OpenGL are axele orientate ca pe hartie

    auxInitWindow(char* nume) creaz o fereastr conform setrilor anterioare (care pot fi modificate ulterior), n titlul ferestrei fiind scris numele dat ca parametru. Dac programul se oprete aici, se va crea doar o ferastr goal (implicit fundalul acesteia este negru). De-acum toate comenzile OpenGL se vor executa n aceast fereastr.

    auxInitDisplayMode(Gluint mode) iniializeaz modul de afiare folosit cnd se va crea fereastra. Mode specific:

    (0,0) X

    Y

    (0,0) X Y

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    7

    folosirea unei ferestre cu buffer simplu sau dublu: AUX_SINGLE sau AUX_DOUBLE modelul de culoare folosit - se recomanda AUX_RGBA folosirea bufferului de adncime pentru algoritmul z-buffer: AUX_DEPTH Pentru a obine valoarea lui mode putem aplica ntre valorile care ne intereseaz. O fereastr cu buffer simplu presupune faptul c toate comenzile de desenare se fac n fereastra afiat; alternativa este un buffer dublu, cnd comenzile de desenare creeaz o scen efectiv n afara ferestrei, apoi rapid este trecut n fereastra afiat se folosete des n animaie. Modelul de culoare RGBA presupune ca pentru a defini o culoare trebuie specificate componentele red (rosu), green (verde) i blue (albastru).

    2. Gestiunea ferestrelor folosind biblioteca GLUT

    Pe lng standardul OpenGL, glut ofer i funcii care uureaz realizarea unei interfee cu utilizatorul. Enumerm cteva dintre:

    glutInitDisplayMode (unsigned int mode) Initializeaz modul de afiare. Mode specific: - modelul de culoare folosit - se recomand GLUT_RGB - folosirea unei ferestre cu buffer simplu sau dublu: GLUT_SINGLE sau GLUT_DOUBLE - folosirea bufferului de adncime pentru algoritmul z-buffer: GLUT_DEPTH Pentru a obine valoarea lui mode putem aplica | ntre valorile care ne intereseaz.

    glutInitWindowPosition(int x, int y) Poziioneaz fereastra fa de colul stnga-sus al ecranului.

    glutInitWindowSize(int width, int height) stabilete dimensiunea ferestrei.

    int glutCreateWindow(char* nume) creaz o fereastr cu un context OpenGL. int glutDestroyWindow(int window) distruge fereastra window mpreun cu toate subferestrele ei.

    3. Culori

    glColor3f (GLfloat R, GLfloat G, GLfloat B)

    Se stabilete culoarea cu care se va desena pn o schimbm din nou, de componente R,G,B ce au valori reale de la 0.0 la 1.0. De exemplu:

    Culoarea rezultata

    Componenta rosu

    Componenta verde

    Componenta albastru

    Black 0.0 0.0 0.0 Red 1.0 0.0 0.0 Green 0.0 1.0 0.0 Yellow 1.0 1.0 0.0 Blue 0.0 0.0 1.0 Magenta 1.0 0.0 1.0 Cyan 0.0 1.0 1.0 Dark gray 0.25 0.25 0.25 Light gray 0.75 0.75 0.75 Brown 0.60 0.40 0.12 Pumpkin orange 0.98 0.625 0.12 Pastel pink 0.98 .04 0.7

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    8

    Barney purple 0.6 0.4 0.7 White 1.0 1.0 1.0

    void glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)

    Stabilete culoarea cu care se va cura interiorul ferestrei, prin parametrii dai stabilindu-se componentele culorii. Este similar cu specificarea culorilor n Windows folosind macrouri RGB pentru a crea o valoare COLORREF cu valori ntregi ns, ntre 0 i 255. Cel de-al patrulea parametru este folosit pentru amestecarea culorilor i efecte speciale i reprezint opacitatea transluciditatea (proprietatea de a fi parial transparent). Dac nu se doresc efecte speciale, atunci alfa = 1.0f.

    void glClear (GL_COLOR_BUFFER_BIT) terge efectiv eventualele desene din fereastra curent. Constanta dat ca parametru arat ce

    buffer vrem s tergem. Prin buffer ntelegem zona unde se memoreaz informaiile unei imagini. OpenGL folosete mai multe buffere n diverse scopuri: GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_ACCUM_BUFFER_BIT, GL_STENCIL_BUFFER_BIT. Putem terge mai multe cu acelai apel; de exemplu, glClear(GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT) terge imaginea i bufferul folosit pentru a determina care figuri sunt vizibile (folosit de algoritmul z-buffer). Componentele R, G, B ale unui desen au buffere separate, dar de obicei sunt referite prin buffer-ul culorii.

    glFlush () Se execut comenzile OpenGL neexecutate nc, de obicei: glClearColor, glClear i desenarea primitivelor. Intern, OpenGL folosete un render pipeline ce proceseaz comenzile secvenial.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    9

    #include //#include //#include

    void CALLBACK Deseneaza(void) //functia efectiva pentru desenare { glClearColor(1.0f,1.0f,1.0f,1.0f);//culoarea de sters fer = alb glClear(GL_COLOR_BUFFER_BIT);//se sterge efectiv fereastra glColor3f(1.0f,0.0f,0.0f);//culoarea de desenare = rosu glBegin(GL_TRIANGLES); glVertex3f(100.0f, 125.0f, 0.0f); glVertex3f(100.0f, 230.0f, 0.0f); glVertex3f(140.0f, 230.0f, 0.0f); glEnd(); glFlush(); } int main() { auxInitDisplayMode(AUX_SINGLE | AUX_RGBA); auxInitPosition(50,50,300,300); auxInitWindow("P1-OpenGL"); auxMainLoop(Deseneaza); return 0; }

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    10

    4. Execuia aplicaiei

    auxMainLoop(void (*f)(void)) Preia numele funciei ce deseneaz ceva n fereastra curent i programul ruleaz pn cnd

    fereastra n care se deseneaz este nchis. Funcia CALLBACK se apeleaz cnd fereastra este afiat prima dat, cnd fereastra este mutat sau redimensionat.

    Procesul de desenare n OpenGL este numit deseori rendering, iar functia de desenare render function. Cuvntul CALLBACK spune librariei OpenGL s apeleze aceasta funcie de fiecare dat cnd fereastra se actualizeaz n funcie de comportamentul utilizatorului.

    5. Desenarea primitivelor in OpenGL

    Exist mai multe tipuri de primitive pe care le putem desena folosind OpenGL. Pentru nceput ns nu le voi prezenta pe toate. Putem desena ceva pe ecran folosind funcia:

    glVertex3f(GLfloat x, GLfloat y, GLfloat z) // punct 3D de coordonate (x,y,z) Pentru a avea vreun efect apelurile acestei functii trebuiesc ncadrate ntre apelurile glBegin(GLenum tip_primitiva) si glEnd(), unde tipul primitivei este identificat printr-una din constantele:

    GL_POINTS pentru desenare puncte GL_LINES, GL_LINESTRIP, GL_LINE_LOOP pentru segmente. GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN triunghiuri GL_QUADS, GL_QUAD_STRIP pentru patrulatere GL_POLYGON pentru poligoane

    ntre glBegin si glEnd putem apela i glColor* pentru a stabili culoarea vrfurilor urmtoare. Modul n care sunt afiate poligoanele se poate stabili (nainte de glBegin) folosind:

    glPolygonMode (GLenum face, GLenum mode)

    unde, face poate fi GL_FRONT_AND_BACK sau GL_FRONT sau GL_BACK. Aceste constante identific feele fa sau spate (n mod implicit feele care sunt definite prin vrfuri parcurse n sens trigonometric sunt considerate fe fa). Mode poate fi GL_POINT, GL_LINE sau GL_FILL.

    Desenarea liniilor n OpenGL Exemplu: glBegin (GL_LINES); glVertex3f (x1, y1, z1); glVertex3f (x2, y2, z2); glVertex3f (x3, y3, z3); glVertex3f (x4, y4, z4); glVertex3f (x5, y5, z5); glVertex3f (x6, y6, z6); glEnd();

    Fie vi punctul de coordonate (xi, yi, zi). Comanda de mai sus va uni v1 cu v2, v3 cu v4 si v5 cu v6. n general, dac se specific 2n puncte i se folosete optiunea GL_LINES se vor desena n segmente de dreapt ce unesc v2i-1 cu v2i, i =1, 2,, n.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    11

    Dac se dau n vrfuri i se folosete GL_LINE_STRIP, atunci se vor desena o linie poligonal ce unete vrfurile vi cu vi+1, unde i = 1, 2,, n-1.

    Dac se dau n vrfuri i se folosete GL_LINE_LOOP, atunci se vor desena o linie poligonal ce unete vrfurile vi cu vi+1, unde i = 1, 2,, n-1 si apoi vn cu v1.

    6. Desenarea poligoanelor in OpenGl

    OpenGl are comenzi pentru desenarea triunghiurilor, a patrulaterelor si a poligoanelor convexe, nu prin desenarea conturului acestuia, ci prin umplerea interiorului acestora cu o culoare anume. Pentru desenarea unui triunghi de varfuri vi(xi, yi, zi):

    glBegin(GL_TRIANGLES); glVertex3f (x1, y1, z1); glVertex3f (x2, y2, z2); glVertex3f (x3, y3, z3); glEnd();

    glBegin(GL_TRIANGLES); glVertex3f (x1, y1, z1); glVertex3f (x2, y2, z2); glVertex3f (x3, y3, z3); glVertex3f (x4, y4, z4); glVertex3f (x5, y5, z5); glVertex3f (x6, y6, z6); glEnd();

    Se pot specifica mai multe triunhiuri in acelasi glBegin (GL_TRIANGLES), pentru desenarea a n triunghiuri fiind necesare 3*n comenzi glVertex*.

    Deseori se dorete combinarea a mai multor triunghiuri pentru a obine o suprafa continu. Pentru aceasta este convenabil declararea triunghiurilor o singur dat (fr a specifica vrfurile comune de mai multe ori pentru fiecare triunghi). Dac se folosete GL_TRIANGLE_STRIP i se specific n vrfuri, atunci se deseneaz triunghiurile (vi, vi+1,vi+2) , pentru i = 1, 2,,n-2. Alt variant este aceea n care un vrf este comun: GL_TRIANGLE_FAN i vrfurile v1,...,vn. Deseneaz triunghiurile (v1, vi, vi+1), pentru i = 2, 3,.., n-1.

    Pentru desenarea patrulaterelor convexe, OpenGL nu verific dac acesta sunt convexe, ci imparte patrulaterul n 2 triunghiuri pentru a-l desena ca un poligon plin. Comanda pentru desenarea unuia sau mai multor patrulatere este:

    glBegin (GL_QUADS); glVertex3f (x1, y1, z1);

    glVertex3f (xn, yn, zn); glEnd();

    unde n este multiplu de 4. Se deseneaza n/4 patrulatere cu vrfurile v4i-3, v4i-2, v4i-1, v4i, cu 1in/4. Se poate de asemenea folosi GL_QUADS_STRIP pentru a uni patrulatere n acest caz n trebuie s fie par i se deseneaz n/21 patrulatere cu vrfurile v2i-3, v2i-2, v2i-1, v2i, cu 2 i n/2.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    12

    Specificarea vrfurilor pentru GL_QUADS i pentru GL_QUAD_STRIP se face diferit: pentru GL_QUADS vrfurile sunt specificate n sens trigonometric, ns pentru GL_QUAD_STRIP

    acestea sunt date ca perechi citite de la stanga la dreapta. OpenGL permite si desenarea unor poligoane cu un numar arbitrar de varfuri. Presupune ca poligonul este planar, convex si simplu (un poligon este simplu daca muchiile nu se interesecteaza decat in capetele acestora) si nu face verificari. Pentru desenare se apeleaza glBegin cu parametrul GL_POLYGON si se specifica varfurile acestuia.

    Dimensiunea punctelor se controleaz cu comanda glPointSize (GLfloat dimensiune)

    unde dimensiune reprezint limea n pixeli a punctelor, care trebuie s fie mai mare dect 0.0, valoarea implicit fiind 1.0.

    Grosimea liniilor se controleaza cu comanda glLineWidth(GLfloat grosime)

    unde grosimea reprezint limea n pixeli cu care se vor desena liniile dupa setare; trebuie s fie mai mare decat 0.0, valoarea implicit fiind 1.0.

    void auxWireSphere(GLdouble raza); //are atribut de contur - sfer centrat n origine, pentru care se specific raza

    void auxWireCube(Gldouble latura); //are atribut de contur - cub centrat n origine, pentru care se specific latura

    void auxWireBox(Gldouble latime,Gldouble inalt,Gldouble adancime); - paralelipiped centrat n origine, pentru care se specific limea, nlimea i adncimea

    void auxWireTorus(Gldouble razaInter, Gldouble razaExter); - tor (form de colac) centrat n origine, pentru care se specific raza interioar i cea exterioar

    void auxWireCylinder(Gldouble baza, Gldouble inaltimea); - cilindru centrat n origine, pentru care se specific baza i nlimea

    void auxWireIcosahedron(Gldouble raza); - icosaedru (poliedru cu 20 fete triunghiulare) centrat n origine pentru care se specific raza.

    void auxWireOctahedron(Gldouble raza); - octaedru (poliedru cu 8 fete triunghiulare) centrat n origine pentru care se specific raza.

    void auxWireTetrahedron(Gldouble raza); - tetraedru (poliedru cu 4 fee triunghiulare) centrat n origine pentru care se specific raza.

    void auxWireDodecahedron(Gldouble raza); - dodecaedru (poliedru cu 12 fee pentagonale) centrat n origine pentru care se specific raza.

    void auxWireCone(Gldouble raza, Gldouble inaltime); - con centrat n origine pentru care se specific raza bazei i nlimea

    void auxWireTeapot(Gldouble dimensiune); //are atribut de contur - ceainic centrat n origine pt care se specifica dimensiunea (aprox. raza)

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    13

    Setri pentru tipul de linie / umplere poligoane

    Funcia

    void glLineStipple(Glint factor, GLushort pattern);

    specific tipul de linie ce va fi folosit. Al doilea argument, pattern, reprezint 16 bii (0=pixel stins, 1=pixel aprins) ce se vor repeta pn se deseneaz linia respectiv, iar primul argument este un factor de multiplicare pentru fiecare pixel n parte. De exemplu, cu forma 0x3F07 (care n binar este 0011111100000111), o linie va avea 3 pixeli aprini, apoi 5 stini, 6 aprini, 2 stini, etc (bitul de ordin cel mai mic este folosit nti, de acea se citete invers). Pentru un parametru factor (implicit 1) cu valoarea 2, o linie va avea 6 pixeli aprini, apoi 10 stini, 12 aprini, 4 stini, etc.

    Exemple: glLineStipple(1,0x0101); //dotted line glLineStipple(1,0x00FF); //dashed line glLineStipple(1,0xF00F); //long dashed line glLineStipple(1,0x1C47); //dash/dot/dash line

    Pentru a putea folosi efectiv tipul de linie specificat, mai trebuie apelat funcia

    glEnable(GL_LINE_STIPPLE);

    altfel implicit este activ funcia glDisable(GL_LINE_STIPPLE)i ca tip de linie se va folosi linia continu (echivalent cu glLineStipple de parametri: pattern=0xFFFF i factor=1).

    Poligoanele sunt umplute cu pat de culoare (form continu), dar se pot specifica 32*32 bii ca pattern de umplere prin intermediul funciei

    void glPolygonStipple(const GLubyte *mask);

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    14

    Similar, aceast funcie are efect dac este apelat glEnable(GL_POLYGON_STIPPLE), implicit fiind activ funcia glDisable(GL_POLYGON_STIPPLE).

    Exemplu: GLubyte fly[] = {

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60, 0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20, 0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20, 0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC, 0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30, 0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0, 0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0, 0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30, 0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08, 0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08, 0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08};

    conduce la urmtoarea forma de umplere anterioar, iar

    GLubyte halftone[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55, 0x55, 0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55, 0x55, 0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55, 0x55,0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55, 0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55, 0x55, 0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,0xAA,0xAA,0xAA,0xAA,0x55,0x55, 0x55,0x55, 0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55,0xAA,0xAA,0xAA,0xAA,0x55,0x55,0x55,0x55};

    conduce la forma de umplere:

    #include #include #include void CALLBACK Deseneaza() {GLubyte fly[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60, 0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20, 0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20, 0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC, 0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30, 0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0, 0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0, 0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30, 0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08, 0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08, 0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08};

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    15

    GLubyte halftone[] = { 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};

    glClearColor(1.0f,1.0f,1.0f,0.0f);//culoarea de sters fer = alb glClear(GL_COLOR_BUFFER_BIT);//se sterge efectiv fereastra

    glColor3f(1.0,0.0,0.0);//culoare de umplere glRectf(25.0,25.0,125.0,125.0);//dreptunghi umplut simplu

    glEnable (GL_POLYGON_STIPPLE); //activez optiunea umplere cu alte forme glPolygonStipple (fly); glRectf (125.0, 25.0, 225.0, 125.0);//dreptunghi umplut cu patter-ul fly glPolygonStipple (halftone); glRectf(225.0, 25.0, 325.0, 125.0);//dreptunghi umplut cu halftone glDisable (GL_POLYGON_STIPPLE); //dezactivez optiunea umplere cu forme glFlush (); } void CALLBACK Redimensioneaza (GLsizei w, GLsizei h) { if (h==0) h=1; glViewport(0,0,w,h);

    glMatrixMode(GL_PROJECTION); //vom lucra cu matr curenta M de proiectie glLoadIdentity();//M=I4 if (w

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    16

    n program sunt umplute dreptunghiuri din plan folosind funcia OpenGL:

    void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);

    unde (x1,y1) reprezint coordonatele unui vtf al dreptunghiului, iar (x2,y2) reprezint coordonatele vrfului opus.

    Funcia RedimFereastra face ca n cazul modificrii dimensiunilor ferestrei, desenul s fie proporional cu dimeniunile specificate (iar n cazul unui ptrat, acesta s rmn ptrat la modificarea dimensiunilor ferestrei) se spune c se pstreaz o rat de aspect (engl., aspect ratio) uniform pe cele dou axe. Aspect ratio reprezint n general raportul dintre numrul de pixeli pe unitate de lungime pe vertical i numrul de pixeli de pe unitate de lungime pe orizontal. Astfel, dac noua nlime a ferestrei este mai mare, coordonatele pe Ox rmn la fel, iar toate coordonatele pe Oy se scaleaz cu raportul h/w; n cazul n care limea ferestrei este mai mare, coordonatele pe Oy rmn la fel, iar toate coordonatele pe Ox se scaleaz cu raportul w/h.

    Pentru aceasta se folosete proiecia paralel ortografic (ortogonal) glOrtho de prototip:

    void glOrtho(Gldouble stanga, Gldouble dreapta, Gldouble jos, Gldouble sus, Gldouble aproape, Gldouble departe);

    n spatiul cartezian 3D, valorile stanga i dreapta reprezint coordonatele minime i maxime de pe axa Ox; jos i sus sunt cele corespunztoarele de pe axa Oy, iar aproape i departe pentru axa Oz (reamintim c este orientat cu partea pozitiv n afara ecranului). Aceast proiecie specific i faptul c volumul de vedere este un paralelipiped dreptunghic (vezi pagina urmtoare). n exemplul nostru, punctele sunt (-0.5, -0.5), (-0.5, 0.5), (0, 0.5), deci sunt vizibile n [-1, 1]*[-1,1], aadar am ales stnga = -1, dreapta=1, jos = -1 i sus=1 cu pstrarea ratei de aspect uniform.

    Pentru proiecie paralel ortogonal mai exist o funcie OpenGl, gluOrtho2D, care este similar cu glOrtho, avnd fixai parametrii: aproape la 1 i departe la -1.

    INTERPOLAREA N SPAIUL CULORILOR

    S considerm dou culori specificate n modelul RGB, C1=(1,0,0) - rou i C2=(0,1,0) - verde. Dac le interpolm se obine: C = t*C2 + (1-t)*C1, unde t [0,1] (pentru ponderi egale, t= 0.5) se obine culoarea gri C = (0.5, 0.5, 0).

    n OpenGL, exist funcia

    void glShadeModel(GLenum mode)

    n care parametrul mode poate lua valorile GL_SMOOTH (valoarea implicit) sau GL_FLAT i care stabilete modelul nuanelor (shading model). Cnd modelul este GL_FLAT, se folosete doar o singur culoare per poligon, n timp ce la modelul GL_SMOOTH culoarea unui poligon este obinut prin interpolarea culorilor de-a lungul vrfurilor poligonului.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    17

    Aplicaie: Triunghi cu muchii/interior colorate

    #include

    void Initializari() { glClearColor(1.0,1.0,1.0,0.0); //fundalul alb glClear(GL_COLOR_BUFFER_BIT); glFlush(); //se sterge ecranul cu alb

    //glShadeModel(GL_FLAT);//oricum model implicit glShadeModel(GL_SMOOTH); //cu interpolarea culorilor glLineWidth(3); } void CALLBACK Deseneaza(void) { glBegin(GL_LINE_LOOP); //(GL_TRIANGLES); //conturul, respetiv sau interiorul triunghiului glColor3f(0.0, 1.0, 0.0); //verde glVertex2f(100.0,100.0);//vf.stanga-jos (1) glColor3f(1.0, 0.0, 0.0); //rosu glVertex2f(400.0,100.0);//vf.dreapta-jos (2) glColor3f(0.0, 0.0, 1.0); //albastru glVertex2f(250.0,300.0); //vf.de sus (3) glEnd(); glFlush(); } 3

    int main () { auxInitDisplayMode(AUX_SINGLE | AUX_RGB); auxInitPosition(10,10,500,400); auxInitWindow("Triunghi colorat"); Initializari() ; 1 2 //glShadeModel(GL_SMOOTH);//oricum model implicit 3 glShadeModel(GL_FLAT); glLineWidth(3);

    auxMainLoop(Deseneaza); return 0; } 1 2

    Pentru desenarea muchiilor triunghiului am folosit primitiva GL_LINE_LOOP, care unete primul vrf cu al doilea, al doilea cu al treilea i al treilea cu primul. Dac se las modelul shading implicit (adic nu se specific explicit un model shading sau se apeleaz glShadeModel(GL_SMOOTH) atunci muchiile triunghiului apar astfel: - culoarea muchiei care unete vrful dreapta-jos (1) cu cel din stanga-jos (2) este interpolare ntre

    verde i rou; - culoarea muchiei care unete vrful stanga-jos (1) cu cel de sus (3) este interpolare ntre rou i

    albastru; - culoarea muchiei care unete vrful de sus (3) cu cel din dreapta-jos (2) este interpolare ntre

    albastru i verde. Dac se apeleaz glShadeModel(GL_FLAT) atunci muchiile triunghiului apar astfel:

    - muchia care unete vrful dreapta-jos (1) cu cel din stanga-jos (2) are culoarea roie; - muchia care unete vrful stanga-jos (1) cu cel de sus (3) are culoarea albastr;

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    18

    - muchia care unete vrful de sus (3) cu cel din dreapta-jos (2) are culoarea verde.

    Dac n locul primitivei GL_LINE_LOOP se folosete GL_TRIANGLES atunci se va colora interiorul triunghiul, iar dac modelul este GL_SMOOTH atunci culoarea este obinut prin interpolare ntre culorile rou, albastru i verde (lng vrful stnga-jos va fi zon verde, lng vrful dreapta-jos va fi zon roie, iar lng vrful de sus va fi zon albastr), altfel (cu modelul GL_FLAT) culoarea este albastr.

    TRANSFORMRI GEOMETRICE 3D

    Transformrile geometrice tridimensionale cuprind: translaia, scalarea, rotaia, simetria (oglindirea), forfecarea i proiecia obiectelor 3D. Aa cum transformrile 2D se reprezint prin matrice 33 folosind coordonate omogene i transformrile 3D pot fi reprezentate prin matrice 44 reprezentnd punctele 3D n coordonate omogene. Astfel, punctul din spaiu (x, y, z) se reprezint prin vectorul (xw, yw, zw, w), unde w este un parametru real. Reprezentarea standard a unui punct omogen (x, y, z, w) cu w0 este (x/w, y/w, z/w, 1). Punctele pentru care w=0 sunt puncte la infinit.

    Translaia tridimensional

    Matricea de translaie este T(dx, dy, dz) =

    1000100010001

    dzdydx

    . Daca (x, y, z) sunt coordonatele

    unui punct P din spaiu, prin translatare cu matricea T(dx, dy, dz) el este dus n punctul P de coordonate (x, y, z), unde x = x + dx

    y = y + dy

    z = z + dz

    sau scris n forma matriceal: (x y z 1)t = T(dx, dy, dz) (x y z 1)t.

    Scalarea tridimensional fa de origine

    Matricea de scalare general (local) S(sx, sy, sz)=

    1000000000000

    sz

    sysx

    . Dac (x, y, z) sunt

    coordonatele unui punct P din spaiu, prin scalare cu matricea S(sx, sy, sz) el este dus n punctul P de coordonate (x,y,z), unde x = x * sx

    y = y * sy

    z = z * sz

    sau scris in forma matriceala: (x y z 1) = S(sx, sy, sz) (x y z 1).

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    19

    Ca i n cazul transformrilor 2D, factorii de scalare sunt numere pozitive. Un factor de scalare subunitar produce o micorare a vectorului de poziie (cel ce uneste originea cu punctul) al punctului scalat, iar un factor de scal supraunitar produce o mrire a vectorului de pozitie.

    Scalarea uniform (global) se obine folosind matricea S(s)=

    s000010000100001

    . Prin scalare

    globala punctul P este transformat in punctul astfel (x y z 1)=S(s)(x y z1)=(x y z s)=(x/s y/s z/s 1).

    Acelai efect se poate obine si prin scalare locala data de matricea S(s) =

    10000/10000/10000/1

    s

    s

    s

    .

    Dac factorul de scalare s este subunitar, se produce o mrire a vectorului de poziie, iar dac factorul de scalare s este supraunitar, atunci se produce o micorare a vectorului de poziie.

    Rotaia tridimensional n jurul unei axe a sistemului de coordonate

    Rotaia oarecare n spaiu se descompune n cel mult trei rotaii, maxim cte una dup fiecare ax a sistemului de coordonate.

    n cazul rotaiei n jurul axei Ox, coordonatele x ale vectorilor de poziie nu se schimb; rotaia apare n plane perpendiculare pe axa Ox. Similar, n cazul rotaiei n jurul axei Oy sau Oz, coordonatele y, respectiv z ale vectorilor de poziie nu se schimb, pentru c rotaia se efectueaz n plane perpendiculare pe axa Oy sau Oz.

    Plecnd de la matricea de rotaie n plan n jurul originii i innd cont de faptul c n cazul rotaiei n jurul axei Ox, coordonata x nu se schimba, matricea de rotaie n jurul axei Ox cu unghiul este:

    Rx()=

    aa

    a-a

    10000cossin00sincos00001

    , de unde P= Rx() P implic:

    a+a=

    a-a=

    =

    cossin'sincos'

    '

    zyzzyy

    xx

    Analog, rotaia n jurul axei Oy cu unghiul este dat de

    Ry()=

    bb-

    bb

    10000cos0sin00100sin0cos

    , de unde P= Ry() P implic:

    b+b-=

    =

    b+b=

    cossin''

    sincos'

    zxz

    yyzxx

    iar n jurul axei Oz cu unghiul este dat de

    Rz()=

    qq

    q-q

    1000010000cossin00sincos

    , de unde P= Rz() P implic:

    =

    q+q=

    q-q=

    zz

    yxyyxx

    '

    cossin'sincos'

    Coloanele i liniile matricelor 3*3 din colul stnga-sus al matricelor de rotaie sunt vectori perpendiculari, iar respectivele matrice sunt ortogonale, deci au determinantul 1. Transformrile

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    20

    ortogonale conserv distanele i unghiurile. Inversa unei matrice ortogonale M este chiar transpusa acesteia. Toate matricele de transformare au inverse:

    [T(dx, dy, dz)]-1 = T(dx,dy,dz), [S(sx, sy, sz)]-1 = S(1/sx, 1/sy, 1/sz), [Rx()]-1 = Rx(), [Ry()]-1 = Ry(), [Rz()]-1 = Rz().

    Oglindirea (simetria) tridimensionala

    Fa de planul xOy: Oxy =

    -

    1000010000100001

    . Similar Oyz =

    -

    1000010000100001

    si Oxz =

    -

    1000010000100001

    .

    Simetria fata de axa Oy: Oy =

    -

    -

    1000010000100001

    , iar fata de origine OO =

    -

    -

    -

    1000010000100001

    Forfecarea tridimensional

    H =

    1000010101

    igfdcb

    .

    Compunerea transformarilor 3D

    Exemplul 1. Obiectiv: transformare lui P1P2 si P1P3

    Operaii: 1. translaie P1 n (0,0,0) 2. rotaie fa de Oy 3. rotaie fa de Ox 4. rotaie fa de Oz

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    21

    Exemplul 2: Rotaia unui obiect n jurul unei drepte arbitrare, dar paralel cu o anumit ax de coordonate presupune:

    1. translatarea obiectului astfel nct axa de rotaie s coincid cu axa paralel de coordonate; 2. efectuarea rotaiei 3. translatarea obiectului astfel incat axa de rotatie sa fie mutata in pozitia originala.

    Dac axa de rotatie nu este paralel cu nici una din axele de coordonate, este necesar rotaia n prealabil a acestei axe astfel nct s fie paralel cu una din axele de coordonate. n final se aplic transformarea invers pentru a aduce axa de rotaie la orientarea iniial.

    Exemplul 3: Simetria fa de un plan oarecare se poate rezolva aplicnd sistemului de referin o translaie i o rotaie, astfel nct un plan de coordonate s se suprapun peste planul dat i apoi se efectueaz simetria fa de acel plan de coordonate; dup aceea se face roto-translaia invers. Analog se procedeaz n cazul simetriei fa de o dreapt oarecare. n cazul simetriei fa de un punct, este suficient o translaie aplicat sistemului de coordonate astfel nct originea s ajung n punctul dat, apoi se aplic relaiile de simetrie fa de origine; dup calcularea coordonatelor punctului simetric, se aplic translaia inversa.

    Exemplul 4: Simetriile se pot exprima ca produs de simetrii fa de planele de coordonate. Simetria fa de o ax se obine prin concatenarea simetriilor fa de cele doua plane a cror intersectie este axa, iar simetria fa de origine rezult prin aplicarea succesiv a celor trei simetrii fa de planele de coordonate. La rndul lor, aceste simetrii fa de planele de coordonate se pot obine folosind simetria fa de un singur plan de coordonate i rotaiile care suprapun planele de coordonate unul peste celllalt.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    22

    PROIECII (3D->2D)

    Una dintre problemele reprezentrii unei scene 3D apare n momentul n care dorim s afiam un obiect 3D pe display-ul calculatorului (2D) => trebuie s transformm obiectul 3D ntr-unul 2D ce va putea fi redat pe ecran. n general proieciile presupun transformarea unor puncte dintr-un spatiu n-dimensional ntr-un sistem de dimensiune mai mic decat n (n cazul nostru de la 3D la 2D).

    Proiecia unui punct tridimensional este definit astfel: dreptele (razele) de proiecie, numite i proiectori, trec printr-un punct dat al spaiului, numit centru de proiectie (punct de vedere) i prin fiecare punct al corpului, intersectnd planul de proiecie pentru a forma proiecia.

    n funcie de centrul de proiectie se definesc 2 tipuri pricipale de proiecii: proiecie perspectiv, cnd centrul de proiecie este la distan finit fa de planul de proiecie proiecia paralel, cnd centrul de proiecie este "la infinit" fa de planul de proiecie (n acest

    caz proiectorii devin paraleli) Proiecia perspectiv se specific printr-un centru de proiecie, iar proiecia paralel printr-o

    direcie de proiecie. Centrul de proiecie, fiind un punct, este dat n coordonate omogene de forma (xc, yc, zc, 1). Direcia de proiecie poate fi descris printr-un vector de directie v=ai+bj+ck sau prin dou puncte A(x1, y1, z1) i B(x2, y2, z2), caz in care componentele a, b, c, ale vectorului directie se calculeaz astfel: a = x2-x1, b=y2-y1, c=z2-z1.

    Observaii: - efectul vizual al proieciei perspective este asemnator cu cel realizat de tehnica fotografic i

    de sistemul vizual uman; proiecia caracteristic este aceea c dimensiunea proieciei perspective a unui obiect variaz invers proporional cu distana de la obiect la centrul de proiecie; distanele nu sunt cele reale, unghiurile se pstreaz numai dac aparin unei fee ale obiectului paralel cu planul de proiecie, iar liniile paralele nu sunt proiectate, n general, n linii paralele; lungimile unor segmente egale n spaiu pot aprea diferite n imagine, depinznd de apropierea de centrul de proiecie.

    - proiecia paralel pstreaz paralelismul liniilor, dar nu se pstreaz unghiurile (mai puin cele aflate n planuri paralele cu planul de proiecie)

    Sunt folosite pentru: proiectia perspectiva este potrivit pentru generarea imaginilor foto-realistice, dezavantajul ei

    aparnd n medii "tehnice", aprecierea distanelor fiind dificil, liniile paralele (3D) proiectate (2D) nefiind de obicei paralele (exista proiectie perspectiv cu 3 puncte de convergenta, dar noi vom discuta doar cazul cu un singur punct)

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    23

    proiectia paralel nu red imaginea n mod realistic (din punctul de vedere al ochiului uman), ns poate fi util n efectuarea de msurtori.

    Exist o serie de cazuri particulare att pentru proieciile paralele ct i pentru cele perspective:

    Proiecia perspectiv

    n proiecia perspectiv, liniile paralele ntre ele, dar neparalele cu planul de proiecie converg ctre un anumit punct numit punct de fug (engl., vanish point).

    Dac liniile sunt paralele cu una din axele de coordonate, atunci punctul de fug este numit punct de fug (axial) al axei respective. Exist cel mult trei asemenea puncte de fug axiale ntr-un desen, cte unul pentru fiecare ax. Numrul de puncte de fug principale depinde de numrul de axe de coordonate care intersecteaz planul de proiecie. De exemplu, dac planul de proiecie taie doar axa Oz, atunci numai axa Oz are punct de fug, deoarece linile paralele cu axele Ox si Oy sunt paralele i n planul de proiecie i nu au puncte de fug (nu se intersecteaz n planul de proiecie).

    Proiecia perspectiv a unui cub pe un plan care taie numai axa Oz: a) Constructia proieciei b) Dou proiecii perspective cu un punct de fug

    Proieciile perspective cu dou puncte de fug sunt utilizate des in arhitectura i design industrial.

    Proiecie geometric

    plan

    Perspectiv Cu un punct de fug Cu dou puncte de fug Cu trei puncte de fug

    Paralel

    Oblic Cabinet Cavalier altele

    Ortogonal Elevaie (de sus) Plan (frontal) Profil (lateral) Axometric

    Izometric altele

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    24

    Z

    Y

    X

    P(x, y, 0) P(x,y,z)

    C(xc,yc,zc)

    Cub cu dou puncte de fug axial (planul de proiecie este paralel cu Oy)

    Proieciile perspective cu trei puncte de fug sunt rar folosite.

    Exemplu: Proiecia perspectiv pe planul z=0 (xOy) Notm cu P'(x',y',z'), unde z=0, punctul rezultat prin

    proiecia perspectiv a punctului P(x,y,z) n planul z=0, considernd drept centru de proiecie punctul C(xc,yc,zc). Coordonatele punctului P' se pot afla scriind ecuaia dreptei 3D ce trece prin cele 3 puncte:

    xcx

    xcx

    -

    -'

    =

    ycyycy

    -

    -'

    =

    zcz

    zcz

    -

    -'

    Cum P este punct in planul z=0 rezulta ca z=0 (punctul este n planul z=0) i deci

    -

    -

    =

    -

    -

    =

    zcz

    yzczycyzcz

    xzczxcx

    '

    '

    n general, pentru a gsi coordonatele n proiecia perspectiv a unui punct material se rezolv sistemul format din ecuaia planului de proiecie i ecuaia razei virtuale. Uneori aceast modalitate este greoaie. De aceea este util sa fie exprimate coordonatele perspective relativ la triedrul (sistemul de coordonate) tridreptunghic de referint asociat planului de proiecie i normalei pe acest plan dus din centrul de proiectie. Se determin, n primul rnd, transformarea tridimensional care transpune reperul cartezian al lumii reale (n care este descris obiectul) n reperul cartezian asociat planului de proiecie i normalei la acesta, dus prin centrul de proiecie. Se aplic aceast transformare obiectului, apoi se proiecteaz.

    Proiecia paralel

    n funcie de unghiul dintre direcia de proiecie i normala la planul de proiecie, proiecia paralel poate fi: - proiecie ortografic (ortogonal), n cazul n care direcia de proiecie coincide cu normala la

    planul de proiecie, adic direcia de proiecie este perpendicular pe planul de proiecie; - proiectie oblic, n cazul n care direcia de proiecie difer de normala la planul de proiecie.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    25

    Proiectia ortografic (ortogonal) Cele mai des folosite proiectii ortogonale sunt cele ce utilizeaz plane de proiecie perpendiculare pe axele de coordonate. Denumirea dat n desenul tehnic unor asemenea proiecii ale obiectelor sunt: - plan (vedere de sus) - profil (vedere laterala) - elevaie (vedere frontala). n figura alturat, se prezint aceste proiecii ale unei case (originea sistemului de coordonate se afl la intersectia celor trei plane de proiecie). Aceste proiecii au proprietatea de a pstra distanele i unghiurile, astfel ncat sunt des utilizate n inginerie i constructii. Natura tridimensional a obiectului este nsa greu de inteles, chiar daca se studiaz simultan cele trei proiecii ale respectivului obiect. Fie punctul 3D de coordonate omogene (x,y,z,1). Vederea frontal (proiecia pe planul XOY) are matricea caracteristic

    1000000000100001

    , astfel nct ecuatiile transformarii sunt: x=x, y=y i z=0.

    Pentru vederea de sus (proiectia pe planul XOZ) se efectueaza rotatia de unghi 900 in jurul axei OX i proiecia pe planul XOY:

    1000000000100001

    -

    1000001001000001

    , astfel nct: x=x, y=z i z=0.

    Pentru vederea lateral (proiectia pe planul YOZ) se efectueaz rotaia de unghi 900 n jurul axei OY i proiecia pe planul XOY:

    1000000000100001

    -

    1000000100100100

    , astfel nct: x=z, y=y i z=0.

    Alte tipuri de proiecii ortogonale particulare sunt proieciile axonometrice, pentru care planul de proiecie nu este perpendicular pe nici o ax a sistemului de referin. Acestea pstreaz paralelismul liniilor, dar nu i unghiurile. Distanele se msoar de-a lungul fiecrei axe de coordonate, n general, cu factori de scal diferii. Cea mai utilizat proiectie ortografic axonometric este proiectia izometric, pentru care directia de proiectie (care coincide cu normala la planul de proiectie) face unghiuri egale cu cele trei axe ale sistemului de referin. n cazul acestei proiecii, cei trei factori de scal pentru msurarea lungimilor sunt egali, iar axele principale se proiecteaz n plan n trei drepte care fac unghiuri egale.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    26

    Proiecii izometrice. a) Construirea proieciei unui cub n direcia (1,-1,-1) b) Proiecia izometric a versorilor n direcia (1,1,1)

    Exista doar 8 direcii de proiecie care permit proiecii izometrice.

    Proiecia oblic

    Este obinut prin proiectarea unui obiect de-a lungul unor linii paralele care nu-s perpendiculare pe planul de proiecie. Proiecia unei fee a obiectului, paralel cu planul de proiecie, permite msurarea corect a unghiurilor i distantelor, celelalte proiectii ale fetelor permitand doar masurarea distantelor.

    Proiecia oblic. (a) Construirea proieciei punctului M(0,0,1) pe planul XOY (b) Proiecia unui punct oarecare pe planul XOY (c) Proiecia unui cub pe un plan paralel cu axa OY

    Prin convenie, o proiecie oblic pe planul XOY este caracterizat prin punctul n care este proiectat punctul M(0,0,1) pe planul XOY, distana r de la origine a noului punct i unghiul dintre raza r si axa OX (vezi (a)). n funcie de aceste valori, se pot exprima noile coordonate (x,y,z) ale proieciei oblice pe planul XOY a unui punct oarecare (x,y,z) (vezi (b)):

    =

    a+=

    a+=

    0'sin'cos'

    z

    zryyzrxx

    , adic n coordonate omogene

    1'

    '

    '

    z

    yx

    =

    a

    a

    100000000sin100cos01

    r

    r

    1z

    yx

    .

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    27

    v

    Z

    Y

    X

    P(x, y, 0)

    P(x, y, z)

    Proiecia ortogonal se obtine cand r = 0. Cele mai frecvente proiecii oblice sunt:

    a) proiecia cavalier, pentru care r = 1 b) proiecia cabinet, pentru care r =

    Proiecii oblice ale cubului unitate. (a) Proiecia cavalier cu direcia de proiecie ( 3 /2, 1/2, 1) (b) Proiecia cabinet cu direcia de proiectie ( 3 /4, 1/4, 1)

    n proiecia cavalier, direcia de proiecie face un unghi de 450 cu planul de proiecie, astfel nct proiecia unui segment de dreapt perpendicular pe planul de proiecie are aceeai lungime ca i segmentul nsui.

    n proiecia cabinet, direcia de proiecie face un unghi de arctg(2)63.40 cu planul de proiecie, astfel nct segmentele perpendiculare pe planul de proiecie se proiecteaz cu 1/2 din lungimea lor real.

    Dintre proieciile oblice, proiecia cabinet ofer imaginile cele mai realiste.

    Proiectia paralel oblic pe planul z=0 (xOy)

    Notm cu P'(x',y',z'), unde z=0, punctul rezultat prin proiecia perspectiv a punctului P(x,y,z) n planul z=0 dup direcia dat de vectorul v=ai+bj+ck.

    Coordonatele punctului P' se pot afla scriind ecuaia dreptei 3D ce trece prin P i este paralel cu

    vectorul v: a

    xx -'=

    byy -'

    =

    c

    zz -'. Cum z=0 se obine

    -=

    -=

    c

    bzyyc

    azxx

    '

    '

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    28

    MATRICE DE TRANSFORMARE DE MODELARE N OPENGL

    Pe scurt, n OpenGL exist urmtoarele tipuri de transformri: - vizualizare, care specific localizarea punctului de vizualizare (observatorul), implicit

    observatorul este plasat n originea sistemului de cordonate (0,0,0) i cu privirea ctre axa negativ Oz (ctre interiorul monitorului);

    - modelare, care mut obiectele de-a lungul scenei; - modelare-vizualizare, care descrie dualitatea transformrilor de vizualizare modelare; - proiecie, care decupeaz i dimensioneaz volumul de vizualizare i proiecteaz obiectele din

    volumul de vizualizare pe fereastra de vizualizare; - viewport, care mapeaz coordonatele de ieire finale n coordonate ale ferestrei de redare.

    Transformrile de vizualizare-modelare (MODELVIEW) conduc de fapt la acelai lucru n ceea ce privete apariia desenului. De exemplu, se obine aceeai scena dac se mut un obiect mai n spate sau dac se mut sistemul de referin mai n fa. Termenul de modelview este folosit pentru a specifica dac ne referim la aceast transformare ca fiind o transformare de modelare sau o transformare de vizualizare, dar ambele sunt transformari de modelview.

    Matricea de vizualizare a modelului este o matrice 4 4 ce transform sistemul de coordonate utilizat pentru plasarea obiectelor din desen. Punctele 3D (vertices) ce se folosesc n cadrul primitivelor sunt vectori coloan, care se nmultesc cu matricea Modelview pentru a se obine noile coordonate ale punctului conform acestei transformri n raport cu sistemul de coordonate al observatorului. Punctele 3D sunt de fapt vectori coloan cu 4 componente, a patra componenta fiind valoarea w, ce reprezint factorul de scala (care implicit are valoarea 1).

    OpenGL are cteva funcii ce permit realizarea transformrilor geometrice 3D (precum translaia, scalarea, rotaia) care transform poziia punctelor ulterior specificate cu glVertex*.

    nainte de folosirea transformrilor, se folosete funcia:

    glMatrixMode(GL_MODELVIEW);

    specific faptul c mai departe se va lucra cu matrice de modelare (care poziioneaz un obiect undeva n lumea specificat anterior) sau vizualizare sau proiecie i eventual cu stiva de matrice de modelare. Funcia glMatrixMode are prototipul

    void glMatrixMode(Glenum mode),

    unde mode poate fi GL_MODELVIEW, GL_PROJECTION sau GL_TEXTURE. Matricele de modelare i cele de proiecie influeneaz mpreun poziia obiectelor. Funcia

    glLoadIdentity();

    are prototipul void glLoadIdentity(void) i iniializeaz/nlocuiete matricea de modelare omogen M cu matricea identitate 4*4 (MI4).

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    29

    Funcia

    glTranslatef(dx,dy,dz);

    are prototipul void glTranslatef(GLfloat dx, GLfloat dy, GLfloat dz) i realizeaz actualizarea matricei curente M MT(dx,dy,dz) i implicit translaia obiectelor (apelate ulterior) cu dx pe axa Ox, dy pe axa Oy i dz pe axa Oz (sau altfel spus, mut originea sistemului n punctul (dx, dy, dz)), unde T(dx,dy,dz) este matricea 4*4:

    T(dx, dy, dz) =

    1000100010001

    dzdydx

    .

    O variant a acestei funcii este glTranslated(GLdouble dx,GLdouble dy,GLdouble dz). Pentru a salva sau a restaura sistemul de coordonate netranslatat se poate apela glPushMatrix, respectiv glPopMatrix.

    Funcia

    glRotatef(,a,b,c);

    are prototipul void glRotatef(GLfloat , GLfloat a, GLfloat b, GLfloat c) i realizeaz actualizarea matricei curente M MR(a,b,c)() i implicit realiznd rotaia cu unghi (dat n grade) n sens trigonometric a obiectelor (apelate ulterior) n jurul versorului (a, b, c) sau, altfel spus, n jurul dreptei ax + by + cz=0. Cazuri particulare:

    R(1,0,0)()=Rx()=

    aa

    a-a

    10000cossin00sincos00001

    = matricea coresp. rotaiei n jurul axei Ox cu unghiul

    R(0,1,0)()=Ry()=

    aa

    a-a

    10000cos0sin00100sin0cos

    = matricea coresp. rotaiei n jurul axei Oy cu unghiul

    R(0,0,1)()=Rz()=

    aa

    a-a

    1000010000cossin00sincos

    = matricea coresp. rotaiei n jurul axei Oz cu unghiul

    O variant a acestei funcii este glRotated(GLdouble , GLdouble a, GLdouble b, GLdouble c). Pentru a salva sau a restaura sistemul de coordonate nerotit se poate apela glPushMatrix, respectiv glPopMatrix.

    Funcia

    glScalef(sx,sy,sz);

    are prototipul void glScalef(GLfloat sx, GLfloat sy, GLfloat sz) i realizeaz actualizarea matricei curente M MS(sx,sy,sz) i implicit scalarea obiectelor (apelate ulterior) cu sx pe axa Ox, sy pe axa Oy i sz pe axa Oz (sau altfel spus, mut originea sistemului n punctul (sx, sy, sz)), unde S(sx,sy,sz) este matricea 4*4:

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    30

    S(sx, sy, sz) =

    1000000000000

    sz

    sysx

    .

    O variant a acestei funcii este glScaled(GLdouble sx,GLdouble sy,GLdouble sz). Pentru a salva sau a restaura sistemul de coordonate netranslatat se poate apela glPushMatrix, respectiv glPopMatrix.

    OpenGL nu are funcii speciale pentru transformrile de oglindire/reflexia sau forfecare (engl., shearing). Oglindirea reprezint obinerea imaginii oglin fa de un anumit plan. Oglindirea fa de planele de coordonate se poate realiza cu glScalef; de exemplu

    glScalef(-1.0, 1.0, 1.0); realizeaz oglindirea fa de planul yOz prin schimbarea semnului coordonatei x. n general, funcia glScalef poate fi folosit pentru a obine anumite transformri de oglindire sau forfecare. De asemenea, OpenGL include funcii ce permit iniializarea matricei curente cu o matrice omogen arbitrar 4*4 dup dorin, cu coordonate de tip float:

    void glLoadMatrixf(GLfloat *m); void glLoadMatrixd(GLdouble *m);

    ce realizeaz iniializarea/nlocuirea matricei curente cu matricea m, 4*4, cu elementele scrise n ordine pe coloane (M m). Simlilar,

    void glMultMatrixf(GLfloat *m); void glMultMatrixd(GLdouble *m);

    ce realizeaz nmulirea matricei curente cu matricea m, 4*4 (M Mm).

    Uneori putem avea nevoie s definim o transformare nu fa de cea de dinaintea ei, ci fa de una mai veche. De exemplu, pentru a desena o main, desenam caroseria, apoi aplicm o translaie i desenm prima roat. Pentru a desena celelalte roi, poate ne este mai uor s calculm poziia lor fa de main, nu fa de prima roata. OpenGL ne ofer o posibilitate de a face acest lucru. Exist o stiv de matrice n care se pot memora matrice de transformare sau proiecie.

    n momentul n care apelm

    glPushMatrix();

    matricea curent este salvat n stiv. Apoi putem s modificm i s folosim matricea curent. Cnd vrem s ne ntoarcem la transformarea pstrat n stiv apelm

    glPopMatrix();

    cnd se extrage vrful stivei care se reine n matricea curent. Singurul lucru la care trebuie s fim ateni este s nu apelm glPopMatrix dac nu avem nici o matrice n stiv i, respectiv, s nu depim capacitatea stivei. Desi exist implementari care ofer stive foarte mari sau chiar nelimitate, standardul prevede o stiv de 32 de matrice de transformare (modelare-vizualizare) i o stiv de 2 matrice de proiecie.

    Exemplu: S considerm funcia OpenGL void Triunghi() { glBegin(GL_LINE_LOOP); glVertex3f(0.0f, 1.0f,0.0f); glVertex3f(1.0f, -1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f); glEnd(); }

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    31

    Secvena urmtoare are ca efect transformarea triunghiului: glMatrixMode(GL_MODELVIEW); //vom lucra cu matrice de modelare glLoadIdentity(); //initial, M = I4 glTranslatef(1.0,3.0,0.0); //M=M*T(1,3,0) //se translateaza cu 1 unitate pe Ox si 3 pe Oy glRotatef(-90.0,0.0,0.0,1.0); //M=M*R(90) //-90 grade => in sensul acelor de ceasornic //in jurul lui Oz => in planul XOY Triunghi(); //deseneaza triunghiul in noua pozitie

    Pentru a obine transformarea:

    se poate folosi secvena de cod: glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //M=I4 glRotatef(theta,0,0,1); //M=M*R() => varful in sus, rotit cu theta grade in sens trig. glTranslatef(l,0,0); //M=M*T() glPushMatrix(); //se salveaza M in stiva glTranslatef(0,r,0); //M=M*T(0,r,0) Triunghi(); //triunghiul de sus glPopMatrix(); //se revine la pozitia specificata de vf. stivei glRotatef(180.0,0,0,1); //M=M*R(180) glTranslatef(0,r+1,0); //M=M*T(0,r+1) Triunghi();

    Exemplu:

    glTranslatef(0.0f, 10.0f, 0.0f); // 10 unitati in sus pe Oy auxSolidSphere(1.0f); // desenez prima sfera glTranslatef(10.0f, 0.0f, 0.0f); // 10 unitati in dreapta pe Ox auxSolidSphere(1.0f); // desenez a doua sfera

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    32

    Exemplu:

    glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f, 10.0f, 0.0f); // 10 unitati in sus pe Oy auxSolidSphere(1.0f); // desenez prima sfera

    glLoadIdentity(); // Resetez matricea de modelare glTranslatef(10.0f, 0.0f, 0.0f); // 10 unitati in dreapta pe Ox auxSolidSphere(1.0f) // desenez a doua sfera

    Volumul de vedere (clipping volume)

    Ochiul uman poate observa toate obiectele situate in interiorul unui con de vedere.

    n aplicaiile grafice, se nlocuiete conul de vedere cu o piramid de vedere. Astfel, se poate imagina c observatorul (aparatul de filmat) privete lumea printr-o fereastr dreptunghiular decupat printr-un plan opac, situat la o anumit distan de observator.

    Dac pentru construirea unei imagini n dou dimensiuni sunt necesare specificarea unei ferestre i a unei zone de lucru (viewport), n trei dimensiuni sunt indicate: - un volum de vedere, - un tip de proiecie pe un plan, - o fereastra n acel plan i - o zona de lucru pe suprafaa de vizualizare (desktop). Coninutul volumului de vedere este proiectat n fereastra din planul de proiecie i apoi este transferat n zona de lucru.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    33

    Volumul de vedere. (a) Cazul proieciei perspective (b) Cazul proieciei paralele

    Volumul de vedere mrginete acea poriune din spaiul lumii reale care va fi proiectat pe planul de proiecie. Acesta este definit astfel: 1. n proiecia perspectiv, este ca o piramid semi-infinit cu vrful n centrul de proiecie i cu

    laturile trecnd prin colurile planului de proiecie; 2. n proiecia paralel (n caz particular, ortogonal), este ca un paralelipiped infinit cu laturile

    paralele cu direcia de proiecie.

    Pentru a limita numrul de primitive grafice proiectate n planul de proiecie, aceste volume sunt transformate n corpuri finite prin introducerea a dou plane de limitare, paralele cu planul de proiecie, n fa i n spatele acestuia, aflate la distane bine definite de-a lungul normalei la planul de proiecie. Astfel se obine un trunchi de piramid, respectiv un paralelipiped.

    n urma transformrii de normalizare a volumului de vedere, planele ce definesc frontiera noului volum, numit volum de vedere canonic, sunt: - pentru proiecia paralel: x = 1, x = 1, y = 1, y = 1, z = 0, z = 1; - pentru proiecia perspectiv: x = 1, x = 1, y = 1, y = 1, z = zmin, z = 1;

    Proiecii ale volumului de vedere canonic (a) Cazul proieciei perspective (b) Cazul proieciei paralele

    Volumul de vedere canonic din proiecia perspectiv poate fi transformat n volumul de vedere canonic din proiectia paralel astfel: unui punct (x, y, z) din interiorul trunchiului de piramid i corespunde un punct (x, y, z) din interiorul paralelipipedului prin relaiile

    z

    xx -= ,

    z

    yy -= , 1min

    min

    +

    -

    =

    z

    zzz .

    Matricea corespunztoare indic o transformare perspectiv. Astfel, pentru construirea imaginii prin proiecie perspectiv a unui corp 3D se poate proceda n dou moduri:

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    34

    (a) se proiecteaz fiecare punct component, noile puncte componente fiind stocate separat; (b) se aplic corpului transformarea perspectiv care l deformeaz astfel nct proiecia paralel a

    corpului obinut s coincid cu proiecia perspectiv a obiectului iniial. n acest fel, imaginea va fi stocat n memorie prin chiar coordonatele x i y ale punctelor implicate. Se proiecteaz ortogonal corpul obinut.

    Volumele de vedere asociate specificrii clasice sunt prezentate n figura urmtoare

    (a) Elementele caracteristice ale proieciei n specificarea clasic (b)Volumul de vedere n proiecia paralel (c) Volumul de vedere n proiecia perspectiv

    Definirea volumului de vedere n OpenGL:

    Un alt efect al funciei ModificaDimensiune() este redefinirea volumului de vedere pentru ca dreptunghiul s rmn ptrat. Aspect ratio reprezint raportul dintre numrul de pixeli pe unitate de lungime pe vertical i numrul de pixeli de pe unitate de lungime pe orizontal.

    Dac un viewport nu este ptrat i se face transformarea aici a unui volum de vedere ptrat, se va ajunge la o imagine distorsionat. Astfel c ptratul nostru va fi ptrat doar dac fereastra va fi modificat, dar cu lungimea egal cu nlimea.

    Se poate folosi o proiecie ortografic (paralel ortogonal). Comanda OpenGL corespunztoare acestei proiecii este:

    void glOrtho(GLdouble stanga, GLdouble dreapta, GLdouble jos, GLdouble sus, GLdouble aproape, GLdouble departe);

    n spatiul cartezian 3D, valorile stanga i dreapta reprezint coordonatele minime i maxime de pe axa Ox; jos i sus sunt cele corespunztoarele de pe axa Oy, iar aproape i departe pentru axa Oz aceste valori sunt negative dac planul de proiecie este n spatele punctului de vizualizare.

    nainte de a se face proiecia ortogonal trebuie apelat comanda glLoadIdentity(). Aceasta pentru c glOrtho() modifica volumul de vedere prin nmulirea matricei curente (care este I3) cu matricea descris de volumul de vedere curent dat de argumentele sale. glLoadIdentity() servete ca resetare a sistemului de coordonate la unitate nainte de orice manipulare de matrice.

    Funcia gluOrtoho2D() este echivalent cu glOrtho() cu valori de 0 i 1 pentru aproape i departe.

    Al doilea tip de proiecie din OpenGL este proiecia perspectiv. Volumul de vizualizare are forma unui triunchi de piramid (engl, frustum), cnd obiectele care sunt mai deprtate de poziia de vizualizare (poziia aparatului de fotografiat) apar mai mici.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    35

    Poziia implicit de vizualizare este (0,0,0), privind spre axa z negativ. n OpenGL exist dou funcii care pot specifica o proiecie perspectiv. Ele sunt apelate

    atunci cnd este setat stiva i matricea curent de proiecie (cu glMatrixMode(GL_PROJECTION)).

    void gluPerspective(Gldouble fogy, Gldouble aspect, Gldouble near, Gldouble far); //funcie GLU - fogy = unghiul cmpului de vizualizare (n grade, ntre 0.0 i 180.0) n direcia axei OY. - aspect = raportul dintre w/h (lungimea i nlimea planului din fa) i va fi acelai ca pentru

    viewport pentru evitarea deformrilor. - near, far = distanele de la punctul de vizualizare la planele de decupare apropiat i deprtat

    acestea sunt valori ntotdeauna pozitive.

    void glFrustum(Gldouble stnga, Gldouble dreapta, Gldouble jos, Gldouble sus, Gldouble stnga, Gldouble dreapta); //funcie GLU - stnga, dreapta specific coordonatele pentru planele de decupare stng i drept ale bazei

    mici din volumul de vizualizare; - jos, sus specific coordonatele pentru planele de decupare jos i sus ale bazei mici din

    volumul de vizualizare; - aproape, departe specific coordonatele pentru planele de decupare apropiat i deprtat ale

    volumului de vizualizare aceste valori se dau ntotdeauna pozitive.

    Atenie: gluPerspective i glFrustum nu utilizeaz valoarea 0 pentru aproape.

    Ierarhia transformrilor

    Multe transformri sunt mai bine specificate relativ la altele. De exemplu: - drumul se specific relativ la ora; - maina se specific relativ la drum; - roile se specific relativ la main. Acestea formeaz o ierarhie a transformrilor numit deseori graful scenei. Coborrea n graful scenei este simpl i se realizeaz prin postmultiplicarea matricei curente de transformare. Dar este

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    36

    (100,100)

    (50,50)

    necesar un mecanism de revenire la sistemul de coordonate anterior. Pentru aceasta, n OpenGL, se folosete o stiv pentru aceste matrice de modelare i funciile glPushMatrix() i glPopMatrix() pentru adugarea, respectiv extragerea unei matrice n/din stiv i n funcie de aceasta actualizarea matricei curente de transformare.

    Functii GLUT pentru controlul evenimentelor de intrare:

    glutReshapeFunc( void (*f) (int width, int height) primete ca parametru un pointer la o funcie care trebuie apelat de fiecare dat cnd fereastra este redimensionat.

    glutKeyboardFunc( void (*f) (unsigned char key, int x, int y)) primete ca parametru o funcie care trebuie apelat de fiecare dat cnd se apas/elibereaz o tasta. key este valoarea ASCII. x i y reprezint poziia mouse-ului la apsarea tastei.

    glutMouseFunc( void (*f) (int buton, int stare, int x, int y) . *f va fi apelata la apasarea sau eliberarea unui buton de mouse. Parametrul buton poate fi: GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON. Parametrul state poate fi: GLUT_UP sau GLUT_DOWN. Parametrii x i y reprezint poziia mouse-ului la apariia evenimentului

    glutMotionFunc( void (*f) (int x, int y) . *f va fi apelat la deplasarea mouse-ului n timp ce un buton este apsat. Parametrii x i y reprezint poziia mouse-ului n momentul apsrii.

    //pat_trans.cpp //ptrat care se deplaseaz pe orizontal / vertical la apsarea tastelor stnga-dreapta

    #include //acesta include gl.h, glu.h si windows.h GLfloat x=0.0f;

    void CALLBACK Deseneaza() { glClearColor(1.0,1.0,1.0,1.0); //fundal alb glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); //vom lucra mai departe cu matrice de modelare (facem translatie) glLoadIdentity(); //matricea de modelare M=I4 glTranslatef(x,0.0,0.0); //Translatam fata de varianta initiala a patratului (glLoadIdentity) //si nu fata de pozitia anterioara. //Translatam patratul pe Ox cu x-ul modificat continuu fata de x-ul initial (0) glBegin(GL_QUADS); //patrat cu interiorul interpolat //altfel, glRectf(50,50,100,100); traseaza doar conturul glColor3f(1.0,0.0,0.0); //varful urmator rosu glVertex2f(50.0, 50.0); //vf.stanga-jos

    D C B A

    pop C B A

    push C C B A

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    37

    glColor3f(0.0,1.0,0.0); //vf urmator verde glVertex2f(100.0, 50.0); //vf.dreapta-jos glColor3f(0.0,0.0,1.0); //vf urmator albastru glVertex2f(100.0, 100.0);//vf.dreapta-sus glColor3f(1.0,1.0,0.0); //vf urmator galben glVertex2f(50.0, 100.0);//vf.stanga-sus glEnd(); glFlush(); } void CALLBACK ModificaDimensiune(GLsizei w, GLsizei h) { if (h == 0) h = 1; //pentru a preveni impartire la 0 glMatrixMode(GL_PROJECTION); //vom lucra cu matrice de proiectie glLoadIdentity(); //fie aceasta I4 if (w volumul de vedere: 20...160 //si eventual cu rata de aspect uniforma pe ambele axe } void CALLBACK MutaDreapta() { x+=10; //cu 10 pixeli spre dreapta } void CALLBACK MutaStanga() { x-=10; //cu 10 pixeli spre stanga } void main () { auxInitDisplayMode(AUX_SINGLE | AUX_RGB); auxInitPosition(100, 100, 400, 200); auxInitWindow("Pat. trans. pe Ox cu sagetile stanga-dreapta"); //glShadeModel(GL_FLAT); //-ar face patratul cu o singura culoare (galben) auxKeyFunc(AUX_RIGHT, MutaDreapta); auxKeyFunc(AUX_LEFT, MutaStanga); auxReshapeFunc(ModificaDimensiune); auxMainLoop(Deseneaza); }

    Funcia auxKeyFunc se apeleaz de cte ori se apas o tast.

    void auxKeyFunc(GLint key, void(*function(void));

    Primul parametru al acesteia este o constant care specific ce tast se ateapt a fi apsat. Aceasta poate fi (vezi glaux.h): AUX_RETURN, AUX_ESCAPE, AUX_SPACE, AUX_LEFT, AUX_UP, AUX_RIGHT, AUX_DOWN, AUX_A, AUX_B, ..., AUX_Z, AUX_a, AUX_b, ..., AUX_z, AUX_0, ..., AUX_9. Al doilea parametru reprezint numele funciei CALLBACK care se apeleaz la apsarea tastei specificat ca prim parametru. Imaginea din fereastr este apoi desenat.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    38

    De exemplu, tastei AUX_ESCAPE i se poate asocia o funcie (de exemplu numit inchide) ce conine instruciunea exit(0) ce se gasete n headerul ; astfel ieirea din program se poate face i cu apsarea tastei escape.

    Tem: 1) Modificai programul astfel nct i apsarea tastei sus (AUX_UP), respectiv jos

    (AUX_RIGHT), ptratul s se mite i pe vertical (=>translatare pe Oy). Atenie, pentru c dorim deplasare i pe orizontal i pe vertical, este necesar folosirea a nc unei variabile (y-ul de jos al ptratului)..

    2) n programul prezentat, se observ c dac ptratul este micat mult n stnga atunci el va iei din fereastr. Modificai programul astfel nct la apsarea tastelor ptratul s se mite pn la marginile ferestrei. Sugestie: Corpul funciei MutaStanga se va modifica astfel if(50+x-10>xmin) x-=10; //coltul initial din stanga + x pixeli translatie //+ inca 10 pixeli in stanga ar depasi val min pe x? //daca da, stam pe loc

    iar corpul funciei MutDreapta va conine secvena: if(100+x+10>xmin) x+=10;

    //coltul initial din dreapta + x pixeli translatie //+ inca 10 pixeli spre dreapta ar depasi val max pe x? //daca da, stam pe loc

    3) Modificai programul astfel nct s se translateze ptratul pe orizontal n funcie de poziia sa anterioar, nu fa de cea de la nceputul rulrii programului. Sugestie: colurile ptratului se vor considera variabile (stnga-jos: (x1,y1), dreapta-sus: (x2,y2)) se vor schimba valorile lui x1 cu un pas pe Ox (i nu ale lui x care acum poate reprezenta pasul deplasarii), iar funcia glLoadIdentity de dinaintea funciei glTranslatef dispare de aici i se pune la finalul funciei ModificaDimensiune.

    Similar cu funcia auxKeyFunc exist i auxMouseFunc:

    void auxMouseFunc(int button, mt mode, AUXMOUSEPROC func);

    unde specific ce buton al mouse-ului ar trebui apsat sau eliberat (-vezi glaux.h: AUX_LEFTBUTTON, AUX_MIDDLEBUTTON sau AUX_RIGHTBUTTON), al doilea parametru specific aciunea butonului specificat (AUX_MOUSEDOWN sau AUX_MOUSEUP), iar ultimul parametru reprezint numele funciei CALLBACK care se apeleaz n cazul specificat anterior. nc o modificare: funcia apelat va avea ca parametru AUX_EVENTREC *event; n acest parametru al funciei se returneaz poziia mouse-ului la fiecare eveniment (AUX_MOUSEUP sau AUX_MOUSEDOWN):

    typedef struct _AUX_EVENTREC { GLint data[4]; //contine datele acestui eveniment

    // data [AUX_MOUSEX] = poziia mouse-ului pe Ox //data [AUS_MOUSEYI = poziia mouse-ului pe Ox

    } AUX_EVENTREC;

    De exemplu: void CALLBACK MutaDreapta(AUX_EVENTREC *event) { x+=10; }

    auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,MutaDreapta);

    //rotire_triunghi.cpp //Triunghi ce se rotete n jurul centrului de greutate la apsarea butonului stng.

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    39

    #include

    GLfloat x1=100.0,y1=100.0,x2=200.0,y2=100.0,x3=150.0,y3=150.0; GLfloat xmin,xmax,ymin,ymax;

    void Triunghi(){ glBegin(GL_LINE_LOOP);//conturul triunghului glVertex2f(x1,y1); glVertex2f(x2,y2); glVertex2f(x3,y3); glEnd(); glBegin(GL_POINTS);//centrul de greutate glVertex2f((x1+x2+x3)/3,(y1+y2+y3)/3); glEnd(); }

    void CALLBACK Deseneaza(){ glClearColor(1.0,1.0,1.0,1.0); //fundal alb glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0,0.0,0.0); //desenez cu negru glLineWidth(3.0f); glPointSize(3.0f); Triunghi(); glFlush(); } void CALLBACK ModificaDimensiune(GLsizei w, GLsizei h){ if (h == 0) return; //pentru a preveni impartire la 0 //vom lucra cu matrice de proiectie glMatrixMode(GL_PROJECTION); glLoadIdentity(); //fie aceasta I4 if(w

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    40

    auxInitPosition(100,100,350,300); auxInitWindow("Triunghi care se roteste");

    auxReshapeFunc(ModificaDimensiune); auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,MutaTriunghi); auxMainLoop(Deseneaza); return 0; }

    Tem: - Modificai programul astfel nct s nu se tearg poziiile anterioare ale triunghiului. Sugestie:

    mutai funciile de tergere ecran, n main, imediat dup deschiderea ferestrei. - Adugai i o translaie pe Ox cu 10 uniti i lasai s se vad i poziiile anterioare. - Modificai programul astfel nct triunghiul s se roteasc n jurul centrului su de greutate

    continuu, pn la nchiderea ferestrei (se va folosi auxIdleFunc n loc de auxMouseFunc).

    /* Programul deseneaza o sfera, un con si un tor (colac) * Prin apasarea butonului stang se roteste sfera continuu pana la eliberarea butonului stang. * Similar, prin apasarea butonului drept se roteste torusul continuu pana la eliberarea butonului drept. * Iar prin apasarea butonului din mijloc (daca exista) se roteste conul * continuu pana la eliberarea butonului din mijloc. * Se pot face rotiri si pas cu pas (din 5 in 5 grade) prin apsarea tastelor: * sageata stanga (pt con), sageata dreapta (pt sfera) si sageata jos (pt tor). * La apasarea tastei Escape se iese din program. */ #include #include GLfloat unghi1=0.0f,unghi2=0.0f,unghi3=0.0f;

    GLvoid CALLBACK Deseneaza(GLvoid) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //se sterge efectiv fereastra si buferul de adancime //------ sfera -------- glPushMatrix(); //se retine in stiva matricea curenta (initial I4) glTranslatef(-0.9f,0.0f,0.0f); //in stanga axei Ox glRotatef(50.0f,1.0f,1.0f,1.0f); //pt vizibilitatea sferei se face o rotatie fata de (1,1,1) glRotatef(unghi1,1.0,0.0,0.0); //rotim cu unghi1 in jurul axei Ox //auxWireSphere(0.8); auxSolidSphere(0.8); //in noua pozitie desenez sfera, altfel ar fi fost centrata in origine glPopMatrix(); //matricea curenta se inlocuieste cu ultima matrice retinuta in stiva (de ex. I4) //coord urmatorului obiect sunt calculate fata de pozitia initiala (origine) //si nu fata de sfera //------ conul -------- glPushMatrix(); //retin acesta pozitie (I4) pt a reveni la ea pt tor glTranslatef(0.4f,-1.2f,0.0f); //un pic mai in dreapta si un pic mai in jos fata de origine glRotatef(-70.0f,1.0f,0.0f,0.0f); //se face o rotire fata de Ox pt vizibilitatea conului glRotatef(unghi2,0.0,0.0,1.0); //rotim cu unghi2 fata de axa Oz //aici desenam conul auxSolidCone(0.7,1.7); //auxWireCone(0.7,1.7); glPopMatrix(); //reinitializez matricea curenta cu pozitia anterioara retinuta in stiva (I4)

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    41

    //pt a desena torul nu fata de con ci fata de origine //------ torus -------- glPushMatrix(); //retin in stiva acesta pozitie pt a reveni la ea glTranslatef(1.4f,0.4f,0.0f);//mai in dreapta si mai in sus glRotatef(-70.0f,1.0f,0.0f,0.0f); //rotim fata de Ox pt vizibilitatea sferei glRotatef(unghi3,0.0,0.0,1.0); //se roteste cu unghi3 fata de Oz auxSolidTorus(0.3,0.5); //auxWireTorus(0.3,0.5); glPopMatrix(); //revin la pozitia anterioara (I4) auxSwapBuffers(); } GLvoid CALLBACK ModificaDimensiune(GLsizei w, GLsizei h) { if (h == 0) return; glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (wrotire continua cat timp se tine apasat butonul stang auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSEUP, Stop); //la eliberarea butonului stang nu se mai roteste auxMouseFunc(AUX_RIGHTBUTTON, AUX_MOUSEDOWN, RotTorus);

  • Grafic pe calculator (14.05.2015) Informatica, anul 1 GpC_C04

    42

    auxMouseFunc(AUX_RIGHTBUTTON, AUX_MOUSEUP, Stop); auxMouseFunc(AUX_MIDDLEBUTTON, AUX_MOUSEDOWN, RotCon); auxMouseFunc(AUX_MIDDLEBUTTON, AUX_MOUSEUP, Stop);

    auxKeyFunc(AUX_ESCAPE, Iesire); //desi cu Esc se iese oricum auxKeyFunc(AUX_LEFT, RotatieCon); //se roteste conul cu cate 5 grade auxKeyFunc(AUX_RIGHT, RotatieSfera); //se roteste sfera cu cate 5 grade auxKeyFunc(AUX_DOWN, RotatieTorus); //se roteste torul cu cate 5 grade

    auxReshapeFunc(ModificaDimensiune); auxMainLoop(Deseneaza); }