gk sprawko, WAT, semestr III, Grafika komputerowa


WOJSKOWA AKADEMIA TECHNICZNA

im. Jarosława Dąbrowskiego

Laboratorium z przedmiotu

GRAFIKA KOMPUTEROWA

0x08 graphic

SPRAWOZDANIE

Z ĆWICZENIA LABORATORYJNEGO

Nr 4

Temat ćwiczenia: Modelowanie oświetlenia

Prowadzący: dr inż. Salamon Marek

Wykonał: Sebastian Cygert

Grupa: I8X4S1

Data wykonania ćwiczenia: 21.12.2009

  1. Treść zadania

W ramach ćwiczenia laboratoryjnego otrzymałem do wykonania zestaw 2:

Wykorzystując biblioteki OpenGL i GLUT napisać program przedstawiający perspektywiczny obraz obiektu o następujących parametrach:

  1. Typ obiektu: walec o zmiennej parzystej liczbie podziałów pionowych i poziomych,

  2. Właściwości materiału 1: brązowy błyszczący (widziany w białym świetle),

  3. Właściwości materiału 2: fioletowy emitujący (widziany w białym świetle),

  4. Sposób przyporządkowywania materiałów do obiektu zgodnie ze wzorem: pasy poziome z uwzględnieniem podziałów poziomych.

Obiekt należy oświetlić dwoma źródłami światła o następujących parametrach:

Źródło nr 1:

Źródło nr 2:

Program powinien umożliwiać:

    1. interaktywne, niezależne włączanie i wyłączanie źródeł światła;

    2. interaktywną zmianę liczby podziałów pionowych i poziomych bryły;

    3. interaktywną zmianę wielkości bryły;

    4. interaktywną zmianę położenia obserwatora poprzez podanie następujących parametrów:

- odległości obserwatora od środka układu współrzędnych sceny;

- kąta obrotu wokół osi OY w zakresie [00, 3600] z krokiem 10.

Oświetlony obiekt powinien zawsze znajdować się w centralnej części okna.

  1. Sposób rozwiązania zadania.

Zadania zostały zrealizowane w środowisku programistycznym Microsoft Visual Studio przy pomocy języka C#. Do poprawnego rozwiązania konieczna była umiejętność budowania brył połączona z interaktywną zmianą położenia obserwatora, liczbą podziałów pionowych i poziomych poznane na wcześniejszych zajęciach laboratoryjnych. Ponadto koniecznie było ustawienie odpowiednich właściwości oświetlenia oraz materiału.

  1. Użyte metody oraz kod źródłowy do poszczególnych poleceń.

Realizację treści zadania rozpocząłem od zdefiniowania parametrów materiałów:

//brazowy blyszczacy

const GLfloat ambient_m1[4] = { 0.8f, 0.3f, 0.3f, 1.0f };

const GLfloat diffuse_m1[4] = { 0.0f, 0.0f, 0.0f, 1.0f };

const GLfloat specular_m1[4] = { 0.8f, 0.3f, 0.3f, 1.0f };

// material nr 2 fioletowy emitujacy

const GLfloat ambient_m2[4] = { 1.0f, 0.0f, 1.0f, 1.0f };

const GLfloat diffuse_m2[4] = { 1.0f, 0.0f, 1.0f, 1.0f };

const GLfloat specular_m2[4] = { 1.0f, 0.0f, 1.0f, 1.0f };

const GLfloat emission_m2[4] = { 0.1f, 0.0f, 0.1f, 1.0f } ;

Aby odpowiednio ustawić właściwości materiału należało odpowiednio ustawiać zmienne definiowane przed 4 wartości RGBA

a) ambient określa stopień odbicia światła otaczającego;

b) diffuse - stopień rozproszenia światła rozproszonego,

c) specular - stopień odbicia światła odbitego,

d) emission -określają światło emitowane przez obiekt. Ten ostatni parametr domyślnie jest ustawiony tak, że materiał jest emitujący. Dlatego pierwsza tablica nie zawiera ustawień tego parametru.

Dobranie powyższych parametrów wymagało znajomości powyższych zmiennych. Przy znajdowaniu ustawień dla pierwszego materiału kierowałem się zasadą, która mówi, że powierzchnie błyszczące powinny mieć małe składowe parametru diffuse, zaś spore parametru specular. Materiał drugi wymagał jedynie dobrania odpowiednich wartości dla parametru emission.

