I7X1S1 Loay Achmasiewicz, WAT, semestr III, Grafika komputerowa


WOJSKOWA AKADEMIA TECHNICZNA

IM. JAROSŁAWA DĄBROWSKIEGO

LABORATORIUM GRAFIKI KOMPUTEROWEJ

SPRAWOZDANIE Z ĆWICZENIA LABORATORYJNEGO NR 4

Prowadzący : dr inż. Marek Salamon

Sprawozdanie wykonał : Loay Achmasiewicz

Grupa : I7X1S1

Data wykonania : 03.02.2009

Zestaw zadania : 20

  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 podzielnej przez 3 liczbie podziałów pionowych i poziomych,

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

  3. Właściwości materiału 2: żółty matowy (widziany w białym świetle),

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

  5. Sposób przyporządkowywania materiałów do obiektu zgodnie ze wzorem: pasy pionowe z uwzględnieniem podziałów pionowych.

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. Rozwiązanie Zadania.

Rozwiązanie zadania rozpocząłem od zdefiniowania parametrów oświetlenia oraz materiałów.

// Materiał fioletowy blyszczacy

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

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

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

const GLfloat emission_m1[4] = { 0, 0, 0, 0 };

// material matowy zolty

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

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

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

const GLfloat emission_m2[4] = { 0, 0, 0, 0 };

// material zielony emitujacy

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

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

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

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

//reflektor

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

const GLfloat diffuse_s1[4] = { 1, 1, 1, 1 };

GLfloat specular_s1[4] = { 1, 1, 1, 1 };

GLfloat position_s1[4] = { 0, 0, 0, 1 };

GLfloat direction_s1[4] = { -10, 0, 0 };

// swiatlo kierunkowe

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

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

GLfloat specular_s2[4] = { 1, 1, 1, 1 };

GLfloat position_s2[4] = { 10, 10, 10, 0 };

Składowe parametru ambient określa w jakim stopniu obiekt odbija światło otoczenia. Diffuse określa jaka ilość światła padającego na obiekt ulega na jego powierzchni rozproszeniu, natomiast specular - określa jaka ilość światła odbija się w sposób lustrzany. Aby uzyskać opowiedni rezultat , w materiale pierwszym należało ustawić małe wartości diffuse, a większe specular - dzięki temu otrzymujemy błyszczący materiał (dla drugiego materiału odwotnie).

Trzeci materiał tylko emituje więc ustawiony zostaje parametr emission - emitacja światła przez obiekt (domyślnie parametr ten jest wyzerowany ).

Odnośnie parametrów światła to position służy do określenia pozycji światła w przestrzeni, a direction to kierunek (wektor) w jakim świeci światło.

Następnie napisane zostały funkcje tworzące materiały i światło :

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);

glMaterialfv(GL_FRONT, GL_EMISSION, emission_m1);

}

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, 0);

glMaterialfv(GL_FRONT, GL_EMISSION, emission_m2);

}

void Material3() {

glMaterialfv(GL_FRONT, GL_AMBIENT, ambient_m3);

glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse_m3);

glMaterialfv(GL_FRONT, GL_SPECULAR, specular_m3);

glMaterialf(GL_FRONT, GL_SHININESS, 10);

glMaterialfv(GL_FRONT, GL_EMISSION, emission_m3);

}

Odpowiednio tworzące materiał 1/2/3 . W materiale pierwszym (błyszczący fiolet) parametr SHININESS ma wartosc maksymalna . Dla materiału matowego (w tym przypadku materiał nr2) powinien mieć wartość 0. Dla materiału emitującego , parametr ten jest nieistotny.

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_Light0, 0, 0);

glPushMatrix();

glDisable(GL_LIGHTING);

glColor3f(1, 1, 1);

glutSolidSphere(0.25, 20, 20);

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_LIGHT1, GL_SPOT_CUTOFF, 30);

glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, direction_s1);

glPopMatrix();

}

