3D-grafiikkaa Linuxilla, osa 2

Tänään asennetaan OpenGL- kirjasto C-ohjelmointia varten. Aiempi osa kertoi taustoja 3D-ohjelmoinnista Linuxilla.

Ohjelmointiympäristön palikoiden asentaminen valmistaa kolmanteen osaan. Tänään ei vielä päästä itse koodin äärelle.

3D-grafiikka erityisesti tietokoneella perustuu lähes aina kolmioihin ('triangles'). Viivan piirtoon on olemassa tunnettu ja vanha Bresenhamin algoritmi. Myös rasterisointiin, eli koordinaattien muuntamisessa lopputulokseksi (pikseleiksi) voidaan käyttää kolmioiden tapauksessa Bresenhamia (hyvä lähde kolmiontäyttöalgoritmeihin, Javalla).

Tuleeko tästä ihka aito pelimoottori?

Ei aivan! 🙂 Tässä on jo kuitenkin tulossa "pelimoottorin" ainekset. Todellisuudessa ohjelmistoarkkitehtuuria kannattaa miettiä toki, mutta blogisarjan tähtäimessä on pieni  demo, jolla päästään jo jyvälle.

GPU, piiri vai kortti? Miksi?

Muista, että GPU:n tärkein hyöty on siis vauhdittaa 3-ulotteisen maailman piirtoa; se ottaa pois ohjelmoijan harteilta paljon sellaista raskasta soutamista (algoritmeja), jotka on jo keksitty tuhanteen kertaan. GPU on siis tietokoneen prosessori, jota kutsutaan usein "grafiikkapiiriksi" tai vanhemman fyysisen muodon perusteella 'grafiikkakortiksi'. PC-tietokoneisiin, jossa on tilaa fyysisesti, voidaan laittaa kiinni väylään emolevylle lisäkortteja, jotka lisäävät ominaisuuksia ja GPU:n kohdalla koneen grafiikkakykyjä.

GPU on siis elektroniikkaa, joka sisältää rinnakkaisia polkuja: koska kolmiulotteisen grafiikan laskis ennassa lopulta saavutettavan FPS-lukeman taustalla on paljon numeroiden laskemista, grafiikkaprosessori on suunniteltu erittäin laajasti rinnaislaskentaa hyödyntäväksi. Tällöin saadaan kerralla laskettua hyvin samanlaisia matemaattisia asioita nopeasti.

Ennen GPU:ita ohjelmoija itse teki softalla nämä rutiinit. Pikselit laskettiin yksi kerrallaan. Päästiin vaatimattomampaan tulokseen: piti joko alentaa resoluutiota, jolloin laskentaa on vähemmän määrällisesti, tai tyytyä yksinkertaisempien 3D-efektien ja mallien tuottamaan usein huonomman näköiseen lopputulokseen.

Commodore 64 -aikakauden 1MHz :n nopeudella toimivat prosessorit pystyivät tukemaan ihan kohtuullista vektorigrafiikkaa. Keinot ovat monet, sanoi akka kun kissalla pöytää pyyhki! Siis; tuo 1 megahertsi = tuhannesosa 1 GHz:stä. Resursseja ei ollut liikaa, toisaalta Commodoren näyttö oli aina (vain) 320x200 pikseliä eli yhteensä 64000 kpl; vertaa alla 4K-näyttöjen määriin, yli 8 miljoonaa.

Täytyy muistaa että resoluutioiden lisääntyessä on kyse kertolaskusta, joten laskutoimitus suoritetaan jotta voidaan verrata työmääriä eri resoluutioiden kohdalla. Esimerkiksi ns. 4K-näyttö on nimensä mukaisesti 4000 pikseliä. Koska 4K-standardeja on muutamia, voidaan ottaa vertailuksi kaksi yleistä:

  • DCI 4K jossa 4096 x 2160 = 8,8 miljoonaa pikseliä
  • 4K UHD jossa 3840 x 2160 = 8,3 miljoonaa pikseliä

Miten liike (animaatio) saadaan aikaiseksi?