Następnym krokiem było napisanie funkcji, które będą korzystały ze zdefiniowanych materiałów w celu ustawienia ich w odpowiednim momencie modelowania obiektu. Funkcje te przedstawiają się następująco:

void Material1() {

glMaterialfv(GL_FRONT, GL_AMBIENT, ambient_m1);

glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse_m1);

glMaterialfv(GL_FRONT, GL_SPECULAR, specular_m1);

glMaterialf(GL_FRONT, GL_SHININESS, 128.0f);

}

void Material2() {

glMaterialfv(GL_FRONT, GL_AMBIENT, ambient_m2);

glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse_m2);

glMaterialfv(GL_FRONT, GL_SPECULAR, specular_m2);

glMaterialf(GL_FRONT, GL_SHININESS, 10.0f);

glMaterialfv(GL_FRONT, GL_EMISSION, emission_m2);

}

Został tutaj zdefiniowany nowy parametr : GL_SHININESS. Jest on definiowany przez pojedyńczą wartość z zakresu [0, 128], która określa w jakim stopniu kąt, pod jakim obserwator widzi powierzchnię musi być zgodny z kątem lustrzanego odbicia od niej promieni świetlnych, aby widoczny był efekt odbłysku. Duże wartości powodują zawężenie obszaru występowania odbłysku. Domyślna wartość 0 sprawia, że zjawisko zachodzi zawsze.

Gdy zdefiniowane zostały już materiały mogłem przystąpic do zbudowania walca o zmiennej parzystej liczbie podziałów poziomych i pionowych ponieważ było to zadanie podobne do tego z poprzednich zajęć laboratoryjnych i nie przysporzyło większych problemów.

double dH, dAlfa;

int i, j,parzystosc=1;

// Wyznaczenie kata wyznaczajacego pojedynczy wycinek pionowy

dAlfa = 360.0L/(double)nh;

// Wyznaczenie wysokosci pojedynczego wycinka poziomego

dH = h/(double)nv;

// Wyznaczanie wierzcholkow i wektorow normalnych powierzchni bocznych

for (i = 0; floor((i+1)*dH*1.0E10) <= floor(h*1.0E10); i++)

{

glBegin(GL_TRIANGLE_STRIP);

glNormal3f(0.0, 0.0, 1.0);

glVertex3f(0.0, (i + 1)*dH, r);

glVertex3f(0.0, i*dH, r);

if (i%2 == 0) {

Material1();

parzystosc = 1;

}

if (i%2 == 1) {

Material2();

parzystosc = 0;

}

for (j = 1; j*dAlfa <= 360.0L + dAlfa; j++)

{

glNormal3f(sin(DEG2RAD(j*dAlfa)), 0.0, cos(DEG2RAD(j*dAlfa)));

glVertex3f(r*sin(DEG2RAD(j*dAlfa)), (i + 1)*dH, r*cos(DEG2RAD(j*dAlfa)));

glVertex3f(r*sin(DEG2RAD(j*dAlfa)), i*dH, r*cos(DEG2RAD(j*dAlfa)));

}

glEnd();

}

// Wyznaczenie wierzcholkow i wektorow normalnych dolnej podstawy

glBegin(GL_TRIANGLE_FAN);

glNormal3f(0.0, -1.0, 0.0);

glVertex3f(0.0, 0.0, 0.0);

for (i = 0; i * dAlfa <= 360.0L + dAlfa; i++)

{

glVertex3f(r*sin(DEG2RAD(i*dAlfa)), 0.0, r*cos(DEG2RAD(i*dAlfa)));

}glEnd();

// Wyznaczenie wierzcholkow i wektorow normalnych gornej podstawy

glBegin(GL_TRIANGLE_FAN);

glNormal3f(0.0, 1.0, 0.0);

glVertex3f(0.0, h, 0.0);

for (i = 0; i * dAlfa <= 360.0L + dAlfa; i++){

glVertex3f(r*sin(DEG2RAD(i*dAlfa)), h, r*cos(DEG2RAD(i*dAlfa)));

}

