<< >> Title Contents Index

2. OpenGL lyhyesti


OpenGL (Open Graphics Library) on Silicon Graphicsin (SGI) tekemään (IRIS) GL:ään pohjautuva, grafiikan ohjelmointiin suunniteltu aliohjelmakirjasto. GL oli SGI:n omissa IRIS-grafiikkatyöasemissa toimiva grafiikkarajapinta. IRIS-työasemat oli tarkoitettu erityisesti 3D-grafiikan tekoa varten. Niiden matriisien käsittely oli huomattavasti tehokkaampaa kuin tavallisten kotimikrojen. SGI halusi siirtää GL:n myös muihin laitteistoympäristöihin. Aluksi se tuotti ongelmia, mutta kun SGI vihdoin onnistui vuonna 1992, sai GL myös uuden nimen, OpenGL.

OpenGL:n aliohjelmat on kirjoitettu C-kielellä, ja niitä on mahdollista kutsua C- tai C++-kielisistä ohjelmista. OpenGL sisältää noin 120 piirtämiseen liittyvää aliohjelmakutsua. Monesta aliohjelmasta on valittavana useampi vaihtoehtoehto parametrityypeistä riippuen. Mikäli kaikki aliohjelmakutsut lasketaan erikseen, on niitä yhteensä noin 300.

OpenGL on erityisesti teknistieteellisiin sovelluksiin suunnattu 2D- ja 3D-ohjelmoinnin rajapinta. Objekteja voidaan mm. pinnoittaa eri materiaaleilla ja valaista eri kulmista. OpenGL sisältää myös ympäristöön ja animaatioon liittyviä palveluja.

Luonteeltaan OpenGL on laitteistoriippumaton. Laitteistoriippumattomuus tarkoittaa OpenGL:n tapauksessa sitä, että itse piirtorutiinit pysyvät samanlaisina laitteistosta riippumatta. Ikkunoiden ja väritaulukoiden alustukset, sekä hiiren ja näppäimistön välittämät viestit voivat sen sijaan poiketa eri ympäristöissä. Grafiikkarajapinta löytyy ainakin seuraaviin ympäristöihin:

OpenGL on siirretty myös X-Window-ympäristöön. Laitteistoriippumattomuuden ansiosta OpenGL-sovelluksia on mahdollista hajauttaa. Palvelimella olevaa sovellusta voidaan siis ajaa samanaikaisesti eri käyttöjärjestelmillä varustetuilla laitteilla.

2.1. Merkintätavat ja termit

Tutkielmassa esiteltävät aliohjelmakutsut esitetään kursivoituna tekstinä (esim. glClearColor( )). Tekstin seassa olevat ohjelmakoodit on reunustettu kehyksillä ja koodit on kirjoitettu punaisella. Ohjelmakoodin liittyvät kommentit on erotettu C++:n mukaisella kommentoinnilla ja kommentit on kirjoitettu kursivoituna.

    glClearColor(...)). // Tämä on kommentti
OpenGL:n omat aliohjelmakutsut tunnistaa etuliitteestä gl_ (OpenGL), glu_ (OpenGL Utility Library) tai aux_ (OpenGL Programming Guide Auxiliary Library).

Usein aliohjelmaa kutsuttaessa voidaan valita minkälaisia parametrejä aliohjelmalle halutaan välittää. Esimerkiksi kontrollipisteen paikan määräämiseksi tehty aliohjelma esitellään muodossa glVertex{234}{s i f d}v(TYPE coord). Ensimmäisten kaarisulkujen välissä oleva kokonaisluku kertoo, annetaanko piste kaksi-, kolmi- tai neliulotteisessa koordinaatistossa. Toisten kaarisulkujen sisällä oleva kirjain määrittelee lukutyypin (katso Taulukko 2.1.). Hakasulkujen sisällä oleva kirjain v mahdollistaa taulukon osoitteen viemisen parametrinä. Lopullinen aliohjelman kutsu on esimerkiksi seuraavanlainen:

    glVertex3i( 1, 2, 3); // Parametrinä viedään kolme kokonaislukua, (3i).
Saman lopputuloksen saa myös seuraavasti.

    int point_array = { 1, 2, 3 }; // Taulukko, jossa kolme kokonaislukua.
    glVertex3iv( point_array ); // Parametrinä viedään osoite taulukkoon, (3iv).

