Popiol |
Poison Headcrab |
|
|
Dołączył: 02 Lis 2005 |
Posty: 16 |
Przeczytał: 0 tematów
Ostrzeżeń: 0/5
|
Skąd: Wygiełzów |
|
|
|
|
|
|
Są dwa rodzaje świateł: kierunkowe i pozycyjne. Kierunkowe znajdują w pizdu hen hen daleko od sceny i dlatego przy obliczaniu światła brany jest pod uwagę tylko kierunek promieni, które są równoległe. Pozycyjne z kolei są gdzieś w obrębie sceny, albo w pobliżu i przy obliczaniu światła brane jest pod uwagę ich położenie.
Używanie świateł należy włączyć poleceniem glEnable(GL_LIGHTING). Poszczególne światła włącza się poleceniem glEnable(nazwa_swiatla), gdzie nazwa_swiatla może mieć postać: GL_LIGHT0, GL_LIGHT1,...itd. Maksymalną ilość świateł, jakie można włączyć określa stała GL_MAX_LIGHTS i jest to zazwyczaj 8.
Własności światła ustawia się funkcją glLightfv(nazwa_swiatla, nazwa_parametru, wartosc). Litera f w nazwie funkcji oznacza, że podajemy wartości jako floaty, a v, że wartość jest wektorem, a konkretnie wskaźnikiem do tablicy. Zamiast f może być i (wartości całkowite), natomiast v możemy pominąc w przypadku kilku parametrów, które przyjmują pojedyncze wartości.
Jednym z parametrów, które trzeba określić jest GL_POSITION. Wartością jest 4-elementowy wektor, w którym ostatnia wartość określa czy światło ma być kierunkowe czy pozycyjne. Kierunkowemu odpowiada wartość 0, a pozycyjnemu każda inna. Pierwsze trzy wartości wektora określają odpowiednio kierunek lub położenie światła.
Dla trzech parametrów trzeba ustawić kolor, znów w postaci 4-elementowego wektora (czwarty element musi być równy 1 jeśli dany rodzaj światła ma być uwzględniany). Parametr GL_AMBIENT określa kolor światła, które pada na każdą ścianę tak samo, tzw światło otoczenia, jest dodawane do innych świateł, aby nie było zbyt ciemnych miejsc na scenie. Parament GL_DIFFUSE to kolor światła rozproszonego, a GL_SPECULAR światła odbitego. Dla wszystkich świateł oprócz GL_LIGHT0 standardowo kolory mają wartości zerowe, natomiast dla GL_LIGHT0 jedynki. Jeśli robimy światło pozycyjne to kierunek padania światła ustawiamy w parametrze GL_SPOT_DIRECTION. Wartością jest 3-elementowy wektor. Parametr GL_SPOT_CUTOFF to kąt rozwarcia stożka światła, jest pojedynczą liczbą, więc do ustawienia go używamy funckji glLightf. Przydać się może też parametr GL_SPOT_EXPONENT, którego wartości mogą wahać się od 0 do 128. Nie jestem pewny jaką to ma interpretacje, ale chyba chodzi o to jak bardzo odległość od źródła światła wpływa na jego intensywność. Dla 0 światło jest najmocniejsze, a dla 128 najsłabsze. Zresztą poeksperymentujcie to się przekonacie.
Jeśli już ustawiliśmy parametry świateł to można jeszcze ustawić parametry materiału, czyli to jak poszczególne ściany mają zmieniać kolor pod wpływem światła. Parametry te można ustawiać osobno dla różnych obiektów. Służy do tego funkcja glMaterialfv, która przyjmuje trzy parametry. Pierwszy określa stronę ściany, np GL_FRONT_AND_BACK to przód i tył. Drugi argument to nazwa parametru, który chcemy ustawić, np GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR. Trzeci to wskaźnik do 4-elementowej tablicy, w której określamy jakby z jaką intensywnością materiał reaguje na światło, albo inaczej mówiąc określamy kolor, który jest mieszany z kolorem światła (to wszystko jeszcze miesza się z faktycznym kolorem ściany). W zasadzie jeśli własności światła mają być dla wszystkich obiektów jednakowe to chyba nie ma potrzeby używania tej funkcji.
Na koniec jeszcze jedna sprawa, bez której światła nie będą prawidłowo działać. Trzeba ustawić dla każdej ściany tzw wektor normalny, czyli wektor ustawiony prostopadle do ściany, skierowany w stronę przodu ściany. Robi się to poleceniem glNormal3f(x,y,z), gdzie podaje się współrzędne wektora.
Czas na przykładowy program. W inicie dopisujemy:
Kod: | glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
float swiatlo1Pos[] = {-1.0f, 1.0f, -6.0f, 1.0f};
float swiatlo2Pos[] = {1.0f, 1.0f, -6.0f, 1.0f};
float ambient[] = {0.4f, 0.4f, 0.4f, 1.0f};
float diffuse[] = {0.5f, 0.5f, 0.5f, 1.0f};
float kierunek[] = {0.0f, -1.0f, 0.0f};
glLightfv(GL_LIGHT3, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT1, GL_POSITION, swiatlo1Pos);
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, kierunek);
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 10.0f);
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 30.0f) ;
glLightfv(GL_LIGHT2, GL_POSITION, swiatlo2Pos);
glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT2, GL_SPOT_DIRECTION, kierunek);
glLightf(GL_LIGHT2, GL_SPOT_EXPONENT, 10.0f);
glLightf(GL_LIGHT2, GL_SPOT_CUTOFF, 30.0f) ;
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
glEnable(GL_LIGHT3); |
Dodajemy dwie funkcje:
Kod: | void kostka(GLfloat szer, GLfloat wys, GLfloat gleb) {
szer *= 0.5; wys *= 0.5; gleb *= 0.5;
glBegin(GL_QUADS);
glNormal3f(0.0f,0.0f,1.0f);
glVertex3f(szer,-wys,gleb);
glVertex3f(szer,wys,gleb);
glVertex3f(-szer,wys,gleb);
glVertex3f(-szer,-wys,gleb);
glNormal3f(0.0f,0.0f,-1.0f);
glVertex3f(-szer,-wys,-gleb);
glVertex3f(-szer,wys,-gleb);
glVertex3f(szer,wys,-gleb);
glVertex3f(szer,-wys,-gleb);
glNormal3f(-1.0f,0.0f,0.0f);
glVertex3f(-szer,wys,gleb);
glVertex3f(-szer,wys,-gleb);
glVertex3f(-szer,-wys,-gleb);
glVertex3f(-szer,-wys,gleb);
glNormal3f(1.0f,0.0f,0.0f);
glVertex3f(szer,-wys,gleb);
glVertex3f(szer,-wys,-gleb);
glVertex3f(szer,wys,-gleb);
glVertex3f(szer,wys,gleb);
glNormal3f(0.0f,-1.0f,0.0f);
glVertex3f(-szer,-wys,gleb);
glVertex3f(-szer,-wys,-gleb);
glVertex3f(szer,-wys,-gleb);
glVertex3f(szer,-wys,gleb);
glNormal3f(0.0f,1.0f,0.0f);
glVertex3f(szer,wys,gleb);
glVertex3f(szer,wys,-gleb);
glVertex3f(-szer,wys,-gleb);
glVertex3f(-szer,wys,gleb);
glEnd();
}
void lampka(float x, float y, float z) {
glPushMatrix();
if (z) glRotatef(90.0f, 1, 1, 0);
if (x || y || z) glRotatef(90.0f, y+z, -x+z, 0);
gluCylinder(gluNewQuadric(), 0.35, 0.1, 0.4, 4, 1);
glTranslatef(0.0f, 0.0f, -1.5f);
kostka(0.1,0.1,3);
glPopMatrix();
} |
A w renderze piszemy:
Kod: | glColor3ub(150,150,200);
glTranslatef(-1.0f, 1.0f, -6.0f);
lampka(0,-1,0);
glTranslatef(2.0f, 0.0f, 0.0f);
lampka(0,-1,0);
glTranslatef(-1.0f, -2.5f, 0.0f);
glRotatef(kat,0,1,0);
kat++;
glTranslatef(-1.5f, 0.0f, 0.0f);
kostka(1,1,1);
glTranslatef(1.5f, 0.0f, 0.0f);
kostka(1,1,1);
glTranslatef(1.5f, 0.0f, 0.0f);
kostka(1,1,1); |
Trzeba jeszcze tylko zdefiniować globalną zmienną kat typu float i przypisać jej wartość 1. |
|