Jak widać z powyższego listingu, modelowanie walca odbywa się w trzech etapach. Najpierw tworzona jest ściana boczna. Na samym początku zewnętrznej pętli przechodzącej przez wszystkie podziały poziome, ustawiany jest materiał. To jaki zostanie wybrany, zależy od aktualnego ustawienia zmiennej mat. Wewnątrz pętli wewnętrznej, przechodzącej przez wszystkie podziały pionowe, definiowane są odpowiednie punkty (wierzchołki prostokątów). Jest ich 4, gdyż zdecydowałem się na tryb GL_QUADS.

Jednak do prawidłowego generowania efektów oświetlenia, a w szczególności określenia orientacji wierzchołków obiektów względem źródeł światła, biblioteka OpenGL wymaga definiowania wektorów normalnych (prostopadłych). Tym zajmuje się zestaw instrukcji pod koniec wewnętrznej pętli (wykorzystany jest iloczyn wektorowy).

Rysowanie podstaw odbywa się w bardzo podobny sposób. Na koniec funkcji rysującej walec znajduje się wywołanie funkcji ustawiającej światło. Jest ważne, aby wszystkie parametry ustawić tuż po narysowaniu obiektu.

Następnie należało zdefiniować parametry światła:

/reflektor

const GLfloat diffuse_s1[4] = { 1.0f, 1.0f, 0.0f, 1.0f};

const GLfloat ambient_s1[4] = { 1, 1, 0, 1 };

const GLfloat specular_s1[4] = { 1.0f, 1.0f, 0.0f, 1.0f};

const GLfloat position_s1[4] = { 0.0f, 0.0f, 1.0f, 1.0f};

const GLfloat direction_s1[4] = { 0.0f, 0.0f, -1.0f};

const GLfloat spot_direction_s1[4] = { 0.0f, 0.0f, -1.0f};

const GLfloat ambient_s2[4] = {0.8, 0, 0, 1 }; //kierunkowe

const GLfloat diffuse_s2[4] = { 0.0f, 0.0f, 1.0f, 0.8f};

const GLfloat specular_s2[4] ={ 0.0f, 0.0f, 1.0f, 0.8f};

const GLfloat position_s2[4] = { -10.0f, -5.0f, 10.0f, 1.0f};

const GLfloat spot_direction_s2[3] ={ 10.0f, 5.0f, -10.0f}; // spot direction

Zmienne boolowskie określają, czy dane źródło światła jest włączone - domyślnie oba źródła są wyłączone.

Parametr position określa położenie źródła światła, jak się okaże składowe tego parametru podane są w układzie współrzędnych sceny. Parametr spot direction to znormalizowany, trójwspółrzędny wektor określający kierunek reflektora.

Tym razem odpowiednie dobranie powyższych parametrów nie było już takie trudne. Zatem odbyło się to szybko i przeszedłem do realizacji funkcji ustawiających wyżej zdefiniowane źródła światła:

void Swiatlo1() {

glPushMatrix();

glEnable(GL_LIGHTING);

glRotatef(kat_y, 1, 0, 0);

glRotatef(kat_x, 0, 1, 0);

glRotatef(kat_z, 0, 0, 1);

glTranslatef(R_L2, R_L1, 0);

glPushMatrix();

glDisable(GL_LIGHTING);

glColor3f(1.0f, 1.0f, 0.0f);

glutSolidSphere(0.4f, 30, 30);

glEnable(GL_LIGHTING);

glPopMatrix();

glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse_s1);

glLightfv(GL_LIGHT1, GL_SPECULAR, specular_s1);

glLightfv(GL_LIGHT1, GL_POSITION, position_s1);

glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 30.0f); //kat odciecia

glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction_s1);

glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, direction_s1);

glPopMatrix();

}

void Swiatlo2() {

glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuse_s2);

glLightfv(GL_LIGHT2, GL_SPECULAR, specular_s2);

glLightfv(GL_LIGHT2, GL_POSITION, position_s2);

glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction_s2);

}

Parametry każdego ze źródła światła można modyfikować niezależnie od pozostałych źródeł światła. Służą do tego funkcje z grupy glLight, których zastosowanie widać na powyższym listingu.

Słowo komentarza należy się pierwszej funkcji. Mianowicie jak widać położenie źródła światła nr 1 zależy od pewnych zmiennych, które użytkownik może interaktywnie zmieniać. Z powyższego listingu wynika także, że reprezentacją tegoż źródła jest kula o kolorze żółtym. Parametr spot exponent to wykładnik tłumienia kątowego reflektora, zaś parametr spot cutoff to po prostu kąt odcięcia reflektora.