Naiivi idea on piirtää, ja sen jälkeen ennen uuden framen piirtämistä tyhjentää koko ruutu (erase). Eli räpsytellään ruutua, ikäänkuin: ennenkuin piirretään uusi kuva, niin pyyhitään taulusienellä vanha pois juuri ennen uuden piirtoa. Tällä on omat ongelmansa, joihin on myös ratkaisut. GPU hoitaa nämä oikeasti, veikkaisin. Mutta: ei mennä vielä näin pitkälle - näihin palataan myöhemmin tulevissa blogeissa. Keskitytään toistaiseksi tiukasti tuohon kolmioiden piirtelyyn ja ensimmäisen ohjelman aikaansaamiseen.

Älä nysvää - vaan valjasta prosessori töihin!

Meitä, ohjelmoijina, kiinnostaa grafiikkaprosessorin (GPU:n) valjastaminen tekemään operaatiot. GPU osaa laittaa ruudulle 2-ulotteista pikselidataa. GPU tuntee vaikka mitä lisätemppuja. Yksinkertaisimmatkin grafiikkaprosessorit pystyvät tarjoamaan nykypäivänä kaikki ominaisuudet hienojen pelien tekemiseen. Isoimmat erot tulevat lopulta siinä, kuinka suuriresoluutioisen näytön GPU jaksaa pitää pyörimässä esimerkiksi 50, 60 tai 100 framea sekunnissa.

Ennen kuin GPU voi antaa näytönohjaimelle 2-ulotteisen valmiin taideteoksen, se laskee kaikenlaista tarvittavaa: pyörittelee esineiden koordinaatteja kolmiulotteisesti, värjää pintoja, laskee varjojen valoisuuksia, laskee mitkä esineet peittävät toisia esineitä; voi laskea heijastuksia; asettaa tekstuureja kohdilleen pinnoille; ja näin poispäin.

Me ohjastamme prosessoria ainoastaan korkealla tasolla: kerromme..

  • mitä piirretään (objekti-data eli esineet)
  • miten asiat väritetään (valaistus + tekstuurit eli täytenahat)
  • millaisia erikoisefektejä halutaan (sumua? Tulta, savua?) esineiden lisäksi
  • mistä näkövinkkelistä ("kamerasta") kuvaus tehdään

Kirjastojen asennus

OpenGL asentuu, kunhan tietää minkänimistä pakettia etsiä. (Eli: "kaikki on helppoa, kunhan osaa". Jep jep)

Monesti ainakin itse hieman turhaudun sen kanssa, että "saman asian tekemiseksi on miljoona tapaa". Linux-maailmassa tuo edellämainittu vielä korostuu, koska useilla eri distroilla (jakelupaketti) on hieman erilainen käsitys siitä, missä kansioissa asioiden pitäisi olla. Onneksi ollaan jo nykypäivänä kohtuullisen lähellä jonkinlaista standardi-käsitystä.

Linuxin 3 tarpeellista grafiikkaohjelmoinnin pakettia

  1. libGL (on siis openGL-kirjasto)
  2. GLU (OpenGL korkeamman tason funktiot ja rakenteet)
  3. freeGLUT (auttaa tekemään valmiita 3D-ohjelmia)

Asiaa selittää mm. tämä sivu. Lyhyesti sanottuna:

  • libGL toimii rajapintana oikean grafiikkakortin ja ohjelmakoodin välillä (alin taso)
  • GLU

Palatko halusta tietää lisää?

"GL" tulee sanoista Graphics Library. GL on tehokas SGI-yrityksen tekemien työasemien grafiikkastandardi. Silicon Graphics oli pioneeri tietokonegrafiikan alalla; he tekivät niin elokuvien erikoistehosteita kuin arkkitehti- ja suunnittelutoimistojen tehokkaat SGI-työasemat.

Näissä tietokoneissa on vakiona aikaansa nähden (1990-luku) erittäin tehokkaat grafiikkakortit. Ohessa on Silicon Graphicsin perustajan Jim Clarken suunnittelema ns. Geometry Engine -piisiru, suurennettuna.

Mitä seuraavaksi?

Osa 3 tulee tarjoamaan jo toimivan ohjelman.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.