Warszawa, 21.12.07
WOJSKOWA AKADEMIA TECHNICZNA
IM. JAROSŁAW DĄBROWSKIEGO
W WARSZAWIE
Przemysław Opała
Gr. I6Y1S1
Sprawozdanie z Laboratorium Grafiki Komputerowej
Temat Laboratorium: Modelowanie tekstur
Prowadzący:
mgr inż. Mariusz Pazur
Treść zadania:
Wykorzystując biblioteki OpenGL i GLUT napisać program przedstawiający perspektywiczny obraz stożka, na który została od
wzorowana 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ść:
Zmiany rozmiarów tekstury w zakresie od 4x4 do 128x128 tekseli z zachowaniem proporcji wzorca.
Powielania tekstury w zakresie od 1 do 5 niezależnie w kierunku poziomym i pionowym (GL_REPEAT).
Zmiany metody filtrowania tekstury (GL_NEAREST, GL_LINEAR)
Zmiany trybu teksturowania (GL_DECAL, GL_MODULATE, GL_BLEND)
Zmiany położenia źródła światła.
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 [0o, 360o] z krokiem 1o.
Oświetlony obiekt powinien zawsze znajdować się w centralnej części okna.
Rozwiązanie zadania:
Celem zadania było nałożenie tekstury, o określonym wzorze, aby to uczynić jeszcze zanim zaimplementuje same nakładanie tekstury na obiekt, należy stworzyć wzór oczekiwanej tekstury, trzeba zatem określić kolor odpowiednich fragmentów tekstury, jest to realizowane u mnie w programie przez funkcję typu float* Tekstury(), która zwraca wskaźnik adres zawierający dane o teksturze.
float* Tekstury()
{
float *tekstura;
float *q;
int rozmiar = 4*size*size;
int i;
float kolor1[4] = {0.0, 1.0, 0.0, 1.0}; //zielony
float kolor2[4] = {0.0, 0.0, 0.0, 0.0}; //przezroczysty
tekstura = new float[rozmiar];
q = tekstura;
//q = new float[rozmiar];
int numer=0;
int polowka=int(size/2);
int cwiartka=int(size/4);
for (i=0;i<polowka;i++){
for (int zonk=0;zonk<size;zonk++){
if ((zonk>=0)&&(zonk<size)){
*(q++) = kolor1[0];
*(q++) = kolor1[1];
*(q++) = kolor1[2];
*(q++) = kolor1[3];
}
}
}
for (i=0;i<polowka;i++){
for (int zonk=0;zonk<size;zonk++) {
if(zonk<polowka){
*(q++) = kolor1[0];
*(q++) = kolor1[1];
*(q++) = kolor1[2];
*(q++) = kolor1[3];
}
else{*(q++) = kolor2[0];
*(q++) = kolor2[1];
*(q++) = kolor2[2];
*(q++) = kolor2[3];
}
}
}
return tekstura;
}
Ustalenie kolorów tekstury odbywa się poprzez wskaźnik q, pod adresem którego umieszczone są współrzędne kolorów użytych do tekstury, po każdym przypisaniu współrzędnej adres jest zwiększany, zatem kolor tekstury umieszczam w pamięci, zgodnie z wzorem tekstury, zatem do połowy cała tekstura jest koloru zielonego, a połowa drugiej połowy jest koloru zielonego, reszta natomiast przezroczysta.
Teraz nadszedł czas na zdefiniowanie samej tekstury oraz jej parametrów, definiowanie tekstury odbywa się poprzez funkcję
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ą:
GL_CLAMP - poza zakresem używany jest kolor ramki tekstury lub stały kolor
GL_REPEAT - tekstura jest powtarzana na całej powierzchni wielokąta
Kolejnym etapem w programie była możliwość zmiany trybu teksturowania, należało użyć trzech trybów GL_DECAL, GL_MODULATE, GL_BLE
Funkcją realizującą powyższe zadanie jest następująca funkcja:
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,tryb);
Funkcja ta ustala aktualny sposób teksturowania, w moim przypadku używam parametrów GL_TEXTURE_ENV oraz GL_TEXTURE_ENV_MODE, który umożliwia mi wybór za parametr tryb jednego z trzech trybów teksturowania, poniżej omawiam znaczenie trzech możliwych sposobów teksturowania:
GL_MODULATE - kolor piksela tekstury jest mnożony przez kolor piksela ekranu
GL_DECAL - piksele tekstury zastępują piksele na ekranie
GL_BLEND - kolor piksela tekstury jest mnożony przez kolor piksela ekranu i łączony ze stałym kolorem
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();
}
Sterowanie klawiszami:
Światło:
j l- wokół osi Y
i k- wokół osi X
Sterowanie obiektem:
a d- wokół osi Y
w x wokół osi X
Zmiana trybów:
2-GL_DECAL
3-GL_MODULATE
4-GL_BLEND
1-GL_LINEAR
1-GL_NEAREST
Powielanie tekstury:
+ - w kierunku pionowym
* / w kierunku poziomym
] [ - zmiania rozmiaru tekstury
Prezentacja uzyskanych wyników:
Nałożenie tekstury:
Obrót stożka i oświetlenia:
Minimalny rozmiar tekstury:
Maksymalny rozmiar tekstury:
Tryb GL_NEAREST
Tryb GL_LINEAR i GL_DECAL
Tryb GL_DECAL i GL_NEAREST
Tryb GL_MODULATE
Tryb GL_BLEND
Powielona tekstura:
Kod programu:
#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* Tekstury()
{
float *tekstura;
float *q;
int rozmiar = 4*size*size;
int i;
float kolor1[4] = {0.0, 1.0, 0.0, 1.0}; //zielony
float kolor2[4] = {0.0, 0.0, 0.0, 0.0}; //przezroczysty
tekstura = new float[rozmiar];
q = tekstura;
//q = new float[rozmiar];
int numer=0;
int polowka=int(size/2);
int cwiartka=int(size/4);
//pierwsze dwie linie tekstury
for (i=0;i<polowka;i++){
for (int zonk=0;zonk<size;zonk++){
if ((zonk>=0)&&(zonk<size)){
*(q++) = kolor1[0];
*(q++) = kolor1[1];
*(q++) = kolor1[2];
*(q++) = kolor1[3];
}
/* else{
*(q++) = kolor2[0];
*(q++) = kolor2[1];
*(q++) = kolor2[2];
*(q++) = kolor2[3];
}*/
}
}
//trzecia linia tekstury
for (i=0;i<polowka;i++){
for (int zonk=0;zonk<size;zonk++) {
if(zonk<polowka){
*(q++) = kolor1[0];
*(q++) = kolor1[1];
*(q++) = kolor1[2];
*(q++) = kolor1[3];
}
else{*(q++) = kolor2[0];
*(q++) = kolor2[1];
*(q++) = kolor2[2];
*(q++) = kolor2[3];
}
}
}
return tekstura;
}
void RysujSzescian(double a)
{
float* tekstura = Tekstury();
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");
// 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;
}
- zielony
a
4a