sprko-pieci, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3


  1. Temat indywidualnego zadania laboratoryjnego

  1. Wstęp

W trakcie trwania ćwiczenia laboratoryjnego nie udało mi się wykonać wszystkich punków zadania. Brakowało implementacji zmiennego nachylenia orbity względem osi X i Z oraz zmiany promienia orbity kołowej reflektora.

Dodałem kod, który umożliwia taką interakcję. Ponadto dla pełniejszego zobrazowania umieściłem w programie sekwencje instrukcji, która odpowiada za narysowanie aktualnej orbity reflektora. Dodałem także sferę która wskazuje położenie źródła światła nr 1 oraz osie układu współrzędnych.

Modyfikacje zaznaczyłem w algorytmie rozwiązania zadania pionową linią.

  1. Algorytm rozwiązania zadania - rysowanie zadanego obiektu

- kod programu

// Zmienne globalne

double katY = -20.0; // kat okreslajacy polozenie obserwatora względem osi Y

double katRX = 0.0; // kat odchylenia orbity reflektora (swiatlo nr 1) wzgledem osi X

double katRY = 0.0; // kat określający położenie reflektora (swiatlo nr 1) wzgledem osi Y

double katRZ = 0.0; // kat odchylenia orbity reflektora (swiatlo nr 1) wzgledem osi Z

double katX = 20.0; // kat okreslajacy polozenie obserwatora względem osi X

int lPionowych; // liczba pionowych podziałow bryly

int lPoziomych; // liczba piozminych podzialow bryly

double promien; // promien podstawy rysowanej bryly

double wysokosc; // wysokosc rysowanej bryly

int szerokoscOkna = 800;

Int wysokoscOkna = 600;

int lightSwitch[2]={0,0}; // tablica okreslajaca stan źrodla swiatla 0 - wylaczone, 1- wlaczone

float rRef=4; // promien orbity po ktorej porusza sie reflektor

// Tablica parametrow swiatla

GLfloat swiatlo[7][4];

GLfloat swiatlo2[7][4];

// Tablica parametrow materialu z jakiego wykonany jest walec

GLfloat material[4][4];

GLfloat material2[4][4];

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

{

double dH, dAlfa, dR;

int i, j;

int zmienna=1;

dAlfa = 360.0L/(double)nh;

dH = h/(double)nv;

dR = r/nv;

// Pocztaek tworzenia ukladu wspolrzednych

glBegin(GL_LINES);

// Os X

glColor3f(1.0, 0.0, 0.0);

glVertex3f(-20.0, 0.0, 0.0);

glVertex3f(20.0, 0.0, 0.0);

// Os Y

glColor3f(0.0,1.0,0.0);

glVertex3f(0.0, -20.0, 0.0);

glVertex3f(0.0, 20.0, 0.0);

// Os Z

glColor3f(0.0,0.0,1.0);

glVertex3f(0.0, 0.0, -20.0);

glVertex3f(0.0, 0.0, 20.0);

// Koniec tworzenia ukladu wspolrzednych

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

// Wyznaczanie wierzcholkow i wektorow normalnych powierzchni bocznych

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

{

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

{

DefiniujMaterial(zmienna);

glBegin(GL_QUADS);

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

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

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

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

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

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

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

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

glEnd();

zmienna=!zmienna;

}

r-=dR;

}

}

void UstawDomyslneWartosciParametrow(void)

