OpenTK
Pierwsza publikacja tekstu: 2. listopada 2009 r.
Wraz ze wzrostem popularności platformy .NET oczywistym było, że zaczną powstawać i rozwijać się narzędzia służące do tworzenia aplikacji
multimedialnych, a przede wszystkim gier. Wspierany przez Microsoft zarządzany DirectX został jakiś czas temu zastąpiony przez
XNA – narzędzie umożliwiające łatwe i szybkie tworzenie tego typu aplikacji
dla Windows oraz konsoli Xbox360. W ramach Mono został uruchomiony projekt Mono.XNA, który ma być
docelowo przenośnym zamiennikiem w/w, opartym na OpenGL i bibliotece SDL – póki co wciąż jest we wczesnej fazie rozwoju.
SlimDX dostarcza nieoficjalne wsparcie dla nowszych wersji DirectX, ale platformą docelową musi być wtedy
Windows XP lub nowszy. Dużą popularnością cieszy się przenośny Tao Framework, zestaw
umożliwiający korzystanie z najpopularniejszych bibliotek przydatnych do tworzenia gier. Jego największą wadą jest kiepskie wykorzystywanie mechanizmów
oferowanych przez C# – otrzymujemy kolekcję klas, zawierających funkcje importowane z danej biblioteki oraz zbiór stałych wartości, przyjmowanych jako argumenty tych
metod. Zapis w stylu Gl.glClearColor(0.0f, 0.0f, 1.0f, 0.0f) jest wtedy powszechny i niewiele odbiega od zapisu w językach proceduralnych (choć może to być zaletą w przypadku przepisywania kodu np. z C++).
Częściowym rozwiązaniem kłopotów z przenośnością i kiepskim stylem kodu jest biblioteka Open Toolkit. Początkowo miała oferować tylko lepszą obsługę OpenGL-a niż Tao Framework, lecz z czasem zaczęto dodawać coraz więcej funkcji, związanych nie tylko z wyświetlaniem grafiki, ale także zarządzaniem oknami, wsparciem dla urządzeń wejściowych, elementami algebry przydatnymi w programowaniu grafiki (wektory, macierze, kwaterniony) czy dźwiękiem. Opiera się ona na trzech bibliotekach: OpenGL (grafika), OpenAL (dźwięk), OpenCL (zaawansowane obliczenia). Jest zgodna z .NET Framework 2.0 (Mono 2.0), można ją więc z powodzeniem wykorzystywać we wszystkich kompatybilnych językach zarządzanych. Wystarczy dołączyć jeden plik DLL do projektu, by gotowy program działał pod Windows, Linuksem czy MacOS-em (pomijam konieczność obecności w/w bibliotek w wypadku korzystania z nich; OpenAL SDK jest dostępny do ściągnięcia na stronach Creative Labs).
OpenTK wykorzystuje cechy C# takie jak przeciążanie funkcji, silna typizacja oraz typy generyczne. Wspomniany wcześniej zapis w Tao, tutaj przedstawia się tak:
GL.ClearColor(Color.Blue) – można zauważyć brak zbędnych prefiksów i sufiksów oraz wykorzystanie predefiniowanych kolorów z przestrzeni nazw
System.Drawing. Inny przykład, tym razem dotyczący braku silnej typizacji w Tao: Gl.glMatrixMode(Gl.GL_MODELVIEW) – funkcja przyjmuje
jako argument parametr typu int, co oznacza że można przekazać jej praktycznie dowolną wartość liczbową (np. przez przypadkowe podanie zupełnie niezwiązanej
z tą metodą stałej, zdefiniowanej w ramach Tao.OpenGl.Gl). Kod się skompiluje, ale będzie powodował najprawdopodobniej błędy w wyświetlaniu.
W OpenTK identycznie działający fragment wygląda następująco: GL.MatrixMode(MatrixMode.Modelview) – MatrixMode jest typem
wyliczeniowym, który zawiera listę wszystkich możliwych macierzy obsługiwanych przez OpenGL; kompilator nie pozwoli tu na wpisanie czegoś innego.
Podstawową klasą jest GameWindow która m.in. zarządza oknem na każdej obsługiwanej platformie. W każdej aplikacji korzystającej
z OpenTK, definiuje się dziedziczącą po niej własną klasę, przeciążającą funkcje związane z rysowaniem, wczytywaniem zasobów czy odświeżaniem stanu
gry. Dostępne są także pola Keyboard, Mouse i Joysticks, umożliwiające łatwy odczyt stanu urządzeń wejściowych. Oprócz tego dołączona jest dodatkowa
kontrolka wyświetlająca grafikę 3D, którą można umieścić na oknie projektu używającego Windows Forms, WPF czy GTK#.
Przestrzeń Math oferuje struktury Vector[2|3|4], Quaternion oraz Matrix[3|4], wzorowane na tych z XNA.
Domyślnie wykorzystywana jest pojedyncza precyzja (Single, float), ale istnieją także wersje dla podwójnej (Double, postfiks d
w nazwie klasy, np. Vector3d) oraz połowicznej (Half: typ 16-bitowy, 1 bit znaku, 5 cechy, 10 mantysy; nadaje się do przenoszenia danych
z/do GPU, jest mało precyzyjny i nie obsługuje operacji arytmetycznych – postfiks h, np. Vector2h). Mając dany obiekt typu
Vector2d, możemy w prosty sposób rzutować go na bliźniaczy typ, np. Vector2h. Wszystkie struktury oferują pomocnicze metody
(także statyczne) przydatne do typowych działań, np. obliczanie iloczynu wektorowego, kąta między wektorami, tworzenie macierzy widoku, normalizacja
wektora lub kwaternionu.
W ramach przestrzeni Graphics, zdefiniowane są cztery inne:OpenGL, ES10, ES11, ES20. Pierwsza z nich zawiera wszystkie funkcje
dostępne w ramach "zwykłego" OpenGL-a (w tym momencie wspierana jest wersja 3.2), pozostałe obejmują funkcje trzech kolejnych specyfikacji OpenGL ES, przeznaczonej
dla urządzeń o mniejszych możliwościach graficznych i będącej jednocześnie podzbiorem w/w. Należy więc dobrać zestaw funkcji do możliwości urządzenia
docelowego, sygnalizując użycie właściwej przestrzeni na początku kodu. Działanie garbage collectora może powodować pewne
problemy z buforami wierzchołków (Vertex Buffers) – w pewnych sytuacjach uznaje je za nieużywane i usuwa z pamięci, co może powodować błędy
w wykonywaniu programu. Zalecanie jest korzystanie z obiektów VBO (Vertex Buffers Objects), przechowywanych w pamięci karty graficznej,
co ma dodatkowo wpływ na wzrost wydajności. Jeśli nie są dostępne, pozostaje korzystanie z list wyświetlania.
W dziedzinie obsługi dźwięku, OpenTK wspiera na chwilę obecną wyłącznie bibliotekę OpenAL w wersji 1.1 wraz z rozszerzeniami – wszystkie funkcje mogące powodować kłopoty nie są importowane ze względów bezpieczeństwa. Jest ona prosta w obsłudze i wspiera dźwięk przestrzenny – znalazła zastosowanie także w komercyjnych produktach (m.in. gry z serii Star Wars Jedi Knight, produkcje bazujące na silniku Unreal 2 i 3 itd.). Nazewnictwo funkcji i sposób programowania bardzo przypomina OpenGL, nie ma też problemów z przenośnością na obsługiwane platformy.
Zagadkę może stanowić obecność wsparcia dla OpenCL (Open Computing Language), którego oficjalna specyfikacja została przedstawiona w grudniu zeszłego roku. Umożliwia on tworzenie programów wykonywanych na heterogenicznych platformach, np. złożonych zarówno z CPU jak i GPU – powoduje to drastyczny wzrost wydajności obliczeniowej. Póki co, można to traktować raczej jako ciekawostkę, bo dzisiaj tylko najnowsze karty graficzne wiodących producentów wspierają ten standard.
Na stronie projektu znajdują się odnośniki do dodatków stworzonych przez społeczność, m.in. biblioteki do wczytywania modeli, zarządzania sceną. Uwagi, sugestie oraz błędy można zgłaszać na forum i są one uwzględniane przez twórców OpenTK. Tam też można znaleźć zapowiedzi zmian, nowości oraz wsparcie techniczne. Widać, że autorzy starają się dopracować swój projekt przed wypuszczeniem zbliżającej się wersji 1.0. Biblioteka wydaje się dobrą propozycją dla mniejszych projektów, które mają być przenośne i oparte na własnych rozwiązaniach, a nie gotowych silnikach.