Jakie zalety mają OpenGL, SFML i SDL w porównaniu do renderowania programowego?

24

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ę.

użytkownik148013
źródło
11
później w swojej serii (około odcinka 220) użyje opengl. Powodem tego jest szybkość.
maniak zapadkowy
5
Sztuką jest określenie, co narysować na ekranie. Wszystkie tekstury i cieniowania GPU, trójkąty, projekcje z kamery itp. Muszą być wykonane najpierw, aby zdecydować, jaki kolor powinien mieć każdy piksel. Przesuwanie kolorów pikseli na ekran to łatwa część.
user14146
2
Dla przypomnienia, SDL i OpenGL nie wykluczają się wzajemnie. SDL to „warstwa abstrakcji sprzętu”, która obsługuje okna, zdarzenia i dane wejściowe, a nie tylko bibliotekę graficzną. SDL ma również obsługę, która może być używana w połączeniu z OpenGL, dzięki czemu SDL może wykonywać wszystkie operacje inne niż graficzne, podczas gdy OpenGL obsługuje grafikę. Zauważ też, że najczęściej OpenGL działa bezpośrednio z GPU, podczas gdy SDL może, ale nie musi, w zależności od wersji i systemu, dla którego jest kompilowana.
Pharap
SFML używa OpenGL do renderowania, więc tak naprawdę wszystko SFML zapewnia prostszy interfejs do korzystania z OpenGL.
Cornstalks
2
Techcnailyl, co robi Casey, nadal korzysta z biblioteki graficznej. Biblioteka nazywa się GDI i chociaż jest częścią głównego API systemu operacyjnego, nadal jest technicznie biblioteką graficzną.
Pharap

Odpowiedzi:

41

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).

Richard Greenlees
źródło
12
OpenGL zna terminy takie jak punkty, linie i trójkąty. Przez większość czasu będziesz pracować z trójkątami. Aby dowiedzieć się, jak pracować z OpenGL , mogę polecić opengl-tutorial.org . Aby dowiedzieć się, co robi OpenGL pod maską, zajrzyj na oficjalną wiki: opengl.org/wiki/Rendering_Pipeline_Overview
tkausl
1
Miałem zamiar dać +1, ale nie podoba mi się to, że „wymyślałem koło”, ponieważ wydaje mi się, że robi to złe wrażenie w kontekście historii komputerów. Na pierwszym miejscu było renderowanie bitmap, dlatego też OpenGL „wymyślił koło”. Miały jednak dwa dobre powody: 1) standaryzację i 2) przyspieszenie GPU. Ponowne wynalezienie koła nie zawsze jest złe, jeśli nowa wersja stanowi ulepszenie (tj. Koła z oponami w porównaniu z kołami drewnianymi wagonami). Kluczową kwestią tutaj nie powinno być to, że renderowanie oprogramowania wymyśla na nowo koło, powinno być to, że jest gorsze od renderowania za pomocą GPU.
Pharap
4
@Pharap, z wyjątkiem tego , że teraz napisanie renderera oprogramowania absolutnie odkrywa koło, bez względu na to, czy było to historycznie.
porglezomp
1
To tylko połowa odpowiedzi. Następna odpowiedź to druga połowa, ale pełna odpowiedź (w tym trochę wyjaśnienia różnicy między OpenGL i innymi rzeczami, o których wspomina) byłaby właściwą odpowiedzią na to pytanie.
Jasper
1
@ user148013 „Czy Opengl zna terminy takie jak punkt, linia, trójkąt?” Współczesny OpenGL zajmuje się wyłącznie tymi prymitywami. Nie można rasteryzować niczego oprócz nich.
Nax 'vi-vim-nvim'
25

Moje pytanie brzmi: po co męczyć się z użyciem czegoś takiego jak open gl, sfml, sdl, gdy wszystko, co musisz zrobić, to po prostu przydzielić bufor, przekazać mapę bitową i narysować ją na ekranie?

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.

