10
Grafică pe calculator în C şi OpenGL 1 Sistemul de vizualizare OpenGL 1. Definirea proiecŃiei perspectivă şi a volumului de vizualizare În OpenGL un punct este reprezentat printr-un vector coloană. Pentru matricele 4 4 × utilizate în reprezentarea unei transformări geometrice în coordonate omogene, este utilizată convenŃia coloană majoră. Conform acestei convenŃii, fiind dat un număr de 16 valori reale, în ordinea 15 1 0 , , , a a a K , matricea corespunzătoare este: = 15 11 7 3 14 10 6 2 13 9 5 1 12 8 4 0 a a a a a a a a a a a a a a a a A . (1) Sistemul de referinŃă universal, WCS, definit în OpenGL este un sistem drept. De asemenea, sistemul de referinŃă de observare, VCS, este un sistem drept şi este definit, ca localizare şi orientare, în raport cu sistemul de referinŃă universal. Originea sistemului de referinŃă de observare, coincide cu centrul de proiecŃie (sistemul de vizualizare OpenGL constituie un caz particular al sistemului PHIGS). În sistemul de referinŃă de observare se poate defini o transformare de proiecŃie paralelă ortografică sau de proiecŃie perspectivă. OpenGL oferă funcŃii ce permit definirea proiecŃiei perspectivă pe un plan perpendicular pe axa v z a sistemului de referinŃă de observare, cu direcŃia de observare spre v z (fig.1). Fig. 1 Definirea proiecŃiei perspectivă şi a volumului de vizualizare în OpenGL AB BC D CDzfar z = v znear z = v v y v x v z v z DirecŃia de observare v O

Lab5

Embed Size (px)

DESCRIPTION

Компьютерная графика