{

// Tablica parametrow materialu

GLfloat param_materialu[6][4] = {

{1.0, 1.0, 0.2, 1.0}, // [0] wspolczynnik odbicia swiatla otoczenia

{1.0, 1.0, 0.0, 1.0}, // [1] wspolczynnik odbicia swiatla rozproszonego

{1.0, 1.0, 0.0, 1.0}, // [2] wspolczynnik odbicia swiatla lustrzanego

{1.0, 1.0, 0.0, 1.0}}; // [3] polysk

GLfloat param_materialu2[6][4] = {

{0.0, 0.0, 0.0, 0.0}, // [0] wspolczynnik odbicia swiatla otoczenia

{0.0, 0.0, 1.0, 1.0}, // [1] wspolczynnik odbicia swiatla rozproszonego

{0.0, 0.0, 0.0, 0.0}, // [2] wspolczynnik odbicia swiatla lustrzanego

{0.0, 0.0, 0.0, 0.0}}; // [3] polysk

// Tablica parametrow swiatla

GLfloat param_swiatla[10][4] = {

{0.0, 0.0, 0.0, 0.0}, // [0] otoczenie

{1.0, 1.0, 1.0, 0.0}, // [1] rozproszenie

{1.0, 1.0, 1.0, 0.0}, // [2] lustrzane

{0.0, 0.0, 1.0, 0.0}, // [3] polozenie

{0.0, 0.0, -1.0, 0.0}, // [4] kierunek swiecenia

{120.0, 0.0, 0.0, 0.0}, // [5] tlumienie katowe swiatla

{10.0, 0.0, 0.0, 0.0}};// [6] kat odciecia swiatla

GLfloat param_swiatla2[10][4] = {

{1.0, 1.0, 0.0, 0.8}, // [0] otoczenie

{1.0, 1.0, 0.0, 0.8}, // [1] rozproszenie

{1.0, 1.0, 0.0, 0.8}, // [2] lustrzane

{10.0, 10.0, 10.0, 0.0}, // [3] polozenie

{0.0, 0.0, -1.0, 0.0}, // [4] kierunek swiecenia

{0.0, 0.0, 0.0, 0.0}, // [5] tlumienie katowe swiatla

{0.0, 0.0, 0.0, 0.0}};// [6] kat odciecia swiatla

// Skopiowanie zawartosci tablic param_* do tablic globalnych

memcpy(material, param_materialu, 4*4*sizeof(GLfloat));

memcpy(swiatlo, param_swiatla, 7*4*sizeof(GLfloat));

memcpy(material2, param_materialu2, 4*4*sizeof(GLfloat));

memcpy(swiatlo2, param_swiatla2, 7*4*sizeof(GLfloat));

lPionowych = 8; // Liczba podzialow pionowych

lPoziomych = 4; // Liczba podzialow poziomych

promien = 1.0; // Promien walca

wysokosc = 2.0; // Wysokosc walca

glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

}

void WlaczOswietlenie(int s1, int s2)

{

// Odblokowanie oswietlenia

glEnable(GL_LIGHTING);

// Odblokowanie zerowego zrodla swiatla

if (s1==1)

{

glEnable(GL_LIGHT0);

katRY=( katRY +5)%360;

swiatlo[3][0]=rRef*cos(DEG2RAD(katRY));

swiatlo[3][1]=wysokosc/2;

swiatlo[3][2]=rRef*sin(DEG2RAD(katRY));

swiatlo[3][3]=1.0;

swiatlo[4][0]=-rRef*cos(DEG2RAD(katRY));

swiatlo[4][1]=-wysokosc/3;

swiatlo[4][2]=-rRef*sin(DEG2RAD(katRY));

swiatlo[4][3]=-1.0;

// Inicjowanie zrodla swiatla

glLightfv(GL_LIGHT0, GL_AMBIENT, swiatlo[0]);

glLightfv(GL_LIGHT0, GL_DIFFUSE, swiatlo[1]);

glLightfv(GL_LIGHT0, GL_SPECULAR, swiatlo[2]);

glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, swiatlo[5][0]);

glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, swiatlo[6][0]);

}

else glDisable(GL_LIGHT0);

if (s2==1)

{

glEnable(GL_LIGHT1);

glLightfv(GL_LIGHT1, GL_DIFFUSE, swiatlo2[1]);

glLightfv(GL_LIGHT1, GL_SPECULAR, swiatlo2[2]);

glLightfv(GL_LIGHT1, GL_POSITION, swiatlo2[3]);

}

else glDisable(GL_LIGHT1);

}

void DefiniujMaterial(int typ)

{

if(typ==0)

{

glMaterialfv(GL_FRONT, GL_AMBIENT, material[0]);

glMaterialfv(GL_FRONT, GL_DIFFUSE, material[1]);

glMaterialfv(GL_FRONT, GL_SPECULAR, material[2]);

glMaterialfv(GL_FRONT, GL_SHININESS, material[3]);

}

else

{

glMaterialfv(GL_FRONT, GL_AMBIENT, material2[0]);

glMaterialfv(GL_FRONT, GL_DIFFUSE, material2[1]);

glMaterialfv(GL_FRONT, GL_SPECULAR, material2[2]);

glMaterialfv(GL_FRONT, GL_SHININESS, material2[3]);

}

}

