pildi autor sskennel.
Tänane küsimuste ja vastuste seanss tuleb meile viisakalt SuperUseriga, mis on Q & A veebisaitide kogukonna juhtimisgruppide Stack Exchange osakond.
Küsimus
SuperUseri lugeja Sathya esitas küsimuse:
Siin näete OpenGL API-ga põhineva väikese C ++ programmi nimega Triangle.exe ekraanipilti.
Mul oli lihtsalt uudishimulik ja tahtsin teada kogu protsessi, kui klõpsate Windows XP-s topeltklõpsu Triangle.exe, kuni näen monitori pööratavat kolmnurka. Mis juhtub, kuidas toimib interaktiivne protsessori (kes esmalt käitleb.exe) ja graafikaprotsessoriga (mis lõpuks väljub kolmnurga ekraanil)?
Ma arvan, et see pöörleva kolmnurga kuvamine on muuhulgas peamiselt järgmine riist-tarkvara.
Riistvara
- HDD
- Süsteemimälu (RAM)
- Protsessor
- Videomälu
- GPU
- LCD ekraan
Tarkvara
- Operatsioonisüsteem
- DirectX / OpenGL API
- Nvidia draiver
Kas keegi võib protsessi selgitada, võib-olla mingi voolukava illustreerimiseks?
See ei tohiks olla keerukas seletus, mis hõlmab iga sammu (arvan, et see ulatub kaugemale), kuid seletus võib olla vahepealne IT-mees.
Ma olen päris kindel, et paljud inimesed, kes isegi nimetaksid end ise, ei suuda IT-spetsialistid seda protsessi õigesti kirjeldada.
Vastus
Pilt, mille esitas JasonC ja mis on saadaval taustpildina siin.
Ta kirjutab:
Otsustasin veidi kirjutada programmeerimise aspektist ja kuidas komponendid üksteisega räägivad. Võibolla on see teatavates valdkondades mõnevõrra valgus.
Esitlus
Mida läheb isegi selle üksikpildi kuvamiseks, mille olete oma küsimusele postitanud, ekraanil kuvatud?
Ekraanil on kolmnurka juhtida mitmel viisil. Lihtsuse huvides eeldame, et tipppuhve ei kasutata. (A tipppuuron mäluvaldkond, kus saate salvestada koordinaate.) Oletame, et programm lihtsalt rääkis graafika töötlemise torujuhtme kohta iga tipu kohta (tipp on lihtsalt koordinaat ruumis) järjest.
Aga, enne kui saame midagi teha, peame esmalt esinema mõned tellingud. Me näeme miks hiljem:
// 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();
Mida see siis tehti?
Kui kirjutad programmi, mis soovib graafika kaarti kasutada, valib see tavaliselt juhi jaoks mingi liidese. Mõned hästi tuntud liidesed juhi jaoks on:
- OpenGL
- Direct3D
- CUDA
Selles näites jääme OpenGLiga kinni. Nüüd, sinu juhi jaoks liides mis annab sulle kõik tööriistad, mida peate oma programmi tegema rääkima videokaardile (või draiverile, mis seejärel kõnelused kaardile).
See liides on teile kindel tööriistad. Need tööriistad on kujundatud API-st, mida saate oma programmist helistada.
See API on see, mida me näeme ülaltoodud näites. Lähemalt vaatame.
Tellingud
Enne tegeliku tegeliku joonistamist peate tegema seadistamine. Peate määratlema oma vaatepordi (piirkond, mida tegelikult muudetakse), teie perspektiivi ( kaamera oma maailmale), millist anti-aliasingi te kasutate (oma kolmnurga teravdamiseks) …
Kuid me ei vaata seda ühtegi. Me lihtsalt vaatame asju, mida peate tegema iga raamistik. Meeldib:
Ekraani puhastamine
Graafika torujuhe ei lase ekraanil sinu iga raami. Peate seda rääkima. Miks? See on põhjus, miks:
Kui te ei eemalda ekraani, saate lihtsalt edasi lükkama see kõik raame. Sellepärast me kutsume
glClear
koos
GL_COLOR_BUFFER_BIT
seatud Teine bitt (
GL_DEPTH_BUFFER_BIT
) ütleb OpenGLile, et kustutada sügavuspuhver. Seda puhvrit kasutatakse, et määrata, millised pikslid on teiste pikslite ees (või taga).
Muutumine
Ümberkujundamine on osa, kus me võtame kõik sisendkoordinaadid (meie kolmnurga tipud) ja rakendame meie ModelView-maatriksit. See on maatriks, mis selgitab kuidas meie mudel (tipud) pööratakse, skaleeritakse ja tõlgitakse (teisaldatakse).
Järgnevalt rakendame Projection-maatriksit. See liigub kõik koordinaadid nii, et nad näevad meie kaamera korralikult kinni.
Nüüd transformeerime veel kord meie Viewport maatriksiga. Me teeme seda meie mastaabiks mudel meie monitori suurusele. Nüüd on meil tippude komplekt, mis on valmis renderdamiseks!
Läheme tagasi transformatsioonile natuke hiljem.
Joonistamine
Kolmnurgast juhtimiseks võime lihtsalt OpenGLile uue versiooni alustada kolmnurkade loend helistades
glBegin
koos
GL_TRIANGLES
konstantne On ka muid vorme, mida saate joonistada. Nagu kolmnurga riba või kolmnurga ventilaator.Need on ennekõike optimeeringud, kuna need nõuavad sama palju triangleid joonestamiseks CPU ja graafikaprotsessoriga.
Pärast seda võime esitada loetelu kolmest tipust, mis peaks moodustama iga kolmnurga. Iga kolmnurk kasutab 3 koordinaati (nagu me 3D-ruumis). Lisaks pakun ka mulle a värv iga tipu jaoks helistades
glColor3f
enne kutsudes
glVertex3f
OpenGL arvutab kolmest tipust (kolmnurga kolmnurgad) varju automaatselt. See interpoleerib värvi üle kogu hulknurga näo.
Koostoimimine
Nüüd, kui klõpsate aknal. Rakendus peab võtma ainult akna sõnumi, mis viitab klikile. Seejärel saate oma soovitud programmis käivitada mis tahes toimingu.
See saab palju kui sa tahad 3D-stseeniga suhelda hakata.
Esmalt peate selgelt teada, millises pikslis kasutaja klõpsas aknas. Siis võtke oma vaatenurkarvesse saab arvutada ray suuna, alates hiireklõpsu punkti oma stseeni. Seejärel saate arvutada, kas teie stseenis on ükski objekt lõikub selle rayga. Nüüd saate teada, kas kasutaja klõpsas objekti.
Niisiis, kuidas sa selle pöörleksid?
Muutumine
Olen teadlik kahte tüüpi muutustest, mida üldiselt rakendatakse:
- Matrix-põhine muundamine
- Luupõhine muundamine
Erinevus on see luud mõjuta üksinda tipud. Maatriksid mõjutavad alati kõiki joonistatud tippe samamoodi. Vaatame näitena.
Näide
Varem laadime meie identiteedi maatriks enne meie kolmnurka joonistamist. Identiteedi maatriks on see, mis lihtsalt pakub pole ümberkujundamist üleüldse. Niisiis, mida iganes ma teen, on minu seisukoht vaid mõju. Nii et kolmnurka ei pöörata üldse.
Kui ma tahan seda nüüd pöörata, võin ma kas matemaatikat ise teha (CPU-is) ja lihtsalt helistada
glVertex3f
koosmuu koordinaadid (mis on pööratud). Või lubaksin graafikaprotsessoril kogu töö teha, helistades
glRotatef
enne joonistamist:
// Rotate The Triangle On The Y axis glRotatef(amount,0.0f,1.0f,0.0f);
amount
on loomulikult ainult fikseeritud väärtus. Kui sa tahad elavdada, peate jälgima
amount
ja suurendage seda iga raami.
Nii et oota, mis juhtus kogu maatriks-jutuga varem?
Selles lihtsas näites me ei pea maatrikseid hoolitsema. Me lihtsalt helistame
glRotatef
ja ta hoolitseb selle eest, mis meie jaoks on.
glRotate
toodab rotatsiooni
angle
vektori x y z ümbermõõt. Praegust maatriksit (seeglMatrixMode) korrutatakse pööratav maatriks tootega, mis asendab praeguse maatriksi, sest kui argumendiks kutsuti, kui justGlMultMatrix kutsutakse järgmise maatriksiga:
x 2 1 - c + cx y 1 - c - z z 1 - c + y s s s 1 - - - - 1 - c - x s 0 x z 1 - c - y ss zz 1 - c + x sz 2 ½ 1 cc c 0 0 0 0 1
Noh, aitäh!
Järeldus
Mis saab selgeks, on palju rääkida et OpenGL. Kuid see ei räägi meid midagi. Kus on teatis?
Ainuke asi, mida OpenGL meile selles näites ütleb, on kui see on tehtud. Iga operatsioon võtab teatud aja. Mõned toimingud on üsna pikad, teised on uskumatult kiire.
Tippude saatmine GPU-le on nii kiire, ma isegi ei tea, kuidas seda väljendada. Tuhandete tippude saatmine CPU-st GPU-le, iga üksiku raami puhul pole tõenäoliselt üldse mingit probleemi.
Ekraani puhastamine võib võtta millisekundi või veelgi hullem (pidage meeles, et tavaliselt on iga raami saamiseks tavaliselt ainult 16 millisekundit aega), olenevalt sellest, kui suur on teie vaateala. Selle tühjendamiseks peab OpenGL juhtima iga piksli värvi, mida soovite kustutada, see võib olla miljoneid piksleid.
Peale selle võime vaid OpenGLilt vaid meie graafikakaardi võimaluste kohta (maksimaalne resolutsioon, maksimaalne vastupidavus, maksimaalne värvide sügavus jne).
Kuid võime täita ka tekstuuri, milles on igaühel konkreetne värv. Seega on iga piksli väärtus ja tekstuur on hiiglaslik "fail", mis on täidetud andmetega. Võime selle laadida graafikakaardile (luues tekstuuri puhvri), siis laadige varjestus, öelge sellele varjule, et kasutame meie tekstuuri sisendina ja käitame meie "faili" jaoks väga suuri arvutusi.
Seejärel saab meie arvutusest (uute värvide kujul) muuta uueks tekstuuriks.
Nii saate graafikutöötlust tööd teha ka teistmoodi. Ma eeldan, et CUDA täidab seda aspekti sarnaselt, kuid mul pole kunagi olnud võimalust sellega töötada.
Me tõesti vaid pisut puudutasime kogu teemat. 3D-graafika programmeerimine on metsalise põrgu.
Kas teil on seletamiseks midagi lisada? Helistage kommentaarides. Kas soovite lugeda rohkem vastuseid teistelt tech-savvy Stack Exchange'i kasutajatelt? Tutvu täieliku arutelu teemaga siit.