A számítógép központi processzora (CPU) és a grafikus processzora (GPU) minden pillanatban kölcsönhatásba lép, amikor számítógépét használja, hogy éles és érzékeny vizuális felületet nyújtson Önnek. Olvassa el, 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 a SuperUser jóvoltából érkeznek hozzánk - a Stack Exchange alosztályához, amely a Q & A webhelyek közösségi hajtású csoportosulása.
A kérdés
Sathya, a SuperUser olvasója feltette a kérdést:
Itt láthat egy képernyőképet egy kis, Triangle.exe nevű C ++ programról, amely az OpenGL API-n alapuló forgó háromszöggel rendelkezik.
Igaz, nagyon egyszerű példa, de úgy gondolom, hogy ez alkalmazható más grafikus kártyák műveleteire is.
Csak kíváncsi voltam, és meg akartam ismerni az egész folyamatot, a Windows XP alatt végzett Triangle.exe dupla kattintásával, amíg meg nem látom a monitoron forgó háromszöget. Mi történik, hogyan hat egymással a CPU (amely először kezeli az .exe-t) és a GPU (amely végül a képernyőn megjelenő háromszöget adja ki)?
Gondolom, ennek a forgó háromszögnek a megjelenítésében elsősorban a következő hardver / szoftver vesz részt:
Hardver
- HDD
- Rendszer memória (RAM)
- processzor
- Videomemória
- GPU
- LCD kijelzö
Szoftver
- Operációs rendszer
- DirectX / OpenGL API
- Nvidia Driver
Meg tudja valaki magyarázni a folyamatot, esetleg valamilyen folyamatábrával szemléltetni?
Nem egy összetett magyarázatnak kell lennie, amely minden egyes lépést lefed (kitalálhatja, hogy ez meghaladná a hatókört), hanem egy magyarázatot, amelyet egy köztes informatikus követhet.
Biztos vagyok benne, hogy sok olyan ember, aki magát informatikusnak is nevezné, nem tudja helyesen leírni ezt a folyamatot.
A válasz
Bár a közösség több tagja válaszolt a kérdésre, Oliver Salzburg túllépte a mérföldet, és nemcsak részletes válaszadással, hanem kiváló kísérő grafikával is válaszolt rá.
JasonC képe, háttérképként itt érhető el .
Ír:
Úgy döntöttem, hogy írok egy kicsit a programozási szempontról és arról, hogy az alkatrészek hogyan beszélnek egymással. Talán fényt derít bizonyos területekre.
A prezentáció
Mi kell ahhoz, hogy a képernyőn meg lehessen rajzolni azt az egyetlen képet, amelyet feltett a kérdésébe?
Sokféleképpen rajzolhatunk háromszöget a képernyőn. Tegyük fel, hogy az egyszerűség kedvéért nem használtunk csúcspuffereket. (A csúcspuffer egy olyan memóriaterület, ahol koordinátákat tárol.) Tegyük fel, hogy a program egyszerűen elmondta a grafikus feldolgozó folyamatnak minden egyes csúcsot (egy csúcs csak egy koordináta a térben) egy sorban.
De , mielőtt bármit is rajzolhatnánk, először állványokat kell futtatnunk. Meglátjuk miért a későbbiekben:
// A képernyő és a mélységi puffer törlése glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Az aktuális Modelview mátrix visszaállítása glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Rajzolás háromszögekkel 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); // Háromszögtől balra (elöl) glVertex3f (-1,0f, -1,0f, 1,0f); Kék glColor3f (0,0f, 0,0f, 1,0f); // Háromszögtől jobbra (elöl) glVertex3f (1,0f, -1,0f, 1,0f); // Kész rajz glEnd ();
Tehát mit tett ez?
Amikor olyan programot ír, amely használni kívánja a grafikus kártyát, akkor általában valamilyen interfészt választ az illesztőprogramhoz. Néhány jól ismert interfész a meghajtóhoz:
- OpenGL
- Direct3D
- CSODÁK
Ebben a példában ragaszkodunk az OpenGL-hez. Most, a te interfész a meghajtóhoz ez az, ami megadja a program elkészítéséhez szükséges összes eszközt beszélgetés a grafikus kártyára (vagy az illesztőprogramra, amely aztán tárgyalásokat a kártyához).
Ez a felület biztosan biztosítani fogja Önt eszközök . Ezek az eszközök egy TŰZ amelyet a programjából hívhat.
Ezt az API-t látjuk használni a fenti példában. Nézzük meg közelebbről.
Az állványzat
Mielőtt valóban elvégezhetne bármilyen tényleges rajzot, el kell végeznie a beállít . Meg kell határoznia a nézetablakot (a ténylegesen megjelenítendő területet), perspektíváját (a kamera a világotokba), milyen anti-aliasinget fog használni (a háromszög éleinek simításához) ...
De ebből egyiket sem fogjuk megvizsgálni. Csak egy pillantást vetünk a dolgokra, amelyeket meg kell tennie minden képkocka . Tetszik:
A képernyő törlése
A grafikus folyamat nem fogja minden képnél kitörölni a képernyőt. El kell mondanod. Miért? Ez az oka:
Ha nem törli a képernyőt, akkor egyszerűen
húzza át
minden képkocka. Ezért hívjuk
glClear
a ... val
GL_COLOR_BUFFER_BIT
készlet. A másik bit (
GL_DEPTH_BUFFER_BIT
) azt mondja az OpenGL-nek, hogy törölje a
mélység
puffer. Ezt a puffert használják annak meghatározására, hogy melyik képpontok vannak a többi képpont előtt vagy mögött.
átalakítás
A transzformáció az a rész, ahol az összes bemeneti koordinátát (háromszögünk csúcsait) megkapjuk és a ModelView mátrixot alkalmazzuk. Ez az a mátrix magyarázza hogy a mi modell (a csúcsokat) elforgatják, méretezik és lefordítják (mozgatják).
Ezután alkalmazzuk a Vetítési mátrixunkat. Ez az összes koordinátát úgy mozgatja, hogy azok megfelelően nézzenek a kameránk felé.
Most még egyszer átalakulunk, a Viewport mátrixunkkal. Ezt azért tesszük, hogy méretezzük modell a monitorunk méretéhez. Most van egy sor csúcsunk, amelyek készen állnak a megjelenítésre!
Kicsit később visszatérünk az átalakuláshoz.
Rajz
Háromszög megrajzolásához egyszerűen azt mondhatjuk az OpenGL-nek, hogy indítson újat
háromszögek listája
hívással
glBegin
a ... val
GL_TRIANGLES
állandó.
Vannak más rajzok is. Mint egy
háromszögcsík
vagy a
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 ugyanannyi háromszög rajzolásához.
Ezt követően megadhatunk egy listát 3 csúcsból álló halmazokból, amelyeknek az egyes háromszögeket kell alkotnia. Minden háromszög 3 koordinátát használ (ahogyan mi a 3D-térben vagyunk). Ezenkívül megadom a
szín
minden csúcsra, hívással
glColor3f
előtt
hívás
glVertex3f
.
A 3 csúcs (a háromszög 3 sarka) közötti árnyékot az OpenGL kiszámítja automatikusan . Interpolálja a színt a sokszög teljes felületén.
Kölcsönhatás
Most, amikor rákattint az ablakra. Az alkalmazásnak csak a ablaküzenet ami jelzi a kattanást. Ezután bármely kívánt műveletet futtathat a programjában.
Ez megkapja a sok nehezebb, ha el akarja kezdeni az interakciót a 3D jelenettel.
Először egyértelműen tudnia kell, hogy a felhasználó melyik képpontnál kattintott az ablakra. Aztán, véve a perspektíva figyelembe véve kiszámíthatja a sugár irányát az egérkattintás pontjától a jelenetig. Ezután kiszámíthatja, hogy van-e valamilyen tárgy a jelenetében keresztezi azzal a sugárral . Most már tudja, hogy a felhasználó kattintott-e egy objektumra.
Szóval, hogyan kell azt forgatni?
átalakítás
Kétféle transzformációról tudok, amelyeket általában alkalmaznak:
- Mátrix alapú transzformáció
- Csontalapú transzformáció
A különbség az csontok befolyásolja szingli csúcsok . A mátrixok ugyanúgy befolyásolják az összes rajzolt csúcsot. Nézzünk meg egy példát.
Példa
Korábban betöltöttük identitásmátrix mielőtt megrajzoljuk a háromszögünket. Az identitásmátrix egyszerűen megadja nincs átalakulás egyáltalán. Tehát bármit is rajzolok, csak a perspektívám befolyásolja. Tehát a háromszöget egyáltalán nem fogják elforgatni.
Ha most el akarom forgatni, akkor vagy megtehetem a matematikát (a CPU-n), és egyszerűen felhívhatom
glVertex3f
val vel
Egyéb
koordináták (amelyek el vannak forgatva). Vagy hagyhatom, hogy a GPU elvégezze az összes munkát, hívással
glRotatef
rajzolás előtt:
// A háromszög forgatása az Y tengelyen glRotatef (összeg, 0,0f, 1,0f, 0,0f);
összeg
természetesen csak egy rögzített érték. Ha akarod
élénk
, nyomon kell követnie
összeg
és minden képkockán növelje.
Szóval, várj, mi történt a mátrix összes előadásával korábban?
Ebben az egyszerű példában nem kell törődnünk a mátrixokkal. Egyszerűen hívunk
glRotatef
és minderről gondoskodik számunkra.
glRotateforgatását produkáljaszögfok az x y z vektor körül. Az aktuális mátrix (lásd glMatrixMode ) egy rotációs mátrixszal megszorozzuk, a szorzat az aktuális mátrixot helyettesíti, mintha glMultMatrix a következő mátrix argumentummal hívták meg: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
Nos, köszönöm ezt!
Következtetés
Ami nyilvánvalóvá válik, sok szó esik nak nek OpenGL. De nem sokatmondó minket bármi. Hol van a kommunikáció?
Az egyetlen dolog, amit az OpenGL mond nekünk ebben a példában, az az amikor kész . Minden művelet egy bizonyos időt vesz igénybe. Egyes műveletek hihetetlenül hosszúak, mások hihetetlenül gyorsak.
Csúcs küldése a GPU-ra olyan gyors lesz, nem is tudnám, hogyan fejezzem ki. A CPU-ból a GPU-ba, minden egyes képkockába ezernyi csúcs küldése valószínűleg nem kérdés.
A képernyő törlése ez milliszekundumig vagy annál rosszabb ideig tarthat (ne feledje, hogy általában csak körülbelül 16 milliszekundum van az egyes kockák rajzolására), attól függően, hogy mekkora a nézetablak. A törléshez az OpenGL-nek minden egyes pixelt meg kell rajzolnia abban a színben, amelyre törölni szeretne, ez több millió pixel lehet.
Ezen kívül jóformán csak az OpenGL-t kérdezhetjük meg a grafikus adapterünk képességeiről (max. Felbontás, max. Aliasítás, max. Színmélység ...).
De a textúrát olyan pixelekkel is kitölthetjük, amelyek mindegyikének van egy meghatározott színe. Mindegyik pixelnek van értéke, és a textúra egy óriási, fájlokkal feltöltött fájl. Betölthetjük ezt a grafikus kártyára (textúra puffer létrehozásával), majd betölthetjük a árnyékoló , mondja meg annak az árnyékolónak, hogy a textúránkat használja inputként, és futtasson néhány rendkívül nehéz számítást a „fájlunkon”.
Ezután a számítás eredményét (új színek formájában) új textúrává alakíthatjuk.
Így lehet a GPU-t más módon is működtetni. Feltételezem, hogy a CUDA ehhez a szemponthoz hasonlóan teljesít, de soha nem volt lehetőségem vele dolgozni.
Igazából csak kissé érintettük az egész témát. A 3D grafika programozása pokoli fenevad.
Van valami hozzáfűzhető a magyarázathoz? Hangzik el a megjegyzésekben. Szeretne további válaszokat olvasni más, hozzáértő Stack Exchange-felhasználóktól? Nézze meg a teljes vitafonalat itt .