Tekstissä esiintyy muutama termi, jotka voivat normaalisti tarkoittaa hieman eri asioita. Seuraavassa on selvitys siitä, mitä niillä tässä monisteessa tarkoitetaan.

Objekti on jokin useammasta pisteestä, viivasta, kaaresta tai näiden yhdistelmistä rakennettu kappale. Objekti voi olla esimerkiksi pallo, neliö tai seinä.

Malli on useammasta objektista rakennettu piirros. Malli voi olla esimerkiksi puu (lehdet ja runko) tai auto (renkaat, kori jne).

Näkymä on lopullinen näkyvä piirros näytöllä. Näkymä voi koostua useammasta mallista ja objektista, mutta yhtä hyvin näkymässä voi olla vain yksi objekti.

Rautalankamalli on objekti, josta esitetään ainoastaan reunaviivat. Reunaviivat näkyvät kaikista objektin osista, vaikka ne olisivatkin toisen objektin takana.

Pintamalli on objekti, jonka pinnat on "täytetty" joko värittämällä tai halutulla bittikartalla. Jos kaksi objektin osaa sijoittuvat päällekkäin, on pintamallissa valittava halutaanko piirtää kauempana, vaiko lähempänä oleva objektin osa.

Aliohjelmille välitettävien parametrien tyypit on selostettu taulukossa 2.1.

lyhenne

datatyyppi
C-kielessä
OpenGL syntaksi
mahdolliset arvot
b
8-bit integer
signed char
Glbyte
-128 - 127
s
16-bit integer
short
Glshort
-32768 - 32767
i
32-bit integer
long
GLint, GLsizei
-2147483648 - 2147483647
f
32-bit floating-point
float
GLfloat, GLclampf
3,4E +/- 38
d
64-bit floating-point
double
Gldouble, Glclampd
1,7E +/- 308
ub
8-bit unsigned integer
unsigned char
Glubyte, Glboolean
0 - 255
us
16-bit unsigned integer
unsigned short
Glushort
0 - 65535
ui
32-bit unsigned integer
unsigned long
GLuint, Glenum, Glbitfield
0 - 4294967295
Taulukko 2.1. Aliohjelmille välitettävien parametrien tyypit.

2.2. Yksinkertainen OpenGL ohjelma

Valmiiden piirtorutiiniensa ansiosta OpenGL-ohjelman koodi voi olla hyvinkin yksinkertainen. Vaadittavat toimenpiteet ovat

Seuraava yksinkertainen OpenGL-ohjelmakoodi piirtää valkoisen kolmion mustalle pohjalle:

    #include "glos.h"

    #include <GL/gl.h>
    #include <GL/glaux.h>
    #include <GL/glu.h>

    int main( void )
    {

      auxInitDisplayMode( AUX_SINGLE | AUX_RGB );
      auxInitPosition( 0, 0, 250, 250 ); // Alustaa ikkunan GLAUX aliohjelmakirjaston
      auxInitWindow( "Kolmio" ); // aliohjelmilla.

      glClearColor( 0.0, 0.0, 0.0, 0.0 ); // Määrää pohjavärin mustaksi.
      glClear( GL_COLOR_BUFFER_BIT ); // Suorittaa taustan värityksen.
      glColor3f ( 1.0, 1.0, 1.0 ); // Piirtoväri valkoiseksi.
      glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ); // Määrää koordinaatiston...
      // (left, right, bottom, top, near, far).
      glBegin ( GL_POLYGON ); // Aloitetaan polygonin määrittely.
        glVertex2f( -0.5, -0.5 ); // Vasen alareuna.
        glVertex2f( 0.0, 0.5 ); // Keskellä ylhäällä.
        glVertex2f( 0.5, -0.5 ); // Oikea alareuna.
      glEnd( ); // Polygonin määrittely valmis.
      glFlush( ); // Suorittaa piirron puskurist.a ikkunaan.
      Sleep( 3000 ); // Pitää ikkunan näkyvissä 3 sek.
      return( 0 );
    }


Kuva 2.1. Yksinkertainen OpenGL-ohjelma.

Tulevissa esimerkkiohjelmissa pääohjelma jaetaan osiin. Pääohjelmassa pidetään ikkunan alustuksesta ja avauksesta huolehtivat aliohjelmat. Kaksi muuta GLAUX-aliohjelmakirjaston aliohjelmaa huolehtivat ikkunan koordinaatiston ja piirron päivityksestä.

