fotka od sskennel.
Dnešná relácia otázok a odpovedí sa k nám pridelí zdvorilosťou SuperUser - podskupiny Stack Exchange, zoskupenia webových stránok Otázky a odpovede.
Otázka
Čítačka SuperUser Sathya položila otázku:
Tu môžete vidieť snímku malého programu C ++ s názvom Triangle.exe s rotujúcim trojuholníkom založeným na API OpenGL.
Bol som len zvedavý a chcel som poznať celý proces dvojitým kliknutím na Triangle.exe pod Windows XP, kým nevidím trojuholník, ktorý sa otáča na monitore. Čo sa stane, ako interagujú procesor (ktorý najprv spracováva.exe) a GPU (ktorý nakoniec vyvedie trojuholník na obrazovku)?
Myslím, že zapojenie do zobrazovania tohto rotujúceho trojuholníka je predovšetkým nasledujúci hardvér / softvér okrem iného:
technické vybavenie
- HDD
- Systémová pamäť (RAM)
- CPU
- Video pamäť
- GPU
- displej LCD
softvér
- Operačný systém
- API rozhrania DirectX / OpenGL
- Ovládač Nvidia
Môže niekto vysvetliť proces, možno s nejakým vývojovým diagramom pre ilustráciu?
Nemalo by to byť zložité vysvetlenie, ktoré by pokrývalo každý jednotlivý krok (domnieva sa, že by šlo nad rámec rozsahu), ale vysvetlenie, ktoré môže nasledovať prechodný IT chlap.
Som si celkom istý, že veľa ľudí, ktorí by dokonca nazvali samotní IT odborníci, tento proces nesprávne opísali.
Odpoveď
Obrázok JasonC, k dispozícii ako tapeta tu.
On píše:
Rozhodla som sa napísať trochu o aspekte programovania a o tom, ako jednotlivé komponenty hovoria. Možno to bude mať určité svetlo v určitých oblastiach.
Prezentácia
Čo potrebuje, aby ste dokonca získali ten jediný obrázok, ktorý ste uviedli vo svojej otázke, nakreslenej na obrazovke?
Existuje mnoho spôsobov, ako nakresliť trojuholník na obrazovke. Pre jednoduchosť predpokladajme, že sa nepoužívali žiadne vertikálne vyrovnávacie pamäte. (A vertex bufferje oblasť pamäte, kde ukladáte súradnice.) Predpokladajme, že program jednoducho povedal, že grafické spracovanie potrubia o každom jednotlivom vrchole (vrchol je len súradnicou vo vesmíre) v rade.
ale, predtým, ako môžeme nakresliť čokoľvek, najskôr musíme spustiť nejaké lešenie. Uvidíme prečo neskôr:
// Clear The Screen And The Depth Buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Reset The Current Modelview Matrix glMatrixMode(GL_MODELVIEW); glLoadIdentity(); // Drawing Using Triangles glBegin(GL_TRIANGLES); // Red glColor3f(1.0f,0.0f,0.0f); // Top Of Triangle (Front) glVertex3f( 0.0f, 1.0f, 0.0f); // Green glColor3f(0.0f,1.0f,0.0f); // Left Of Triangle (Front) glVertex3f(-1.0f,-1.0f, 1.0f); // Blue glColor3f(0.0f,0.0f,1.0f); // Right Of Triangle (Front) glVertex3f( 1.0f,-1.0f, 1.0f); // Done Drawing glEnd();
Takže čo robilo to?
Keď napíšete program, ktorý chce používať grafickú kartu, zvyčajne si vyberiete nejaké rozhranie pre vodiča. Niektoré známe rozhrania s ovládačom sú:
- OpenGL
- Direct3D
- CUDA
Pre tento príklad budeme držať OpenGL. Teraz, tvoj rozhranie pre vodiča je to, čo vám dáva všetky nástroje, ktoré potrebujete na vytvorenie programu rozprávanie na grafickú kartu (alebo ovládač, ktorý potom rokovania na kartu).
Toto rozhranie vám prinesie istotu náradie, Tieto nástroje majú podobu rozhrania API, ktoré môžete vo svojom programe zavolať.
Toto rozhranie API je to, čo vidíme v príklade vyššie. Pozrime sa bližšie.
Lešenie
Skôr než budete môcť skutočne urobiť akýkoľvek skutočný výkres, budete musieť vykonať a nastaviť, Musíte definovať svoj výhľad (oblasť, ktorá sa skutočne vykreslí), váš pohľad ( fotoaparát do svojho sveta), aké anti-aliasing budete používať (aby ste vyhladili hranu svojho trojuholníka) …
Ale nebudeme sa na to pozerať. Len sa pozrieme na to, čo budete musieť urobiť na každý snímok, Páči sa mi to:
Vymazanie obrazovky
Grafické potrubie vám neosmieňa každý snímok. Musíte to povedať. Prečo? To je dôvod, prečo:
Ak nechcete obrazovku vyčistiť, jednoducho nakresliť každý rám. Preto voláme
glClear
s
GL_COLOR_BUFFER_BIT
nastavený. Druhý bit (
GL_DEPTH_BUFFER_BIT
) hovorí OpenGL, aby vymazal hĺbkapufer. Tento buffer sa používa na určenie, ktoré pixely sú vpredu (alebo za) ostatné pixely.
premena
Transformácia je časť, v ktorej preberáme všetky vstupné súradnice (vrcholy nášho trojuholníka) a aplikujeme našu maticu ModelView. Toto je matica vysvetľuje ako naše Model (vrcholy) sú otočené, zmenšené a preložené (presunuté).
Potom použijeme našu projekčnú maticu. Toto posúva všetky súradnice tak, aby boli správne nasmerované k fotoaparátu.
Teraz sa znova transformujeme s našou maticou Viewport. Robíme to, aby sme naši zmenili Model na veľkosť nášho monitora. Teraz máme súbor vrcholov, ktoré sú pripravené na vykreslenie!
Vrátime sa k transformácii trochu neskôr.
kreslenie
Ak chcete nakresliť trojuholník, môžeme jednoducho povedať, že OpenGL začne nový zoznam trojúhelníkov zavolaním
glBegin
s
GL_TRIANGLES
konštantný. Existujú aj iné formy, ktoré môžete nakresliť. Ako trojuholníkový pás alebo trojuholníkový ventilátor.Ide predovšetkým o optimalizácie, pretože vyžadujú menšiu komunikáciu medzi procesorom a GPU, aby sa nakreslil rovnaký počet trojuholníkov.
Potom môžeme poskytnúť zoznam sád 3 vrcholov, ktoré by mali tvoriť každý trojuholník. Každý trojuholník používa 3 súradnice (pretože sme v 3D-priestore). Okrem toho tiež poskytujem farba pre každý vrchol, volaním
glColor3f
pred povolania
glVertex3f
Odtieň medzi 3 vrcholmi (3 rohy trojuholníka) sa vypočíta podľa OpenGL automaticky, Interpoluje farbu na celej ploche mnohouholníka.
Interakcia
Teraz, keď kliknete na okno. Aplikácia musí zachytiť len okennú správu, ktorá signalizuje kliknutie. Potom môžete spustiť akúkoľvek akciu vo vašom programe, ktorý chcete.
To dostane a veľa ťažšie, keď začnete pracovať s vašou 3D scénou.
Najprv musíte jasne vedieť, na ktorom pixeli používateľ klepol na okno. Potom vezmite svoje perspektíva, môžete vypočítať smer lúča, odkedy kliknete myšou do scény. Potom môžete vypočítať akýkoľvek objekt vo vašej scéne pretína s týmto lúčom. Teraz už viete, či používateľ klikol na objekt.
Takže, ako to robíte?
premena
Som si vedomý dvoch typov transformácií, ktoré sa všeobecne uplatňujú:
- Transformácia založená na matici
- Transformácia na báze kostnej hmoty
Rozdiel je v tom ostatky ovplyvniť jeden vrcholy, Matrice vždy ovplyvňujú všetky nakreslené vrcholy rovnakým spôsobom. Pozrime sa na príklad.
príklad
Skôr sme naložili naše identity matrix pred nakreslením nášho trojuholníka. Identifikačná matica je jednoduchá žiadna transformácia vôbec. Takže, čokoľvek som kresliť, je ovplyvnená iba mojou perspektívou. Takže trojuholník sa vôbec nezmení.
Ak to chcem teraz otočiť, mohol by som buď urobiť matematiku sám (na CPU) a jednoducho zavolať
glVertex3f
sostatné súradnice (ktoré sú otočené). Alebo som mohol nechať GPU robiť všetku prácu, volaním
glRotatef
pred nakreslením:
// Rotate The Triangle On The Y axis glRotatef(amount,0.0f,1.0f,0.0f);
amount
je samozrejme len pevnou hodnotou. Ak chceš oživiť, budete musieť sledovať
amount
a zvýšiť ho každý obrázok.
Takže, počkajte, čo sa stalo so všetkými diskusiami o matici skôr?
V tomto jednoduchom príklade sa nemusíte starať o matrice. Jednoducho zavoláme
glRotatef
a stará sa o všetko pre nás.
glRotate
rotuje sa
angle
stupňov okolo vektora x y z. Súčasná matica (seeglMatrixMode) sa násobí rotačnou maticou s produktom nahradzujúcim aktuálnu maticu, pretože ifglMultMatrix bol nazvaný s nasledujúcou maticou ako 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, ďakujem za to!
záver
Čo je zrejmé, je veľa rozprávania na OpenGL. Ale to nehovorí nami čokoľvek. Kde je komunikácia?
Jediná vec, ktorú nám v tomto príklade hovorí OpenGL, je keď je to hotovo, Každá operácia bude trvať určitý čas. Niektoré operácie sú neuveriteľne dlhé, iné sú neuveriteľne rýchle.
Odoslanie vrcholu na GPU bude tak rýchlo, ja by som ani nevedel, ako to vyjadriť. Odosielanie tisícov vrcholov z CPU do GPU, každý jednotlivý snímok, je s najväčšou pravdepodobnosťou žiadnym problémom.
Vymazanie obrazovky môže trvať milisekunda alebo horšie (majte na pamäti, zvyčajne máte len 16 milisekúnd času nakresliť každý snímok), v závislosti na veľkosti vášho výrezu. Ak chcete ho odstrániť, OpenGL musí nakresliť každý pixel vo farbe, ktorú chcete vymazať, čo môže byť milióny pixelov.
Okrem toho môžeme prakticky požiadať OpenGL o možnosti grafického adaptéra (max. Rozlíšenie, max. Anti-aliasing, maximálna farebná hĺbka …).
Ale môžeme tiež naplniť textúru s pixelmi, ktoré majú špecifickú farbu. Každý pixel tak má hodnotu a textúra je obrovský "súbor" naplnený údajmi. Môžeme ho nahrať do grafickej karty (vytvorením vyrovnávacej pamäte textúry), potom načítať shader, povedať, že shader používa našu štruktúru ako vstup a spustiť niektoré mimoriadne ťažké výpočty na našom "súbore".
Môžeme potom "vykresliť" výsledok nášho výpočtu (vo forme nových farieb) do novej štruktúry.
Takto môžete GPU pracovať pre vás inými spôsobmi. Predpokladám, že CUDA sa podobá tomuto aspektu, ale nikdy som nemala príležitosť pracovať s ním.
Naozaj sme sa len trochu dotkli celého predmetu. Programovanie 3D grafiky je peklo šelmy.
Máte niečo doplniť vysvetlenie? Zvuk vypnúť v komentároch. Chcete si prečítať viac odpovedí od iných používateľov technológie Stack Exchange? Pozrite sa na celý diskusný príspevok tu.