Wojskowa Akademia Techniczna
Grafika Komputerowa
Sprawozdanie z pracy laboratoryjnej nr 4
Prowadz cy: mgr in . Mariusz Pazur
Data wykonania wiczenia: 15.01.2008r.
Wykonał: Karol Zalewski – I6Y3S1
1.Tre zadania
Zadanie 1
Wykorzystuj c biblioteki OpenGL i GLUT napisa program przedstawiaj cy perspektywiczny
obraz
sto ka, na który została odwzorowana dwuwymiarowa tekstura RGBA zdefiniowana
wzorcem:
Obiekt o wietlony jest białym wiatłem ze ródła reflektorowego (spot), a parametry jego
materiału maj warto ci domy lne, z wyj tkiem GL_SPECULAR, który ma przyjmowa
warto
(1.0, 1.0, 1.0, 1.0). U ytkownik powinien mie mo liwo :
1.
Zmiany rozmiarów tekstury w zakresie od 4x4 do 128x128 tekseli z zachowaniem
proporcji wzorca.
2.
Powielania tekstury w zakresie od 1 do 5 niezale nie w kierunku poziomym i
pionowym (GL_REPEAT).
3.
Zmiany metody filtrowania tekstury (GL_NEAREST, GL_LINEAR)
4.
Zmiany trybu teksturowania (GL_DECAL, GL_MODULATE, GL_BLEND)
5.
Zmiany poło enia ródła wiatła.
6.
Zmiany poło enia obserwatora poprzez podanie nast puj cych parametrów:
− odległo ci obserwatora od rodka układu współrz dnych sceny,
− wysoko ci wzgl dem płaszczyzny XZ,
− k ta obrotu wokół osi OY w zakresie [0
o
, 360
o
] z krokiem 1
o
.
O wietlony obiekt powinien zawsze znajdowa si w centralnej cz ci okna.
4a
4a
- niebieski
- ółty
2.Metoda rozwi zania zadania
Zadanie polegało na nało eniu wy ej opisanej tekstury na obiekt sto ka. Wzór
tekstury opisałem poni szym kodem:
float* GeneratorTekstury()
{
float *tekstura;
float *wskaznik;
int rozmiar = 4*size*size;
int i;
float kolor1[4] = {1.0, 1.0, 0.0, 1.0}; // ółty
float kolor2[4] = {0.0, 0.0, 1.0, 1.0}; //niebieski
tekstura = new float[rozmiar];
wskaznik = tekstura;
int numer=0;
int polowka=int(size/2);
int cwiartka=int(size/4);
int temp=size-1;
for (i=0;i<size;i++){
for (int zonk=0;zonk<size;zonk++){
if ((zonk==temp)){
*(wskaznik++) = kolor2[0];
*(wskaznik++) = kolor2[1];
*(wskaznik++) = kolor2[2];
*(wskaznik++) = kolor2[3];
}
else{
*(wskaznik++) = kolor1[0];
*(wskaznik++) = kolor1[1];
*(wskaznik++) = kolor1[2];
*(wskaznik++) = kolor1[3];
}
}
temp--;
}
return tekstura;
}
Sam tekstur oraz jej parametry zdefiniowałem poprzez funkcje
glTexImage2D(GL_TEXTURE_2D,0,param,size,size,0,GL_RGBA,GL_FLOAT,tekstura);
funkcja ta tworzy dwuwymiarow tekstur , w której nie u ywam mipmapy o szeroko ci i
wysoko ci size, bez obramowania formatu GL_RGBA oraz typu GL_FLOAT, natomiast
tekstura jest wska nikiem na tablic zawieraj c dane o teksturze.
Po nało eniu tekstury rzadko zdarza si , e jednemu pikselowi ekranu odpowiada jeden punkt
tekstury, najcz ciej zdarza si , e jednemu punktowi tekstury odpowiada kilka pikseli
obrazu (mamy wówczas do czynienia z powi kszeniem) lub jednemu pikselowi obrazu
odpowiada kilka punktów tekstury (pomniejszenie). Wówczas pojawia si problem jaki zatem
kolor przypisa pikselowi. Rozwi zaniem problemu jest filtrowanie tekstury, tak mo liwo
daje OpenGL, sposób filtracji mo na wybra przez odpowiednie dobranie parametrów funkcji
glTexParametr, w zadaniu okre lone jest, e nale y wybra jedn z dwóch metod filtracji:
GL_NEAREST lub GL_LINEAR, pierwsza z nich polega na tym, i danemu pikselowi
przyporz dkowujemy kolor punktu tekstury poło onego najbli ej rodka danego piksela,
natomiast druga metoda polega na tym, i kolor piksela obliczana jest jako rednia wa ona
obliczona na podstawie tablicy 2x2 punktów tekstury le cych najbli ej tego piksela.
Sposób filtracji w moim programie realizuj poni sze funkcje:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,tryb2);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,tryb2);
Ponadto w zadaniu powiedziane jest, e umo liwione ma by powielanie tekstury w kierunku
poziomym oraz pionowym, funkcja b d ca rozwi zaniem tego problemu przedstawiona
zostaje poni ej:
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
Parametry GL_TEXTURE_WRAP_S (okre la sposób traktowania współrz dnej
S tekstury poza
zakresem od 0.0 do 1.0) oraz
GL_TEXTURE_WRAP_T(Okre la sposób traktowania współrz dnej T
tekstury poza zakresem od 0.0 do 1.0).Mo liwymi warto ciami s :
Po zdefiniowaniu tekstury mo na przej do jej nakładania, istotnym elementem nakładania tekstury
jest
oczywi cie
uaktywnienie
tekstury,
które
odbywa
si
za
pomoc
funkcji
glEnable(GL_TEXTURE_2D)
Sam proces teksturowania polega na ustaleniu w jaki sposób poszczególne punkty tekstury zostan
przypisane poszczególnym wierzchołkom figur podstawowych.
Funkcja glTexCoord*() wywołana przed glVertex*() powoduje przypisanie odpowiednim
wierzchołkom figur podstawowych (ustalonych za pomoc funkcji glVertex*()) ustalonego
(argumenty funkcji glTexCoord*()) punktu tekstury.
W programie sto ek rysowany jest za pomoc kwadratów, w ten sposób, e ustalona jest ilo
podziałów pionowych i poziomych sto ka, zatem aby odpowiednio przypisa danym wierzchołkom
odpowiednie punkty pikseli, równie niejako dziele pionowo i poziomo tekstur , tak by
odpowiedniemu wierzchołkowi przypisa odpowiedni punkt tekstury.
Program nakładaj cy tekstur na sto ek:
double texX = 0, texY = 0, texX2=0,texY2=0;
double texS_x, texS_y;
texS_x=(float)rozx/c;
texS_y=(float)rozy/b;
int ih,iv;
int pion,poz,smash;
float x1,x2,y1,y2,z1,z2,r1,r2;
float ctg_alfa; //kšt nachylenia ciany bocznej do podstawy
float H,R;
float top_point;
H=5;
R=3;
ctg_alfa=R/H;
pion=b;
poz=c;
smash=0;
top_point=4;
for(ih=smash;ih<pion;ih++,texY+=texS_y)
{
y1=top_point-ih*H/pion;
y2=top_point-(ih+1)*H/pion;
r1=(ih*H/pion)*ctg_alfa; //r=h*ctg(alfa)
r2=((ih+1)*H/pion)*ctg_alfa;
glBegin(GL_QUAD_STRIP);
for(iv=poz;iv>=0;iv--,texX+=texS_x) {
texX2=texX+texS_x;
texY2=texY+texS_y;
x1=r1*cos(iv*2*GL_PI/poz);
z1=r1*sin(iv*2*GL_PI/poz);
x2=r2*cos(iv*2*GL_PI/poz);
z2=r2*sin(iv*2*GL_PI/poz);
glNormal3f(x1,y1,z1);
glTexCoord2f(texX, texY);
glVertex3f(x1,y1,z1);
glNormal3f(x2,y2,z2);
glTexCoord2f(texX, texY2);
glVertex3f(x2,y2,z2);
}
texX-=texS_x;
glEnd();
}
3.Wyniki
Nało ona tekstura:
Tryb GL_NEAREST:
Tryb GL_LINEAR:
Tryb GL_BLEND:
Tryb GL_DECAL:
Kod programu:
#include "stdafx.h"
#include <GL\glut.h>
#include <math.h>
#include <string.h>
#define DLUGOSC_BOKU 4.0
#define OBSERWATOR_ODLEGLOSC 20.0
#define OBSERWATOR_OBROT_X 20.0
#define OBSERWATOR_OBROT_Y -70.0
#define OBSERWATOR_FOV_Y 30.0
#define pi 3.141592
#define POT(x) (x*x)
#define LPOZ_MENU_SWIATLA 10
#define LPOZ_MENU_MATERIALU 5
#define GL_PI 3.141592
float rozx=1.0;
float rozy=1.0;
int size=32;
int pasy=2;
int tryb=GL_MODULATE;
int tryb2=GL_LINEAR;
int param=4;
bool m;
int zrodlo1 = 1; //zrodlo nr 1 wlaczone
double bok = DLUGOSC_BOKU; // Dlugosc boku szescianu
int szerokoscOkna = 800;
int wysokoscOkna = 600;
int b=14;//ilo podziałów poziomych
int c=26;//ilo podziałów pionowych
float OBO=OBSERWATOR_ODLEGLOSC;
float OBX=OBSERWATOR_OBROT_X;
float OBY=OBSERWATOR_OBROT_Y;
float OX=0,OZ=0; //kšty nachylenia orbity ródła wiatła
float wys=12;//wysokosc walca
float H=0.0;//wysokosc obserwatora
float wys_ekr=0.0;
int kat=0; //nachylenie obserwatora do plaszczyzny obiketu
float odl=sqrt(OBO*OBO-H*H);//odleglosc obserwatora
float rzs=8,hzs=0;
int kzs=0;
// Prototypy funkcji
void RysujSzescian(double a);
void UstawParametryWidoku(int szer, int wys);
void WyswietlObraz(void);
void ObslugaKlawiatury(unsigned char klawisz, int x, int y);
void UstawDomyslneWartosciParametrow(void);
double stdorad(double x);//zamian stopni na radiany
double raddost(double x);//zamian radianów na stopnie
double stdorad(double x){
return ((x*pi)/180.0);
}
double raddost(double x){
return ((180.0*x)/pi);
}
GLfloat swiatlo1[10][4];
GLfloat material1[5][4];
void UstawDomyslneWartosciParametrow(void)
{
// Tablica parametrow materialu nr 1 - bialy
GLfloat param_materialu1[5][4] = {
{1.0, 1.0, 0.0, 1.0}, // [0] współczynnik odbicia wiatła otoczenia
{1.0, 1.0, 0.0, 1.0}, // [1] współczynnik odbicia wiatła rozproszonego
{1.0, 1.0, 1.0, 1.0}, // [2] współczynnik odbicia wiatła lustrzanego
{40.0, 0.0, 0.0, 0.0}, // [3] połysk
{0.0, 0.0, 0.0, 1.0}}; // [4] kolor wiatła emitowanego
// Tablica parametrów ródła wiatła nr 1
GLfloat param_swiatla1[10][4] = {
{0.0, 0.0, 0.0, 1.0}, // [0] otoczenie
{1.0, 1.0, 1.0, 1.0}, // [1] rozproszenie
{1.0, 1.0, 1.0, 1.0}, // [2] lustrzane
{5, 0, 0, 1.0}, // [3] poło enie
{-1, 0, 0, 1.0}, // [4] kierunek wiecenia
{4.0, 0.0, 0.0, 0.0}, // [5] tlumienie kštowe swiatła
{90.0, 0.0, 0.0, 0.0}, // [6] kšt odciecia wiatła
{1.0, 0.0, 0.0, 0.0}, // [7] stale tlumienie
{0.0, 0.0, 0.0, 0.0}, // [8] tlumienie liniowe
{0.0, 0.0, 0.0, 0.0}}; // [9] tlumienie kwadratowe
// Skopiowanie zawartosci tablic param_* do tablic globalnych
memcpy(material1, param_materialu1, LPOZ_MENU_MATERIALU*4*sizeof(GLfloat));
memcpy(swiatlo1, param_swiatla1, LPOZ_MENU_SWIATLA*4*sizeof(GLfloat));
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
}
void DefiniujMaterial1(void)
{
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material1[2]);
}
void pozycjaswiatla(float r, float h, int kat)
{
kzs=kat%360;
float alfa=stdorad(kzs);
GLfloat v[3]={r*cos(alfa),h,r*sin(alfa)};
swiatlo1[3][0]=v[0];
swiatlo1[3][1]=v[1];
swiatlo1[3][2]=v[2];
swiatlo1[4][0]=(-1)*v[0];
swiatlo1[4][1]=(-1)*v[1];//+wys/2;
swiatlo1[4][2]=(-1)*v[2];
}
void WlaczOswietlenie(void)
{
glPushMatrix();
glRotatef(OX,1.0,0.0,0.0);
glRotatef(OZ,0.0,0.0,1.0);
// Odblokowanie oswietlenia
glEnable(GL_LIGHTING);
// Odblokowanie zrodla swiatla nr 1
if (zrodlo1 == 1){
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, swiatlo1[0]);
glLightfv(GL_LIGHT0, GL_DIFFUSE, swiatlo1[1]);
glLightfv(GL_LIGHT0, GL_SPECULAR, swiatlo1[2]);
glLightfv(GL_LIGHT0, GL_POSITION, swiatlo1[3]);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, swiatlo1[4]);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, swiatlo1[5][0]);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, swiatlo1[6][0]);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, swiatlo1[7][0]);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, swiatlo1[8][0]);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, swiatlo1[9][0]);
//ustawienie czarnej kulki symbolizujacej pozycje reflektora
//kulka nie jest oswietlana
glPushAttrib(GL_LIGHTING_BIT);
glPushMatrix();
glDisable(GL_LIGHTING);
glTranslatef(swiatlo1[3][0],swiatlo1[3][1],swiatlo1[3][2]);
glColor3f(0.0,0.0,0.0);
glutSolidSphere(0.4,20,20);
glPopMatrix();
glPopAttrib();
}
else glDisable(GL_LIGHT0);
glPopMatrix();
}
float* GeneratorTekstury()
{
float *tekstura;
float *wskaznik;
int rozmiar = 4*size*size;
int i;
float kolor1[4] = {1.0, 1.0, 0.0, 1.0}; //zolty
float kolor2[4] = {0.0, 0.0, 1.0, 1.0}; //niebieski
tekstura = new float[rozmiar];
wskaznik = tekstura;
int numer=0;
int polowka=int(size/2);
int cwiartka=int(size/4);
int temp=size-1;
for (i=0;i<size;i++){
for (int zonk=0;zonk<size;zonk++){
if ((zonk==temp)){
*(wskaznik++) = kolor2[0];
*(wskaznik++) = kolor2[1];
*(wskaznik++) = kolor2[2];
*(wskaznik++) = kolor2[3];
}
else{
*(wskaznik++) = kolor1[0];
*(wskaznik++) = kolor1[1];
*(wskaznik++) = kolor1[2];
*(wskaznik++) = kolor1[3];
}
}
temp--;
}
return tekstura;
}
void RysujSzescian(double a)
{
float* tekstura = GeneratorTekstury();
glTexImage2D(GL_TEXTURE_2D,0,param,size,size,0,GL_RGBA,GL_FLOAT,tekstura);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,tryb2);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,tryb2);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,tryb);
glEnable(GL_TEXTURE_2D);
double texX = 0, texY = 0, texX2=0,texY2=0;
double texS_x, texS_y;
texS_x=(float)rozx/c;
texS_y=(float)rozy/b;
int ih,iv;
int pion,poz,smash;
float x1,x2,y1,y2,z1,z2,r1,r2;
float ctg_alfa; //kšt nachylenia ciany bocznej do podstawy
float H,R;
float top_point;
H=5;
R=3;
ctg_alfa=R/H;
pion=b;
poz=c;
smash=0;
top_point=4;
for(ih=smash;ih<pion;ih++,texY+=texS_y)
{
y1=top_point-ih*H/pion;
y2=top_point-(ih+1)*H/pion;
r1=(ih*H/pion)*ctg_alfa; //r=h*ctg(alfa)
r2=((ih+1)*H/pion)*ctg_alfa;
glBegin(GL_QUAD_STRIP);
for(iv=poz;iv>=0;iv--,texX+=texS_x) {
texX2=texX+texS_x;
texY2=texY+texS_y;
x1=r1*cos(iv*2*GL_PI/poz);
z1=r1*sin(iv*2*GL_PI/poz);
x2=r2*cos(iv*2*GL_PI/poz);
z2=r2*sin(iv*2*GL_PI/poz);
glNormal3f(x1,y1,z1);
glTexCoord2f(texX, texY);
glVertex3f(x1,y1,z1);
glNormal3f(x2,y2,z2);
glTexCoord2f(texX, texY2);
glVertex3f(x2,y2,z2);
}
texX-=texS_x;
glEnd();
}
delete(tekstura);
}
//////////////////////////////////////////////////////////////////////////////////////////
// Funkcja ustawiajaca parametry rzutu perspektywicznego i rozmiary viewportu. Powinna
// by wywolywana kazdorazowo po zmianie rozmiarow okna programu.
void UstawParametryWidoku(int szer, int wys)
{
// Zapamietanie wielkosci widoku
szerokoscOkna = szer;
wysokoscOkna = wys;
// Ustawienie parametrow viewportu
glViewport(0, 0, szerokoscOkna, wysokoscOkna);
// Przejscie w tryb modyfikacji macierzy rzutowania
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(OBSERWATOR_FOV_Y, (float)szerokoscOkna/(float)wysokoscOkna, 1.0,
1000.0);
}
//////////////////////////////////////////////////////////////////////////////////////////
// Funkcja wyswietlajaca pojedyncza klatke animacji
void WyswietlObraz(void)
{
// Wyczyszczenie bufora koloru i bufora glebokosci
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glClearColor(0.0, 0.0, 1.0, 1.0);
// Przejscie w tryb modyfikacji macierzy przeksztalcen geometrycznych
glMatrixMode(GL_MODELVIEW);
// Zastapienie aktywnej macierzy macierza jednostkowa
glLoadIdentity();
// Ustalenie polozenia obserwatora
glTranslatef(0, 0, -OBO);
glRotatef(OBX, 1, 0, 0);
glRotatef(OBY, 0, 1, 0);
WlaczOswietlenie();
// Narysowanie szescianu
RysujSzescian(bok);
// Przelaczenie buforow ramki
glutSwapBuffers();
}
//////////////////////////////////////////////////////////////////////////////////////////
// Funkcja obslugi klawiatury
void ObslugaKlawiatury(unsigned char klawisz, int x, int y)
{
if(klawisz == '=') {
OBO += 1.0;
H=OBO*sin(stdorad(OBX)); }
else if (klawisz == '-') {
OBO -= 1.0;
H=OBO*sin(stdorad(OBX)); }
else if (klawisz == 'q') b+=2;
else if (klawisz == 'e') { if (b>3) {b-=2; } }
else if (klawisz == 'z') c+=2;
else if (klawisz == 'c') { if (c>3) {c-=2; } }
else if (klawisz == 'w') {
H=OBO*sin(stdorad(OBX));
odl=OBO*cos(stdorad(OBX));
H+=0.5;
OBO=sqrt(H*H+odl*odl);
OBX=raddost(atan(H/odl)); }
else if (klawisz == 'x') {
H=OBO*sin(stdorad(OBX));
odl=OBO*cos(stdorad(OBX));
H-=0.5;
OBO=sqrt(H*H+odl*odl);
OBX=raddost(atan(H/odl)); }
else if (klawisz == 'u') {
rzs+=0.1;
pozycjaswiatla(rzs,hzs,kzs); }
else if (klawisz == 'o') {
rzs-=0.1;
pozycjaswiatla(rzs,hzs,kzs); }
else if (klawisz == 'j') {
kzs+=5;
pozycjaswiatla(rzs,hzs,kzs); }
else if (klawisz == 'l') {
kzs-=5;
pozycjaswiatla(rzs,hzs,kzs); }
else if (klawisz == 'n') zrodlo1 = (zrodlo1 == 1) ? 0 : 1;
else if (klawisz == 'i') {
hzs+=0.1;
pozycjaswiatla(rzs,hzs,kzs); }
else if (klawisz == 'k') {
hzs-=0.1;
pozycjaswiatla(rzs,hzs,kzs); }
else if (klawisz == 't') OX+=5;
else if (klawisz == 'g') OX-=5;
else if (klawisz == 'a') OBY+=5;
else if (klawisz == 'd') OBY-=5;
else if (klawisz == 'y') OZ+=5;
else if (klawisz == 'h') OZ-=5;
else if (klawisz == ']'){ if (size<128)size*=2; } //tekstura powiekszanie
else if (klawisz == '['){ if (size>4)size/=2; } //tekstura pomniejszanie
else if (klawisz == '1'){ tryb2 = (tryb2 == GL_LINEAR) ? GL_NEAREST : GL_LINEAR; }
else if (klawisz == '2') tryb=GL_DECAL;
else if (klawisz == '3') tryb=GL_MODULATE;
else if (klawisz == '4') tryb=GL_BLEND;
else if (klawisz == '+'){ if (rozx<5)rozx+=1.0; } //powielanie tekstury
else if (klawisz == '-'){ if (rozx>1)rozx-=1.0; }
else if (klawisz == '*'){ if (rozy<5)rozy+=1.0; }
else if (klawisz == '/'){ if (rozy>1)rozy-=1.0; }
else if (klawisz == 27) exit(0);
}
int main(int argc, char **argv)
{
// Zainicjowanie biblioteki GLUT
glutInit(&argc, argv);
// Ustawienie trybu wyswietlania
glutInitDisplayMode (GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
// Ustawienie polozenia dolnego lewego rogu okna
glutInitWindowPosition(100, 100);
// Ustawienie rozmiarow okna
glutInitWindowSize(szerokoscOkna, wysokoscOkna);
// Utworzenie okna
glutCreateWindow("Stozek z tekstura i oswietleniem wykonany przez Karola Zalewskiego");
// Odblokowanie bufora glebokosci
glEnable(GL_DEPTH_TEST);
// Wielokšty o kierunku zgodnym do ruchu wskazówek sš widziane z przodu
glFrontFace(GL_CW);
// Ustawienie wartosci czyszczacej zawartosc bufora glebokosci
glClearDepth(1000.0);
// Ustawienie funkcji wykonywanej na danych w buforze glebokosci
glDepthFunc(GL_LEQUAL);
// Odblokowanie wykonywania operacji na skladowych "alfa"
glEnable(GL_BLEND);
// Ustawienie koloru czyszczenia bufora ramki
glClearColor (0.2f, 0.5f, 0.3f, 0.5f);
// Wlaczenie wyswietlania wielokatow w postaci obrysow (przydatne w celach
diagnostycznych).
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// Zarejestrowanie funkcji (callback) odpowiedzialnej za
glutDisplayFunc(WyswietlObraz);
// Zarejestrowanie funkcji (callback) wywolywanej za kazdym razem kiedy
// zmieniane sa rozmiary okna
glutReshapeFunc(UstawParametryWidoku);
// Zarejestrowanie funkcji wykonywanej gdy okno nie obsluguje
// zadnych zadan
glutIdleFunc(WyswietlObraz);
// Zarejestrowanie funkcji obslugi klawiatury
glutKeyboardFunc(ObslugaKlawiatury);
// Ustawienie domyslnych wartosci parametrow
UstawDomyslneWartosciParametrow();
// Obsluga glownej petli programu (wywolywanie zarejestrowanych callbackow
// w odpowiedzi na odbierane zdarzenia lub obsluga stanu bezczynnosci)
glutMainLoop();
return 0;
}