void Swiatlo2() {

glPushMatrix();

glTranslatef(10, 10, 10);

glPushMatrix();

glDisable(GL_LIGHTING);

glColor3f(0, 1, 0);

glutWireSphere(0.25, 20, 20);

glEnable(GL_LIGHTING);

glPopMatrix();

glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuse_s2);

glLightfv(GL_LIGHT2, GL_SPECULAR, specular_s2);

glLightfv(GL_LIGHT2, GL_POSITION, position_s2);

glPopMatrix();

}

Parametry źródeł światła mogą być modyfikowane niezależnie od innych źródeł. Język OpenGL pozwala na zdefiniowanie do 8 źródeł światła w jednej scenie. Dla każdego źródła jest domyślna nazwa GL_LIGHTn ,gdzie n od 0 do 7. Oczywiście aby zdefiniować źródło GL_LIGHT1 musi już istnieć źródło GL_LIGHT0. Aby włączyć źródło światła trzeba się posłużyć funkcja glEnable(GL_LIGHTn) , odpowiednio do wyłączenia źródła światła służy funkcja glDisable(GL_LIGHTn) (początkowo wszystkie źródła są wyłączone).

W funkcji Swiatlo1 widać , że źródło światła reprezentuje biała kula . Odpowiednio w drugiej funkcji reprezentantem jest zielona kula (nie jest to potrzebne gdyż położenie źródła jest stałe ), w przypadku oddalenia obserwatora można zauważyć owe źródło.

Funkcja tworząca walec :

void RysujWalec(double h, double r, int nv, int nh)

{

double dH, dAlfa;

int i, j;

// 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);

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

{

if (j%3 == 0) {

Material1();

} else if (j%3 ==1){

Material3();

} else {

Material2();

}

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++)

{ if (i%3 == 1) {

Material3();

} else if (i%3 ==0){

Material1();

} else

Material2();

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++){

if (i%3 == 1) {

Material3();

} else if (i%3 ==0){

Material1();

} else

Material2();

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

}

glEnd();

Swiatlo1();

Swiatlo2();

}

Funkcja rysuje walec o zadanej wysokości, promieniu oraz liczbie podziałów pionowych i poziomych. Tryb modelowania powierzchni bocznej to GL_TRIANGLE_STRIP , a podstaw to GL_TRIANGLE_FAN. Dodatkowo w zależności wyniku j%3 oraz i%3 używane są odpowiednie materiały. Jak widać funkcja powyżej również konstruuje wektory normalne , dzięki czemu oświetlenie jest generowane prawidłowo. Wektor normalny danej powierzchni to wektor do niej prostopadły. Określa on jej orientację w przestrzeni, w szczególności względem źródła światła i obserwatora. Na jego podstawie można wyznaczyć ilość światła jaka dociera do powierzchni i ilość, która w kierunku obserwatora jest od niej odbijana. W OpenGL obliczenia związane z oświetleniem wkonywane są dla wierzchołków.

  1. Wyniki działania programu.

1 2

0x01 graphic
0x01 graphic

3 4

0x01 graphic
0x01 graphic

1 - Walec bez oświetlenia.

2 - Walec oświetlany reflektorem.

3 - Walec oświetlany światłem kierunkowym (zielonym).

4 - Walec oświetlany reflektorem oraz światłem kierunkowym.

  1. Obsługa klawiatury.

Funkcja odpowiedzialna za obsługę klawiatury :

void ObslugaKlawiatury(unsigned char klawisz, int x, int y)

{

switch(klawisz)

{

case '-': OBSERWATOR_ODLEGLOSC++;

break;

case '+': OBSERWATOR_ODLEGLOSC--;

break;

case 'v': OBSERWATOR_OBROT_Y++;

break;

case 'b': OBSERWATOR_OBROT_Y--;

break;

case '4': R_Light0+=0.1;

break;

case '$': R_Light0-=0.1;

break;

case '8':

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

break;

case '*':

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

break;

case '9':

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

break;

case '(':

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

break;

case 'w':

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

break;

case 'W':

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

break;

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 '3':

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

break;

case '#' :

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

break;

case '7':

kat_y+=0.5;

break;

case '&':

kat_y-=0.5;

break;

case '1': glEnable(GL_LIGHT1);

break;

case '!': glDisable(GL_LIGHT1);

break;

case '2': glEnable(GL_LIGHT2);

break;

case '@': glDisable(GL_LIGHT2);

break;

case 27:

exit(0);

}

}

