Aktualizacja: 23.06.2005  Wersja: 0.4.48
Szukaj ::..
Temat ::..

..:: HOME ::..

  ::..:: INTERNETOWY SERWIS PROGRAMISTYCZNY ::..::

 

 

TURTORIAL 7
Wyświetlenie świata 3D

Po pobraniu danych i załadowaniu sektora do pamięci należy teraz zastanowić się w jaki sposób wyświetlić to na ekranie. Język C++ w połączeniu z OpenGl daje możliwość wykonywania szeregu operacji (obrotów, translacji) a położenie kamery obserwatora może być zmieniane zgodnie z wolą programisty. Zajmując się prostymi przekształceniami zwykle nie jest potrzebne ingerowanie w położenie kamery podczas trwania programu, lecz aplikacje bardziej zaawansowane były by bezużyteczne bez takiej możliwości. Bo co to byłby za świat 3D, którego nie można zwiedzić. Byłby to tylko obraz statyczny widziany okiem kamery stworzony na podstawie wykreowanego świata 3D. Dobry silnik 3D daje użytkownikowi możliwość chodzenia wokoło i zwiedzania tegoż świata bez większych ograniczeń. Taki też silnik postaram się przedstawić. Jedną z metod jest przesuwanie kamery w określone miejsce i ponowne tworzenie świata 3D ale już przemieszczonego względem przesunięcia kamery. Nie należy to do najszybszych i najprostszych rzeczy do zaprogramowania zatem należy rozpatrywać drogi ułatwiające nam to zadanie. Trzeba wziąć pod uwagę:
· obrót i translacje kamery w zależności od rozkazów użytkownika, 
· obracanie świata 3D w przeciwną stronę do zamierzonego obrotu kamery co da efekt złudzenia, że kamera została obrócona,
· translacja świata przeciwna do zamierzonej translacji kamery co także da efekt poruszania kamery.
Powyższe założenia nie powinny sprawić programiście większych trudności . Poniżej przedstawiam przykład opracowania obrotów i translacji kamery:

if (klawisz[VK_RIGHT]) // jeśli naciśnięto klawisz w prawo
{
// obróć scenę w lewo
yobrot -= 1.5f; 
}

if (klawisz[VK_LEFT]) // jeśli naciśnięto klawisz w lewo
{
// obróć scenę w prawo
yobrot += 1.5f; 
}

if (klawisz[VK_UP]) // jeśli naciśnięto klawisz do przodu

// przesuń scenę do tyłu zmniejszając wartość zmiennej xpozycja określającej wartość współrzędnej x
xpozycja -= (float)sin(kierunek*pi180) * 0.05f; 
// przesuń scenę do tyłu zmniejszając wartość zmiennej zpozycja określającej wartość współrzędnej z
zpozycja -= (float)cos(kierunek*pi180) * 0.05f; 
}

if (keys[VK_DOWN]) // jeśli naciśnięto klawisz w dół
{
// przesuń scenę do przodu zmniejszając wartość zmiennej xpozycja określającej wartość współrzędnej x
xpozycja += (float)sin(kierunek*pi180) * 0.05f; 
// przesuń scenę do tyłu zmniejszając wartość zmiennej zpozycja określającej wartość współrzędnej z
zpozycja += (float)cos(kierunek*pi180) * 0.05f; 
}

Ten sposób poruszania się ogólnie mówiąc nie powinien nastręczyć trudności. Podczas naciśnięcia jednego z klawiszy w lewo lub w prawo następuje inkrementacja lub dekrementacja wartości yobrot określającej wartość położenia względem osi oy. Jeśli natomiast naciśnięto jeden z klawiszy w górę lub w dół to następuje bardziej skomplikowane obliczenie położenia kamery przy użyciu sinusów i cosinusów. Stała pi180 jest stałą konwertującą kąt pomiędzy stopniami i radianami (określa wartość jednego stopnia wyrażoną w radianach). Wartość tą wyznaczamy na podstawie wzorów matematycznych.
Wiedząc, że:
2P Radiana = 360 Stopni

Wyznaczam wartość jednego stopnia:

1 Stopień = (2P Radiana)/360
1 Stopień = 0.0174532925 Radiana

Zatem stałą tę należy wywołać na początku programu w następujący sposób:

const float pi180 = 0.0174532925f;

Na podstawie wszystkich powyższych założeń można opracować główną funkcję wyświetlającą naszą zadeklarowaną scenę (świat 3D). 