Citation preview

  • Grafic pe calculator n C i OpenGL

    1

    Sistemul de vizualizare OpenGL

    1. Definirea proieciei perspectiv i a volumului de vizualizare

    n OpenGL un punct este reprezentat printr-un vector coloan. Pentru matricele 44 utilizate n reprezentarea unei transformri geometrice n coordonate omogene, este utilizat convenia coloan major. Conform acestei convenii, fiind dat un numr de 16 valori reale, n ordinea 1510 ,,, aaa K , matricea corespunztoare este:

    =

    151173

    141062

    13951

    12840

    aaaa

    aaaa

    aaaa

    aaaa

    A . (1)

    Sistemul de referin universal, WCS, definit n OpenGL este un sistem drept. De

    asemenea, sistemul de referin de observare, VCS, este un sistem drept i este definit, ca localizare i orientare, n raport cu sistemul de referin universal. Originea sistemului de referin de observare, coincide cu centrul de proiecie (sistemul de vizualizare OpenGL constituie un caz particular al sistemului PHIGS).

    n sistemul de referin de observare se poate defini o transformare de proiecie paralel ortografic sau de proiecie perspectiv. OpenGL ofer funcii ce permit definirea proieciei perspectiv pe un plan perpendicular pe axa vz a sistemului de referin de

    observare, cu direcia de observare spre vz (fig.1).

    Fig. 1 Definirea proieciei perspectiv i a volumului de vizualizare n OpenGL

    A

    B

    B

    C D

    C

    D zfarz =v

    znearz =v

    vy

    vx

    vz

    vz

    Direcia de observare

    vO

  • Lucrarea 5

    2

    Volumul de vizualizare n cazul proieciei perspectiv, n OpenGL, este un trunchi de piramid, DCBAABCD . Trunchiul de piramid de vizualizare (frustum), este determinat de intersecia a dou plane de vizualizare, planul apropiat i planul deprtat, cu patru plane laterale. Planul de vizualizare apropiat este i planul n care sunt proiectate toate obiectele vizibile ale scenei. Suprafaa ABCD din planul de vizualizare apropiat (planul de proiecie) constituie fereastra de vizualizare (view plane window). Prin urmare, trunchiul de piramid de vizualizare este orientat spre vz i este fi definit prin urmtoarele valori:

    (left, bottom) i (right, top): coordonatele colurilor ferestrei din planul din fa (ale ferestrei de vizualizare);

    znear: distana (ca valoare pozitiv) de la poziia observatorului la planul din fa; zfar: distana (ca valoare pozitiv) de la poziia observatorului la planul din spate.

    Funcia OpenGL care definete o proiecie perspectiv ca cea din figura 1 este: void glFrustum(GLdouble left, GLdouble right, GLdouble bottom,

    GLdouble top, GLdouble znear, GLdouble zfar);

    Colurile ferestrei 2D din planul de proiecie, (left, bottom, -znear) i (right, top, -zfar) sunt mapate pe colurile stnga-jos i dreapta-sus ale ferestrei 2D din sistemul coordonatelor de decupare, adic )1,1,1( i )1,1,1( . Matricea de proiecie este urmtoarea:

    +

    +

    +

    =

    0100

    200

    02

    0

    002

    znearzfar

    znearzfar

    znearzfar

    znearzfar

    bottomtop

    bottomtop

    bottomtop

    znear

    leftright

    leftright

    leftright

    znear

    M P . (2)

    O alt funcie care poate fi folosit pentru definirea proieciei perspectiv este: void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble znear, GLdouble zfar); Funcia gluPerspective() creeaz un volum de vizualizare la fel ca i funcia glFrustum(), dar specificarea se face n alt mod. n cazul acestei funcii volumul de vizualizare se specific prin unghiul de vizualizare n planul vvv yxO (deschiderea camerei de luat vederi), raportul

    dintre limea i nlimea ferestrei definite n planul apropiat i distanele la planul apropiat, respectiv deprtat (ca valori pozitive). Deci parametrii funciei sunt:

    fovy: unghiul de vizualizare n planul vvv yxO , care trebuie s fie n intervalul

    [ ]0.180,0.0 ; aspect: raportul lime/nlime al laturilor ferestrei din planul apropiat; acest raport

    trebuie s corespund raportului lime/nlime asociat porii de afiare. De exemplu, dac 2=aspect , atunci unghiul de vizualizare pe direcia axei vx este de dou ori mai

    mare dect cel pe direcia axei vy . Dac poarta de afiare are limea de dou ori mai

    mare dect nlimea, atunci imaginea va fi afiat nedistorsionat.

  • Grafic pe calculator n C i OpenGL

    3

    znear, zfar: distanele ntre observator i planele de decupare de-a lungul axei vz negative (se iau ca valori pozitive).

    2. Compunerea transformrilor geometrice Pentru a efectua transformri geometrice compuse nu este eficient s se calculeze

    produsul dintre matricea de reprezentare a fiecrui punct i matricele de transformri succesive. Este de preferat s se calculeze o matrice de transformare compus, care se poate aplica unuia sau mai multor obiecte. Pentru calculul matricelor de transformare compuse (prin produs de matrice) se folosete o matrice de transformare curent C i operaii de acumulare n matricea curent prin nmulire la dreapta. Rezultatul nmulirii nlocuiete coninutul matricei curente.

    De exemplu, pentru secvena de transformri n ordinea nMMM ,,, 21 K , aplicate

    obiectelor scenei, mai nti se iniializeaz matricea curent C cu matricea identitate, dup care se calculeaz matricea compus prin postmultiplicare (nmulire la dreapta) n ordine invers celei n care se aplic matricele componente.

    IC = nn MMCC ==

    11 == nnn MMMCC ......................................... 1211 MMMMMCC nn == K (3)

    121 MMMMMC nn == K

    PMMMPMP nn == 11 K

    n aceast transformare, se aplic mai nti matricea 1M punctului P . Punctului astfel rezultat

    i se aplic transformarea 2M .a.m.d . Acest mod de calcul al matricelor compuse este folosit n OpenGL.

    Matricea curent se poate iniializa cu matricea identitate prin funcia glLoadIndentity() sau cu o matrice oarecare, dat de un pointer la un vector de 16 valori consecutive, prin funcia glLoadMatrix#().

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

    Valorile din vectorul GLdouble *m (respectiv GLfloat *m) sunt atribuite n ordinea

    coloan major matricei curente. Coninutul matricei curente poate fi modificat prin multiplicare (la dreapta) cu o alt

    matrice, dat printr-un vector de 16 valori de tip double sau float utiliznd funcia glMultMatrix#().

    glMultMatrixd( const GLdouble *m);

  • Lucrarea 5

    4

    glMultMatrixf( const GLfloat *m);

    Matricea iniial C este astfel nlocuit cu produsul MC , unde M este matricea corespunztoare vectorului dat de pointerul m. Crearea unei matrice pentru o transformare elementar (translaie, scalare etc.) i nmulirea ei cu matricea curent se poate face prin apelul unei singure funcii OpenGL.

    Transformrile compuse se efectueaz prin acumularea produsului matricelor componente n matricea curent. De exemplu, transformrile de modelare din lucrarea precedent au fost implementate n OpenGL dup cum urmeaz: Transformarea )2,2,2()0,8,0(2 STM = :

    glTranslated(0,-8,0); glScaled(2,2,2);

    Transformarea )2,1,2()4/()0,0,8(3 SRTM z = : glTranslated(8,0,0); glRotated(45,0,0,1); glScaled(2,1,2);

    Transformarea )2,1,2()4/()0,0,8(4 SRTM z = glTranslated(-8,0,0); glRotated(-45,0,0,1); glScaled(2,1,2);

    3. Stivele matricelor de transformare utilizate n OpenGL

    Transformarea unui obiect din sistemul de referin local n sistemul de referin normalizat este compus din succesiunea transformrilor de modelare (instaniere) iM , de

    observare vM i de normalizare nM :

    in MMMM = v (4)

    Transformarea de instaniere iM este, n general, specific fiecrui obiect, deci se

    calculeaz pentru fiecare obiect n parte. Pentru cele mai multe din aplicaiile grafice, n care scena este observat dintr-un

    singur punct de observare, matricea de observare vM este unic pentru toate obiectele dintr-

    un cadru dat, dar se modific n cadrul urmtor (imaginea urmtoare), dac observatorul i-a schimbat poziia de observare (situaie ntlnit n grafica interactiv).

    Matricea de normalizare nM este definit de parametrii de proiecie care corespund

    sistemului grafic. Aceast matrice este o caracteristic constructiv a sistemului grafic i rmne constant pe toat perioada desfurrii programului, pentru toate obiectele i pentru toate imaginile generate. n concluzie, sunt necesare urmtoarele matrice de transformare n cursul generrii imaginilor succesive, la momentele (cadrele) K,2,1, ++ iii .

    Cadrul i : 1v iin MMMM = , pentru obiectul 1

  • Grafic pe calculator n C i OpenGL

    5

    2v iin MMMM = , pentru obiectul 2 ................................ ikin MMMM = v , pentru obiectul k ................................

    Cadrul 1+i : 11v iin MMMM = + , pentru obiectul 1

    21v iin MMMM = + , pentru obiectul 2 ................................ ikin MMMM = +1v , pentru obiectul k ................................ Pentru a eficientiza organizarea acestor operaii de transformri succesive, n OpenGL se folosesc mai multe stive de matrice de transformare, n care sunt reinute i reutilizate matricele intermediare de transformare.

    Transformrile de modelare i de observare sunt efectuate ntr-o stiv de matrice, numit stiva matricelor de modelare-vizualizare (modelview matrix stack). Transformarea de normalizare este prelucrat ntr-o stiv de matrice separat, numit stiva matricelor de proiecie (projection matrix stack). Mai exist nc o stiv de matrice pentru operaiile de texturare, numit stiva matricelor de texturare (texture matrix stack). Separarea matricelor de modelare-vizualizare i de proiecie permite execuia n paralel a operaiilor din pipeline-ul grafic al acceleratoarelor hardware care au prevzute resurse pentru astfel de prelucrri.

    Fiecare stiv de matrice se comport asemntor cu o stiv obinuit asupra creia se opereaz prin funcii de introducere (push) i extragere (pop). Aceste funcii difer foarte puin de funciile push i pop folosite n general n programare.

    n orice moment, una din cele trei stive de matrice este declarat ca stiv curent i toate operaiile cu matricele de transformare sunt adresate stivei curente. Setarea unei stivei curente se face prin apelul funciei:

    void glMatrixMode(GLenum mode);

    unde argumentul mode poate fi una din constantele simbolice GL_MODELVIEW, GL_PROJECTION sau GL_TEXTURE pentru setarea ca stiv curent a stivei de modelare-vizualizare, a stivei de proiecie sau a stivei de texturare. Matricea din vrful stivei curente este matricea curent C , cu care se efectueaz operaiile cu matrice (glLoadIdentitz(), glTranslate#(), glLoadMatrix#(), glMultMatrix#(), etc.). Operaiile efectuate cu o stiv se realizeaz prin intermediul funciilor:

    - glPushMatrix() care se apeleaz atunci cnd o matrice aflat n capul stivei trebuie salvat pentru a fi utilizat ulterior;

    - glPopMatrix() care se apeleaz atunci cnd operaiile de compunere a matricelor trebuie s continue cu o matrice aflat sub capul stivei.

    n figura 2 este ilustrat modul de acionare a funciilor glPushMatrix() i glPopMatrix().

  • Lucrarea 5

    6

    Fig. 2 Operaii cu stiva matricelor de transformare

    Stivele matricelor de transformare sunt deosebit de utile pentru redarea scenelor i a obiectelor modelate ierarhic, n care scena sau fiecare obiect este compus din mai multe subobiecte, pe mai multe nivele de ierarhie. Fiecare obiect component este definit printr-o matrice de localizare relativ la obiectul cruia i aparine (obiect printe), i instanierea acestuia se obine prin compunerea matricei de localizare proprii cu matricea de localizare a obiectului printe. n continuare prezentm modalitatea de adugare a noi obiecte a cror micare trebuie descris n raport de un obiect precedent. Presupunem c scena conine obiectele nooo ,,, 21 K ,

    aflate n micare unele fa de altele. Dorim s adugm obiectul 1+no , care se va mica n

    raport cu obiectul no (fig. 3). Considerm c matricea de transformare care permite

    localizarea i orientarea obiectului no n raport cu sistemul universal este nM , iar localizarea

    i orientarea obiectului 1+no este dat de matricea 1+nM .

    Fig. 3 Modelarea obiectelor definite ierarhic

    MC =

    M

    M

    M

    M

    M

    MC =

    M

    M

    M

    TMC =

    MC =

    M

    M

    glPushMatrix() glPopMatrix() glTranslate#()

    1+no

    y

    x

    z

    O 1o

    1+nx

    ny

    nz

    no

    1+ny

    1+nM

    nM

    1, +nnM

  • Grafic pe calculator n C i OpenGL

    7

    Putem scrie: 1,1 ++ = nnnn MMM , (5)

    unde 1, +nnM este matricea care realizeaz poziionarea obiectului 1+no n raport cu no .

    innd cont de cele de mai sus, rezult c se poate adopta urmtoarea strategie: la adugarea obiectului no se va memora (glPushMatrix()) matricea de transformare

    nM (fr a fi inclus i scalarea);

    se reface nM (glPopMatrix()) i se poziioneaz obiectul 1+no relativ la obiectul no

    (eventual se va memora matricea 1+nM , fr includerea scalrii, pentru adugarea unui

    nou obiect). 3. Aplicaii n aplicaiile urmtoare se urmrete utilizarea stivelor matricelor de transformri geometrice. Exemplul 1

    S se construiasc un bra articulat de robot, constituit din patru segmente: bra, antebra i dou degete (fig. 4).

    Fig. 4 Bra de robot Braul trebuie s se roteasc n jurul umrului (captul din stnga al primului segment) i cotului. Micrile de rotaie au loc att timp ct sunt apsate anumite taste.

  • Lucrarea 5

    8

    Indicaii. Pentru construirea celor patru segmente (bra, antebra i cele dou degete) se poate folosi scalarea unui cub, dar mai nti trebuie aplicat o transformare care s orienteze corespunztor fiecare segment. Deoarece sistemul de coordonate local al modelului (cubului) este iniial n centrul cubului, trebuie translat sistemul de coordonate local pe o muchie a cubului (sau pe una din feele cubului), altfel, rotaiile cubului se vor face fa de centrul lui i nu fa de punctul de pivotare. Dup apelul lui glTranslate#() (pentru stabilirea punctului de pivotare) i glRotate#() (pentru a pivota cubul), se va efectua translaia sistemului de coordonate n vechiul punct. Apoi cubul este scalat i trasat, n felul acesta construind primul segment (braul). Codul pentru primul segment este:

    glTranslatef (-1.0, 0.0, 0.0); glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0); glTranslatef (1.0, 0.0, 0.0); glPushMatrix();

    glScalef (2.0, 0.4, 1.0); glutWireCube (1.0);

    glPopMatrix();

    Pentru construirea celui de-al doilea segment, trebuie mutat sistemul de coordonate

    local n urmtorul punct de pivotare (rotaie). Deoarece sistemul de coordonate local al obiectului precedent a fost rotit anterior, axa x este deja de-a lungul braului. De aceea translarea de-a lungul axei x deplaseaz sistemul de coordonate n urmtorul punct de rotaie (ncheietura braului). Odat stabilit punctul de rotaie se poate utiliza acelai cod pentru trasarea celui de-al doilea segment ca i pentru primul segment. Acest procedeu poate continua pentru un numr oarecare de elemente (bra, antebra, mn, degete). glTranslatef (1.0, 0.0, 0.0); glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0); glTranslatef (1.5, 0.0, 0.0); glPushMatrix(); glScalef (3.0, 0.4, 1.0); glutWireCube (1.0); glPopMatrix();

    Folosind indicaiile de mai sus s se completeze programul de mai jos astfel nct s se realizeze funciile cerute. static int shoulder = 0, elbow = 30, finger=15; //unghiuri de rotatie GLfloat x1 = 3, x2 = 5, x3 = 1; //dimensiuni segmente GLfloat xp1 = -5; //pozitia pe x a primului punct de pivotare void init(void) { .......... } void display(void) { glClear (GL_COLOR_BUFFER_BIT); glColor3f(1, 0, 0); glPushMatrix();

  • Grafic pe calculator n C i OpenGL

    9

    //primul obiect (brat) .......... //al doilea obiect (antebrat) .......... //deget superior .......... //deget inferior .......... glPopMatrix(); glutSwapBuffers(); glFlush(); } void reshape (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h);

    //transformarea de proiectie

    glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);

    //transformarea de observare .......... } void keyboard (unsigned char key, int x, int y) { .......... glutPostRedisplay(); }

    Probleme propuse 1. Modificai problema din exemplul 1 adugnd i alte segmente la bra. De exemplu, adugai cteva degete la mn ca n fig. 5. Pivotarea se va face n jurul muchiei marginale a unui segment.

  • Lucrarea 5

    10

    Fig. 5 Bra de robot cu degete 2. S se modifice problema anterioar adugnd articulaii sferice n jurul crora s se efectueze micarea de rotaie. Observaie. n vederea adugrii de pri suplimentare la braul de robot (degete, eventual articulaii sferice pentru micarea de rotaie n jurul lor) se poate consulta programul "glutmech.cpp" sau "glutmech.exe".