tkausl
źródło
8
Tworzy grę 2D, to inny temat jak 3D. A kiedy mówię powoli , niekoniecznie oznacza to, że ma mniej niż 60 fps, ale oznacza, że ​​karta graficzna wykona tę samą pracę w ułamku czasu potrzebnym procesorowi, przynajmniej jeśli chodzi o przestrzeń 3D.
tkausl
4
Powodem, dla którego GPU są w tym lepsze, jest to, że są skonfigurowane do równoległego wywoływania shaderów.
maniak zapadkowy
4
@ user148013 Z tego, co widziałem od tego faceta, powiedziałbym, że jest dokładnym przeciwieństwem „bardzo mądrego”.
Bartek Banachewicz
4
Renderowanie jest nie tylko wolniejsze (program renderujący Casey był zaskakująco szybki). Jest to również dużo danych, które można przesyłać z ogólnej pamięci RAM do pamięci RAM wideo. Przesunięcie gigantycznej mapy bitowej na kartę graficzną, w zależności od rodzaju magistrali, może zająć znaczną część czasu. Korzystając z GPU, od czasu do czasu wypychasz tekstury i używasz ich do wyświetlania klatka po klatce.
Adrian McCarthy
2
@ user148013 Istnieje różnica między krzykliwym a dobrym programowaniem. Mogą się nakładać, ale często są w konflikcie. Umieściłbym „Mogę renderować w oprogramowaniu [tak jak MESA może ...]” pod krzykliwym i na pewno nie dobrym rozwiązaniem .
11

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.

Bálint
źródło
Czy renderowanie oprogramowania jest możliwe także w systemie OS X? Ponieważ wydaje się, że wszystko, co ma związek z grafiką, zostało wykonane przez OpenGl teraz Metal.
user148013
2
@ user148013 Masz pewne nieporozumienia. OpenGL jest wieloplatformowym interfejsem API, więc może działać na OS X, w rzeczywistości może działać na wszystkich urządzeniach z „nowoczesnym” GPU (po 2000 r.) Metal to osobny interfejs API tylko dla urządzeń Apple. Renderowanie oprogramowania jest również odrębną cechą od obu z nich i tak, można to zrobić również w systemie OS X. Zasadniczo po prostu ustawia ręcznie piksele na ekranie za pomocą procesora.
Bálint
Właśnie dlatego zapytałem, ponieważ o ile wiem, renderowania oprogramowania nie można wykonać na OS X. Cocoa sięga do OpenGl, Quarz używa OpenGl, Core Framework używa OpenGl. Wszyscy teraz używają Metalu jako swojego sposobu szybciej. Ale nie znalazłem żadnej funkcji, która rysuje bufor na ekranie bez użycia GPU (OpenGl, Metal).
user148013
1
@ user148013 Ponieważ nie jest specyficzny dla systemu operacyjnego ani implementacji. Powiedzmy, że chcesz wdrożyć go w Javie, ponieważ jest to słynny wybór dla rozwoju wielu platform. W java możesz to zrobić, najpierw tworząc okno (JFrame), a następnie zamiast prostego rysowania na nim, rysujesz na obrazie, a następnie umieszczasz go na ramce. Nie będzie jednak znać terminów „trójkąt” ani „linia”. Tylko kolory. Musisz to zaimplementować za pomocą algorytmu rasteryzacji. Dlatego wolimy OpenGL, jest szybszy i nieco łatwiejszy w użyciu. Zasadniczo jest to interfejs API rasteryzacji.
Bálint
2
@ user148013 Dlaczego nie mogli? Jeśli mogą otworzyć okno i narysować na nim 1 obraz bez interfejsu API, mogą to zrobić.
Bálint
8

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!

erich8
źródło
2
Myślę, że to dobra odpowiedź, ponieważ wyjaśnia, dlaczego korzystanie z ram jest dobre, nie umniejszając pomysłu ponownego wynalezienia koła do celów edukacyjnych.
Pharap
3

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.

Uri Popow
źródło
3

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.

Aiman ​​Al-Eryani
źródło
0

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 :

Sprzęt graficzny Genesis składa się z 2 przewijalnych płaszczyzn. Każdy samolot składa się z płytek. Każda płytka ma kwadrat 8 x 8 pikseli i 4 bity na piksel. Każdy piksel może więc mieć 16 kolorów. Każdy kafelek może używać 1 z 4 tabel kolorów, więc na ekranie można uzyskać 64 kolory jednocześnie, ale tylko 16 w dowolnym kafelku. Kafelki wymagają 32 bajtów. Jest 64K pamięci graficznej. Pozwoliłoby to na 2048 unikalnych kafelków, gdyby pamięć została wykorzystana do niczego innego.

pjc50
źródło
-2

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 .

SmugLispWeenie
źródło