Na końcu przystąpiłem do obsługi funkcji klawiatury realizującej :

a) zmiana odległości obserwatora

switch(klawisz)

{

case '+': OBSERWATOR_ODLEGLOSC++;

break;

case '-': OBSERWATOR_ODLEGLOSC--;

break;

b) obrót obserwatora wokól osi OY

case 'a': OBSERWATOR_OBROT_Y++;

break;

case 'd': OBSERWATOR_OBROT_Y--;

break;

c) odległość reflektora

case 'q':

R_L2+=0.1;

break;

case 'Q':

R_L2-=0.1;

break;

d) ilośc podziałów pionowych oraz poziomych

case '3':

lPionowych = (lPionowych == LPION_MAX)? LPION_MAX : lPionowych + 2;

break;

case '#':

lPionowych = (lPionowych == LPION_MIN)? LPION_MIN : lPionowych - 2;

break;

case '4':

lPoziomych = (lPoziomych == LPOZ_MAX)? LPOZ_MAX : lPoziomych + 2;

break;

case '$':

lPoziomych = (lPoziomych == LPOZ_MIN)? LPOZ_MIN : lPoziomych - 2;

break;

e) wysokość walca

case 'w':

wysokosc = (wysokosc == WYS_MAX) ? WYS_MAX : wysokosc + 1;

break;

case 'W':

wysokosc = (wysokosc == 1) ? wysokosc : wysokosc - 1;

break;

f) promień walca

case 'p':

promien = (promien == R_MAX) ? R_MAX : promien + 1;

break;

case 'P':

promien = (promien == 1) ? promien : promien - 1;

break;

case 'r':

UstawDomyslneWartosciParametrow();

break;

case '5':

g) prędkość relfektora

if(roznica<2) roznica=roznica+0.5;

break;

case '%' :

if(roznica>1) roznica=roznica-0.5;

break;

h) kąt nachylenia reflektora

case '6':

kat_y+=0.5;

break;

case '^':

kat_y-=0.5;

break;

i) włączenie I wyłaczenie reflektora

case '2': glEnable(GL_LIGHT1);

break;

case '@': glDisable(GL_LIGHT1);

break;

j) właczenie I wyłaczęnie światła kierunkowego;

case '1': glEnable(GL_LIGHT2);

break;

case '!': glDisable(GL_LIGHT2);

break;

case 27:

exit(0);

}Jak widać obsługuje ona jedynie położenie obserwatora. Zmienne phi oraz theta wykorzystywane są w obliczeniach położenia obserwatora. Należy bowiem zauważyć, że obserwator zrealizowany został w układzie współrzędnych sferycznych (porusza się po sferze, w której środku jest obserwowany obiekt), zatem pojawienie się tych dwóch zmiennych jest naturalne.

- 7 -



Wyszukiwarka

Podobne podstrony:
Zadanie poprawkowe GK 2008, WAT, semestr III, Grafika komputerowa
gk cw1, WAT, semestr III, Grafika komputerowa
gk efekty kody, WAT, semestr III, Grafika komputerowa
sciaga z gk, WAT, semestr III, Grafika komputerowa
I Ćwiczenie 5, WAT, semestr III, Grafika komputerowa
I7X1S1 Loay Achmasiewicz, WAT, semestr III, Grafika komputerowa
I Ćwiczenie 6, WAT, semestr III, Grafika komputerowa
50, WAT, semestr III, Grafika komputerowa
Laboratorium3 PGK zadania, WAT, semestr III, Grafika komputerowa
Ogolne, WAT, semestr III, Grafika komputerowa
Zadania I7X1N1poprawkowe, WAT, semestr III, Grafika komputerowa
Zadania I7X, WAT, semestr III, Grafika komputerowa
I Ćwiczenia 4 zadania(na czysto), WAT, semestr III, Grafika komputerowa
Paulina Kot I7X1N1 sprawozdanie Lampka, WAT, semestr III, Grafika komputerowa
Grupa I7X poprawkowe, WAT, semestr III, Grafika komputerowa
Laszuk kubek, WAT, semestr III, Grafika komputerowa
Laboratorium3 PGK zadania C02C, WAT, semestr III, Grafika komputerowa
Ciuchcia, WAT, semestr III, Grafika komputerowa

więcej podobnych podstron