Jūsu datora Centrālā procesora bloks (CPU) un grafiskā procesora bloks (GPU) mijiedarbojas ik brīdi, kad izmantojat datoru, lai nodrošinātu kraukšķīgu un atsaucīgu vizuālo saskarni. Lasiet tālāk, lai labāk izprastu, kā viņi strādā kopā.
Fotoattēls ar sskennel.
Šodienas jautājumu un atbilžu sesija mums priecājas par SuperUser - Stack Exchange dalību, Q & A tīmekļa vietņu kopienas diskusiju grupu.
SuperUser lasītājs Sathya uzdeva jautājumu:
Šeit jūs varat redzēt nelielu C + + ekrānuzņēmumu ar Triangle.exe ar rotējošu trīsstūri, pamatojoties uz OpenGL API.
Protams, tas ir ļoti vienkāršs piemērs, bet es uzskatu, ka tas ir piemērojams citām grafisko karšu darbībām.
Man bija tikai ziņkārīgs un vēlējās uzzināt visu procesu no dubultklikšķi uz Triangle.exe, izmantojot Windows XP, līdz es redzu trijstūri, kas rotē uz monitora. Kas notiek, kā mijiedarboties ar CPU (kas vispirms apstrādā .exe) un GPU (kas visbeidzot izsauc trijstūri ekrānā)?
Man šķiet, ka šis rotējošais trijstūris tiek parādīts galvenokārt šādā aparatūrā / programmatūrā:
Aparatūra
Programmatūra
Vai kāds var izskaidrot procesu, varbūt ar kāda veida plūsmas diagrammu ilustrācijai?
Tam nevajadzētu būt sarežģītam paskaidrojumam, kas aptver katru soli (domājams, ka tas pārsniegs darbības jomu), bet paskaidrojumu var sekot arī starpnieks IT puisis.
Esmu diezgan pārliecināts, ka daudzi cilvēki, kas pat sevi sauc par IT speciālistiem, nevarēja pareizi aprakstīt šo procesu.
Lai gan daudzi kopienas locekļi atbildēja uz jautājumu, Olivers Zalcburga devās papildu mile un atbildēja ne tikai ar detalizētu atbildi, bet arī ar lielisku grafiku.
Image by JasonC, kas pieejams kā tapetes šeit.
Viņš raksta:
Es nolēmu rakstīt mazliet par programmēšanas aspektu un to, kā komponenti runā viens ar otru. Varbūt tas noteiktos apgabalos atstās nelielu gaismu.
Kāds ir tas, ka pat vienam attēlam, kuru esat ievietojis savā jautājumā, ir attēlots ekrānā?
Ekrānā ir daudz iespēju trīsstūri uzzīmēt. Lai iegūtu vienkāršību, pieņemsim, ka nav izmantoti virsotņu buferi. (A virsotnes buferisir atmiņas lauks, kurā jūs saglabājat koordinātas.) Pieņemsim, ka programma vienkārši teica grafikas apstrādes cauruļvadam par katru virsotni (virsotne ir tikai koordinātas kosmosā) pēc kārtas.
Bet, pirms mēs varam izdarīt kaut ko, mums vispirms ir jābrauc daži sastatnes. Redzēsim kāpēc vēlāk:
// Notīrīt ekrānu un dziļuma buferu glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // atiestatīt pašreizējo Modelview Matrix glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Zīmējumu izmantošana trijstūri glBegin (GL_TRIANGLES); // Red glColor3f (1.0f, 0.0f, 0.0f); // augšējā trijstūra (priekšējā) glVertex3f (0.0f, 1.0f, 0.0f); // Green glColor3f (0.0f, 1.0f, 0.0f); / / Pa kreisi no trijstūra (priekšējā) glVertex3f (-1.0f, -1.0f, 1.0f); // Blue glColor3f (0.0f, 0.0f, 1.0f); // labais trijstūris (priekšējais) glVertex3f (1.0f, -1.0f, 1.0f); // izdarīts zīmējums glEnd ();
Kad jūs rakstāt programmu, kas vēlas izmantot grafisko karti, jūs parasti izvēlaties kādu interfeisu vadītājam. Daži labi pazīstami saskarnes ar vadītāju:
Šajā piemērā mēs izmantosim OpenGL. Tagad, tavs saskarne ar vadītāju ir tas, kas dod jums visus nepieciešamos rīkus, lai izveidotu savu programmu sarunāties uz grafikas karti (vai draiveri, kas tad sarunas uz karti).
Šī saskarne ir saistīta, lai sniegtu jums noteiktu instrumenti. Šie rīki veido API, kuru jūs varat zvanīt no savas programmas.
Šis API ir tas, ko mēs redzam, tiek izmantots iepriekš minētajā piemērā. Apskatīsim tuvāk.
Pirms jūs patiešām varat veikt jebkuru faktisko zīmējumu, jums būs jāveic a uzstādīt. Jums ir jādefinē jūsu skatu apgabals (apgabals, kas faktiski tiks padarīts), jūsu perspektīva ( kamera jūsu pasaule), kāds anti-aliasing jūs izmantojat (lai izlīdzinātu malas jūsu trīsstūra) ...
Bet mēs to neuzskatīsim. Mēs vienkārši iezīmēsim lietas, kas jums būs jādara katrs rāmis. Kā:
Ekrāna notīrīšana
Grafiskais cauruļvads netiks iztīrīts ekrāns jums katram rāmim. Tev tas būs jādara. Kāpēc Tāpēc:
Ja neiztīrīsiet ekrānu, jūs vienkārši pārvilkt tas katrs rāmis. Tieši tāpēc mēs zvanām glClear
ArGL_COLOR_BUFFER_BIT
iestatīt Otrais bits (GL_DEPTH_BUFFER_BIT
) saka OpenGL, lai notīrītu dziļumsbuferšķīdums. Šis buferis tiek izmantots, lai noteiktu, kuri pikseļi atrodas (vai aiz tiem) ar citiem pikseļiem.
Pārveidošana
Attēlu avots
Transformācija ir tā daļa, kurā mēs ņemam visas ieejas koordinātas (mūsu trīsstūra virsotnes) un izmantojam ModelView matricu. Šī ir matrica skaidro kā mūsu modelis (virsotnes) tiek pagrieztas, mērogojamas un tulkotas (pārvietotas).
Tālāk mēs izmantojam mūsu Projicēšanas matricu. Tas pārvieto visas koordinātas, lai pareizi saskaras ar mūsu kameru.
Tagad mēs pārveidojam vēlreiz, izmantojot mūsu Viewport matricu. Mēs to darām, lai mērotu mūsu modelis līdz mūsu monitora izmēram. Tagad mums ir virknes virsotņu, kas ir gatavi padarīt!
Mēs atgriezīsimies pie transformācijas nedaudz vēlāk.
Zīmējums
Lai izveidotu trīsstūri, mēs varam vienkārši pateikt OpenGL, lai sāktu jaunu trijstūru saraksts zvanot glBegin
Ar GL_TRIANGLES
nemainīgs
Ir arī citas veidlapas, kuras varat izdarīt. Tāpat kā trijstūra lente vai trijstūra ventilators. Tie ir galvenokārt optimizācija, jo tie prasa mazāku saziņu starp CPU un GPU, lai iegūtu tādu pašu trijstūru summu.
Pēc tam mēs varam nodrošināt sarakstu ar 3 virsotņu komplektiem, kuriem būtu jāizveido katrs trijstūris. Katrā trīsstūrī izmanto 3 koordinātas (kā mēs esam 3D-telpā). Turklāt es arī sniedzu a krāsa par katru virsotni, zvanotglColor3f
pirms tam zvanot glVertex3f
.
OpenGL aprēķina ēnojumu starp 3 virsotnēm (trīs stūra stūriem)automātiski. Tas interpolēs krāsu visā daudzstūra pusē.
Tagad, kad jūs noklikšķināt uz loga. Lietojumam ir jāsaglabā loga ziņa, kas norāda uz klikšķi. Tad jūs varat palaist jebkuru darbību savā programmā, kuru vēlaties.
Tas izpaužas partija ja vēlaties sākt mijiedarboties ar 3D ainu.
Vispirms ir skaidri jāzina, pie kura piksela lietotājs noklikšķināja uz loga. Tad, ņemot savu perspektīvavērā, jūs varat aprēķināt staru virzienu, sākot ar peles klikšķi uz jūsu skatuves. Pēc tam jūs varat aprēķināt, vai kāds objekts jūsu skatuves krustojas ar šo staru. Tagad jūs zināt, vai lietotājs noklikšķina uz objekta.
Tātad, kā jūs to pagriezt?
Es esmu informēts par divu veidu pārveidojumiem, kurus parasti izmanto:
Atšķirība ir tā kauli ietekmēt vienu virsotnes. Matricas vienmēr ietekmē visas uzzīmētās virsmas tādā pašā veidā. Apskatīsim piemēru.
Piemērs
Agrāk mēs ielādējām mūsu identitātes matrica pirms zīmēšanas mūsu trīsstūris. Identitātes matrica ir tā, kas vienkārši sniedz nav pārveidošanas pavisam. Tātad, ko es izdarīšu, to ietekmē tikai mana perspektīva. Tātad trijstūris netiks pagriezts vispār.
Ja es vēlos pagriezt to tagad, es varētu vai nu pats math pats (uz CPU) vai vienkārši zvanīt glVertex3f
arcits koordinātas (kas tiek pagrieztas). Vai arī es varētu ļaut GPU veikt visu darbu, zvanot glRotatef
pirms zīmēšanas:
/ Pagriezt trīsstūri uz Y asi glRotatef (summa, 0.0f, 1.0f, 0.0f);
summa
protams, ir tikai fiksēta vērtība. Ja Tu gribi animēt, jums vajadzēs sekot līdzi summa
un palieliniet to katru rāmi.
Šajā vienkāršajā piemērā mums nav jārūpējas par matricām. Mēs vienkārši zvanām glRotatef
un tas rūpējas par visu, kas mums ir.
glRotate
ražo rotācijuleņķis
grādi ap vektoru x y z. Pašreizējo matricu (seeglMatrixMode) reizina ar rotācijas matricu ar produktu, kas aizstāj pašreizējo matrici, jo kā argumentu sauca ifglMultMatrix ar šādu matricu:x 2 1 - c + cx ı y-1-c-z sx-z-1-c + ys 0 y x x 1 - c + z sy 2 ¼ 1 - c + c ¨ z 1 - c - x s 0 x z 1 - c - y s z z 1 - c + x sz 2 ½ 1 c c c 0 0 0 0 1
Nu, paldies par to!
Tas, kas kļūst acīmredzams, ir daudz runāt uz OpenGL. Bet tas nav stāsta mums kaut kas. Kur ir saziņa?
Vienīgais, ko OpenGL šajā piemērā mums stāsta, ir kad tas ir izdarīts. Katra darbība prasīs noteiktu laiku. Daži operācijas notiek neticami ilgi, citi ir neticami ātri.
Augšdaļas nosūtīšana uz GPU būs tik ātri, es pat nezinu, kā to izteikt. Tiks nosūtīti tūkstošiem virsotņu no CPU uz GPU, un katrs rāmis, visticamāk, nav problēmu vispār.
Ekrāna notīrīšana var ņemt milisekunžu vai sliktāk (paturiet prātā, parasti katram kadram ir tikai aptuveni 16 milisekundes laika), atkarībā no tā, cik liela ir jūsu skata vieta. Lai to notīrītu, OpenGL jākārto katrs atsevišķs pikseļu krāsa, kuru vēlaties notīrīt, tas varētu būt miljoniem pikseļu.
Izņemot to, mēs varam diezgan daudz jautāt tikai OpenGL par mūsu grafikas adaptera iespējām (maksimālā izšķirtspēja, maksimālā pretskatīšanās, maksimālais krāsu dziļums ...).
Bet mēs varam arī aizpildīt tekstūru ar pikseļiem, kuriem katrai ir noteikta krāsa. Tādējādi katram pikselim ir vērtība, un tekstūra ir milzīgs "fails", kas piepildīts ar datiem. Mēs to varam ielādēt grafikas kartē (izveidojot tekstūras buferi), pēc tam ielādējiet shaderu, paziņojiet, ka shader izmantos mūsu tekstūru kā ievadi un palaidīsim dažus ļoti smagus aprēķinus mūsu "failā".
Pēc tam mēs varam "padarīt" mūsu aprēķinu rezultātu (jaunu krāsu formā) jaunā tekstūrā.
Tādā veidā jūs varat padarīt GPU darbu jums citos veidos. Es uzskatu, ka CUDA darbojas līdzīgi šim aspektam, bet man nekad nav bijusi iespēja strādāt ar to.
Mēs patiešām tikai nedaudz pieskārāsim visu tēmu. 3D grafikas programmēšana ir zvēra ellē.
Attēla avots
Vai kaut ko pievienot paskaidrojumam? Skatieties komentāros. Vēlaties lasīt citas atbildes no citiem tehnoloģiju savvy Stack Exchange lietotājiem? Šeit skatiet pilnu diskusiju pavedienu.