Zacząłem oglądać strumień Handmade Hero , gdzie Casey Muratori tworzy silnik gry bez użycia ram lub tym podobnych. Wczoraj dotarłem do części, w której pokazał, jak obraz jest rysowany na ekranie. O ile rozumiem, po prostu przydzielił trochę pamięci tak dużej, jak rozmiar ekranu, na który chce narysować. Następnie stworzył bitmapę, którą przekazał do przydzielonej pamięci bufora i narysował ją na ekranie za pomocą funkcji specyficznej dla systemu operacyjnego.
Wydaje się to dość proste. Użyłem GameMakera, zmieniłem na Love2D, trochę pracowałem z Sprite Kit, ale zawsze zastanawiałem się, co tak naprawdę dzieje się pod tymi czasami mylącymi warstwami.
Biorąc to pod uwagę, dlaczego nawet męczyć się z użyciem bibliotek graficznych (OpenGL, SFML, SDL,…), gdy wszystko, co musisz zrobić, to po prostu przydzielić bufor, przekazać mapę bitową i narysować ją na ekranie?
Jeśli chcesz narysować na ekranie różne rzeczy, po prostu napisz je do mapy bitowej, która następnie zostanie przekazana do bufora. Jestem całkiem nowy w programowaniu, ale wydaje mi się to dość proste. Proszę popraw mnie jeżeli się mylę.
źródło
Odpowiedzi:
Nie chodzi tylko o szybkość wykonania, ale także o prostotę. Chociaż rendering oprogramowania zastosowany w tym przykładzie byłby o wiele wolniejszy niż przy użyciu akceleracji sprzętowej (tj. GPU), narysowanie kilku bitmap na ekranie jest tak trywialnym zadaniem, że nie zauważysz spadku wydajności.
Jednak działania niskiego poziomu, takie jak rasteryzacja trójkątów, sortowanie głębokości itp., Są dobrze zrozumiałymi pojęciami, które GPU może obsłużyć niejawnie za pomocą kilku poleceń. Ponowne wdrożenie tych w trybie oprogramowania zasadniczo wymyśla koło. Jest to w porządku, jeśli chcesz dowiedzieć się, jak renderowanie odbywa się na niskim poziomie, sam napisałem program do renderowania oprogramowania 3D, aby trochę go zbadać, ale w większości przypadków strata czasu, gdy OpenGL może to zrobić szybciej pudełko.
Podany przykład brzmi niezwykle prosto, wystarczy narysować pojedynczy obraz na ekranie, dlatego implementacja jest łatwa. Gdy zaczniesz nakładać warstwy na złożoność, przekonasz się, że coraz trudniej jest poprawnie renderować wszystko. Rzeczy, które ludzie musieli robić w czasach Quake'a renderowania oprogramowania 3D, były szalone, choć doceniam, że nie posuwasz się tak daleko (jeszcze).
źródło
Krótko: Ponieważ jest szybki (OpenGL, DirectX).
Długie:
Możesz myśleć, że możesz zrobić to wszystko sam. Narysuj piksele na ekranie. Możesz napisać małą bibliotekę do rysowania kształtów, takich jak quady lub trójkąty. To oczywiście zadziała. Istnieje wiele bibliotek, które dokładnie to robią. Niektóre z nich implementują nawet specyfikację OpenGL (więc są one jak oprogramowanie dla Opengl), co zrobi dokładnie to, co robi Casey Muratori. Obliczają wszystko po stronie oprogramowania, ustawiają piksele po stronie oprogramowania i zapisują wynik na ekranie.
Jest to jednak powolne . Procesor, który ostatecznie wykona wszystkie te rzeczy, nie został stworzony dla tego scenariusza. Po to są GPU. OpenGL (o ile oczywiście nie jest to implementacja programowa), bierze wszystko, co mu każesz i wypycha wszystkie dane, wszystkie połączenia losowe, prawie wszystko na kartę graficzną i nakazuje GPU wykonanie pracy. Procesor graficzny został stworzony specjalnie do tego rodzaju zadań. Mnożenie liczb zmiennoprzecinkowych (to jest to, co często robisz podczas rysowania sceny 3D) i wykonywanie programów cieniujących. I to równolegle. Aby dowiedzieć się, jak szybki jest procesor graficzny, pomyśl o prostej scenie 3D na pełnym ekranie z 1920 x 1080 pikseli. Są to, pomnożone, 2 073 600 pikseli do narysowania. Dla każdegopiksel, procesor graficzny uruchomi moduł cieniujący fragmenty przynajmniej raz , przeważnie więcej niż jeden raz. Załóżmy teraz, że pracujemy z prędkością 60 klatek na sekundę. Oznacza to, że procesor graficzny uruchamia moduł cieniujący fragmentów 2 073 600 * 60 = 124 416 000 razy na sekundę . Czy uważasz, że możesz zrobić coś takiego na swoim CPU? (To dość uproszczone objaśnienie, jest o wiele więcej rzeczy do rozważenia, np. Ile pikseli przesuwasz się przez bliższe obiekty, ile MSAA używasz itd., Jednak 124.446.000 razy na sekundę jest prawdopodobnie najniższą możliwą do uzyskania, a ty z łatwością uzyskasz więcej niż 60 klatek na sekundę dzięki prostej scenie)
To właśnie robią OpenGL i Direct3D, za jakie silniki widzą odpowiedź @Uri Popovs.
źródło
To, co robi, nazywa się renderingiem oprogramowania , a OpenGL nazywa się renderingiem GPU
Jaka jest różnica między nimi? Szybkość i pamięć.
Rasteryzacja (wypełnianie trójkątów na ekranie) zajmuje trochę czasu. Jeśli robisz to na procesorze, zasadniczo zabierasz ten czas logice gry, zwłaszcza jeśli nie jest dobrze zoptymalizowana.
I nie ma znaczenia, jak mały jest obraz, musi przeznaczyć na to pewną ilość pamięci. Procesory graficzne mają do tego pamięć wideo.
źródło
Podczas gdy odpowiedzi od innych są bardziej poprawne niż jakakolwiek odpowiedź, którą mogę udzielić, chcę wskazać podstawowe nieporozumienie dotyczące sposobu działania oprogramowania, które moim zdaniem leży u podstaw twojego pytania. Chociaż zawsze można robić rzeczy „samodzielnie” bez frameworka i często przynosi to ogromne korzyści edukacyjne, w rzeczywistości nie jest tak tworzone nowoczesne oprogramowanie.
Ktoś stworzył sprzęt i języki maszyn, które na nim działają. Ktoś inny tworzy języki i kompilatory wyższego poziomu, sterowniki i systemy operacyjne, biblioteki graficzne i tak dalej. Każdy z nas opiera się na pracy naszych poprzedników. To nie tylko „w porządku”, to wymóg.
Rysujesz linię tego, co jest „akceptowalne” lub nie w dowolnym punkcie łańcucha narzędzi. Równie łatwo można powiedzieć „po co używać C ++, skoro można zrobić to samo w asemblerze?” Lub „po co polegać na sterownikach klawiatury, skoro równie łatwo można odczytać napięcia wychodzące z jego przewodów i samemu je obliczyć?” Nie ma wystarczającej liczby godzin w ciągu dnia lub lat w życiu, aby każdy mógł zrobić wszystko sam.
Nie dotyczy to tylko tworzenia oprogramowania, ale ogólnie życia współczesnego. Czy słyszałeś kiedyś o gościu, który zbudował toster od zera? http://www.thomasthwaites.com/the-toaster-project/ . Zajęło to naprawdę dużo czasu i dużo wysiłku. Do tostera. Spróbuj samodzielnie zbudować wszystko , co jest potrzebne do zaktualizowania gry wideo z eteru!
źródło
Silniki robią znacznie więcej niż tylko rysowanie obrazu na ekranie. Obsługują oświetlenie, cienie, dane wejściowe, wykrywanie kolizji. Nawet sama część renderowania jest o wiele bardziej złożona niż po prostu przesuwanie bufora na ekran. Szczególnie w przypadku scen 3D musisz wykonać wiele obliczeń na znacznie bardziej złożonych danych niż mapa bitowa. Pozwól, że dam ci analogię do samochodu: to, co opisujesz jako proste, to wydech samochodu. Po prostu wykonujesz rurę o odpowiednim rozmiarze, a następnie przepychasz gaz z jednego końca na drugi. Jednak nie jest to jedyna rzecz, która dzieje się w mechanizmie samochodu.
źródło
Powyższe odpowiedzi są doskonałe, ale tak naprawdę żadna nie jest najważniejszym powodem, dla którego preferowane są OpenGL i takie. Głównym powodem jest wykorzystanie dedykowanego sprzętu zaprojektowanego specjalnie do pracy z takimi rzeczami, jak renderowanie milionów pikseli na ekranie, GPU .
W przypadku renderowania programowego przy użyciu procesora moduł renderujący zapętla się jeden po drugim po wszystkich pikselach na mapie bitowej i wydaje polecenia, aby każdy z nich wyświetlał się na ekranie. Jeśli więc renderujesz obraz o wymiarach 1000 x 1000, to 1 000 000 pętli dla twojego procesora. W końcu zostały zaprojektowane z myślą o kontroli; wiele warunków, skoki z jednego zestawu instrukcji do drugiego i ścisły kierunek przepływu kontroli. Jednak procesor graficzny został zaprojektowany ze świadomością, że będzie wykonywał wiele podobnych pętli nad pikselami na ekranie.Procesor graficzny wykorzystałby pętlę for z iteracjami 1000000 i podzieliłby pracę na ogromną liczbę rdzeni, aby każdy z nich pracował ** równolegle i niezależnie od siebie **. Zatem w przeciwieństwie do procesora, za każdym razem, gdy GPU napotka warunek if-else, obsłuży obie gałęzie kodu do dwóch rdzeni, a NASTĘPNIE na samym końcu sprawdzi, co warunek ocenia i odrzuca wynik niepotrzebnej gałęzi (dlatego wiele warunków if-else w shaderach GPU jest odrzuconych; zawsze są one odpowiedzialne za marnotrawstwo).
Tak więc, procesory graficzne są zbudowane wokół równoległości . Dzięki temu praca z pikselami jest dla nich znacznie szybsza w porównaniu do procesorów.
źródło
Zobacz Czy naprawdę muszę korzystać z graficznego interfejsu API?
Jasne, możesz poprosić o bufor, ustawić w nim trochę bitów i zapisać go na ekranie. Był to w zasadzie jedyny sposób na programowanie grafiki na PC, dopóki nie pojawił się akcelerator grafiki w połowie lat 90. z 3DFX. Nawet w systemie Windows DirectX został opracowany w celu zapewnienia bezpośredniego dostępu do pamięci wideo.
Ale na sprzęcie przeznaczonym do gier innych niż PC zawsze istniały techniki przyspieszania grafiki poprzez odciążanie procesora. Nawet Atari 2600 miał „sprity sprzętowe”, częściowo dlatego, że nie miał wystarczającej ilości pamięci RAM dla bufora ramki.
Później (w połowie lat 80.) konsole do gier zostały zoptymalizowane pod kątem gier platformowych. Ponownie, bez bufora ramki; zamiast tego programista może określić siatki płytek :
źródło
Nowoczesne procesory są wystarczająco szybkie, aby wykonać dowolną grę 2d w oprogramowaniu, więc dla grafiki 2d OpenGL / DirectX nie przyniesie żadnych korzyści, oprócz dodania jeszcze jednej zależności i warstwy złożoności do twojego projektu, np. Ustawienia matrycy projekcji 3D, aby narysować kilka ikonek i przesyłanie danych do GPU.
OpenGL zmusiłby cię również do spakowania wszystkich duszków w tekstury 512x512 (artefakt starych konsol, takich jak PSX, pakowanie grafiki na stronach pamięci wideo), wymagający napisania dość złożonego kodu pakowania duszków.
Z drugiej strony, jeśli robisz 3d, renderując miliony trójkątów ze złożonym cieniowaniem, to GPU jest nieuniknione. Dawno temu istniała prostsza tylko wersja 2d Direct3d, o nazwie DirectDraw, która przyspieszała rysowanie sprite przez GPU, ale teraz Microsoft już go nie obsługuje, być może dlatego, że procesory są wystarczająco szybkie, aby wykonać 2d bez żadnego przyspieszenia, jeśli nie zależy ci na oszczędzaniu energii .
źródło