void WyswietlObraz(void)

{

int j;

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

UstawParametryWidoku(szerokoscOkna, wysokoscOkna);

WlaczOswietlenie(lightSwitch[0], lightSwitch[1]);

glTranslatef(0, 0, -obsR);

glRotatef(katX, 1, 0, 0);

glRotatef(katY, 0, 1, 0);

glPushMatrix();

glTranslatef(0.0, swiatlo[3][1], 0.0);

glRotatef(katRX, 1,0,0);

glRotatef(katRZ, 0,0,1);

glDisable(GL_LIGHTING);

glBegin(GL_LINES);

glColor3f(0.0,0.0,0.0);

for(j=0; j<=360.0L; j++)

{

glVertex3f(rRef*sin(DEG2RAD(j)), 0.0, rRef*cos(DEG2RAD(j)));

glVertex3f(rRef*sin(DEG2RAD(j+1)), 0.0, rRef*cos(DEG2RAD(j+1)));

}

glEnd();

glTranslatef(swiatlo[3][0], 0.0, swiatlo[3][2]);

glutWireSphere(0.25, 20, 20);

glEnable(GL_LIGHTING);

glLightfv(GL_LIGHT0, GL_POSITION, swiatlo[3]);

glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, swiatlo[4]);

glPopMatrix();

Wprowadzona modyfikacja

RysujWalec(wysokosc, promien, lPoziomych, lPionowych);

glutSwapBuffers();

}

Realizacja zadania opiera się o kod i funkcje zamieszczone powyżej.

Pierwsza procedura odpowiedzialna jest na narysowanie w scenie oświetlanego obiektu - stożek oraz osi układu współrzędnych, w odniesieniu do których łatwo ocenić aktualne położenie elementów sceny.

Funkcja przyjmuje jako parametry kolejno

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

i interpretuje w następujący sposób

1. wysokość bryły

2. promień podstawy

3. liczba podziałów pionowych

4. liczba podziałów poziomych

Wstępnie procedura rysuje układ współrzędnych

glBegin(GL_LINES);

// Os X

glColor3f(0.0, 0.0, 0.0);

glVertex3f(-20.0, 0.0, 0.0);

glVertex3f(20.0, 0.0, 0.0);

// Os Y

glColor3f(0.0,0.0,0.0);

glVertex3f(0.0, -20.0, 0.0);

glVertex3f(0.0, 20.0, 0.0);

// Os Z

glColor3f(0.0,0.0,0.0);

glVertex3f(0.0, 0.0, -20.0);

glVertex3f(0.0, 0.0, 20.0);

// Koniec tworzenia ukladu wspolrzednych

glEnd();

z wykorzystaniem trybu graficznego opartego na liniach. Łączy dwa punkty umieszczone na odpowiedniej osi. Następnie, w oparciu o techniki poznane na pierwszych ćwiczeniach laboratoryjnych, w trybie graficznym GL_QUADS wykreślam stożek

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

// Wyznaczanie wierzcholkow i wektorow normalnych powierzchni bocznych

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

{

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

{

DefiniujMaterial(zmienna);

glBegin(GL_QUADS);

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

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

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

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

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

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

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

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

glEnd();

zmienna=!zmienna;

}

r-=dR;

}

Poprzez wprowadzenie co ciała procedury zmiennej

Int zmienna=0;

której wartość ulega zmianie przy każdym obiegu wewnętrznej pętli oraz wywoływaniu w wewnętrznej pętli procedury:

DefiniujMaterial(zmienna);

Uzyskałem możliwość zmiany charaktery wykorzystywanego materiału pomiędzy dwoma. Wynikiem takiego działania jest stożek o układzie powierzchni bocznej - szachownica.

0x01 graphic

Wykorzystana procedura została opisana w dalszej części sprawozdania.

Druga procedura odpowiada za nadanie wartości początkowych parametrom określającym charakter źródeł światła i materiałów.

Parametry dla światła składają się na tablice dwu wymiarową:

