Hogyan működik a CPU és a GPU a számítógépes grafika rendereléséhez?
A számítógép központi feldolgozóegysége (CPU) és a grafikus feldolgozó egység (GPU) minden egyes pillanatban kölcsönhatásba lép a számítógéppel, hogy tiszta és érzékeny vizuális felületet biztosítson. Olvassa tovább, hogy jobban megértse, hogyan működnek együtt.
A képet készítette sskennel.
A mai Kérdések és válaszok munkamenet jön számunkra a SuperUser-Stack Exchange alosztályának, a Q & A webhelyek közösségi meghajtó csoportosításának.
A kérdés
A SuperUser olvasó Sathya felvetette a kérdést:
Itt látható egy kis C ++ program, a Triangle.exe egy képe, amely az OpenGL API alapján forgó háromszöggel rendelkezik..
Igaz, hogy ez egy nagyon alapvető példa, de azt hiszem, ez más grafikus kártyákkal kapcsolatos műveletekre is alkalmazható.
Csak kíváncsi voltam és meg akartam tudni az egész folyamatot, amikor a Windows XP alatt a dupla kattintással rákattintok a Triangle.exe-re, amíg nem látom a monitoron forgó háromszöget. Mi történik, hogyan működik a CPU (amely először kezeli az .exe-t) és a GPU (amely végül kiadja a háromszöget a képernyőn)?
Azt hiszem, ennek a forgó háromszögnek a megjelenítésében elsősorban a következő hardver / szoftver tartozik:
Hardver
- HDD
- Rendszer memória (RAM)
- processzor
- Videomemória
- GPU
- LCD kijelzö
Szoftver
- Operációs rendszer
- DirectX / OpenGL API
- Nvidia illesztőprogram
Lehet bárki megmagyarázni a folyamatot, talán valamilyen folyamatábrával illusztrálni?
Nem szabad olyan összetett magyarázat, amely minden egyes lépést lefed (a találgatáson túlmutató találgatás), hanem egy közbenső informatikai srác magyarázata.
Biztos vagyok benne, hogy sok ember, aki még IT-szakembernek is nevezné, nem tudta megfelelően leírni ezt a folyamatot.
A válasz
Bár több közösségi tag válaszolt a kérdésre, Oliver Salzburg elment az extra mérföldre, és nemcsak részletes választ, hanem kiváló kísérő grafikát is válaszolt.
JasonC képe itt elérhető háttérképként.
Ír:
Úgy döntöttem, hogy írok egy kicsit a programozási szempontról és arról, hogy az összetevők hogyan beszélnek egymással. Talán megvilágíthat bizonyos területeken.
A prezentáció
Mire van szükség ahhoz, hogy az egyetlen képed, amit a kérdésedben feltettél, a képernyőn húzott?
Sokféle módon lehet rajzolni egy háromszöget a képernyőn. Az egyszerűség kedvéért feltételezzük, hogy nem használtunk csúcspuffereket. (A csúcspufferegy memóriaterület, ahol a koordinátákat tárolja.) Tegyük fel, hogy a program egyszerűen elmondta a grafikus feldolgozó csővezetéknek minden egyes csúcsról (egy csúcs csak egy koordinátát jelent az űrben) egy sorban.
De, Mielőtt bármit megrajzolhatnánk, először néhány állványt kell futtatnunk. Meglátjuk miért majd később:
// Törölje a képernyőt és a mélységi puffert (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Az aktuális Modelview mátrix glMatrixMode (GL_MODELVIEW) visszaállítása; glLoadIdentity (); // Rajzolás háromszögek használatával glBegin (GL_TRIANGLES); // Piros glColor3f (1.0f, 0.0f, 0.0f); // A háromszög teteje (elöl) glVertex3f (0.0f, 1.0f, 0.0f); // Zöld glColor3f (0.0f, 1.0f, 0.0f); // A háromszög bal oldala (elöl) glVertex3f (-1.0f, -1.0f, 1.0f); // Kék glColor3f (0.0f, 0.0f, 1.0f); // A háromszög joga (elöl) glVertex3f (1.0f, -1.0f, 1.0f); // Kész Rajz glEnd ();
Szóval mit tett ez?
Amikor egy olyan programot ír, amely használni kívánja a grafikus kártyát, akkor általában valamilyen interfészt választ ki az illesztőprogramhoz. Néhány jól ismert interfész a vezetőhöz:
- OpenGL
- Direct3D
- CUDA
Ehhez a példához az OpenGL-t fogjuk használni. Most, a illesztőprogramhoz Ez az, ami megadja az összes eszközt, amire szüksége van a program létrehozásához beszélgetés a grafikus kártyára (vagy az illesztőprogramra, amelyik akkor lesz beszél a kártyához).
Ez az interfész köteles biztosítani szerszámok. Ezek az eszközök olyan API formátumúak, amelyeket a programból hívhat.
Ez az API az, amit a fenti példában használunk. Nézzük közelebbről.
Az állványzat
Mielőtt valóban bármilyen rajzot készítene, végre kell hajtania a beállít. Meg kell határoznia a nézetablakot (a ténylegesen megjelenő területet), a perspektívát (a kamera a világodba), milyen anti-aliasing-ot fogsz használni (a háromszög széleinek simításához)…
De ezt nem fogjuk megnézni. Csak megnézzük a dolgokat, amiket meg kell tenned minden keret. Mint:
A képernyő törlése
A grafikus csővezeték nem fogja tisztítani a képernyőt minden keret számára. Meg kell mondanod. Miért? Ez az oka:
Ha nem törli a képernyőt, egyszerűen egyszerűen húzza át minden keretben. Ezért hívjuk glClear
a ... valGL_COLOR_BUFFER_BIT
készlet. A másik bit (GL_DEPTH_BUFFER_BIT
) megmondja az OpenGL-nek, hogy törölje a mélységpuffer. Ezt a puffert használjuk annak meghatározására, hogy melyik pixel van más (vagy mögött) más pixeleken.
átalakítás
Képforrás
Az átalakítás az a rész, ahol minden beviteli koordinátát (háromszögünk csúcsai) vesszük, és alkalmazzuk a ModelView mátrixunkat. Ez a mátrix magyarázza hogyan modell (a csúcsok) elforgatásra, méretezésre és lefordításra kerülnek (áthelyezve).
Ezután a kivetítő mátrixot alkalmazzuk. Ez az összes koordinátát úgy mozgatja, hogy helyesen nézzen szembe a kamerával.
Most újra átalakítjuk a Viewport mátrixunkkal. Ezt úgy csináljuk, hogy mérlegeljük modell a monitor méretéhez. Most van egy sor csúcs, amely készen áll a renderelésre!
Egy kicsit később visszatérünk az átalakításhoz.
Rajz
Háromszög rajzolásához egyszerűen elmondhatjuk az OpenGL-nek, hogy elindítson egy újat háromszögek listája hívással glBegin
a ... val GL_TRIANGLES
állandó.
Vannak más formák is. Mint egy háromszög szalag vagy háromszög ventilátor. Ezek elsősorban optimalizálások, mivel kevesebb kommunikációt igényelnek a CPU és a GPU között, hogy ugyanolyan mennyiségű háromszöget rajzoljanak ki.
Ezt követően 3 csúcskészletet adhatunk meg, amelyeknek minden háromszögnek ki kell egészítenie. Minden háromszög 3 koordinátát használ (ahogy a 3D-s térben vagyunk). Ezenkívül a szín minden csúcsra hívás útjánglColor3f
előtt hívás glVertex3f
.
A 3 csúcs közötti árnyalatot (a háromszög három sarkát) az OpenGL számítja kiautomatikusan. Interpolálja a színt a sokszög egész arcán.
Interakció
Most, amikor rákattint az ablakra. Az alkalmazásnak csak az ablak üzenetét kell rögzítenie, amely jelzi a kattintást. Ezután futtathat bármilyen műveletet a kívánt programban.
Ez egy sok nehezebb, ha el akarja kezdeni a 3D-s jelenetet.
Először egyértelműen tudnia kell, hogy melyik pixelre kattint a felhasználó az ablakra. Akkor, vegye el távlatifigyelembe véve, kiszámíthatja a sugár irányát az egérkattintástól a jelenetig. Ezután kiszámíthatja, hogy van-e objektum a jelenetben metsző ezzel a sugárral. Most már tudja, hogy a felhasználó rákattintott egy objektumra.
Szóval, hogyan tudod forgatni?
átalakítás
Tisztában vagyok az általánosan alkalmazott két típusú átalakítással:
- Mátrix alapú transzformáció
- Csont alapú transzformáció
A különbség az csontok hatással van az egyszemélyre csúcsok. A mátrixok mindig ugyanúgy befolyásolják az összes rajzolt csúcsot. Nézzünk egy példát.
Példa
Korábban betöltöttük identitás mátrix a háromszög rajzolása előtt. Az identitás mátrix az, amely egyszerűen biztosít nincs átalakulás egyáltalán. Tehát, bármit is rajzolok, csak a perspektívám érinti. Tehát a háromszög egyáltalán nem forog.
Ha most el akarom forgatni, akkor magam is elvégezhetem a matematikát (a CPU-n), és egyszerűen hívhatok glVertex3f
val velmás koordináták (amelyek el vannak forgatva). Vagy hagyhatom, hogy a GPU elvégezze a munkát glRotatef
rajz előtt:
// A háromszög elforgatása az Y tengelyen glRotatef (összeg, 0,0f, 1,0f, 0,0f);
összeg
természetesen csak egy fix érték. Ha akarod élő, nyomon kell követnie összeg
és növelje minden keretben.
Tehát, várj, mi történt az összes mátrix beszélgetéssel korábban?
Ebben az egyszerű példában nem kell törődnünk a mátrixokkal. Egyszerűen hívjuk glRotatef
és gondoskodik róla mindent.
glRotate
forgatását eredményeziszög
fokban az x y z vektor körül. Az aktuális mátrixot (seeglMatrixMode) megszorozzuk egy forgási mátrixgal az aktuális mátrixot helyettesítő termékkel, mivel az ifglMultMatrix az alábbi mátrixmal hívták meg argumentumként:x 2 1 - c + cx y 1 - c - z sx z 1 - c + y s 0 y x 1 - c + z sy 2 1 - c + cy z 1 - c - x s 0 x z 1 - c - y sy z 1 - c + x sz 2 1 - c + c 0 0 0 0 1
Hát, köszönöm!
Következtetés
Ami nyilvánvalóvá válik, van egy csomó beszélgetés nak nek OpenGL. De ez nem mondja minket bármi. Hol van a kommunikáció?
Az egyetlen dolog, amit OpenGL mesél nekünk ebben a példában mikor kész. Minden művelet bizonyos ideig tart. Néhány művelet hihetetlenül hosszú, mások hihetetlenül gyorsak.
Vertex küldése a GPU-hoz olyan gyors lesz, nem is tudnám, hogyan kell kifejezni. Több ezer csúcs küldése a CPU-ról a GPU-ra, minden egyes képkocka, valószínűleg egyáltalán nem jelent problémát.
A képernyő törlése ez lehet milliszekundum vagy rosszabb (tartsd szem előtt, általában csak kb. 16 milliszekundum van minden egyes képkocka rajzolásához), attól függően, hogy mekkora a nézetablak. A törléshez az OpenGL-nek minden egyes képpontot azon a színen kell rajzolnia, amelyet törölni szeretne, ami milliónyi pixel lehet..
Ettől eltekintve, csak az OpenGL-et tudjuk megkérdezni grafikus adapterünk képességeiről (max felbontás, max. Aliasing, max. Színmélység,…).
De egy olyan textúrát is kitölthetünk, amelynek pixeljei mindegyiknek van egy meghatározott színe. Így minden egyes pixel értéket tart, és a textúra egy óriási „fájl”, amely adatokkal van kitöltve. Ezt betölthetjük a grafikus kártyára (textúrapuffer létrehozásával), majd betölthetünk egy árnyékolót, mondhatjuk el, hogy a shader használja a textúrát bemenetként, és futtasson néhány rendkívül nehéz számítást a „fájlunkban”.
Ezután „kiszámíthatjuk” számításunk eredményét (új színek formájában) egy új textúrává.
Így teheted a GPU-t más módon is. Feltételezem, hogy a CUDA hasonlóan működik, de sosem volt lehetőségem dolgozni vele.
Tényleg csak kissé megérintettük az egész témát. A 3D grafikus programozás egy fenevad.
Képforrás
Van valami, amit hozzá kell adni a magyarázathoz? Kikapcsolja a megjegyzéseket. Szeretne további válaszokat olvasni más tech-savvy Stack Exchange felhasználóktól? Nézze meg a teljes beszélgetés szálát itt.