Središnja jedinica za obradu (CPU) i grafička jedinica za obradu (GPU) vašeg računala reagiraju svaki trenutak kada koristite računalo kako bi vam pružio čist i osjetljiv vizualni sučelje. Pročitajte kako biste bolje razumjeli kako rade zajedno.
Fotografija tvrtke sskennel.
Današnja pitanja i odgovori nam se javljaju zahvaljujući SuperUseru - podjele Stack Exchange-a, zajedničkom pogonu Q & A web stranica.
SuperUser čitač Sathya postavio je pitanje:
Ovdje možete vidjeti snimku zaslona malog C ++ programa nazvanog Triangle.exe s rotirajućim trokutom na temelju OpenGL API-ja.
Doduše, vrlo osnovni primjer, ali mislim da je primjenjiv na druge operacije grafičkih kartica.
Bio sam samo znatiželjan i htio sam znati cijeli proces od dvostrukog klika na Triangle.exe u sustavu Windows XP dok ne vidim trokut koji rotira na monitoru. Što se događa, kako interakcioniraju procesori (koji prvo obrađuju .exe) i GPU (koji konačno izlaze trokut na zaslonu)?
Pretpostavljam da su uključeni u prikazivanje ovog rotirajućeg trokuta prvenstveno sljedeći hardver / softver među ostalima:
Hardver
Softver
Može li itko objasniti taj proces, možda s nekom vrstom dijagrama toka za ilustraciju?
To ne bi trebalo biti složeno objašnjenje koje pokriva svaki pojedini korak (pretpostavljam da bi se nadmašio opseg), ali objašnjenje koje može biti posredni IT momak.
Siguran sam da mnogi ljudi koji bi se čak nazivali IT profesionalcima, nisu mogli ispravno opisati taj postupak.
Iako je više članova zajednice odgovorilo na pitanje, Oliver Salzburg je otišao na dodatnu milju i odgovorio je ne samo s detaljnim odgovorom već i izvrsnom pratećom grafikom.
Slika JasonC, dostupna kao pozadina ovdje.
Piše:
Odlučio sam napisati malo o programskom aspektu i kako komponente međusobno razgovaraju. Možda će proći neko svjetlo na određenim područjima.
Što je potrebno da biste imali i tu jednu sliku koju ste postavili na svoje pitanje, nacrtana na zaslonu?
Postoji mnogo načina kako nacrtati trokut na zaslonu. Za jednostavnost, pretpostavimo da nisu korišteni vršni puferi. (A vertex puferPretpostavimo da program jednostavno govori o cjevovodu za obradu grafike o svakom pojedinom vrhu (vrh je samo koordinata u svemiru) u nizu.
Ali, prije nego što možemo izvući bilo što, najprije moramo izvoditi neke skele. Vidjet ćemo zašto kasnije:
// Poništi zaslon i dubinski pufer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Resetirajte trenutni matematski prikaz glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Crtanje pomoću trokuta glBegin (GL_TRIANGLES); // Red glColor3f (1.0f, 0.0f, 0.0f); // Vrh trokuta (prednji) glVertex3f (0.0f, 1.0f, 0.0f); // Green glColor3f (0.0f, 1.0f, 0.0f); // Lijevo od trokuta (prednji) glVertex3f (-1.0f, -1.0f, 1.0f); // Plavi glColor3f (0.0f, 0.0f, 1.0f); // Pravo od trokuta (prednji) glVertex3f (1.0f, -1.0f, 1.0f); // Gotovo crtanje glEnd ();
Kada napišete program koji želi koristiti grafičku karticu, obično odaberete neko sučelje upravljačkom programu. Neki poznati sučelja vozaču su:
Za ovaj primjer ćemo se držati OpenGL-a. Sada, tvoje sučelje za vozača je ono što vam daje sve alate potrebne za izradu vašeg programa razgovor na grafičku karticu (ili vozač, koji je tada razgovori na karticu).
Ovo je sučelje obvezno dati vam određene podatke alat, Ovi alati imaju oblik API-ja koji možete nazvati iz svog programa.
Taj API je ono što vidimo da se koristi u gornjem primjeru. Pogledajmo bliže.
Prije nego što stvarno možete napraviti bilo koji crtež, morat ćete izvršiti a postaviti, Morate definirati svoj prikaz (područje koje će se stvarno prikazati), vašu perspektivu ( fotoaparat u svoj svijet), kakav ćete anti-aliasing koristiti (kako biste izravnali rubove vašeg trokuta) ...
Ali to nećemo gledati. Samo ćemo pogledati stvari koje ćete morati učiniti svaki okvir, Kao:
Brisanje zaslona
Grafički cjevovod neće očistiti zaslon za svaki okvir. Morat ćeš to reći. Zašto? To je razlog zašto:
Ako ne očistite zaslon, jednostavno ćete crtati to svaki okvir. Zato zovemo glClear
sGL_COLOR_BUFFER_BIT
postavljen. Drugi bit (GL_DEPTH_BUFFER_BIT
) govori OpenGL - u za brisanje dubinapufer. Ovaj se spremnik upotrebljava za određivanje piksela koji se nalaze ispred (ili iza) drugih piksela.
Transformacija
Izvor slike
Transformacija je dio gdje uzmemo sve koordinate unosa (vrhovi našeg trokuta) i primjenjujemo matricu ModelView. Ovo je matrica koja objašnjava kako naše model (vrhovi) se okreću, skalirati i prevesti (premještati).
Zatim primjenjujemo našu Projekcijsku matricu. To pomiče sve koordinate tako da se sučeljavaju s našom kamerom ispravno.
Sada smo preobrazili još jednom, s našom matricom Viewport. To činimo kako bismo skalirali svoje model na veličinu našeg monitora. Sada imamo skup vrhova koji su spremni za pružanje!
Vratit ćemo se transformaciji malo kasnije.
Crtanje
Da biste nacrtali trokut, možemo jednostavno reći OpenGL-u da započne novu popis trokuta pozivom glBegin
s GL_TRIANGLES
konstantno.
Postoje i drugi oblici koje možete izvući. Poput trokutaste trake ili trokutastog ventilatora. To su prvenstveno optimizacije jer zahtijevaju manje komunikacije između CPU-a i GPU-a kako bi privukle istu količinu trokuta.
Nakon toga možemo ponuditi popis skupova od 3 vertices koji bi trebali sastaviti svaki trokut. Svaki trokut koristi 3 koordinate (kao što smo u 3D prostoru). Osim toga, također pružam a boja za svaki vrh, pozivomglColor3f
prije zvanje glVertex3f
.
Sjena između 3 vrhova (3 kutna trokuta) izračunava OpenGLautomatsko, Interpolirat će boju na cijelom licu poligona.
Sada kada kliknete na prozor. Aplikacija mora uhvatiti samo poruku prozora koja signalizira klik. Tada možete pokrenuti bilo koju akciju u svom programu koji želite.
Ovo dobiva a mnogo teže nakon što počnete interakciju s 3D scenom.
Prvo morate jasno znati na kojem je piksel korisnik kliknuo prozor. Zatim, uzimajući svoje perspektivau obzir, možete izračunati smjer zrake, od točke klikanja miša u vašu scenu. Zatim možete izračunati bilo koji objekt u vašoj sceni ukrštava s tom zrakom. Sada znate je li korisnik kliknuo objekt.
Dakle, kako ćete ga rotirati?
Svjestan sam dvije vrste transformacija koje se općenito primjenjuju:
Razlika je u tome kosti utjecati na pojedinačno vrhovi, Matrice uvijek utječu na sve nacrtane vertice na isti način. Pogledajmo primjer.
Primjer
Ranije smo učitali našu Matrica identiteta prije crtanja našeg trokuta. Matrica identiteta je ona koja jednostavno pruža nema transformacije uopće. Dakle, ono što ja nacrtam, samo utječe na moju perspektivu. Dakle, trokut neće biti zakrenut.
Ako ga sada želim zakretati, ja sam ili sam mogao napraviti matematiku (na CPU-u) i jednostavno nazvati glVertex3f
sdrugo koordinate (koje su zakrenute). Ili bih mogao dopustiti GPU-u da obavlja sav posao, pozivom glRotatef
prije crtanja:
Rotiranje trokuta na osi Y glRotatef (iznos, 0.0f, 1.0f, 0.0f);
iznos
je, naravno, samo fiksna vrijednost. Ako želiš animirati, morat ćete pratiti iznos
i povećati svaki okvir.
U ovom jednostavnom primjeru, ne moramo brinuti o matricama. Jednostavno zovemo glRotatef
i brine se za sve to za nas.
glRotate
proizvodi rotacijukut
stupnjeva oko vektora x y z. Sadašnja matrica (seeglMatrixMode) se pomnoži s rotirajućom matricom s proizvodom koji zamjenjuje trenutnu matricu, kao ifglMultMatrix zove se sa sljedećom matricom kao svoj argument:x-1-c-x-x-1-c-y-y-x-1-c-y- 1-c-x-c-c-c-c-c-c-c-c-c-
Pa, hvala na to!
Ono što postaje očigledno je puno govora do OpenGL. Ali to ne govori nas bilo što. Gdje je komunikacija?
Jedina stvar koju nam govori u ovom primjeru je OpenGL kada je to učinjeno, Svaka operacija će trajati određeno vrijeme. Neka operacija traje nevjerojatno dugo, drugi su nevjerojatno brzi.
Slanje vrhova na GPU će biti tako brzo, ne bih ni znala kako to izraziti. Slanje tisuća vrhova s CPU-a na GPU, svaki pojedini okvir, najvjerojatnije nije problem.
Brisanje zaslona može potrajati milisekundi ili još gore (imajte na umu da obično imate samo oko 16 milisekunde vremena za privlačenje svakog okvira), ovisno o tome koliko je vaš prozor vidljiv. Da biste ga izbrisali, OpenGL mora nacrtati svaki piksel u boji koju želite očistiti, a to bi moglo biti milijune piksela.
Osim toga, možemo samo pitati OpenGL o mogućnostima našeg grafičkog adaptera (maks. Razlučivost, max anti-aliasing, maksimalna dubina boja, ...).
Ali možemo također popuniti teksturu s pikselima koji imaju određenu boju. Svaki piksel na taj način ima vrijednost, a tekstura je ogromna "datoteka" ispunjena podacima. To možemo učitati u grafičku karticu (stvaranjem tampona teksture), a zatim učitati shader, reći da shader upotrebljava našu teksturu kao unos i izvodi iznimno teške izračune na našoj "datoteci".
Tada možemo "izvući" rezultat našeg računanja (u obliku novih boja) u novu teksturu.
Tako možete raditi GPU za vas na druge načine. Pretpostavljam da je CUDA sličan tom aspektu, ali nikada nisam imao priliku raditi s njom.
Samo smo malo dotakli cijeli predmet. 3D programiranje grafike je pakao zvijeri.
Izvor slike
Imate li nešto za objašnjenje? Zvuči u komentarima. Želite li pročitati više odgovora od drugih tehnoloških korisnika Stack Exchangea? Pogledajte ovdje cijelu raspravu.