GLfloat swiatlo[10][4];

gdzie pierwszy wymiar [10] określa kolejne parametry a drugi [4] i wartości w systemie RGBA. I kolejno są to:

1. GL_AMBIENT - światło otaczające (brak określonego kierunku)

2. GL_DIFFUSE - światło rozproszone (główny składnik światłą)

3. GL_SPECULAR - światło odbłysków (podobne do GL_AMBIENT)

4. GL_POSITION - określa pozycje światła (4 składowa 1.0 dla refl.)

5. GL_SPOT_DIRECTION - kierunek świecenia reflektora

6. GL_SPOT_EXPONENT - tłumienie kątowe światła (1. element, pozostałe składowe eliminowane)

7. GL_SPOT_CUTOFF - połowa kąta rozwarcia snopa światła refl. (1. element, pozostałe składowe eliminowane).

Dalej wypełniane są dwie tablice zawierające informacje o charakterze materiału, z jakiego zamodelowany będzie obiekt. Tablica materiału jest również dwuwymiarowa:

GLfloat material[4][4];

Gdzie pierwszy wymiar [4] określa parametr, natomiast drugi [4] składowe parametru. I są to:

1. GL_AMBIENT - współczynnik odbicia światła otoczenia

2. GL_DIFFUSE -współczynnik odbicia światła rozproszonego

3. GL_SPECULAR - współczynnik odbicia światła lustrzanego

4. GL_SHININESS - połysk

Kolejna funkcja odpowiada za nadawaniu parametrów światłom oraz udostępnia możliwość niezależne ich włączanie/wyłączanie. Przyjmuje dwa parametry, na podstawie których określa stan źródła światła - włączone/wyłączone. Interpretacja pierwszej zmiennej ma wpływ na światło nr 1, drugiej na nr 2. Dla wartości jeden światło jest włączone, a dla różnej od 1 wyłączone. Dla reflektora podczas włączenia światła następuje obliczanie położenia na obicie dla każdej klatki obrazu.

katRY=( katRY +5)%360;

Pozwala to na uzyskanie obrotu, ruchu po orbicie, poprzez wyznaczenie położenia z równania okręgu.

swiatlo[3][0]=rRef*cos(DEG2RAD(katRY));

swiatlo[3][1]=wysokosc/2;

swiatlo[3][2]=rRef*sin(DEG2RAD(katRY));

swiatlo[3][3]=1.0;

natomiast kierunek świecenia wyznaczany jest jako wartość przeciwna do położenia

swiatlo[4][0]=-rRef*cos(DEG2RAD(katRY));

swiatlo[4][1]=-wysokosc/3;

swiatlo[4][2]=-rRef*sin(DEG2RAD(katRY));

swiatlo[4][3]=-1.0;

Po określeniu położenia i kierunku następuje przypisanie parametrów do światła (tablica GLfloat swiatlo[10][4];)

glLightfv(GL_LIGHT0, GL_AMBIENT, swiatlo[0]);

glLightfv(GL_LIGHT0, GL_DIFFUSE, swiatlo[1]);

glLightfv(GL_LIGHT0, GL_SPECULAR, swiatlo[2]);

glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, swiatlo[5][0]);

glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, swiatlo[6][0]);

W przypadku źródła nr 2, przy włączaniu następuje jedynie określenie parametrów źródła (tablica GLfloat swiatlo2[10][4];)

glEnable(GL_LIGHT1);

glLightfv(GL_LIGHT1, GL_DIFFUSE, swiatlo2[1]);

glLightfv(GL_LIGHT1, GL_SPECULAR, swiatlo2[2]);

glLightfv(GL_LIGHT1, GL_POSITION, swiatlo2[3]);

Drugie światło, kierunkowe, określane jest za pomocą tylko czterech pierwszych parametrów. Pozostałe spowodowałyby zmianę charakteru źródła z kierunkowego na reflektor.

Kolejna procedura odpowiada za nadanie parametrów wykorzystywanemu materiałowi. Ponieważ wykorzystuje dwa rodzaje materiału funkcja pobiera parametr, po którego interpretacji nadaje parametry materiałowi. Dla wartości zero materiał ma właściwości określone przez tablice

