Juha-Pekka Jokela | jpjokela@gmail.com
OpenGL-kurssi, osa 5

Tämä kurssi sopii kaikille, jotka ovat kiinnostuneita OpenGL-ohjelmoinnista. Kurssin osat 1 ja 2 käsiteltiin Sakussa #47 (1/2005), osa 3 Sakussa #48 (2/2005) ja osa 4 Sakussa #49 (1/2006).

Paljon on opittu uutta sitten edellisen osan kirjoittamisen, tärkeimpänä ehkä se, ettei piirtoa kannata toteuttaa lainkaan sillä tavalla kuin se aiemmin tehtiin. Immediate moden ja display listien sijaan kannattaa sijoittaa arvot taulukkoon, jolloin OpenGL:lle voi yksinkertaisesti antaa osoittimet oikeisiin kohtiin ja käskeä piirtämään määritelty määrä elementtejä haluttuna tyyppinä, esim. GL_TRIANGLES. Toki itse mallin datat kannattaa piilottaa omaan rakenteeseen ja piirtofunktiot funktioon, joka ottaa argumentikseen osoittimen rakenteeseen, kuten esimerkissäkin on tehty.

glEnableClientState ottaa määritellyn ominaisuuden käyttöön

void glEnableClientState(GLenum cap);
cap: Mitä enabloidaan (esim. GL_VERTEX_ARRAY)

glVertexPointer määrittelee verteksitaulukon osoittimen

void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
size: Verteksikohtaisien elementtien määrä (esim. 3)
type: Elementin tyyppi (esim. GL_FLOAT)
stride Montako tavua eri elementtien välillä on (esim. 0)
pointer: Osoitin taulukkoon

Vertex arraylla piirron voi tehdä kahdella eri tavalla:

glDrawArrays siirtää verteksitaulukon elementit suoraan

void glDrawArrays(GLenum mode, GLint first, GLsizei count);
mode: Minä primitiivinä piirretään (esim. GL_TRIANGLES)
first: Monennestako verteksistä aloitetaan
count: Montako verteksiä piirretään

glDrawElements piirtää verteksitaulukon elementit indeksitaulukkoa käyttäen

void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
mode: Minä primitiivinä piirretään (esim. GL_TRIANGLES)
count: Montako verteksiä piirretään
type: Indeksitaulukon elementtien tyyppi (esim. GL_UNSIGNED_INT)
indices: Osoitin indeksitaulukon haluttuun kohtaan. Kukin indeksin numero määrittää, mikä verteksi kulloinkin piirretään. Tämä mahdollistaa saman verteksin käyttämisen useaan kertaan samaa mallia piirrettäessä.


Nopeimmin OpenGL-piirto tapahtuu Vertex Buffer Objectin (VBO) avulla. Tätä ei kuitenkaan Amiga-puolella vieläkään tueta, paitsi AROS:issa. Käytännön toteutus on kuitenkin erittäin lähellä verteksitaulukoita. Lähinnä ero on siinä, että ennen käyttöä data kopioidaan näytönohjaimen muistiin, eikä sitä tarvitse joka piirtokerta lähettää uudestaan, paitsi jos sisältöä tarvitsee muuttaa.

Toki uudemmissa OpenGL-versioissa on luovuttu täysin vanhemmasta "Fixed function" -piirrosta, joka on toistaiseksi ainoa tapa AmigaOS4:llä ja MorphOS:lla, mutta perusidea verteksien ja indeksien laittamisesta taulukkoon (ja kopioimisesta näytönohjaimen muistiin) on edelleen käytössä, ainoastaan glVertexPointer() ym. funktiot täytyy korvata uusilla korvaavilla.

Immediate mode ja display listit taas on poistettu kauan sitten. Muokkaamalla koodin käyttämään vertex arrayta (tai VBO:ta) koodista tulee myös paljon helpommin portattava OpenGL ES1:lle, joka on OpenGL:n mobiiliversio. Kuten desktop-puolellakin, myös tästä on shadereita käyttävä 2.x-versio, jonka toimintaperiaate on pitkälti erilainen fixed functionin kanssa.

Koodin kääntö MorphOS:lla (muuta tiedoston nimi osa5.txt -> osa5.c):
gcc osa5.c -noixemul -lGL -lglut -lm -o osa5

> Esimerkkikoodi


Sivun alkuun