WOJSKOWA AKADEMIA TECHNICZNA
Sprawozdanie laboratoryjne z przedmiotu
GRAFIKA KOMPUTEROWA
Wykonujący ćwiczenie: Paweł Madejski
Prowadzący: dr inż. Marek Salamon
Data wykonania: 18.11.2008r
Grupa szkoleniowa: I7X1S1
Treść zadania (zestaw 10):
Narysować ¾ walca w trybie GL_QUADS o promieniu podstawy 5, środku w punkcie (0,0,0) i wysokości 4.
Dodać funkcjonalność zmiany punktu patrzenia obserwatora, oddalenia figury, oraz zmianę dokładności rysowania figury w pionie i poziomie (równoważne z ilością linii).
Opis zadania:
Do wykonania zadania laboratoryjnego należało użyć funkcji modelowania w trójwymiarowej przestrzeni. Czyli trójargumentowe współrzędne punktów (glVertex3f(x,y,z) - x,y,z są współrzędnymi na osiach OX,OY,OZ). Do narysowania walca użyłem trzy rodzaje prymitywów: GL_TRIANGLE_FAN - rysowanie trójkątów z których wszystkie mają wspólny wierzchołek, GL_QUADS - rysowanie kwadratu, GL_LINE_STRIP - rysowanie sekwancji linii. Podstawy boczne i górne walca budujemy za pomocą prymitywu GL_TRIANGLE FUN w której to funkcji wierzchołki podstawy dolnej i górnej mają współrzędne: odpowiednio (0,0-h/2,0) i (0, 0+h/2, 0) gdzie h to wysokość walca. Zabieg taki jest konieczny gdyż to środek walca ma się znajdować w początku układu współrzędnych a nie środek jednej z jego podstaw. Reszta wierzchołków wyznaczana w pętli, gdzie po każdym obrocie wyznaczana jest współrzędna kolejnego punktu. Ściany boczne wyznaczono zgodnie z treścią zadania w trybie GL_QUADS. Do wyznaczania kolejnych punktów również użyto podobnej pętli jak w przypadku rysowania podstaw. Po narysowaniu podstaw oraz ścian bocznych należało narysować linie siatki. Te zostały wykonane za pomocą prymitywu GL_LINE_STRIP. Operacja ta została tym razem wkonana za pomocą dwóch pętli: jednej odpowiadającej za wyznaczenie odległości między kolejnymi liniami i drugiej odpowiedzialnej za wyznaczanie kolejnych współrzędnych punktów. Kiedy figura była już gotowa należało wykonać część odpowiedzialną za integrację z operatorem (ilość podziałów, rotacje oraz odległość od obserwatora). Rotację i odległość wykonano za pomocą funkcji: glTranslatef(x,y,z);
glRotatef(kąt obrotu,x,y,z);. Prawdę mówiąc w tym wypadku obserwator zostaje trochę oszukany przez program ponieważ nie zmienia się jego pozycja (działo by się tak gdybyśmy do tego celu użyli fonkcji gluLookAt()).
Wygląd działania programu przedstawiają poniższe obrazy (screeny wykonane za pomocą programu msPaint).
Rys1. Wygląd ogólny walca .
Rys.2 Walec ze zwiększoną liczbą linii siatki
Rys.3 Walec po obrocie wokół osi OY
Rys.4 Walec po obrotach wokół wszystkich 3 osi (OX,OY i OZ)
Wykonanie zadania:
Poniżej zamieszczam funkcję rysującą wcześniej opisany walec.
float i=0, j=0;
float pr = 5.0;
float h = 4.0;
//podstawa dolna
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0,0-h/2,0);
for(i=0 ; i<=KAT ; i=i+(180/a)){
glVertex3f(pr*cos(pi*i/180), 0-h/2, pr*sin(pi*i/180));
}
glEnd();;
//podstawa gorna
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0, 0+h/2, 0);
for(i=0 ; i<=KAT ; i=i+(180/a)){
glVertex3f(pr*cos(pi*i/180), 0+h/2, pr*sin(pi*i/180));
}
glEnd();
//boki
glBegin(GL_QUADS);
for(i=0 ; i<=KAT ; i=i+(180/a)){
glVertex3f(pr*cos(pi*i/180), 0-h/2 ,pr*sin(pi*i/180));
glVertex3f(pr*cos(pi*i/180), 0+h/2 , pr*sin(pi*i/180));
glVertex3f(pr*cos(pi*i/180),0-h/2 ,pr*sin(pi*i/180));
glVertex3f(pr*cos(pi*i/180), 0+h/2, pr*sin(pi*i/180));
}
glEnd();
//linie siatki poziomej
for( j=0-h/2; j<=0+h/2; j=j+h/a){
glBegin(GL_LINE_STRIP);
for(i=0 ; i<=KAT ; i=i+(180/a))
glVertex3f(pr*cos(pi*i/180), j, pr*sin(pi*i/180));
glVertex3f(0,j,0);
glVertex3f(pr,j,0);
glEnd();
}
Kod odpowiedzialny za pozycję i obrót figury umieszczony w funkcji WyświetlObraz(), kropki oznaczają pozostałe niezmieniane części bloku
void WyswietlObraz(void)
{
...
// Ustalenie polozenia obserwatora
glTranslatef(0, 0, -OBSERWATOR_ODLEGLOSC);
glRotatef(OBSERWATOR_OBROT_X, 1, 0, 0);
glRotatef(OBSERWATOR_OBROT_Y, 0, 1, 0);
glRotatef(OBSERWATOR_OBROT_Z, 0, 0, 1);
...
}
Wnioski:
Celem ćwiczeń było zapoznanie się z metodami rysowania oraz manipulowania obiektami w trójwymiarowym układzie współrzędnych za pomocą prymitywów OpenGL. Zapoznanie się z metodami rysowania obiektów daje nam wiedzę niezbędną do zrozumienia gotowych funkcji ryzujących podstawowe obiekty zawartych w bibliotece glut.h (np. do rysowania walca używamy funkcji gluCylinder()). Sprawne posługiwanie się tymi prymitywami jest bazową umiejętnością budowania obiektów i bez niej nie da się modelować w 3D. W tym przykładzie zbędne mogą się wydać linie siatki poziomej jednak będą one nam pomagały wypełniać kratki figury różnymi odcieniami koloru co pozwoli na bardziej realistyczny wygląd modelu.