GLfloat material[4][4

czyli żółty błyszczący. Natomiast dla parametry różnego od zera charakter materiału określa tablica

GLfloat material2[4][4];

czyli niebieski matowy.

Ostatnia funkcja umieszcza w scenie aktualną orbitę po której porusza się reflektor oraz rysuje na niej kulę, której położenie odpowiada aktualnej pozycji reflektora

glPushMatrix();

glTranslatef(0.0, swiatlo[3][1], 0.0);

glRotatef(katRX, 1,0,0);

glRotatef(katRZ, 0,0,1);

glDisable(GL_LIGHTING);

glBegin(GL_LINES);

glColor3f(0.0,0.0,0.0);

for(j=0; j<=360.0L; j++)

{

glVertex3f(rRef*sin(DEG2RAD(j)), 0.0, rRef*cos(DEG2RAD(j)));

glVertex3f(rRef*sin(DEG2RAD(j+1)), 0.0, rRef*cos(DEG2RAD(j+1)));

}

glEnd();

glTranslatef(swiatlo[3][0], 0.0, swiatlo[3][2]);

glutWireSphere(0.25, 20, 20);

glEnable(GL_LIGHTING);

glLightfv(GL_LIGHT0, GL_POSITION, swiatlo[3]);

glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, swiatlo[4]);

glPopMatrix();

Wstępnie dokonywana jest rotacja układu współrzędnych względem środka orbity - pozwala to na uzyskanie efektu zmiany kąta orbity reflektora względem odpowiednio osi X i Z. Wyłączam światło, żeby nie miało wpływy na kolor rysowanej orbity. Dalej rysuje orbitę - linie łączące ramiona kąta o wartości 1° w odległości równej promieniowi orbity od jej środka.

Translacja pozwala mi się przesunąć na orbitę, do miejsca, gdzie aktualnie znajduje się reflektor. W tym punkcie rysuje sferę wykorzystując wbudowaną funkcję OpenGL.

0x01 graphic

Włączam wyłączone światło i ustawiam pozycje oraz kierunek świecenia reflektora poprzez jego odpowiednie parametry.

Dalej wywołują procedurę rysującą stożek. Otrzymuje pełną scenę (brak oświetlenia):

0x01 graphic

Poprzez interaktywnie rozwiązane niezależne włączanie świateł

case '1':

if (lightSwitch[0]==0) lightSwitch[0]=1;

else lightSwitch[0]=0;

break;

case '2':

if (lightSwitch[1]==0) lightSwitch[1]=1;

else lightSwitch[1]=0;

break;

umieszczone w procedurze obsługującą klawiaturę otrzymuje następujące efekty

0x01 graphic

włączone światło nr 1

reflektor

0x01 graphic

włączone oświetlenie nr 2

kierunkowe (10,10,10)

0x01 graphic

włączone oświetlenie

nr 1 oraz nr 2

Poniższe rysunki obrazują zmianę promienia orbity reflektora. Obywa się to poprzez zmianę wartości zmiennej w procedurze obsługującej klawiaturę:

case 'R':

case 'r':

rRef=(rRef<30) ? rRef+0.1 : 30;

break;

case 'F':

case 'f':

rRef=(rRef>wysokosc/2) ? rRef-0.1 : wysokosc/2;

break;

Oraz obliczanie położenia reflektora dla każdej klatki animacji w procedurze odpowiedzialnej za sterowaniem światłem.

0x01 graphic

0x01 graphic

Interaktywna zmiana kąta nachylenia orbity do osi Z

0x01 graphic

0x01 graphic

Interaktywna zmiana kąta nachylenia orbity do osi X

0x01 graphic

0x01 graphic

  1. Kod źródłowy programu

#include <math.h>

#include <string.h>

#include <stdio.h>

#include <GL/glut.h>

#define M_PI 3.14159

// Makro przeliczajace stopnie na radiany

#define DEG2RAD(x) ((float)(x)*M_PI/180.0)

// Zmienne globalne

double katY = -20.0;

double katRX = 0.0;

double katRY = 0.0;

double katRZ = 0.0;

double katX = 20.0;

int lPionowych;

int lPoziomych;

double promien;

double wysokosc;

int szerokoscOkna = 800;

int wysokoscOkna = 600;

int lightSwitch[2]={0,0};

