Podczas tworzenia abstrakcji systemu lepiej jest mieć różne interfejsy API ukryte przez wspólny interfejs na najniższym poziomie, który ma sens.
Biorąc pod uwagę różne nowoczesne (bez stałego potoku funkcji) natywne interfejsy API grafiki: OpenGLES 2.0+, OpengGL 3.0+, DirectX 10.0+, Xbox DirectX 9, LibGCM
Jeśli ktoś miałby stworzyć bezstanowy graficzny interfejs API niskiego poziomu, aby usiąść nad nimi wszystkimi, jaki byłby najlepszy sposób, aby uczynić go tak cienkim i najszybszym, jak to możliwe?
architecture
software-engineering
graphics
cross-platform
NocturnDragon
źródło
źródło
Odpowiedzi:
Najniższy poziom, który ma sens z mojego punktu widzenia, to coś, co mówi o zasobach zaangażowanych w renderowanie - vb / ib, renderowanie powierzchni, tekstur, shaderów, bloków stanów itp.
Problem polega na tym, że niektóre z nich muszą być w różnych formatach, w zależności od interfejsu API - tam jest trochę trudniej. Najłatwiejszym sposobem jest wstępne przetworzenie zasobów statycznych dla odpowiedniego interfejsu API. W przypadku dynamicznych używaj tylko shaderów do ich generowania - dzięki temu pozostawanie w formatach natywnych jest dość proste.
Wszystko, co wtedy robisz na wyższym poziomie, to konfigurowanie potoków z dołączonymi zasobami i przekazywanie ich do GPU. Przekonasz się, że nie wszystko można ładnie wydobyć w ten sposób, zwłaszcza jeśli skorzystasz z trików specyficznych dla sprzętu. Ale to dobry początek.
(Sidenote: jeśli traktujesz sztuczki związane z platformą jako specjalny rodzaj zasobów, możesz posunąć całą tę koncepcję dość daleko).
W ten sposób stworzysz dwie rzeczy: menedżera zasobów sprzętowych oraz zestaw narzędzi do skonfigurowania DAG tych zasobów.
źródło
Biorąc pod uwagę szeroki zakres interfejsów API, które chcesz objąć, typowe podejście do owijania może być nieefektywne i może powodować trudności w mapowaniu koncepcji interfejsów API w kilku innych interfejsach API, które mogą, ale nie muszą, wspierać różne funkcje w różnym stopniu.
W rezultacie najbardziej sensownym podejściem byłoby stworzenie API zorientowanego na funkcje . Chociaż takie podejście uniemożliwia użytkownikowi interfejsu API korzystanie ze wszystkich dostępnych funkcji, znacznie upraszcza implementację każdego zaplecza i umożliwia optymalizacje specyficzne dla zaplecza, które w innym przypadku nie byłyby możliwe.
Znacznie upraszcza także zarządzanie nieobsługiwaną funkcjonalnością dla użytkownika interfejsu API; nie muszą już sprawdzać, czy funkcja X istnieje, i określać, których funkcji dotyczy, ale zamiast tego muszą tylko zapytać samą funkcję, aby sprawdzić, czy jest obsługiwana w bieżącej konfiguracji. Nawet jeśli obsługujesz częściowe lub ograniczone tryby funkcji, podany kontekst znacznie ułatwia zarządzanie.
Jeśli chodzi o tworzenie renderera bezstanowego (zwanego również renderowaniem opartym na przesyłaniu ), zwykle do spakowania i przesłania poleceń do renderowania używa się 64-bitowego klucza . Od tego momentu istnieje duża elastyczność pod względem wykonywania poleceń i informacji, które należy przesyłać, w zależności od funkcji i możliwości, które chcesz obsługiwać.
źródło
Na początek każdy interfejs API działa inaczej, więc nie trzeba dodawać, że owijanie wszystkich powyższych interfejsów API byłoby trudne. To powiedziawszy, czasem trzeba to zrobić: w pewnym momencie gra musi po prostu działać na więcej niż jednej platformie, niezależnie od tego, jak ciężko to zrobić.
Myślę, że najlepszym sposobem na zrobienie tego jest wymyślenie funkcji, które można zaimplementować we wszystkich bazowych interfejsach API, i streszczenie tego i tylko to. Jeśli tworzysz grę wieloplatformową, nie zaimplementowałbyś wszystkich niejasnych funkcji obsługiwanych przez każdy interfejs API, zaimplementowałbyś tylko to, czego potrzebujesz. Pomaga to również utrzymać interfejs API mały i szybki.
Aby uniknąć upakowania implementacji każdego innego interfejsu API w danych wyjściowych, kompilacja powinna odbywać się przy użyciu neutralnych dla platformy plików nagłówkowych i specyficznych dla platformy plików kodu. Wówczas plik kodu specyficzny dla platformy docelowej byłby jedynym skompilowanym, utrzymującym API mały.
źródło
Jest na ten temat artykuł na temat GPU Pro autorstwa Emila Perssona (Humus)
http://gpupro.blogspot.com/2009/12/making-it-large-beautiful-fast-and.html
źródło
Możesz sprawdzić bibliotekę SDL lub Allegro . Obie są niskopoziomowymi, wysoce przenośnymi bibliotekami gier, które umożliwiają podłączenie ich w kontekście OpenGL, dzięki czemu można tam renderować swoją grafikę. SDL słynie z tego, że został użyty przez nieistniejącego Loki Games do przeniesienia niektórych popularnych gier z 2000 roku na Linuksa, a Allegro ma dużo czasu i ma świetną społeczność amatorskich twórców gier.
źródło