Ikkunan koon muutoksesta ja koordinaatiston päivityksestä huolehtii aliohjelma auxReshapeFunc(...), jolle viedään parametrinä varsinaisen koodin sisältävän aliohjelman kutsu ilman parametrejä. Jos esimerkiksi tarkoitus olisi kutsua aliohjelmaa PaivitaKoko(int leveys, int korkeus) aina kun ikkunan koko muuttuu, täytyisi kutsua aliohjelmaa auxReshapeFunc(PaivitaKoko). Piirtoalueen päivityksestä huolehtii aliohjelma auxMainLoop(...), jolle viedään viedään vastaavasti parametrinä piirtorutiinit määrittelevän aliohjelman nimi. Värien ja materiaalien alustukset suoritetaan aliohjelmassa AlustaArvot( ).

Ikkunan koordinaatiston päivitys tapahtuu aliohjelmassa:

    static void CALLBACK PaivitaKoko( int leveys, int korkeus )
    {
      ...
    }

Ikkunaan suoritettavat piirtorutiinit suoritetaan aliohjelmassa:

    static void CALLBACK Piirra( void )
    {
      ...
    }

Pääohjelma olisi nyt seuraavanlainen:

    #include "glos.h"
    #include <GL/gl.h>
    #include <GL/glaux.h>
    #include <GL/glu.h>

    // Tähän väliin tulisi oikeasti aliohjelmat
    // void AlustaArvot( ){...},
    // static void CALLBACK PaivitaKoko( int leveys, int korkeus ){...} ja
    // static void CALLBACK Piirra( ){...}.

    int main( void )
    {
      auxInitDisplayMode( AUX_SINGLE | AUX_RGBA );// SingleBuffer ja RGBA värit.
      auxInitPosition( 0, 0, 300, 300 ); // Ikkunan paikka ja koko.
      auxInitWindow("Otsikko"); // Ikkunan otsikko.
      AlustaArvot( ); // Värien ja materiaalien alustukset.
      auxReshapeFunc( PaivitaKoko ); // Päivittää kokoa.
      auxMainLoop( Piirra ); // Päivittää piirrot.
      return( 0 );
    }

Mikäli pääohjelman koodi ei muutu (paitsi ehkä ikkunan koko ja otsikko), esitetään ainoastaan aliohjelmat AlustaArvot( ), PaivitaKoko(...) ja Piirra( ).

2.3. Mihin OpenGL pystyy?

OpenGL:n hyöty ja tehokkuus tulevat ilmi, kun halutaan lisätä tiettyjä ominaisuuksia suunniteltuun kuvaan.

Kuva voidaan esittää joko rautalanka- tai pintamallina (katso Kuva 2.2.). Rautalankamallissa näkyvät ainoastaan objektien ääriviivat. Kaikki objektien ääriviivat näkyvät, vaikka ne olisivatkin toisen objektin takana. Pintamallissa jokaisen objektin pinta täytetään tietyllä värillä.


Kuva 2.2. Rautalankamalli ja pintamalli.

Luonnossa silmä ei näe kaukana olevia kohteita yhtä tarkasti kuin lähellä olevia. Samalla tavalla OpenGL mahdollistaa syvyysvaikutelman himmentämällä kauempana katsojasta olevien objektien rajoja.

Usein objektien reunat näyttävät epäluonnollisilta, koska reunalla olevasta pikselistä vain osa kuuluu objektiin. Pikselin väri jouduttaisiin valitsemaan kahden vaihtoehdon, objektin ja taustan välillä. Reunoja on mahdollista pehmentää valitsemalla reunalla sijaitsevien pikselien väriksi näiden kahden värin sekoitus (katso Kuva 2.3.).


Kuva 2.3.Rajojen pehmennys.

Animaation lisääminen ja katselupisteen siirtely tekevät usein sovelluksesta mielenkiintoisen ja näyttävän (katso Kuva 2.4.).


Kuva 2.4. Lähikuva ja objektien liike (motion blur).

Luonnossa valo tekee esineiden pinnoista eläviä. OpenGL osaa laskea valon määrän, valonlähteiden paikkojen ja pinnan materiaalin avulla pinnan kirkkauden ja varjostamisen erot. Lisättäessä mahdolliset bittikartat pintojen päälle, saadaan OpenGL:n avulla luotua näyttävää tietokonegrafiikkaa (katso Kuva 2.5.).


Kuva 2.5. Valo, varjot ja bittikartat.


<< >> Title Contents Index