int obrot;

float rRef=4;

int obsR=10;

GLfloat swiatlo[7][4];

GLfloat swiatlo2[7][4];

GLfloat material[6][4];

GLfloat material2[6][4];

void UstawDomyslneWartosciParametrow(void);

void WlaczOswietlenie(int, int);

void DefiniujMaterial(int);

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

void UstawParametryWidoku(int szer, int wys);

void RysujNakladke(void);

void WyswietlObraz(void);

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

void ObslugaKlawiszySpecjalnych(int klawisz, int x, int y);

void UstawDomyslneWartosciParametrow(void)

{

GLfloat param_materialu[6][4] = {

{1.0, 1.0, 0.0, 1.0}, // [0] wspolczynnik odbicia swiatla otoczenia

{1.0, 1.0, 0.0, 1.0}, // [1] wspolczynnik odbicia swiatla rozproszonego

{1.0, 1.0, 0.0, 1.0}, // [2] wspolczynnik odbicia swiatla lustrzanego

{1.0, 1.0, 1.0, 1.0}, // [3] polysk

{0.0, 0.0, 0.0, 1.0}}; // [4] kolor swiatla emitowanego

GLfloat param_materialu2[6][4] =

{

{0.0, 0.0, 0.0, 0.0}, // [0] wspolczynnik odbicia swiatla otoczenia

{0.0, 0.0, 1.0, 1.0}, // [1] wspolczynnik odbicia swiatla rozproszonego

{0.0, 0.0, 0.0, 0.0}, // [2] wspolczynnik odbicia swiatla lustrzanego

{0.0, 0.0, 0.0, 0.0}, // [3] polysk

{0.0, 0.0, 0.0, 0.0}}; // [4] kolor swiatla emitowanego

GLfloat param_swiatla[7][4] = {

{0.0, 0.0, 0.0, 0.0}, // [0] otoczenie

{1.0, 1.0, 1.0, 0.0}, // [1] rozproszenie

{1.0, 1.0, 1.0, 0.0}, // [2] lustrzane

{0.0, 0.0, 1.0, 0.0}, // [3] polozenie

{0.0, 0.0, -1.0, 0.0}, // [4] kierunek swiecenia

{10.0, 0.0, 0.0, 1.0}, // [5] tlumienie katowe swiatla

{10.0, 0.0, 0.0, 0.0}};// [6] kat odciecia swiatla

GLfloat param_swiatla2[7][4] = {

{1.0, 1.0, 0.0, 0.8}, // [0] otoczenie

{1.0, 1.0, 0.0, 0.8}, // [1] rozproszenie

{1.0, 1.0, 0.0, 0.8}, // [2] lustrzane

{10.0, 10.0, 10.0, 0.0}, // [3] polozenie

{0.0, 0.0, -1.0, 0.0}, // [4] kierunek swiecenia

{0.0, 0.0, 0.0, 0.0}, // [5] tlumienie katowe swiatla

{0.0, 0.0, 0.0, 0.0}};// [6] kat odciecia swiatla

memcpy(material, param_materialu, 5*4*sizeof(GLfloat));

memcpy(swiatlo, param_swiatla, 7*4*sizeof(GLfloat));

memcpy(material2, param_materialu2, 5*4*sizeof(GLfloat));

memcpy(swiatlo2, param_swiatla2, 7*4*sizeof(GLfloat));

lPionowych = 8; // Liczba podzialow pionowych

lPoziomych = 4; // Liczba podzialow poziomych

promien = 1.0; // Promien walca

wysokosc = 2.0; // Wysokosc walca

glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

}

void WlaczOswietlenie(int s1, int s2)

{

glEnable(GL_LIGHTING);

if (s1==1)

{

glEnable(GL_LIGHT0);

obrot=(obrot+5)%360;

obrot=45;

swiatlo[3][0]=rRef*cos(DEG2RAD(obrot));

swiatlo[3][1]=wysokosc/2;

swiatlo[3][2]=rRef*sin(DEG2RAD(obrot));

swiatlo[3][3]=1.0;

swiatlo[4][0]=-rRef*cos(DEG2RAD(obrot));

swiatlo[4][1]=-wysokosc/3;

swiatlo[4][2]=-rRef*sin(DEG2RAD(obrot));

swiatlo[4][3]=-1.0;

glLightfv(GL_LIGHT0, GL_AMBIENT, swiatlo[0]);

glLightfv(GL_LIGHT0, GL_DIFFUSE, swiatlo[1]);

glLightfv(GL_LIGHT0, GL_SPECULAR, swiatlo[2]);

glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, swiatlo[5][0]);

glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, swiatlo[6][0]);

}

