Arkanoid 3D krok po kroku II

26.04.2010 - Olgierd Humeńczuk
TrudnośćTrudność

W poprzedniej części nauczyliśmy się jak tworzyć okno z przypiętym kontekstem Open GL, reagujące na podstawowe zdarzenia. Umiemy także wyświetlić ( na razie za pomocą linii ) sześcian. W tej części zajmiemy się tematem światła w grafice czasu rzeczywistego i m.in. nauczymy się korzystać z modelu który oferuje biblioteka Open GL. Zapraszam do lektury.

Oświetlenie

Współczesne trendy

W ciągu ostatnich kilku lat łatwy do zauważenia był ogromny postęp w jakości oświetlenia w grach komputerowych. Jeszcze niedawno istniała bardzo wyraźna granica między modelami oświetlenia, używanymi w grach komputerowych ( grafika czasu rzeczywistego ), a tymi, które używane są w aplikacjach śledzących promienie. Obecnie granica ta zaciera się. Dzięki coraz wydajniejszym kartom graficznym, twórcy gier mogą sięgać po bardziej zaawansowane modele, stosowane dotychczas tylko w grafice realistycznej i adaptować je do swoich potrzeb i możliwości. My zaczniemy jednak od podstaw i nauczymy się najpierw jak działa i jak używać modelu oferowanego przez bibliotekę Open GL.

Rys. 1. Zdjęcie ekranu z gry "Far Cry" 2004 rok.

Rys. 2. Gra "Crysis2" i możliwości jej silnika - rok 2010.


Intuicje


Rys. 3. Jak widzimy przedmioty?

Światło jest jednym z najważniejszych czynników jakie wpływają na jakość symulacji komputerowych. Dzieje się tak dlatego, że ludzkie oko czułe jest na promienie światła odbite od obiektów. Nie ma żadnej innej fizycznej korelacji między wzrokiem a materią.

Promienie światła biorą swój początek we wszystkim, co świeci ( powierzchnie, takie jak lustro, które dobrze odbijają promienie światła, także możemy klasyfikować jako jego źródła ). Na początek załóżmy, że światło zawsze porusza się w linii prostej we wszystkich kierunkach równomiernie ( nie jest to oczywiście prawdą, ale w grafice czasu rzeczywistego bardzo często przyjmuje się takie założenie by uprościć obliczenia ). Co to znaczy widzieć jakiś przedmiot? Kiedy promienie światła, wygenerowane przez nasze np. lampy, trafią w ścianę - odbijają się od jej powierzchni. Część z odbitych promieni trafia do naszych oczu i to właśnie dzięki nim widzimy. Metody generowania obrazów oparte są na tej prostej obserwacji.


Do dzieła!

Aby włączyć obliczanie koloru wielokątów w bibliotece Open GL musimy dodać do naszego kodu odpowiednie instrukcje. W funkcji initOpenGL linię:
1
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );    
zamienimy na:
1
glPolygonMode( GL_FRONT, GL_FILL );    

Zmienimy dzięki temu sposób rasteryzacji wielokątów ( skierowanych do obserwatora przodem ) z obrysowywania liniami na wypełnianie ich kolorem. Jeżeli teraz uruchomimy naszą grę, powinniśmy zobaczyć sześcian, którego ściany wypełnione są jednorodnie kolorem białym.

Zmiana sposobu wyświetlania wielokątów wymaga od nas odpowiedniej kolejności wyświetlania ścian. Aby zrzucić wyznaczanie kolejności renderowania na kartę graficzną, użyjemy wspomnianego w poprzednim artykule bufora głębi. Dodajmy zatem w funkcji initOpenGL następującą linię:

1
glEnable( GL_DEPTH_TEST );

Rys. 4. Działanie bufora głębi
a - wielokąt położony najbliżej obserwatora, b - wielokąt zasłonięty przez a
za - głębokość fragmentu z wielokąta a renderowanego na ekranie
zb - głębokość fragmentu z wielokąt b renderowanego na ekranie

Rys. 4 pokazuje ideę działania bufora głębi. Testowanie głębokości to nic innego jak porównanie odległości od obserwatora do punktu ( domyślnie wartość współrzędnej z ), który chcemy renderować, z wartością zapisaną w buforze głębokości. Rozpatrzymy teraz dwa możliwe scenariusze dla sytuacji z Rys. 4:

  • wielokąt a jest renderowany przed wielokątem b
    • próbka z wielokąta a porównana zostaje z tym co w buforze i wygrywa ( domyślna wartość bufora głębi to 1 )
    • głębokość próbki z wielokąta a zapisana zostaje do bufora głębokości
    • próbka z wielokąta b porównana zostaje z tym co w buforze i przegrywa
    • na ekranie pojawia się piksel w kolorze fragmentu z wielokąta a

  • wielokąt b jest renderowany przed wielokątem a
    • próbka z wielokąta b porównana zostaje z tym co w buforze i wygrywa
    • głębokość próbki z wielokąta b zostaje zapisana do bufora głębokości
    • głębokość próbki z wielokąta a zostaje porównana z tym co w buforze i wygrywa
    • nowa wartość bufora dla tej próbki to głębokość a
    • na ekranie pojawia się piksel w kolorze fragmentu z wielokąta a

Następnym krokiem będzie włączenie liczenia oświetlenia. Ponownie zmodyfikujemy funkcję initOpenGL dodając następującą linię kodu:
1
glEnable( GL_LIGHTING );
W tym momencie brakuje nam dwóch rzeczy:
  • opisu źródła światła
  • opisu materiału z jakiego zrobiony jest nasz obiekt
4.666665
Twoja ocena: Brak Ocena: 4.7 (3 ocen)

Copyright © 2008-2010 Wrocławski Portal Informatyczny

design: rafalpolito.com