//Funkcja odpowiadająca za rysowanie sceny
int RysujScene(GLvoid) 
{
// Czyszczenie ekranu i bufora głębi
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
// Ustawienie bieżącej macierzy
glLoadIdentity(); 

// Tymczasowe wartości wierzchołków X, Y, Z, U, V
GLfloat x_m, y_m, z_m, u_m, v_m;
// Zmienna określająca translacje w osi ox 
GLfloat xtranslacja = -xpozycja; 
// Zmienna określająca translacje w osi oz 
GLfloat ztranslacja = -zpozycja; 
// Kąt obrotu gracza równy (360 stopni) 
GLfloat obrotsceny = 360.0f - yobrot; 
// Zmienna typu całkowitego do przechowywania informacji o liczbie trójkątów
int liczbatrojkatow; 
// Skręcenie w zależności od kierunku obrotu 
glRotatef(obrotsceny,0,1.0f,0); 
// Translacja pozycji sceny względem pozycji obserwatora
glTranslatef(xtranslacja, ytranslacja, ztranslacja); 
// Wybór tekstury w zależności od rodzaju 
glBindTexture(GL_TEXTURE_2D, tekstura[rodzaj]); 
// Pobranie do zmiennej ilości trójkątów sektora pierwszego
liczbatrojkatow = sektor1.liczbatrojkatow; 

// Proces tworzący wszystkie trójkąty sektora 
// Pętla przebiegająca zależnie od ilości trójkątów
for (int petla_m = 0; petla_m < liczbatrojkatow; petla_m++) 
{
// Początek rysowania trójkąta
glBegin(GL_TRIANGLES);
// Typ Normal 
glNormal3f( 0.0f, 0.0f, 1.0f); 
// Współrzędna x pierwszego punktu
x_m = sektor1.TROJKAT[petla_m]. WIERZCHOLEK[0].x; 
// Współrzędna y pierwszego punktu
y_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[0].y; 
// Współrzędna z pierwszego punktu
z_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[0].z; 
// Współrzędna u pierwszego punktu
u_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[0].u; 
// Współrzędna v pierwszego punktu
v_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[0].v;
// Ustawienie kierunku tekstury i współrzędnych punktu
glTexCoord2f(u_m,v_m); 
glVertex3f(x_m,y_m,z_m); 

// Współrzędna x drugiego punktu
x_m = sektor1.TROJKAT[petla_m]. WIERZCHOLEK[1].x; 
// Współrzędna y drugiego punktu
y_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[1].y; 
// Współrzędna z drugiego punktu
z_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[1].z; 
// Współrzędna u drugiego punktu
u_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[1].u; 
// Współrzędna v drugiego punktu
v_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[1].v;
// Ustawienie kierunku tekstury i współrzędnych punktu
glTexCoord2f(u_m,v_m); 
glVertex3f(x_m,y_m,z_m); 

// Współrzędna x trzeciego punktu
x_m = sektor1.TROJKAT[petla_m]. WIERZCHOLEK[2].x; 
// Współrzędna y trzeciego punktu
y_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[2].y; 
// Współrzędna z trzeciego punktu
z_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[2].z; 
// Współrzędna u trzeciego punktu
u_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[2].u; 
// Współrzędna v trzeciego punktu
v_m = sektor1.TROJKAT[petla _m].WIERZCHOLEK[2].v;
// Ustawienie kierunku tekstury i współrzędnych punktu
glTexCoord2f(u_m,v_m); 
glVertex3f(x_m,y_m,z_m); 
// Koniec rysowania trójkąta 
glEnd(); 
}
return TRUE; 
}

 


PP
...

TYP I NAZWA PLIKÓW  DO POBRANIA:
.....
...
...
FORMAT ARCHIWUM:
...
...

<-- TURTORIAL 6   TURTORIAL 8-->

 

Strona poświęcona jest technologiom programowania C++ z wykorzystaniem pakietu Visual C++, Pascal, DELPHI, C oraz technologiom tworzenia grafiki komputerowej z wykorzystaniem OpenGl i innych technik.
Wszelkie materiały zamieszczone zostały na stronie w celach dydaktycznych. Autor nie ponosi odpowiedzialności za treści materiałów oraz skutki wywołane ich wykorzystaniem.

(c) P.PARDEL 2001-2005 gg:1991389

Serwis znajduje się na serwerze www.friko.pl ..::..::..