else glDisable(GL_LIGHT0);

if (s2==1)

{

glEnable(GL_LIGHT1);

glLightfv(GL_LIGHT1, GL_DIFFUSE, swiatlo2[1]);

glLightfv(GL_LIGHT1, GL_SPECULAR, swiatlo2[2]);

glLightfv(GL_LIGHT1, GL_POSITION, swiatlo2[3]);

}

else glDisable(GL_LIGHT1);

}

void DefiniujMaterial(int typ)

{

if(typ==0)

{

glMaterialfv(GL_FRONT, GL_AMBIENT, material[0]);

glMaterialfv(GL_FRONT, GL_DIFFUSE, material[1]);

glMaterialfv(GL_FRONT, GL_SPECULAR, material[2]);

glMaterialfv(GL_FRONT, GL_SHININESS, material[3]);

glMaterialfv(GL_FRONT, GL_EMISSION, material[4]);

}

else

{

glMaterialfv(GL_FRONT, GL_AMBIENT, material2[0]);

glMaterialfv(GL_FRONT, GL_DIFFUSE, material2[1]);

glMaterialfv(GL_FRONT, GL_SPECULAR, material2[2]);

glMaterialfv(GL_FRONT, GL_SHININESS, material2[3]);

glMaterialfv(GL_FRONT, GL_EMISSION, material2[4]);

}

}

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

{

double dH, dAlfa, dR;

int i, j;

int zmienna=1;

dAlfa = 360.0L/(double)nh;

dH = h/(double)nv;

dR = r/nv;

glBegin(GL_LINES);

glColor3f(1.0, 0.0, 0.0);

glVertex3f(-20.0, 0.0, 0.0);

glVertex3f(20.0, 0.0, 0.0);

glColor3f(0.0,1.0,0.0);

glVertex3f(0.0, -20.0, 0.0);

glVertex3f(0.0, 20.0, 0.0);

glColor3f(0.0,0.0,1.0);

glVertex3f(0.0, 0.0, -20.0);

glVertex3f(0.0, 0.0, 20.0);

glEnd();

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

// Wyznaczanie wierzcholkow i wektorow normalnych powierzchni bocznych

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

{

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

{

DefiniujMaterial(zmienna);

glBegin(GL_QUADS);

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

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

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

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

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

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

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

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

glEnd();

zmienna=!zmienna;

}

r-=dR;

}

}

void UstawParametryWidoku(int szer, int wys)

{

szerokoscOkna = szer;

wysokoscOkna = wys;

glViewport(0, 0, szerokoscOkna, wysokoscOkna);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(40.0, (float)szerokoscOkna/(float)wysokoscOkna, 1.0, 1000.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

}

void WyswietlObraz(void)

{

int j;

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

UstawParametryWidoku(szerokoscOkna, wysokoscOkna);

WlaczOswietlenie(lightSwitch[0], lightSwitch[1]);

glTranslatef(0, 0, -obsR);

glRotatef(katX, 1, 0, 0);

glRotatef(katY, 0, 1, 0);

glPushMatrix();

glTranslatef(0.0, swiatlo[3][1], 0.0);

glRotatef(katRX, 1,0,0);

glRotatef(katRZ, 0,0,1);

glDisable(GL_LIGHTING);

glBegin(GL_LINES);

glColor3f(0.0,0.0,0.0);

for(j=0; j<=360.0L; j++)

{

glVertex3f(rRef*sin(DEG2RAD(j)), 0.0, rRef*cos(DEG2RAD(j)));

glVertex3f(rRef*sin(DEG2RAD(j+1)), 0.0, rRef*cos(DEG2RAD(j+1)));

}

glEnd();

glTranslatef(swiatlo[3][0], 0.0, swiatlo[3][2]);

glutWireSphere(0.25, 20, 20);

glEnable(GL_LIGHTING);

glLightfv(GL_LIGHT0, GL_POSITION, swiatlo[3]);

glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, swiatlo[4]);

glPopMatrix();

RysujWalec(wysokosc, promien, lPoziomych, lPionowych);

glutSwapBuffers();

}

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

