Wstęp
Oto podręcznik podstaw programowania grafiki trójwymiarowej za pomocą biblioteki OpenGL. Zaplanowałem go jako aktualizację książki Grafika. Fizyka. Metody numeryczne wydanej przez WN PWN w 2010 roku. Składała się z kilku części: pierwsza dotyczyła właśnie grafiki trójwymiarowej OpenGL, kolejne - fizyki klasycznej punktów materialnych i brył sztywnych oraz metod numerycznych używanych w symulacjach ciał miękkich i brył sztywnych.
Cztery lata, które minęły od wydania tamtej książki, w najmniejszym stopniu nie wpłynęły na aktualność opisanej w niej fizyki. Niestety część dotycząca grafiki zdążyła się bardzo zestarzeć. Niedługo po wydaniu książki, w marcu 2010 roku pojawiły się nowe wersje OpenGL o numerach 3.3 i 4.0, które w tej książce będę nazywał nowoczesnym OpenGL. Problem polega na tym, że te wersje nie dodają do poprzednich nowych funkcji, rozbudowujących je o nowe możliwości. Mamy tu raczej do czynienia z nowym otwarciem albo wręcz rewolucją. Wiele funkcji tradycyjnych, często wykorzystywanych, uznano za przestarzałe i są one obsługiwane wyłącznie w mniej wydajnym profilu zgodności. Profil rdzenny pozbawiony jest takich udogodnień, jak natychmiastowe przesyłanie werteksów, obsługa macierzy czy domyślne shadery implementujące oświetlenie i teksturowanie. To sporo rzeczy, które teraz należy obsłużyć w inny sposób - korzystając z bibliotek znalezionych w internecie lub zaimplementować samodzielnie. Wysiłek, jaki wiąże się z przejściem do nowoczesnego OpenGL w profilu rdzennym, jest na tyle duży, że wielu programistów nie chce go podejmować. W rezultacie sporo nowych aplikacji nadal korzysta z OpenGL w profilu zgodności, nie wykorzystując pełnych możliwości współczesnych kart graficznych.
Zadaniem, które sobie postawiłem, pisząc tę książkę, było wprowadzenie Czytelnika w świat nowoczesnego, ale jednocześnie bardziej wymagającego OpenGL, a na jego przykładzie - w świat nowoczesnej grafiki trójwymiarowej, nie uciekając się do gotowych rozwiązań. Nie chodzi mi zatem o to, żeby ominąć problem, korzystając z gotowych bibliotek, a o samodzielną implementację całego potrzebnego kodu. Dla przykładu: w przypadku macierzy można by użyć popularnej biblioteki GLM, która nie wymaga znajomości algebry macierzy i umiejętności jej samodzielnej implementacji, a przy tym jest już dobrze przetestowana i wobec tego wiarygodna. Ale wówczas nie wykorzystalibyśmy tej szansy, jaką daje nowoczesny OpenGL - szansy pełnego zrozumienia podstaw grafiki 3D, a w tym macierzy (przynajmniej w zakresie, w jakim są potrzebne w grafice). Idąc tym tropem, przedstawiam też kod, który korzystając wyłącznie z funkcji WinAPI, umożliwia tworzenie okien gotowych do wyświetlania grafiki generowanej z użyciem OpenGL w profilu rdzennym, wraz z obsługą klawiatury i myszy. Bibliotekę GLFW, która mogłaby nas w tym wyręczyć, podobnie jak bibliotekę GLM, omawiam w dodatku do książki.
Takie podejście powoduje, że w wielu miejscach książka ma bardzo "techniczny" charakter. Opisuję w niej każdą zmianę kodu, starając się unikać niedopowiedzeń - każdy zmodyfikowany fragment jest zaznaczony i omówiony. Jedną z konsekwencji takiego podejścia jest spora różnorodność omawianych zagadnień. Mimo że głównym tematem pozostaje oczywiście grafika 3D, omawiam także zagadnienia związane z WinAPI, takie jak tworzenie okna, obsługa urządzeń wejścia czy implementacja wektorów i macierzy w C++. Korzystam również z języka GLSL pozwalającego na bezpośrednie programowanie karty graficznej. Należy się wobec tego spodziewać sporej liczby listingów, które trzeba będzie analizować.
Choć książka pomyślana jest jako podręcznik akademicki, w którym nie stronię od wzorów (w części rozdziałów jest ich nawet całkiem sporo) i który pozwoli studentowi lub osobie zainteresowanej programowaniem grafiki 3D na stosunkowo pełne zrozumienie podstaw tej dziedziny, poziom trudności nie jest wyśrubowany. Wzory nie wykraczają poza proste operacje na macierzach.
Książkę tę można traktować również jako opis prostej platformy do tworzenia aplikacji korzystających z grafiki 3D w OpenGL. Wszystkie elementy zamknięte są w klasy (np. Okno lub Aktor), których można swobodnie używać w swoich projektach, w postaci opisanej w książce lub dowolnie przekształconych.
A zatem Czytelnik trzyma w ręku podręcznik podstaw grafiki trójwymiarowej omawianych na przykładzie OpenGL. Zasadne jest pytanie, dlaczego wybrałem OpenGL, skoro świat gier komputerowych jest dziś zdominowany przez konkurencyjny DirectX Microsoftu. Owa dominacja jest niezaprzeczalna i niewiele zmienia fakt, że OpenGL znajduje obecnie nowe przyczółki: jest jedynym API pozwalającym na tworzenie aplikacji 3D w systemie Android (mam na myśli OpenGL ES), obiecujące jest także włączenie go do HTML5 (moduł WebGL). Najważniejszym powodem wyboru OpenGL było jednak coś innego. Zaimponowało mi śmiałe posunięcie grupy Khronos zarządzającej rozwojem OpenGL, która zdecydowała się na odświeżenie tego interfejsu programistycznego, dostosowując go do możliwości współczesnych kart graficznych, ale jednocześnie rezygnując ze zgodności ze starszymi wersjami. Biorąc pod uwagę model dystrybucji nowych wersji, mocno związany z zakupem nowego sprzętu, to było bardzo odważne posunięcie. Wprawdzie nie do końca udało się je konsekwentnie utrzymać - konieczny był kompromis w postaci profilu zgodności, ale profil rdzenny jest coraz częściej używany i powoli staje się standardem OpenGL, choć uczciwie trzeba przyznać, że nadal daleko mu do zdobycia dominacji na rynku gier.
Jacek Matulewski, maj 2014 rok