Jak CPU a GPU Interact to Render Computer Graphics?
Centrální procesor (CPU) a grafická procesorová jednotka (GPU) počítače reagují na každou chvíli, kdy používáte počítač, aby vám poskytli ostré a citlivé vizuální rozhraní. Čtěte dále, abyste lépe pochopili, jak spolupracují.
fotka od sskennel.
Dnešní zasedání Otázky a odpovědi se k nám přichází s laskavým svolením SuperUser - subdivize Stack Exchange, seskupení webových stránek Q & A.
Otázka
Čtenář SuperHouse Sathya položil otázku:
Zde si můžete prohlédnout snímek malého programu C ++ s názvem Triangle.exe s rotujícím trojúhelníkem založeným na OpenGL API.
Samozřejmě velmi základní příklad, ale myslím, že je to použitelné i pro jiné operace grafických karet.
Byl jsem jen zvědavý a chtěl poznat celý proces z dvojitého kliknutí na Triangle.exe pod Windows XP, dokud nevidím, jak se trojúhelník otáčí na monitoru. Co se stane, jak interaguje procesor (který nejprve zpracuje .exe) a GPU (který konečně vyvede trojúhelník na obrazovce)?
Myslím, že zapojený do zobrazování tohoto rotujícího trojúhelníku je především následující hardware / software:
Hardware
- HDD
- Systémová paměť (RAM)
- procesor
- Videopaměť
- GPU
- LCD displej
Software
- Operační systém
- API rozhraní DirectX / OpenGL
- Ovladač Nvidia
Může někdo vysvětlit proces, možná s nějakým vývojovým diagramem pro ilustraci?
Nemělo by to být složité vysvětlení, které by pokrývalo každý jednotlivý krok (odhad, který by překonal rozsah), ale vysvětlení, které může následovat IT člověk.
Jsem si jistý, že spousta lidí, kteří by se dokonce nazývali, odborníci v oblasti IT nemohli tento proces správně popsat.
Odpověď
Ačkoli několik členů komunity odpovídalo na otázku, Oliver Salzburg šel navíc a odpověděl na něj nejen s podrobnou odpovědí, ale vynikající doprovodnou grafikou.
Obrázek JasonC, který je zde k dispozici jako tapeta.
Napsal:
Rozhodla jsem se trochu psát o aspektu programování a o tom, jak jednotlivé komponenty mluví. Možná to jistě osvětlí určité oblasti.
Prezentace
Co je potřeba mít dokonce ten jediný obrázek, který jste vyslali ve své otázce, na obrazovce?
Existuje mnoho způsobů, jak nakreslit trojúhelník na obrazovce. Pro jednoduchost předpokládejme, že nebyly použity žádné vyrovnávací paměti vertexu. (A vertex bufferje oblast paměti, kde ukládáte souřadnice.) Předpokládejme, že program jednoduše řekne grafické zpracování potrubí o každém jednotlivém vrcholu (vrchol je jen souřadnice v prostoru) v řadě.
Ale, než můžeme nakreslit něco, musíme nejprve spustit nějaké lešení. Uvidíme proč později:
// Vymazat obrazovku a vyrovnávací paměť hloubky glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Obnovit aktuální modelovou maticu zobrazení glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Kreslení pomocí trojúhelníků glBegin (GL_TRIANGLES); // červená glColor3f (1.0f, 0.0f, 0.0f); // vrchol trojúhelníku (přední) glVertex3f (0.0f, 1.0f, 0.0f); // Zelená glColor3f (0.0f, 1.0f, 0.0f); // Levý trojúhelník (přední) glVertex3f (-1.0f, -1.0f, 1.0f); // modrá glColor3f (0.0f, 0.0f, 1.0f); // pravý trojúhelník (přední) glVertex3f (1.0f, -1.0f, 1.0f); // Kreslení výkresu ();
Tak co to udělalo?
Když napíšete program, který chce používat grafickou kartu, obvykle si vyberete nějaké rozhraní k ovladači. Některé známé rozhraní pro řidiče jsou:
- OpenGL
- Direct3D
- CUDA
Pro tento příklad budeme držet OpenGL. Teď, tvoje rozhraní k ovladači je to, co vám dává všechny nástroje, které potřebujete pro váš program mluvit na grafickou kartu (nebo ovladač, který pak rozhovory na kartu).
Toto rozhraní vám zajistí jistotu nástroje. Tyto nástroje mají podobu rozhraní API, které můžete volat z vašeho programu.
Toto API je to, co vidíme ve výše uvedeném příkladu. Podívejme se blíže.
Lešení
Než budete moci skutečně provést nějaký skutečný výkres, budete muset provést a založit. Musíte definovat svůj výřez (oblast, která bude skutečně vykreslena), váš pohled ( Fotoaparát do svého světa), jaké anti-aliasing budete používat (k vyhlazení hrany vašeho trojúhelníku) ...
Ale my se na to nebudeme dívat. Jen se podíváme na věci, které budete muset udělat každý snímek. Jako:
Vymazání obrazovky
Grafické potrubí nebude vyčistit obrazovku pro vás každý snímek. Musíte to říct. Proč? To je důvod, proč:
Pokud obrazovku neuložíte, jednoduše přetáhnout každý snímek. Proto voláme glClear
sGL_COLOR_BUFFER_BIT
soubor. Druhý bit (GL_DEPTH_BUFFER_BIT
) řekne OpenGL vymazat hloubkavyrovnávací paměť. Tento buffer slouží k určení, které pixely jsou před (nebo za) jinými pixely.
Proměna
Zdroj obrázku
Transformace je část, ve které přebíráme všechny vstupní souřadnice (vrcholy našeho trojúhelníku) a použijeme naši matici ModelView. Toto je matice vysvětluje jak naše Modelka (vrcholy) jsou otočeny, zmenšeny a přeloženy (přesunuty).
Dále použijeme naši promítací matici. Toto posune všechny souřadnice tak, aby správně našli fotoaparát.
Teď se znovu změníme s naší maticí Viewportu. Děláme to tak, abychom změnili náš Modelka na velikost monitoru. Nyní máme množinu vrcholů, které jsou připraveny k vykreslení!
O trochu později se vrátíme k transformaci.
Výkres
Chcete-li nakreslit trojúhelník, jednoduše řekneme OpenGL, že začne nový seznam trojúhelníků voláním glBegin
s GL_TRIANGLES
konstantní.
Existují i jiné formy, které můžete čerpat. Jako trojúhelníkový pás nebo trojúhelníkový ventilátor. Jedná se především o optimalizace, neboť vyžadují menší komunikaci mezi CPU a GPU, aby se nakreslilo stejné množství trojúhelníků.
Poté můžeme poskytnout seznam souborů tří vrcholů, které tvoří každý trojúhelník. Každý trojúhelník používá 3 souřadnice (protože jsme ve 3D prostoru). Kromě toho také poskytuji barva pro každý vrchol volánímglColor3f
před povolání glVertex3f
.
Stín mezi třemi verzemi (3 rohy trojúhelníku) vypočítá OpenGLautomaticky. Bude interpolovat barvu po celé ploše polygonu.
Interakce
Nyní, když kliknete na okno. Aplikace má pouze zachytit zprávu okna, která signalizuje kliknutí. Poté můžete v požadovaném programu spustit libovolnou akci.
To dostane a hodně obtížnější, jakmile začnete pracovat s vaší 3D scénou.
Nejprve musíte jasně zjistit, na kterém pixelu uživatel klepl na okno. Pak, vezměte své perspektivnímůžete počítat směr paprsku, od okamžiku kliknutí myší do scény. Potom můžete vypočítat, zda má nějaký objekt ve scéně protíná s tímto paprskem. Nyní víte, jestli uživatel klepl na objekt.
Takže, jak to rotujete?
Proměna
Jsem si vědom dvou typů transformací, které se obecně používají:
- Transformace založená na matrici
- Kostní transformace
Rozdíl je v tom kosti ovlivnit jeden vrcholy. Matrice vždy ovlivňují všechny nakreslené vrcholy stejným způsobem. Podívejme se na příklad.
Příklad
Dřív jsme načítali naše matice identity než nakreslíme náš trojúhelník. Matrice totožnosti je jednoduchá žádná transformace vůbec. Takže, co jsem kreslil, je ovlivněn pouze mojí perspektivou. Takže trojúhelník se vůbec neotočí.
Pokud chci to otáčet, mohu buď udělat matematiku (na CPU) a jednoduše zavolat glVertex3f
sjiný souřadnice (které se otáčejí). Nebo bych mohl nechat GPU dělat všechnu práci voláním glRotatef
před kreslením:
// Otočte trojúhelník na ose y glRotatef (množství, 0.0f, 1.0f, 0.0f);
množství
je samozřejmě jen pevnou hodnotou. Pokud chceš animovat, budete muset sledovat množství
a zvětšete jej každý snímek.
Počkejte, co se stalo s celou matrixovou diskusi dříve?
V tomto jednoduchém příkladu se nemusíme starat o matrice. Prostě zavoláme glRotatef
a stará se o to vše pro nás.
glRotate
produkuje rotaciúhel
stupňů kolem vektoru x y z. Současná matice (seeglMatrixMode) se vynásobí maticí rotace s produktem nahrazujícím aktuální matici, protože ifglMultMatrix byl volán s následující maticí jako jeho argument:x 2 1 - c + cx y y 1 - c - z s z 1 - c + y y y 1 - c + z sy 2 1 - c + cy z z 1 - c - x ∈ 1 - c + x sz 2 1 - c + c 0 0 0 0 1
No, díky za to!
Závěr
Je zřejmé, že je spousta diskuse na OpenGL. Ale to neříká nás cokoliv. Kde je komunikace?
Jediná věc, kterou nám OpenGL říká v tomto příkladu, je když je hotovo. Každá operace bude trvat určitou dobu. Některé operace jsou neuvěřitelně dlouhé, jiné jsou neuvěřitelně rychlé.
Odeslání vrcholu na GPU bude tak rychlý, já bych ani nevěděl, jak to vyjádřit. Odesílání tisíců vrcholů z CPU do GPU, každý jednotlivý snímek, je s největší pravděpodobností žádným problémem.
Vymazání obrazovky může trvat milisekundu nebo ještě horší (mějte na paměti, že většinou máte jen 16 milisekund času na kreslení každého snímku), v závislosti na tom, jak velký je váš výřez. Chcete-li ji vymazat, musí OpenGL kreslit každý pixel v barvě, kterou chcete vymazat, to může být miliony pixelů.
Kromě toho můžeme prakticky požádat OpenGL o možnosti grafického adaptéru (max. Rozlišení, max. Anti-aliasing, max. Hloubka barev, ...).
Ale můžeme také vyplnit texturu s pixely, které mají každý konkrétní barvu. Každý pixel tak drží hodnotu a textury je obrovský "soubor" naplněný daty. Můžeme ho načíst do grafické karty (vytvořením vyrovnávací paměti textury), načíst shader, říci, že shader používá naši strukturu jako vstup a řídit některé extrémně těžké výpočty na našem "souboru".
Můžeme potom "vykreslit" výsledek našeho výpočtu (ve formě nových barev) do nové struktury.
Tak můžete GPU pracovat pro vás jinými způsoby. Předpokládám, že se CUDA podobá tomuto aspektu, ale nikdy jsem s ním neměl příležitost pracovat.
Opravdu jsme se jen mírně dotýkali celého tématu. Programování 3D grafiky je peklo zvířete.
Zdroj obrázku
Musíte něco přidat k vysvětlení? Vypadněte v komentářích. Chcete se dozvědět více odpovědí od ostatních uživatelů technologie Stack Exchange? Podívejte se na celý diskusní příspěvek zde.