T-111.4300 Tietokonegrafiikan perusteet OpenGL-ohjelmointi
Id Softwaren huhtikuussa 2004 julkaisema Doom 3 -peli käyttää OpenGL-kirjastoa.
Sisällys Mikä on OpenGL? historia nykytilanne OpenGL:n toiminta Piirtäminen ja matriisit Muuta hyödyllistä kameran sijoittaminen valaistus
Materiaalia Älä usko assaria, lue kirjoja ja kokeile! Kurssikirjaan (Hearn & Baker) hyvä tutustua OpenGL Programming Guide ja OpenGL Reference Manual erittäin hyviä oppaita, löytyvät myös verkosta: paljon tietoa, jota ei löydy näistä kalvoista http://www.opengl.org/documentation/red_book_1.0/ Linkkejä verkosta löytyvään materiaaliin kurssin harjoitusten linkkisivuilla: http://www.tml.tkk.fi/opinnot/t-111.4300/2005/exercises/links.html
Mikä on OpenGL? Matalan tason 2d- ja 3d-grafiikkakirjasto Pohjautuu SGI:n IRIS GL -kirjastoon 80-luvulta Käytännössä standardi, tuettu kaikilla yleisimmillä käyttöjärjestelmillä Tarkoitettu vuorovaikutteiseen tietokonegrafiikkaan Yleiskäyttöinen, ei pelkkä pelikirjasto! Alun perin C-kielelle Nykyään voidaan käyttää myös Pythonilla, Javalla, Perlillä, C#:lla... Nykyiset versiot 1.1-1.4 Versio 2.0 on kehitteillä
OpenGL - kilpailu & tulevaisuus Tärkein kilpailija Microsoftin Direct3D Toimii ainoastaan Windows- ja Xbox-ympäristöissä Jyräämässä erityisesti peleissä OpenGL:n yli Poikkeuksena Doom 3 Molemmat näytönohjaimeista riippumattomia OpenGL Vista/Longhorn -käyttöjärjestelmässä epäselvä Saattaa hidastua jopa 50 prosenttia! OpenGL:stä myös mobiililaitteisiin tarkoitettu OpenGL ES -versio
OpenGL-apukirjastot OpenGL sisältää kolme erillistä kirjastoa: GL, GLU ja GLUT GL eli varsinainen OpenGL-kirjasto hoitaa ainoastaan renderöinnin GLU (OpenGL Utility Library) tarjoaa projektiofunktioita (esimerkiksi gluperspective, glulookat) GLUT (OpenGL Utility Toolkit) tarjoaa ikkunan hallinnan, fonttien käsittelyn ja erilaisia apufunktioita esimerkiksi yksinkertaisten mallien luomiseen ei virallisesti osa OpenGL-kirjastoa ei käytetä Javassa ikkunoiden luomiseen!
Mitä OpenGL ei sisällä? Nämä toiminnallisuudet täytyy ohjelmoida itse, tai käyttää valmiita, OpenGL:n päällä toimivia kirjastoja 1. Scene Graphit OpenGL ei sisällä pysyvää tietorakenetta malleista ja niiden sijainneista, joka säilyisi piirtokertojen välissä Tällaista rakennetta kutsutaan nimellä scene graph 2. Mallien lataaminen OpenGL ei osaa ladata kolmiulotteisia malleja tiedostoista 3. Ray Tracing OpenGL ei tue Ray Tracingia, eli kuvan muodostamista valonsäteiden polkuja seuraamalla Ei toteutettavissa OpenGL:llä
Kolmion piirtäminen Kolmion piirtäminen OpenGL:ssä: gl.glbegin(gl.gl_triangles) // Yläkärki gl.glvertex3f( 0.0f, 1.0f,0.0f); // Vasen alanurkka gl.glvertex3f(-1.0f,-1.0f,0.0f); // Oikea alanurkka gl.glvertex3f( 1.0f,-1.0f,0.0f); gl.glend(); Polygoni esitetään sarjana verteksejä, Verteksien välille muodostuvat polygonin sivut Monimutkaisemmat kappaleet koostuvat useista polygoneista
OpenGL-ohjelmien toimintaperiaate OpenGL perustuu välittömään tilaan Kaikki kuviot piirretään uudelleen joka piirtokerralla Vastakohtana pysyvä tila Nykyisillä näytönohjaimilla onnistuu tehokkaasti Ihmissilmä kokee miellyttävänä ruudunpäivitysnopeuden, joka on vähintään 40 kuvaa sekunnissa
OpenGL Tilakone 1 OpenGL oikeastaan iso tilakone Sisältää yli 100 tilamuuttujaa Kun tila on asetettu, se on voimassa kunnes sitä muutetaan Tilat asetetaan toisistaan riippumattomasti Funktioita tilojen muuttamiseksi Tilat vaikuttavat näytönohjaimen toimintaan Esimerkiksi aktiivinen väri, tekstuuri ja transformaatiot ovat tilan muutoksia Muita tilan muutoksia: valot, sumu...
OpenGL Tilakone 2 Tiloja vaihdetaan funktiokutsuilla Komennot vaikuttavat piirrosprosessiin Ei takeita, että lopputulos olisi samanlainen kahdella eri alustalla
OpenGL Tilakone 3
OpenGL-komentojen syntaksi OpenGL-komennot alkavat etuliitteellä gl, jota seuraa komennon nimi Esim glbegin ja glvertex3f OpenGL-vakiot kirjoitetaan isoin kirjaimin alkavat etuliitteellä GL_ Esim GL_LINE_STRIP Yleensä funktioiden nimet kertovat, montako parametria ne ottavat ja mitä tyyppiä ne ovat Esimerkiksi: glvertex2f (2 float-muotoista parametria) glvertex3f (3 float-muotoista parametria) glvertex3i (3 integer-muotoista parametria)
Piirtäminen OpenGL:ssä Kymmenen erilaista piirtoprimitiiviä Muut kuviot ja mallit piirretään näitä primitiivejä käyttäen
Yksinkertainen OpenGL-ohjelma public void display(gldrawable drawable) { GL gl = drawable.getgl(); gl.glclearcolor(0.0f, 0.0f, 0.0f, 0.0f); gl.glclear(gl.gl_color_buffer_bit); gl.glortho(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f); gl.glcolor3f(1.0f, 1.0f, 1.0f); gl.glbegin(gl.gl_polygon); gl.glvertex2f(-0.5f, -0.5f); gl.glvertex2f(-0.5f, 0.5f); gl.glvertex2f( 0.5f, 0.5f); gl.glvertex2f( 0.5f, -0.5f); gl.glend(); } gl.glflush(); Pohjautuu OpenGL Programming Guide -esimerkkiin
OpenGL koordinaatistot OpenGL:ssä verteksit saadaan ruudulle sopivaan muotoon kolmella affiinimuunnoksella Kaikki 3d-muunnokset ovat affiinimuunnoksia Voidaan laskea homogeenisillä 4x4 matriiseilla Verteksin muuntaminen:
Matriisipinot 1 Matriiseilla määritellään Translaatiot Rotaatiot Skaalaukset Kallistukset (skew) Matriisipino sisältää sarjan muunnosmatriiseja Pinon päällimmäinen matriisi on käytössä oleva matriisi Matriisi lisätään pinoon glpushmatrix()-komennolla Päällimmäinen matriisi poistetaan pinosta glpopmatrix()-komennolla Tyhjää matriisia kutsutaan identiteettimatriisiksi ja sen voi ladata glloadidentity()-komennolla
Matriisipinot 2 OpenGL:ssä on kolme matriisipinoa Katselumatriisit (GL_MODELVIEW) Projektiomatriisit (GL_PROJECTION) Tekstuurimatriisit (GL_TEXTURE) Aktiivista matriisipinoa vaihdetaan seuraavasti: glmatrixmode(gl_modelview); glmatrixmode(gl_projection); Objektien asettelu ja käsittely tapahtuu modelview-pinossa
3d-muunnokset 1 Kappaleiden saaminen oikeille paikoilleen onnistuu 3d-muunnosten avulla: glrotatef( ) kääntää kuvioita gltranslatef( ) siirtää piirrettävää kuviota. glscalef( ) muuttaa kuvion kokoa. Muunnoksilla muutetaan koordinaatistoa, ei kappaletta Vastaavat Modelview-matriisin ja sopivan muunnosmatriisin tuloa Esim muunnosmatriisi pisteiden kääntämiseksi y-akselin ympäri:
3d-muunnokset 2 1. Talleta ensin nykyinen matriisi pinoon glpushmatrix-komennolla 2. Tee tarvittavat muunnokset Järjestyksellä on väliä! 3. Piirrä objekti 4. Palauta edellinen matriisi glpopmatrixkomennolla
Muunnosten järjestys glrotatef(pi/4,0,0,1); gltranslatef(5,0,0); drawcar(); gltranslatef(5,0,0); glrotatef(pi/4,0,0,1); drawcar();
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Perustuu Jeff Chastinen esimerkkiin: http://cims.clayton.edu/itsd4305/
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Identiteetti
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Identiteetti
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Translaatio Identiteetti
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Translaatio Identiteetti
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Rotaatio Translaatio Identiteetti
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Translaatio Identiteetti
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Translaatio Identiteetti
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Translaatio Translaatio Identiteetti
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Translaatio Identiteetti
Matriisipino: esimerkki glloadidentity(); gltranslatef ( ); glrotatef ( ); gltranslate ( ); Identiteetti
Valaistus 1 Valaistu ja valaisematon pallo:
Valaistus 2 Valaistus otettava erikseen käyttöön: glenable(gl_lighting); Jokainen valonlähde otettava erikseen käyttöön glenable(gl_light0); Kolmenlaisia valoja: Pointlight pistevalo, säteilee joka suuntaan Spotlight valokeila, säteet rajatussa kulmassa Directional light äärettömän kaukana oleva pistevalo Spotlightin leveyden määrittää GL_SPOT_CUTOFF -parametri
Valaistus 3 Valonlähteen paikka määritellään GL_POSITIONparametrin avulla Jos paikkamuuttujan viimeinen arvo on 0, valonlähde on suunnattu valo suunnattu valo on äärettömän kaukana float[] light_position = new float[] { 1.0f, 1.0f, 1.0f, 0.0f }; gl.gllightfv(gl.gl_light0, GL.GL_POSITION, light_position);
Valaistus 4 Valonlähteen ominaisuuksia muutetaan gllightfvmetodin avulla, esim: float[] lightdiffuse = new float[] {1.0f, 1.0f, 1.0f, 1.0f}; gl.gllightfv(gl.gl_light0, GL.GL_DIFFUSE, lightdiffuse); Lisää valaistusoppia OpenGL Programming Guidessa: http://www.glprogramming.com/red/chapter05.html
Sävytys 1 (shading) Pinnan polygonien varjostusta OpenGL:ssä kaksi tapaa täyttää polygoni: GL_FLAT polygoni täytetään tasaisella värillä, joka on yhden verteksin väri GL_SMOOTH Gouraud-sävytys verteksien värit interpoloidaan polygonin sisäpuolisille pisteille Valitaan glshademodel()-metodilla
Sävytys 2 Wireframe (lähde: OpenGL Red Book)
Sävytys 3 Antialiased wireframe (lähde: OpenGL Red Book)
Sävytys 4 Flat shading (lähde: OpenGL Red Book)
Sävytys 5 Smooth (gouraud) shading (lähde: OpenGL Red Book)
Sävytys 6 Textured (lähde: OpenGL Red Book)
Ruudun tyhjentäminen Ruudun tyhjennys OpenGL:ssä: glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT); Tyhjentää sekä väri- ja syvyyspuskurin Ruuduntyhjennysvärin muuttaminen: glclearcolor(0.0f, 0.0f, 0.0f, 0.0f);
Kameran sijoittaminen Helpoin tapa sijoittaa kamera on käyttää glu-kirjaston glulookat()-metodia: eye-koordinaatit määrittävät kameran sijainnin center-koordinaatit pisteen, johon kamera katsoo up-koordinaatit ylöspäin osoittavan vektorin glulookat(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);
Geometriset primitiivit GLUT-kirjastosta löytyy metodit yleisimpien geometristen primitiivien piirtämiseen Erityisesti hyötyä yksinkertaisissa testiohjelmissa Kuution piirtäminen: glutsolidcube(1.0f); Muita GLUT-kirjastosta löytyviä primitiivinpiirtometodeja: glutsolidsphere(), glutsolidicosahedron(), glutsolidtorus()