Odpowiednio klawisz 1/! Oraz 2/@ odpowiadają za włączanie i wyłączanie źródeł swiatła.

Klawisze 3/# to zmiana prędkości reflektora.

Klawisze 4/$ to zmiana promienia orbity reflektora.

Klawisze +/- to zmiana odległości obserwatora.

Klawisze v/b to obrót obserwatora względem osi Y.

Klawisze 8/* oraz 9/( odpowiadają za zmianę podziałów pionowych/poziomych walca.

Klawisze w/W oraz p/P to zmiana wysokości oraz promienia walca.

  1. Wnioski

Celem ćwiczenia było zapoznanie się z modelowaniem oświetlenia za pomocą biblioteki OpenGL.

Dla początkujących programistów mierzących się z OpenGL modelowanie oświetlenia może być dość kłopotliwe. W OpenGL przypisując obiektowi parametry materiału , tak naprawdę przypisujemy mu kolor, który owy obiekt ma odbijać. Podczas przypisywania obiektowi koloru za pomocą funkcji glColor ,tak naprawdę jedynie ustawiamy charakterystykę opisującą kolor obiektu, który nie będzie w stanie wejść w żadną reakcję ze światłem. Jest to różnica między przypisywaniem obiektowi koloru , a parametrów materiału.

W rzeczywistości kiedy obiekt jest naświetlony białym światłem, niektóre długości fali światła są pochłaniane , a reszta jest odbijana. To właśnie odbijana cześć definiuje kolor obiektu.

Dla przykładu , czerwona odbija tylko czerwone `cząstki' światła a resztę pochłania.

Pod białym światłem wszystkie przedmioty maja swój naturalny kolor ,gdyż białe światło posiada wszystkie kolory, więc obiekt ma zawsze kolor , który może odbić. Gdy tą samą czerwoną kulę naświetlimy wyłącznie niebieskim światłem , owa kula będzie dla nas koloru czarnego , gdyż w wiązce światła nie będzie koloru czerwonego , który może odbić.

Na początku podczas tworzenia programu , materiały które były definiowane wyglądały zupełnie inaczej niż powinny. Widać to na pierwszym obrazie, przykładowo , żółty kolor tak naprawdę wygląda jak zgniło zielony. Spowodowane jest to brakiem oświetlenia. Dopiero po zaimplementowaniu reflektora białego światła , byłem w stanie sprawdzić czy materiały zostały dobrze zdefiniowane. Podobna sytuacja ma miejsce podczas naświetlenia obiektu dwoma źródłami światła( w tym wypadku biały i zielony). Obiekt znacząco się różni od obiektu oświetlonego wyłącznie reflektorem. Nałożenie się na oświetlanej powierzchni efektów świecenia kilku źródeł światła powoduje, że ta powierzchnia oświetlana jest światłem o parametrach wypadkowych, powstałych z nakładających się źródeł.

Kolejną istotną kwestią są podziały pionowe i poziome. Im jest ich więcej, tym efekt oświetlenia jest bardziej realistyczny. Jednak przy bardzo dużej liczbie podziałów szybkość działania programu drastycznie spada

Podsumowując modelowanie oświetlenia za pomocą biblioteki OpenGL wymaga sporo pracy i czasu, jednakże uzyskiwane efekty są tego warte.

.



Wyszukiwarka

Podobne podstrony:
I Ćwiczenie 5, 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
Zadanie poprawkowe GK 2008, WAT, semestr III, Grafika komputerowa
gk cw1, WAT, semestr III, Grafika komputerowa
Ogolne, WAT, semestr III, Grafika komputerowa
gk efekty kody, 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
gk sprawko, WAT, semestr III, Grafika komputerowa
Przekształcenia instrukcja, WAT, semestr III, Grafika komputerowa

więcej podobnych podstron