{

switch(klawisz)

{

case '+':

obsR=(obsR<30) ? obsR+1 : 30;

break;

case '-':

obsR=(obsR>5) ? obsR-1 : 5;

break;

case 'R':

case 'r':

rRef=(rRef<30) ? rRef+0.1 : 30;

break;

case 'F':

case 'f':

rRef=(rRef>wysokosc/2) ? rRef-0.1 : wysokosc/2;

break;

case 'l':

wysokosc=(wysokosc<10) ? wysokosc+1 : 10;

break;

case 'L':

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

break;

case '1':

if (lightSwitch[0]==0) lightSwitch[0]=1;

else lightSwitch[0]=0;

break;

case '2':

if (lightSwitch[1]==0) lightSwitch[1]=1;

else lightSwitch[1]=0;

break;

case 'v':

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

break;

case 'V':

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

break;

case 'h':

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

break;

case 'H':

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

break;

case 'W':

case 'w':

katRX=(katRX>-90) ? katRX-1 : -90;

break;

case 'S':

case 's':

katRX=(katRX<90) ? katRX+1 : 90;

break;

case 'A':

case 'a':

katRZ=(katRZ>-90) ? katRZ-1 : -90;

break;

case 'D':

case 'd':

katRZ=(katRZ<90) ? katRZ+1 : 90;

break;

case 27:

exit(0);

}

}

void ObslugaKlawiszySpecjalnych(int klawisz, int x, int y)

{

switch(klawisz)

{

case GLUT_KEY_UP:

katX=(katX<90) ? katX+1 : 90;

break;

case GLUT_KEY_DOWN:

katX=(katX>0) ? katX-1 : 0;

break;

case GLUT_KEY_RIGHT:

katY=(katY<360) ? katY+1 : 0;

break;

case GLUT_KEY_LEFT:

katY=(katY>0) ? katY-1 : 360;

break;

}

}

int main(int argc, char **argv)

{

glutInit(&argc, argv);

glutInitDisplayMode (GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);

glutInitWindowPosition(100, 100);

glutInitWindowSize(szerokoscOkna, wysokoscOkna);

glutCreateWindow("Oswietlony walec");

glEnable(GL_DEPTH_TEST);

glDepthFunc(GL_LEQUAL);

glClearDepth(1000.0);

glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glClearColor (1.0, 1.0, 1.0, 0.0);

glutDisplayFunc(WyswietlObraz);

glutReshapeFunc(UstawParametryWidoku);

glutIdleFunc(WyswietlObraz);

glutKeyboardFunc(ObslugaKlawiatury);

glutSpecialFunc(ObslugaKlawiszySpecjalnych);

UstawDomyslneWartosciParametrow();

glutMainLoop();

return 0;

}

13

Copyright ©2005 Piotr Barankiewicz



Wyszukiwarka

Podobne podstrony:
sprawko-pieci, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab2
sprawozdanie oswietlenie, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3
Zadania L3 I6Y3S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3
tresc lab3 gk, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3
Zadania L3 I6Y4S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab3
SPR-ANKI, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab2
sprawozdanie3, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
KWADRYKI, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab2
OpenGl, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
Zadania L3 I6X4S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
Zadania L4 I6Y4S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
Zadania L2 I6Y3S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab2
Opała GK sprawozdanie lab4, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
Zadania L4 I6Y3S1, Studia, WAT Informatyka, s3 - GK - lab grafika komputerowa, Lab4
Zadanie IY4S1, Studia, WAT Informatyka, s3 - GK - grafika komputerowa, LAB2
Rzezba Lab4, Studia, WAT Informatyka, s3 - GK - grafika komputerowa, LAB4
GK LAB3, Studia, WAT Informatyka, s3 - GK - grafika komputerowa, LAB4
Zadania I1Y3S1, Studia, WAT Informatyka, s3 - GK - grafika komputerowa, LAB4

więcej podobnych podstron