OpenGL:n perusteet Osa 4: Valot ja varjot

Koko: px
Aloita esitys sivulta:

Download "OpenGL:n perusteet Osa 4: Valot ja varjot"

Transkriptio

1 OpenGL:n perusteet Osa 4: Valot ja varjot OpenGL on käyttöjärjestelmäriippumaton kirjasto 2D- ja 3D-grafiikan piirtoon. Tämä artikkelisarja opettaa sinulle 3D-grafiikan perusteet OpenGL:ää käyttäen. Esimerkeissä käytetään C\C++ kieltä. Tämä on artikkelisarjan viimeinen osa. 1 Valaistuksen matematiikkaa Oikeassa elämässä näkemämme kuva syntyy, kun jostakin valonlähteestä lähtevä valo heijastuu jostakin pinnasta silmämme verkkokalvolle. Voisimme siis teoriassa laskea virtuaalimaailmassa olevan kappaleen valaistuksen sinkoamalla virtuaalisesta valonlähteestä miljardeittain valonsäteitä ja laskemalla mitkä niistä osuvat renderöimäämme pintaa. Tätä kutsutaan termillä "photon mapping" ja jotkin 3Dmallinnusohjelmat itseasiassa käyttävät tätä menetelmää photorealisten kuvien renderöintiin. Miljardien valonsäteiden radan laskeminen ei kuitenkaan sovi realiaikasovellukselle. Ajutus voidaan tietenkin kääntää päälaelleen. Jäljitetään pinnan jokaisesta pikselistä valonsäteen rataa nurinkurisesti ja katsotaan johtaako se valonlähteeseen. Tätä menetelmää kutsutaan termillä "ray tracing". Tekniikka on huomattavasti kevyempi ja sitä käyttäviä demoja on muutamia, mutta myös tämä tekniikka on vielä liian raskas varsinkin peleille. Vasemmalla ilman valoja. Keskellä valojen kanssa ja oikealla myös varjot mukana. Huomaa lisääntynyt realismi. Koska emme voi laskea valon vaikutusta täydellisen tarkasti, täytyy meidän löytää jokin keino arvioida sitä. Uskottavan valaistuksen aikaansaamiseksi voimme jakaa pinnasta verkkokalvolle saapuvan valon karkeasti neljään eri tyyppiin: ympäristövaloihin (ambient light), hajavaloihin (diffuse light), peiliheijastukseen (specular light) ja itsesäteiltyyn valoon (emissive light).

2 1.1 Hajavalo Hajavalo on valoa, joka tulee suoraan jostakin valonlähteestä pintaan. Pinta absorboi osan tästä valosta ja heijastaa loput eteenpäin silmän verkkokalvolle. Merkitsemme hajavaloa tässä artikkelissa symbolilla D (niin kuin diffuse). Hajavalon määrä on riippuvainen siitä kulmasta, jossa valonsäde saapuu pintaan. Jos L (niin kuin light) on vektori kohti valonlähdettä ja N (niin kuin normal) pinnan normaalivektori ja kummankin näiden vektorien pituus on yksi, niin hajavalon määrä saadaan näiden pistetulona eli N L. Pinta ei kuitenkaan heijasta valon kaikkia aallonpituuksia tasapuolisesti, vaan se absorboi osaa paremmin ja osaa huonommin. Tästa muodostuu pinnan väri. Esim. jos pinta absorboi kaiken muun paitsi punaisen valon näyttää pinta punaiselta. Kaiken lisäksi pintaan saapuva valo ei välttämättä ole valkoista eli sisällä kaikkia mahdollisia aallonpituuksia. Meidän tarvitsee siis kertoa hajavalo vielä pinnan värillä, jota merkitsemme symbolilla C d (niin kuin color ja decal) ja valon värillä, jota merkitsemme symbolilla C l (niin kuin color ja light). Niinpä saamme hajavalon lopulliseksi yhtälöksi: C d * C l * ( N L ). Tässä * ei siis tarkoita pistetuloa vaan värien kertomista komponenteittain. 1.2 Ympäristövalo Ympäristövalo on valoa, jonka ei voida sanoa tulevan mistään tietystä suunnasta ja se vaikuttaa kaikkiin pintoihin samalla tavalla, olkoot ne sitten missä asennossa tahansa suhteessa valonlähteeseen. Tämä johtuu siitä, että valonsäteet kimpoilevat pinnasta toiseen sekoittuen lopulta yhteinäiseksi tasaiseksi valoksi. Merkitsemme tässä artikkelissa ympäristövaloa symbolilla A (niin kuin ambient). Ympäristävalon määrä on koko ajan vakio ja sitä ei oikein voi laskea mitenkään, vaan se sen määrä on arvioitava. Jos minimi on 0 ja maksimi 1, niin realistinen kuva saadaan yleensä hyvin pienillä arvoilla esim 0.1. Koska pinta heijastaa myös ympäristövalosta vain tietyt aallonpituudet, täytyy se kertoa pinnan värillä, joilloin saamme tälle komponentille yhtälön: C l * A. 1.3 Peiliheijastus Kun valo osuu pintaan tietyssä kulmassa, ei pinta absorboikkaan yhtään valoa vaan heijastaa sen sellaisenaan eteenpäin. Kutsumme tällaista valoa peiliheijastuneeksi ja merkitsemme sitä symbolilla S (niin kuin specular). Peiliheijastuksen kulma riippuu

3 pinnan materiaalista, kutsumme tätä ominaisuutta pinnan kiiltävyydeksi ja merkitsemme sitä symbolilla G (niin kuin gloss). Lisäksi tähän vaikuttaa pinnan tasaisuus, jota merkitsemme symbolilla M, realistinen M:n arvo on yleensä välillä Peiliheijastus riippuu valonlähteen sijainnin lisäksi myös siitä mistä kulmasta pintaa katsellaan. Meidän tarvitsee tietää siis vielä vektori, joka osoittaa kohti kameraa. Merkitsemme tätä vektoria symbolilla E (niin kuin eye). Peiliheijastuksen laskemiseeen on kaksi tapaa: ns phong- ja blinn-valaistusmallit. Phong-mallissa meidän tarvitsee tietää vektori R (niin kuin reflection), joka saadaan kun vektori E peilataan vektorin N suhteen. Tämä tehdään kaavalla: R = 2 * (N L) * N - L. Kun R on tiedossa saadaan peiliheijastus kaavasta C l * G * (L R)^M. Eli valon väri kertaa G kertaa L:n ja R:n pistetulo potenssiin M. Pinnan väri ei siis vaikuta peiliheijastukseen. Vektorin R laskeminen on kuitenkin hieman turhan monimutkainen. Tämän takia on olemassa yksinkertaisempi malli Blinn. Blinn-mallissa vektoria R ei tarvita, vaan lasketaan vektori H, joka puolittaa vektoreiden L ja E välisen kulman. Tähän jälkeen peiliheijastus lasketaan yhtälöstä: C l * G * (N H)^M.

4 Potenssilasku ^M kuitenkin muodostaa pienen ongelman. Potenssiin korotus nimittäin on kaikesta nykyajan laskentatehosta huolimatta varsin hidas operaatio varsinkin kun se joudutaan laskemaan, jopa tuhansia kertoja per frame. Tämän takia saattaa joskus olla järkevää lukita M arvoon 16 ja aproksimoida funktiota x^16, jollakin toisella yksinkertaisemmalla funktiolla. Tällaisia ovat mm: max( 0, 4*(x-0.75) ) ja max( 0, 4*(x*x-0.75) ). 1.4 Itsesäteilty valo Viimeinen muoto on itsesäteilty valo. Tämä on valoa, jota pinta itse tuottaa. Tyypillinen itsevalaiseva pinta on fosfori. Merkitsemme tätä valoa symbolilla E (niin kuin emissive). Tätäkään valoa ei voida mitenkään laskea vaan se on arvioitava. Tavallisilla pinnoilla tämä se on yleensä 0. Jos oletamme, että pinta säteilee itsensä väristä valoa saamme tämän komponentin kaavaksi: C d * E. 1.5 Lopullinen valoyhtälö Nyt voimme muodostaa yhtälön, joka antaa meille hyvin realistisen valaistuksen. Laskemme vain eri muodot yhteen eli kokonaisvalo, jota merkitsemme symbolilla I (niin kuin illumination) on A+D+S+E. Jos vielä puramme yhtälön auki blinn-mallin mukaisesti saamme I = C d * A + C d * C l * ( N L ) + C l * G * ( N H ) ^ M + C d * E. Tämä ei ota vielä huomioon sitä tosiasiaa, että valon kirkkaus vaimenee mitä kauempana valonlähteestä ollaan. Yhtälö pitää siis kertoa vaimennustermillä, joka saadaan jakamalla 1 jollakin sopivalla vakiolla k kerrottuna etäisyyden (käytämme symbolia d) neliöllä eli 1/(k*d^2). Tämä olisi siis fysikaalisesti oikein, mutta ei välttämättä hyvän näköinen. Niinpä usein käytetään jotain muuta vaimennus termiä esim: max( 0, 1 - ( d / r )^2 ). Tällöin valon kirkkaus on maksimissaan keskellä valonlähdettä ja hiipuu nollaan saavutettaessä etäisyys r ja on nolla kaikkialla tätä kauempana. Lopullinen (blinn-mallin mukainen) yhtälö on siis: I = 1/(k*d^2) * ( C d * A + C d * C l * ( N L ) + C l * G * ( N H ) ^ M + C d * E ).

5 Jos valonlähteitä on useampia pitää valaistus laskea kaikille valoille erikseen ja sitten summata tulokset. 2 Käytännön toteutus Nyt siis tiedämme valaistukseen tarvittavan yhtälön. Mutta kuinka kappale sitten oikein valaistaan sillä? Helpposti, lasketaan yhtälö kappaleen jokaiselle verteksille ja annetaan tulos värinä OpenGL:lle glcolor3f()-funktiolla. Tehdään seuraavaksi funktio, joka laskee tämän valoyhtälön syötteenään saamalle verteksille. Se saa syötteenään verteksin sijainnin (Pv), valon sijainnin (Pl), pinnan värin (Cd), valon värin (Cl) ja pinnan normaalin (N). Funktio laskee verteksille valon ja antaa sen OpenGL:lle värinä. Yksinkertaisuuden vuoksi se jättää vaimenemisen huomiotta ja olettaa itsesäteillyn valon olevan nolla. void valo(float Pv[3], float Pl[3], float Cd[3], float Cl[3], float N[3]) const float A=0.1; const float G=0.9; const float M=16; float L[3], E[3], H[3], I[3]; float temp; // Laske vektori L, joka osoittaa kohti valoa. L[0]=Pl[0]-Pv[0]; L[1]=Pl[1]-Pv[1];

6 L[2]=Pl[2]-Pv[2]; temp=sqrt(l[0]*l[0]+l[1]*l[1]+l[2]*l[2]); L[0]/=temp; L[1]/=temp; L[2]/=temp; // Laske vektori E, joka osoittaa kohti kameraa. E[0]=-Pv[0]; E[1]=-Pv[1]; E[2]=-Pv[2]; temp=sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]); E[0]/=temp; E[1]/=temp; E[2]/=temp; // Laske vektori H, joka puolittaa vektorien E ja L välisen kulman. H[0]=L[0]+E[0]; H[1]=L[1]+E[1]; H[2]=L[2]+E[2]; temp=sqrt(h[0]*h[0]+h[1]*h[1]+h[2]*h[2]); H[0]/=temp; H[1]/=temp; H[2]/=temp; // Laske ympäristövalo + hajavalo + peiliheijastus I[0]= A*Cd[0] + Cd[0]*Cl[0]*pisteTulo(N, L) + G*Cl[0]*pow(pisteTulo(N, H), M); I[1]= A*Cd[1] + Cd[1]*Cl[1]*pisteTulo(N, L) + G*Cl[1]*pow(pisteTulo(N, H), M); I[2]= A*Cd[2] + Cd[2]*Cl[2]*pisteTulo(N, L) + G*Cl[2]*pow(pisteTulo(N, H), M); // Anna tulos OpenGL:lle. glcolor3f(i[0], I[1], I[2]); Tämä johtaa kuitenkin ongelmaan teksturoinnin yhteydessä. Pinnan värihän saadaan tällöin tekstuurista, joten se voi olla eri jokaisella pikselillä. Miten siis tekstuuri suhtautuu valaistukseen? Jos luit sarjan edellisen osan muistat varmaan, että värin ja tekstuurin yhdistämisestä huolehtii texture environment, joka oletuksena kertoo värin ja tekstuurin keskenään (GL_MODULATE). Jos jätemme valoyhtälöstä pois komponentin C d saamme yhtälön: I = 1/(k*d^2) * ( A + C l * ( N L ) + C l * G * ( N H ) ^ M + E ). Jos nyt laskemme valaistuksen tämän yhtälön mukaisesti ja annamme texture environmentin kertoa värin tektuurilla saamme lopulliseksi väriksi: I = C d * ( 1/(k*d^2) * ( A + C l * ( N L ) + C l * G * ( N H ) ^ M + E ) ), joka on muuten sama kuin alkuperäinen yhtälömmekin paitsi, että myös peiliheijastus tulee kerrottua pinnan värillä. Tämä ei ole suuri katastrofi, jos peiliheijastuksen arvo on mitättömän pieni ( G on noin 0 ), mutta

7 pilaa koko vaikutelman, jos peiliheijastuksen osuus on merkittävä. Tämän ongelman voi korjata toissijaisella värillä, josta puhumme seuraavaksi. 2.1 Toissijainen väri glcolor3f()-funktiolla annettua väriä kutsutaan ensisijaiseksi väriksi. On kuitenkin olemassa laajennus GL_EXT_secondary_color, joka sallii toissijaisen värin määrittämisen. Tämä laajennus tuo mukanaan mm. funktion glsecondarycolor3fext(glfloat red, Glfloat green, Glfloat blue), jolla toissijainen väri annetaan. Toissijainen väri ei osallistu texture environmenttiin, vaan se lisätään (siis lasketaan yhteen) pikselin väriin vasta sen jälkeen kun teksture environment on tehnyt tehtävänsä. Tämä kuitenkin tapahtuu vain, jos GL_ COLOR_SUM_EXT on päällä. Se saadaan päälle kutsulla glenable(gl_ COLOR_SUM_EXT). Korjataan nyt edellisen kappaleen funktiota niin, että se olettaa pinnan värin tulevan tekstuurista ja erottaa peiliheijastuksen toissijaiseen väriin. Funktio olettaa, että GL_EXT_secondary_color-laajennos on tuettu ja että GL_COLOR_SUM_EXT ja GL_TEXTURE_2D ovat päällä ja texture environment on GL_MODULATE-moodissa. void valo2(float Pv[3], float Pl[3], float Cl[3], float N[3]) const float A=0.1; const float G=0.9; const float M=16; float L[3], E[3], H[3], I[3], S[3]; float temp; // Laske vektori L, joka osoittaa kohti valoa. L[0]=Pl[0]-Pv[0]; L[1]=Pl[1]-Pv[1]; L[2]=Pl[2]-Pv[2]; temp=sqrt(l[0]*l[0]+l[1]*l[1]+l[2]*l[2]); L[0]/=temp; L[1]/=temp; L[2]/=temp; // Laske vektori E, joka osoittaa kohti kameraa. E[0]=-Pv[0]; E[1]=-Pv[1]; E[2]=-Pv[2]; temp=sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]); E[0]/=temp;

8 E[1]/=temp; E[2]/=temp; // Laske vektori H, joka puolittaa vektorien E ja L välisen kulman. H[0]=L[0]+E[0]; H[1]=L[1]+E[1]; H[2]=L[2]+E[2]; temp=sqrt(h[0]*h[0]+h[1]*h[1]+h[2]*h[2]); H[0]/=temp; H[1]/=temp; H[2]/=temp; // Laske ympäristövalo + hajavalo I[0]= A + Cl[0]*pisteTulo(N, L); I[1]= A + Cl[1]*pisteTulo(N, L); I[2]= A + Cl[2]*pisteTulo(N, L); // Laske peiliheijastus S[0]= G*Cl[0]*pow(pisteTulo(N, H), M); S[1]= G*Cl[1]*pow(pisteTulo(N, H), M); S[2]= G*Cl[2]*pow(pisteTulo(N, H), M); // Anna tulos OpenGL:lle. glcolor3f(i[0], I[1], I[2]); glsecondarycolor3fext(s[0], S[1], S[2]); 3 OpenGL:n oma valojärjestelmä Ei kuitenkaan ole pakko kirjoittaa omaa funktiota, joka laskee valaistuksen, sillä OpenGL sisältää myös oman valaistusjärjestelmän. Valaistus saadaan päälle kutsulla glenable(gl_lighting);. Kun valaistus on päällä laskee OpenGL valot automaattisesti ja korvaa värit saamillaan tuloksilla. glcolor3f()-funktiolla ei siis ole mitään vaikutusta silloin kun valaistus on päällä! Valonlähteitä on maksimissaan kahdeksan ja niitä voidaan laittaa päälle ja pois yksitellen glenable() ja gldisable()-funktioilla, joille annetaan parametrina GL_LIGHTx, jos x on valon numero väliltä 0-7. Valon attribuutteja (sijaintia, väriä jne...) voidaan muuttaa gllightfv()-funktiolla, jonka prototyyppi näyttää tältä: void gllightfv(glenum light, GLenum pname, const GLfloat *params); Ensimmäinen parametri kertoo valon, jonka attribuutteja muutetaan (siis GL_LIGHTx). Toinen on muuttava attribuutti. Tärkeimmät ovat GL_AMBIENT (ympäristovalon eli

9 A:n arvo), GL_DIFFUSE ja GL_SPECULAR (valon väri eli Cl, OpenGL siis sallii eri valon värit hajavalolle ja peiliheijastukselle), GL_QUADRATIC_ATTENUATION (vaimenemisen vakio k) ja GL_POSITION (valon sijainti). Viimeinen parametri on osoitin 4-komponenttiseen taulukkoon, joka sisältää attribuutin uuden arvon. 3 ensimmäistä kenttää ovat attribuutin uusi arvo ja viimeisen kentän on oltava 1. Paitsi GL_QUADRATIC_ATTENUATION tapauksessa, jossa taulukko sisältää vain yhden arvon. Valaistavan pinnan ominaisuuksia voidaan asettaa glmaterialfv()-funktiolla. Prototyyppi näyttää tältä: void glmaterialfv(glenum face, GLenum pname, const GLfloat *params); Ensimmäisen parametrin on oltava GL_FRONT_AND_BACK. Toisen parametrin mahdolliset arvot ovat: GL_AMBIENT_AND_DIFFUSE (pinnan väri), GL_SPECULAR (pinnan kiiltävyys eli G:n arvo), GL_EMISSION (itsesäteillyn valon määrä eli E:n arvo) ja GL_SHININESS (vakion M arvo). Viimeinen parametri on jälleen kerran osoitin 4 komponenttiseen taulukkoon, joka sisältää uuden arvon. Paitsi GL_SHININESS tapauksessa, jossa taulukko sisältää vain yhden arvon. Koska pinnan normaalia tarvitaan valaistuksen laskemiseen täytyy se antaa OpenGL:lle. Tämä tehdään funktiolla glnormal3f(), jonka prototyyppi näyttää tältä: void glnormal3f(glfloat nx, GLfloat ny, GLfloat nz); Se siis ottaa normaalivektorin x, y ja z komponentit parametrinaan. Huomaa, että tämän vektorin pituuden tulee olla 1. Tätä funktiota kutsutaan glbegin() ja glend()-funktioiden välissä ja jokaiselle verteksille erikseen. On olemassa GL_EXT_separate_specular_color-laajennus, joka saa OpenGL erottamaan laskemansa valon peiliheijastuskomponentin toissijaiseksi väriksi. Tämä tehdään kutsulla

10 gllightmodel(gl_light_model_color_control_ext, GL_ SEPARATE_SPECULAR_COLOR_EXT);. GL_EXT_separate_specular_color saattaa olla tuettuna vaikka GL_EXT_secondary_color ei olisikaan. Oikealla ilman peiliheijastusta ja muissa sen kanssa, mutta keskellä GL_SEPARATE_SPECULAR_COLOR_EXT ei ole päällä kun taas vasemmalla se on. 4 Pikselin tarkka valaistus Huomattavaa on, että OpenGL:n sisäinen valojärjestelmä laskee valot vain vertekseille. Ei siis jokaiselle pikselille erikseen. Tämän jälkeen jokaiselle verteksille lasketut valoarvot (värit), interpoloidaan pikseleille. Kaikki näyttää ihan hyvältä niin kauan kuin polygonien koko on tarpeeksi pieni ja valon lähde kaukana niistä. Jos näin ei ole alkavat virheet näkyä. Parempi olisikin, jos voisimme laskea valoarvot jokaiselle pikselille erikseen jolloin tuloksena olisi huomattavasti realistisempi kuva. Vasemmalla kuvatun 8 kolmiosta koostuvan pinnan valaistus laskettu vertekseille (keskellä) ja pikseleille (oikealla). glcolor3f()-funktiolla ei kuitenkaan voi antaa väriä erikseen jokaiselle pikselille. Ainoastaan vertekseille. Seuraavassa kappaleessa esittelen pikselivarjostimiksi kutsutun tekniikan, jolla tämä ongelma saadaan pois päiväjärjestyksestä, mutta sitä ennen esittelen muutaman kiertotien.

11 Jos sekä valo että piirrettävä polygoni ovat staattisia eli ne eivät liiku voidaan valon vaikutus piirtää etukäteen tekstuuriin esim. jollakin kuvankäsittelyohjelmalla. Tällöin säästetään myös tehoa, kun mitään valaistukseen liittyvää ei tarvitse laskea ajon aikana. Tätä tekniikkaa kutsutaan termillä "lightmapping" ja sitä käyttävät mm. pelit Quake 2 ja 3 sekä half-life. Ajatus voidaan viedä vieläkin pidemmälle. Miksei valoefektejä lasketa tekstuureihin ajon aikana ja muuttuneita tekstuureja sitten ladata uudestaan näytönohjaimen muistiin glteximage2d()-funktiolla. Jos tekstuurit ovat tarpeeksi matalaresoluutioisia, tämä on ihan toimiva vaihtoehto. Jos tekstuurit kuitenkin ovat kovin korkearesoluutioisia kuluu tekstuurien päivittämiseen liikaa aikaa ja menetelmä ei toimi. Tämän tekniikan nimi on dynamic lightmapping. Mm. pelit Alien vs Predator 1 ja 2 käyttävät tätä tekniikkaa. Texture environment osaa laskea erilaisia funktioita jokaiselle pikselille, yhdistäen eri tekstuureja. On itse asiassa mahdollista laskea texture environment:in avulla valoyhtälöt jokaiselle pikselille. Tähän tarvitaan laajennukset GL_ARB_texture_env_combine, GL_ARB_texture_env_crossbar (tai GL_NV_texture_env_combine4) ja GL_ARB_texture_env_dot3 ja vähintään 4 teksturointiyksikköä. Lisäksi peiliheijastuksessa tarvittava potenssiinkorotus ei ole mahdollinen, joten sitä on arvioitava jollakin yksinkertaisemmalla funktiolla. 5 Verteksi- ja pikselivarjostinohjelmat Verteksi- tai pikselivarjostin on ohjelma tai pidemminkin funktio, jonka OpenGL suorittaa jokaista verteksiä/pikseliä kohden. Parasta tässä on, että voit kirjoittaa tämän funktion itse. Näitä funktioita kutsutaan varjostimiksi, koska niitä käytetään usein nimenomaan valaistuksen laskentaan. Varjostinohjelmat saavat syötteenään verteksin/pikselin kaikki arvot, kuten värin ja sijainnin ja tuottavat tuloksenaan uudet arvot. Huomaa, että koska pikselivarjostinohjelmat suoritetaan kerran jokaista pikseliä kohden, ja kuvassa voi helposti olla miljoonia pikseleitä kasvaa tarvittavan tehon määrä valtavaksi. Tämän takia pikselivarjostimet toimivat vain kaikkein uusimmissa näytönohjaimissa, kuten GeForceFX ja Ati Rodeon Nämä varjostimet ovat

12 saatavilla laajennusten GL_ARB_vertex_program, GL_ARB_fragment_program, GL_ARB_vertex_shader ja GL_ARB_fragment_shader muodossa. Verteksivarjostimet eivät tuo varsinaisesti mitään uutta. Ne saavat syötteenään verteksin sijainnin, värin jne. Suorittavat näillä jotain laskentaa ja korvaavat arvot uusilla. Olisit voinut tietenkin laskea nämä uudet arvot omassa ohjelmassasi ja antaa ne OpenGL:lle alkuarvoina, joilloin koko verteksivarjostinta ei olisi tarvittu. Etu on siinä, että verteksivarjostimen koodi suoritetaan näytönohjaimen prosessorilla, joka on nimenomaan erikoistunut grafiikan piirtämiseen ja suorittaa verteksivarjostinohjelman yleensä (joskaan ei aina) nopeammin kuin tietokoneen keskusyksikkö. Näin ollen verteksivarjostimet nostavat ohjelman suorituskykyä, ei sen graafista laatua. Pikselivarjostimet ovat sen sijaan toinen juttu. Ei nimittäin ole muuta keinoa tehdä pikselikohtaisia laskutoimituksia (texture environment:illa kikkailua lukuunottamatta). Niiden avulla on mahdollista laskea blinnin tai phongin valoyhtälöt jokaiselle pikselille erikseen. Mm. Doom 3:n hieno grafiikka perustuu tähän. Valitettavasti pikselivarjostimilla on katastrofaalinen vaikutus suorituskykyyn. Esim. 800x600 resoluutioisessa ikkunassa on pikseliä (olettaen että yhtään pikseliä ei piirretä kahdesti). Jos pikselivarjostin, jossa on vain 10 rivia koodia, suoritetaan jokaiselle pikselille tekee se lähes 5 miljoonaa suoritettavaa koodiriviä. On siinä näytönohjaimella laskemista. Varjostinohjelmat voidaan kirjoittaa, joko konekielellä (laajennukset GL_ARB_vertex_program ja GL_ARB_fragment_program) tai korkeamman tason glslang-kielellä (laajennukset GL_ARB_vertex_shader ja GL_ARB_fragment_shader) (myös Direct3D:llä on vastaavanlainen korkeamman tason kieli nimeltä HLSL). Lisäksi on olemassa NVidian kehittämä Cg. Se on siitä vekkuli, että se toimii sekä OpenGL:ssä, että Direct3D:ssä. Jotta voisit käyttää varjostinohjelmia sinun täytyy opetella jokin näistä kielistä. En kuitenkaan aijo esitellä niitä sen enempää, sillä niistä saisi vaikka oman artikkelinsa. Varjostinohjelmat ovat kuitenkin tulevaisuutta, joten niitä kannattaa joskus edes vilkaista.

13 6 Sapluunapuskuri Ennen kuin voimme mennä eteenpäin pitää minun esitellä sinulle yksi kätevä työkalu nimeltä sapluunapuskuri (englanniksi stencil buffer). Sapluunapuskuri toimii nimensä mukaan sapluunana. Ensin sapluunapuskuriin piirretään jotain, jonka jälkeen sapluunatestaus asetetaan päälle. Tämän jälkeen pikselit piirtyvät vain niihin kohtiin, joissa sapluunapuskuriin on piirretty jotain (tai halutessa toisin päin). Ennen kuin sapluunapuskuria voidaan käyttää pitää se laittaa päälle. Tämä tehdään kutsulla glenable(gl_stencil_test). Sapluunapuskuriin ei kuitenkaan voida tallentaa syvyysarvoja (kuten syvyyspuskuriin) tai väriarvoja kuten väripuskuriin, vaan lukuja väliltä (olettaen, että sapluunapuskurille varattujen bittien määrä per pikseli on 8). Se mitä sapluunapuskurissa olevalle luvulle tapahtuu sinne piirrettäessä valitaan glstencilop()-funktiolla. Prototyyppi näyttää tältä: void glstencilop(glenum fail, GLenum zfail, GLenum zpass); Kolme eri tapausta. Eli mitä tehdään kun pikseli ei läpäise sapluunatestiä (fail), mitä tehdään, kun pikseli läpäisi sapluunatestin, mutta ei syvyystestiä (zfail) ja mitä tehdään, kun pikseli läpäisi molemmat (zpass). Kaikkien parametrien mahdolliset arvot ovat: GL_KEEP (ei muutosta), GL_ZERO (korvataan nollalla), GL_REPLACE (korvataan jollakin vakioarvolla, joka annetaan myöhemmin esiteltävällä glstencilfunc() -funktion ref-parametrina), GL_INCR (kasvattaa lukua yhdellä), GL_DECR (vähentää lukua yhdellä) ja GL_INVERT (kääntää bitit). Käytettävä sapluunatesti voidaan valita funktiolla glstencilfunc(). Sen prototyyppi on tämän näköinen: void glstencilfunc(glenum func, GLint ref, GLuint mask);

14 Parametri func kertoo käytettävän funktion. Mahdollisia vaihtoehtoja ovat GL_NEVER (pikseliä ei koskaan piirretä), GL_ALWAYS (pikseli läpäisee testin aina, eli sapluunatesti on pois päältä), GL_EQUAL (pikseli piirretään vain jos sen kohdalla oleva arvo sapluunapuskurissa on sama kuin ref-parametrin arvo), GL_LESS ja GL_GREATER. Viimeinen parametri on maski. Sen arvo on yleensä ~0 eli binääriluku Ennen käyttöä sapluunapuskuri on tietenkin tyhjennettävä. Se tapahtuu kutsulla glclear(gl_stencil_buffer_bit). Lisäksi on huomattava, että kun kirjoitamme sapluunapuskuriin emme varmaan halua samalla piirtää mitään väripuskuriin. Tämä voidaan estää kutsulla glcolormask(0,0,0,0); ja äskeisen vaikutus saadaan kumottua kutsulla glcolormask(1,1,1,1);. 7 Varjot OpenGL ei sisällä valmista glenable(gl_shadows)-mekanismia, jolla varjot voisi loihtia helposti. Tämä sen takia, että piirtäessään yhtä polygonia OpenGL ei tiedä mitä kaikkea se tulee vielä piirtämään ennen kuin kuva on valmis. On kuitenkin paljon algoritmeja, joilla varjoja voi tehdä. Helpointa olisi tietenkin käyttää ns. feikkivarjoja eli piirtää kuvaan jotain mikä näyttää hieman varjolta esim. musta ympyrä kappaleen alle. Kun halutaan fysikaalisesti realistisia varjoja tarvitaan hieman enemmän työtä. Kaksi kuuluisinta varjoalgoritmia ovat "shadow map"-algoritmi ja stencil shadow volumes - algoritmi. Kumpikaan algoritmi ei perustu siihen, että ne piirtäisivät varjon, vaan pidemminkin piirtävät kaiken muun paitsi varjon, jolloin varjon kohdat jäävät mustiksi. Itse pidän enemmän "stencil shadow volumes"-algoritmista, jota käytämme myös esimerkkiohjelmassamme, mutta esittelen ensin hieman hankalamman "shadow map"- algoritmin perusidean ja jätän yksityiskohdat lukijan oman tutkisen varaan. 7.1 "Shadow map"-algoritmi "Shadow map"-algoritmin idea on seuraavanlainen. Renderoidaan kuva ensin valonlähteen näkökulmasta. Valonlähteen on siis oltava suunnattu, eikä "shadow map"- algoritmi toimi pistemäisille valonlähteille (yksi syy miksi en pidä siitä). Kopioidaan

15 tämän kuvan syvyyspuskuri tekstuuriin. Kutsukaamme tätä tekstuuria nimellä shadow map. Vasemmalla näkymä valonlähteen perspektiivistä katsottuna. Oikealla tämän kuvan syvyyspuskuri esitettynä niin, että vaaleat kohteet ovat lähellä ja tummat kaukana. Huomaa kuinka valo ei "näe" omia varjojaan. Teksturoidaan tällä tekstuurilla kaikki kappaleet valiten tekstuurikoordinaatit niin, että tekstuuri tulee projisoitua kappaleiden päälle valonlähteestä katsottuna. Tämän jälkeen renderoidaan kuva normaalisti samalla testaten jokaiselle pikselille, onko sen etäisyys valonlähteestä suurempi kuin sen kohdalla shadow map:issa oleva arvo. Jos on, pikseli on varjossa ja se voidaan jättää piirtämättä, muuten ei. Vasemmalla näkymä ilman varjoja. Keskellä näkymä teksturoituna "shadow map"-tekstuurilla, joka on projisoitu näkymän päälle. Oikealla näkymä, jossa sellaiset pikselit joiden etäisyys valosta on suurempi kuin arvo sen "shadow map"-tekstuurissa on jätetty piirtämättä (mustiksi). Itse kuvan renderointi valonlähteestä nähtynä ei ole hankalaa. Syvyyspuskurin kopiointi tekstuuriin taas voidaan tehdä glcopytexsubimage2d()-funktiolla. Sen prototyyppi näyttää tältä. void glcopytexsubimage2d( GLenum target, GLint level,

16 GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height ); Ensimmäisen parametrin on oltava GL_TEX_IMAGE_2D ja toisen 0. Offset-parametrit kertovat kohdan tekstuurista, johon kuva kopioidaan (yleensä 0,0) ja x, y kohdan ruudulta, josta data kopioidaan (yleensä 0,0). Width ja height ovat kopioitavan alueen koko. Huomaa, että tektuurin, johon data tällä funktiolla kopioidaan pitää olla jo valmiiksi olemassa eli se on täytetty jollakin datalla käyttäen glteximage2d()-funktioita. Lisäksi tämän tekstuurin tulee olla ns. "depth texture", tai muuten glcopytexsubimage2d() kopioi väridatan eikä syvyysdataa.. Tämä uusi tekstuurimuoto tulee GL_ARB_depth_texture-laajennoksen mukana ja tekstuuri on tätä muotoa, kun glteximage2d()-funktion components-parametri asetetaan symboliin GL_DEPTH_TEXTURE_ARB. Tekstuurikoordinaattien laskeminen eli tekstuurin projisointi kappaleiden päälle on aika matemaattinen juttu, jonka jätän käsittelemättä. Mainittakoon kuitenkin, että OpenGL sisältää automaattisen tekstuurikoordinaattien generoinnin, jolla tämä voidaan hoitaa. Kun shadow map on luotu ja kappaleet teksturoitu sillä jää enää jäljelle kysymys: Kuinka oikein testaamme onko pikseli kauempana valosta kuin sen shadow map arvo? Voisimme tietenkin suorittaa tämän testin pikselivarjostimessa, mutta OpenGL sisältää ihan valmiin laajennuksen tätä varten. Tämän laajennuksen nimi on GL_ARB_shadow. Jätän tähän laajennukseen tutustumisen lukijan omalle vastuulle ja siirryn "stencil shadow volumes"- algoritmiin.

17 7.2 Stencil shadow volumes -algoritmi Shadow volume eli "katvetila" (jos tiedät paremman suomennoksen niin kerro toki minullekkin) on monitahokas, joka sulkee sisäänsä kaikki ne pisteet, jotka jäävät varjoon ja vastaavasti mikään katvetilan ulkopuolella oleva piste ei ole varjossa. Algoritmin idea on muodostaa monitahokkaalle valonlähteestä päin katsottu silhuetti. Venyttää tätä silhuettia valonlähteestä poispäin joilloin muodostuu monitahokkaan katvetila valonlähteen suhteen. Monitahokkaan silhuetin löytäminen saattaa aluksi tuntua hankalalta tehtävältä, mutta se on itse asiassa aika helppoa. Seuraavassa yksi algoritmi. Parempiakin varmasti löytyy, mutta uskon tämän olevan aika helppo ymmärtää. for (jokaiselle monitahokaan taholle) if (tämä taho osoittaa kohti valoa) for (jokaiselle tämän tahon vierustaholle) if (tämä vierustaho EI osoita kohti valoa) Tahojen välinen särmä kuuluu silhuettiin. Silhuetin on löytymisen jälkeen se täytyy venyttää katvetilaksi. Tämä on yksinkertaista. Projisoidaan jokaisesta särmästä kopio poispäin valonlähteestä ja yhdistetään tämä särmä alkuperäisen kanssa nelikulmioksi, joka muodostaa yhden katvetilan tahoista. Näin saadaan päistä avoin katvetila. Tämä katvetila voidaan vielä tarvittaessa sulkea käyttämällä alkuperäisen monitahokkaan omia polygoneja. Kun katvetila on muodostettu herää enää kysymys: Kuinka testataan mitkä pikselit ovat sen sisässä ja mitkä sen ulkopuolella? Kikka on seuraavanlainen. Ensin kuva renderöidään normaalisti, mutta tummemmalla värillä (esim. käyttäen pelkkää ympäristövaloa) täyttäen samalla syvyyspuskuri. Tämän jälkeen syvyyspuskurin päivitys laitetaan pois päältä ( gldepthmask(gl_false) ), mutta säilyttäen syvyystestaus päällä.

18 Tämän jälkeen katvetila piirretään sapluunapuskuriin ja saplaanaoperaatio asetetaan sellaiseksi, että sapluunapuskurin bitit, käännetään aina, kun sinne piirretään jotain ( glstencilop(gl_keep, GL_KEEP, GL_INVERT) ). Näin katvetilan sisään jäävät pikselit saadaan arvoon 1 ja sen ulkopuoliset arvoon 0. Tämä sen takia, että syvyystestauksesta johtuen katvetilan ulkopuoliset bitit käännetään parillinen määrä kertoja, kun taas sisällä olevat pariton määrä kertoja. Tämän jälkeen kuva piirretään uudestaan oikealla värillä, mutta tällä kertaa saplaanatestaus päällä niin, että piirto tapahtuu vain niihin kohtiin missä saplaanapuskurin arvo on 0 ( glstencilfunc(gl_equal, 0, ~0) ). Näin ollen varjostetulle alueelle ei piirry mitään ja niihin jää tumma varjon väri. Oikealla kaksi valaistua keilaa. Keskellä pystyssä olevan keilan katvetila havainnollistettu. Oikealla keilat on piirretty niin, että kaikki katvetilan sisään jäävät pikselit on jätetty piirtämättä (jäävät siis mustiksi). Valitettavasti koverien monitahokkaiden tapauksessa antamani algoritmi tuottaa silhuetteja, jotka leikkaavat itsensä. Tällöin bittien kääntäminen sapluunapuskurissa ei anna oikeaa tulosta (kuten käy myös silloin kun kamera on katvetilan sisässä). Bittien kääntämisen sijaan voidaan käyttää ns. Carmack s reverse -algoritmia, jossa katvetila piirretään kaksi kertaa. Ensimmäisellä kerralla sen etupuoli sapluunapuskurin arvoa kasvattaen ja toisella sen takapuoli sapluunapuskurin arvoa vähentäen, jolloin saadaan taas katvetilan ulkopuolella olevat bitit arvoon 0 ja muut johonkin nollasta poikkeavaan arvoon. Jätän kuitenkin tähän algoritmiin tutustumisen lukijan omalle vastuulle.

19 8 Esimerkkiohjelma Esimerkkiohjelma piirtää tason ja sen päälle kuution ja yhden valonlähteen. Sekä taso, että kuutio valaistaan OpenGL:n omilla valoilla ja varjot tehdään käyttäen stencil shadow volumes -algoritmia. Tämä on tähän astisista esimerkkiohjelmista monimutkaisin, mutta ei mahdoton ymmärtää. Voit imuroida oheisen lähdekoodin ja valmiiksi käännetyn version tästä: #include <windows.h> #include <gl\gl.h> #include <gl\glu.h> #include <math.h> //#include <gl\glext.h> // Ei tarvita tässä ohjelmassa // Määrittele laitekonteksti globaaliksi sitä nimittäin tarvitaan myös pääfunktiossa. HDC hdc; // Valon sijainti float lightpos[4]= 0, 5, 0, 1 ; // Viestinkäsittelijä LRESULT CALLBACK WindowProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) switch (umsg) // Koska piirrämme ikkunan sisällön pääsilmukassa jatkuvasti uudelleen // reakoimme WM_PAINT-viestiin vain tyhjentämällä ikkunan mustaksi. case WM_PAINT: PAINTSTRUCT p; BeginPaint(hwnd, &p); glclear(gl_color_buffer_bit); SwapBuffers(hdc); EndPaint(hwnd, &p); return 0; // Ikkuna yritetään sulkea kutsu PostQuitMessage()-funktiota. case WM_CLOSE: PostQuitMessage(0); return 0; // Käsittele myös WM_SIZE se lähetetään ikkunalle aina kun sen kokoa muutetaan. // Tämä on oiva tilaisuus muuttaa viewport // oikean kokoiseksi peittämään koko ikkuna. case WM_SIZE:

20 // Ikkunan uusi koko saadaan lparam parametrista LOWORD ja HIWORD makroilla. glviewport(0, 0, LOWORD(lParam), HIWORD(lParam)); return 0; // Viestiä ei käsitelty kutsu DefWindowProc()-funktiota. return DefWindowProc(hwnd, umsg, wparam, lparam); int luoikkuna(unsigned int leveys, unsigned int korkeus, char *otsikko) // Rekisteröi ikkunaluokka WNDCLASS wc; memset(&wc, 0, sizeof(wndclass)); wc.style = CS_HREDRAW CS_VREDRAW CS_OWNDC; wc.hcursor= LoadCursor(NULL, IDC_ARROW); wc.lpfnwndproc = (WNDPROC) WindowProc; wc.hinstance = GetModuleHandle(NULL); wc.lpszclassname = "OpenGLtutoriaali"; if (!RegisterClass(&wc)) return 0; // Luo ikkuna RECT r; r.left=getsystemmetrics(sm_cxscreen)/2-leveys/2; r.top=getsystemmetrics(sm_cyscreen)/2-korkeus/2; r.right=r.left+leveys; r.bottom=r.top+korkeus; AdjustWindowRectEx(&r, WS_CLIPSIBLINGS WS_CLIPCHILDREN WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW); HWND hwnd; hwnd=createwindowex(ws_ex_appwindow, "OpenGLtutoriaali", otsikko, WS_CLIPSIBLINGS WS_CLIPCHILDREN WS_OVERLAPPEDWINDOW, r.left, r.top, r.right-r.left, r.bottom-r.top, NULL, NULL, GetModuleHandle(NULL), NULL); // Luo laitekonteksti hdc=getdc(hwnd); if (!hdc) return 0; // Valitse pikseliformaatti PIXELFORMATDESCRIPTOR pfd; memset(&pfd, 0, sizeof(pixelformatdescriptor)); pfd.nsize=sizeof(pixelformatdescriptor); pfd.nversion=1; pfd.dwflags=pfd_draw_to_window PFD_SUPPORT_OPENGL PFD_DOUBLEBUFFER; pfd.ipixeltype=pfd_type_rgba; pfd.credbits=8; pfd.cgreenbits=8; pfd.cbluebits=8; pfd.calphabits=8;

21 pfd.cstencilbits=8; pfd.cdepthbits=16; pfd.ilayertype=pfd_main_plane; int pixelformat; pixelformat=choosepixelformat(hdc, &pfd); if (!pixelformat) return 0; if (!SetPixelFormat(hdc, pixelformat, &pfd)) return 0; // Luo renderöintikonteksti HGLRC hrc; hrc=wglcreatecontext(hdc); if (!hrc) return 0; if (!wglmakecurrent(hdc, hrc)) return 0; // Tuo ikkuna näkyviin ShowWindow(hwnd, SW_SHOW); SetForegroundWindow(hwnd); SetFocus(hwnd); // Palauta onnistuminen return 1; // Laskee kahden vektorin pistetulon float pistetulo(float v1[3], float v2[3]) return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]; // Taso piirretään käyttäen useita pieniä nelikulmioita // paremman valaistuksen saavuttamiseksi void piirrataso(void) int x, z; glbegin(gl_quads); glnormal3f(0,1,0); for (z=0; z<22; z+=2) for (x=0; x<22; x+=2) glvertex3f(-10+x, 0, -10+z); glvertex3f(-10+x, 0, -10+z+2); glvertex3f(-10+x+2, 0, -10+z+2); glvertex3f(-10+x+2, 0, -10+z); glend(); // Piirtää kuution tai sen katvetilan, jos katvetila-parametri on TRUE void piirrakuutio(bool katvetila) // Data piirrettävää kuutiota varten static float vertex[8][3]=-1,0,-1,1,0,-1,-1,2,-1,1,2,-1,

22 -1,0,1, 1,0, 1,-1,2, 1,1,2, 1; static int index[6][4]= 0,2,3,1, 4,5,7,6, 5,1,3,7, 4,6,2,0, 7,3,2,6, 4,0,1,5 ; // Tahojen normaalit static float normal[6][3]=0,0,-1,0,0,1,1,0,0,-1,0,0,0,1,0,0,-1,0; // Katvetilan muodostusta varten jokaisen tahon on tiedettävä naapurinsa. static int naapuri[6][4]=3,4,2,5,5,2,4,3,5,0,4,1, 1,4,0,5,2,0,3,1,3,0,2,1; // Jokaiselle verteksille valoa kohti osoittava vektori. static float L[8][3]; if (!katvetila) // Piirrä kuutio glbegin(gl_quads); int i, j; for (i=0; i<6; i++) glnormal3f(normal[i][0], normal[i][1], normal[i][2]); for (j=0; j<4; j++) glvertex3f(vertex[ index[i][j] ][0], vertex[ index[i][j] ][1], vertex[ index[i][j] ][2]); glend(); else int i,j; // Laske valoa kohti osoittavat vektorit. for (i=0; i<8; i++) L[i][0]=lightPos[0]-vertex[i][0]; L[i][1]=lightPos[1]-vertex[i][1]; L[i][2]=lightPos[2]-vertex[i][2]; // Piirrä katvetila. // Tässä tulee sairaan paljon indeksointia, joka olisi voitu välttää // jonkinlaisen verteksi-structuren ja osoittimien käytöllä. glbegin(gl_quads); // Jokaiselle taholle for (i=0; i<6; i++) // Jos tämä taho osoittaa kohti valoa if (pistetulo( normal[i], L[ index[i][0] ] )>=0) // Jokaiselle vierustaholle for (j=0; j<4; j++) // Jos tämä vierustaho EI osoita kohti valoa if (pistetulo(normal[ naapuri[i][j] ], L[ index[ naapuri[i][j] ][0] ])<0)

23 // Tahojen välinen särmä kuuluu silhuettiin // venytä se nelikulmioksi poispäin valosta. glvertex3f(vertex[ index[i][j] ][0], vertex[ index[i][j] ][1], vertex[ index[i][j] ][2]); glvertex3f(vertex[ index[i][(j+1)%4] ][0], vertex[ index[i][(j+1)%4] ][1], vertex[ index[i][(j+1)%4] ][2]); glvertex3f(vertex[ index[i][(j+1)%4] ][0]-100*L[ index[i][(j+1)%4] ][0], vertex[ index[i][(j+1)%4] ][1]-100*L[ index[i][(j+1)%4] ][1], vertex[ index[i][(j+1)%4] ][2]-100*L[ index[i][(j+1)%4] ][2]); glvertex3f(vertex[ index[i][j] ][0]-100*L[ index[i][j] ][0], vertex[ index[i][j] ][1]-100*L[ index[i][j] ][1], vertex[ index[i][j] ][2]-100*L[ index[i][j] ][2]); glend(); // Pääfunktio int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) float angle=0; // Luo ikkuna if (!luoikkuna(800, 600, "OpenGL:n perusteet - Osa 4: Valot ja varjot")) return 0; // Määrittele viewport koko ikkunan kokoiseksi glviewport(0, 0, 800, 600); // Koska koordinaatisto on itseasiassa matriisi täytyy meidän ottaa // projektiomatriisi käsiteltäväksi ennen gluperspective-kutsua. glmatrixmode(gl_projection); gluperspective(60, 800.0/600.0, 1, 100); // Kaikki matriisia muuttavat käskyt vaikuttavat tämän jälkeen modelview-matriisiin glmatrixmode(gl_modelview); // Laita näkymättömien pintojen poisto ja sysyyspuskurialgoritmi päälle. glenable(gl_cull_face); // Valitse syvyystestausfunktio "<=" oletuksena olevan "<" tilalle. gldepthfunc(gl_lequal); glenable(gl_depth_test); // Aseta valo nro. 0 päälle float Cl[4]=0.8,0.8,0.8,1; float A[4]=0.2,0.2,0.2,1; float Cd[4]=1,1,1,1; gllightfv(gl_light0, GL_DIFFUSE, Cl); // Väri gllightfv(gl_light0, GL_AMBIENT, A); // Ympätisrövalon määrä

24 glmaterialfv(gl_front_and_back, GL_AMBIENT_AND_DIFFUSE, Cd); // Pinnan väri glenable(gl_light0); // OpenGL lisää valaistukseen vielä yhden valonlähteistä // riippumattoman ympäristövalon, josta haluamme päästä eroon. float nolla[4]=0,0,0,1; gllightmodelfv(gl_light_model_ambient, nolla); // Viestinkäsittelysilmukka MSG msg; while(1) if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) if (msg.message==wm_quit) break; TranslateMessage(&msg); DispatchMessage(&msg); else // Tyhjennä väripuskuri, syvyyspuskuri ja sapluunapuskuri glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT GL_STENCIL_BUFFER_BIT); // Aseta modelview-matriisi glloadidentity(); // "Resetoi" matriisi yksikkömatriisiksi gltranslatef(0, -3, -10); // Siirrä hieman kauemmaksi kamerasta glrotatef(angle, 0, 1, 0); // Pyöritä hieman Y-akselin ympäri // Kasvata pyörityskulmaa hieman angle+=0.05; // Siirrä valoa lightpos[0]=5*sin(angle*-0.2); lightpos[1]=5+sin(angle*0.5); lightpos[2]=5*cos(angle*-0.2); gllightfv(gl_light0, GL_POSITION, lightpos); // Ensimmäinen vaihe. // täytetään syvyyspuskuri ja piirretään kuva käyttäen pelkkää ympäristövaloa gldisable(gl_lighting); gldisable(gl_stencil_test); glcolor3f(a[0], A[1], A[2]); piirrataso(); piirrakuutio(false); // Toinen vaihe // Piirrä katvetila sapluunapuskuriin // Jos haluat päästä eroon varjoista kommentoi tämä toinen vaihe pois gldisable(gl_cull_face); // Katvetilasta pitää piirtää kaikki osat glenable(gl_stencil_test); // Sapluunapuskuri päälle glcolormask(0, 0, 0, 0); // Emme halua päivittää väripuskuria gldepthmask(0); // Emmekä syvyyspuskuria glstencilfunc(gl_always, 0, 0); glstencilop(gl_keep, GL_KEEP, GL_INVERT); // Käännä bitit piirtäessä piirrakuutio(true);

25 glenable(gl_cull_face); glcolormask(1, 1, 1, 1); gldepthmask(1); // Viimeinen vaihe // Piirrä lopullinen kuva kohtiin, jossa sapluunapuskurin arvo on 0 glenable(gl_lighting); glstencilfunc(gl_equal, 0, ~0); glstencilop(gl_keep, GL_KEEP, GL_KEEP); piirrataso(); piirrakuutio(false); // Piirrä vielä valonlähde gldisable(gl_lighting); gldisable(gl_stencil_test); glpointsize(5); glbegin(gl_points); glcolor3f(1,1,0); glvertex3f(lightpos[0], lightpos[1], lightpos[2]); glend(); // Vaihda puskuri näytölle. SwapBuffers(hdc); return 0; 9 Loppusanat Tässä artikkelissa opit valoista ja varjoista. Tässä artikkelisarjassa olemme nyt käyneet läpi pintapuolisesti kaikki 3d grafiiikan perusasiat. Lopuksi listaan vielä joitakin linkkejä, joista löydät rutkasti lisää luottevaa OpenGL:stä ja 3D grafiikasta yleensäkkin. keskustelufoorumit löytyvät täältä. OpenGL:n virallinen kotisivu. Uutisia, viralliset speksit ja NeHe Productions. Netin ylivoimaisesti suosituimmat opengl tutoriaalit. - The Red Book. Virallinen OpenGL:n opaskirja. Tämä netistä löytyvä ilmaisversio on aika hemmetin vanha, mutta ajaa asiansa. Uusin versio on saatavilla vain kirjakaupoista.

26 - SGI:n ylläpitämä OpenGL:n laajennusrekisteri. Sama löytyy myös kaikkien näytönohjainvalmistajien kotisivuilta. - OpenGL Hardware Registry. Rekisteri, jossa on lueteltu valtavasti näytönohjaimia ja kerrottu mitä laajennuksia ne tukevat. - Mesa 3D Graphics Library. Software OpenGL "ajurit". Voit kokeilla näiden "ajurien" avulla laajennuksia, joita oma näytönohjaimesi ei tue. - OpenGL faq. Usein kysytyt kysymykset OpenGL:stä. - Game tutorials. 50 aloittelijoille tarkoitettua OpenGL-tutoriaalia. - Ultima game programming. Lähes 100 hieman edistyneimmille tarkoitettua OpenGLtutoriaalia. Raportoithan kaikki tästä artikkelista löytämäsi virheet (niin kirjoitus-, kuin asiavirheetkin) osoitteeseen markus.ilmola@pp.inet.fi, niin korjaan ne mahdollisimman nopeasti. Myös kaikki kommentit ja kysymykset ovat tervetulleita

OpenGL:n perusteet - Osa 2: 3D grafiikka

OpenGL:n perusteet - Osa 2: 3D grafiikka OpenGL:n perusteet - Osa 2: 3D grafiikka OpenGL on käyttöjärjestelmäriippumaton kirjasto 2D- ja 3D-grafiikan piirtoon. Tämä artikkelisarja opettaa sinulle 3D-grafiikan perusteet OpenGL:ää käyttäen. Esimerkeissä

Lisätiedot

OpenGL:n perusteet - Osa 1: Ikkunan luominen

OpenGL:n perusteet - Osa 1: Ikkunan luominen OpenGL:n perusteet - Osa 1: Ikkunan luominen OpenGL on käyttöjärjestelmäriippumaton kirjasto 2D- ja 3D-grafiikan piirtoon. Tämä artikkelisarja opettaa sinulle 3D-grafiikan perusteet OpenGL:ää käyttäen.

Lisätiedot

OpenGL:n perusteet Osa 3: Teksturointi

OpenGL:n perusteet Osa 3: Teksturointi OpenGL:n perusteet Osa 3: Teksturointi OpenGL on käyttöjärjestelmäriippumaton kirjasto 2D- ja 3D-grafiikan piirtoon. Tämä artikkelisarja opettaa sinulle 3D-grafiikan perusteet OpenGL:ää käyttäen. Esimerkeissä

Lisätiedot

Windowsin sanomanvälitys. Juha Järvensivu 2007

Windowsin sanomanvälitys. Juha Järvensivu 2007 Windowsin sanomanvälitys Juha Järvensivu juha.jarvensivu@tut.fi 2007 Sisällys Windowsin sanomat Sanomanvälitysmekanismi Ikkunan kahva Sanomien lähettäminen Esimerkki winamp Tapahtumapohjainen toiminta

Lisätiedot

Sisällys. T-111.4300 Tietokonegrafiikan perusteet. OpenGL-ohjelmointi 11/2007. Mikä on OpenGL?

Sisällys. T-111.4300 Tietokonegrafiikan perusteet. OpenGL-ohjelmointi 11/2007. Mikä on OpenGL? T-111.4300 Tietokonegrafiikan perusteet OpenGL-ohjelmointi 11/2007 Sisällys Mikä on OpenGL? historia nykytilanne OpenGL:n toiminta Piirtäminen ja matriisit Muuta hyödyllistä kameran sijoittaminen valaistus

Lisätiedot

Tampereen yliopisto Tietokonegrafiikka 2013 Tietojenkäsittelytiede Harjoitus

Tampereen yliopisto Tietokonegrafiikka 2013 Tietojenkäsittelytiede Harjoitus Tampereen yliopisto Tietokonegrafiikka 201 Tietojenkäsittelytiede Harjoitus 6 1..201 1. Tarkastellaan Gouraudin sävytysmallia. Olkoon annettuna kolmio ABC, missä A = (0,0,0), B = (2,0,0) ja C = (1,2,0)

Lisätiedot

Luento 10: Näkyvyystarkastelut ja varjot. Sisältö

Luento 10: Näkyvyystarkastelut ja varjot. Sisältö Tietokonegrafiikka / perusteet T-111.300/301 4 ov / 2 ov Luento 10: Näkyvyystarkastelut ja varjot Marko Myllymaa / Lauri Savioja 10/04 Näkyvyystarkastelut ja varjot / 1 Näkyvyystarkastelu Solurenderöinti

Lisätiedot

T Tietokonegrafiikan perusteet. OpenGL-ohjelmointi

T Tietokonegrafiikan perusteet. OpenGL-ohjelmointi 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

Lisätiedot

Luku 6: Grafiikka. 2D-grafiikka 3D-liukuhihna Epäsuora valaistus Laskostuminen Mobiililaitteet Sisätilat Ulkotilat

Luku 6: Grafiikka. 2D-grafiikka 3D-liukuhihna Epäsuora valaistus Laskostuminen Mobiililaitteet Sisätilat Ulkotilat 2D-grafiikka 3D-liukuhihna Epäsuora valaistus Laskostuminen Mobiililaitteet Sisätilat Ulkotilat 2D-piirto 2-ulotteisen grafiikan piirto perustuu yleensä valmiiden kuvien kopioimiseen näyttömuistiin (blitting)

Lisätiedot

3.3 Paraabeli toisen asteen polynomifunktion kuvaajana. Toisen asteen epäyhtälö

3.3 Paraabeli toisen asteen polynomifunktion kuvaajana. Toisen asteen epäyhtälö 3.3 Paraabeli toisen asteen polynomifunktion kuvaajana. Toisen asteen epäyhtälö Yhtälön (tai funktion) y = a + b + c, missä a 0, kuvaaja ei ole suora, mutta ei ole yhtälökään ensimmäistä astetta. Funktioiden

Lisätiedot

Peilaus pisteen ja suoran suhteen Pythonin Turtle moduulilla

Peilaus pisteen ja suoran suhteen Pythonin Turtle moduulilla Peilaus pisteen ja suoran suhteen Pythonin Turtle moduulilla ALKUHARJOITUS Kynän ja paperin avulla peilaaminen koordinaatistossa a) Peilaa pisteen (0,0) suhteen koordinaatistossa sijaitseva - neliö, jonka

Lisätiedot

Windowsin sanomanvälitys. Juha Järvensivu juha.jarvensivu@tut.fi 2008

Windowsin sanomanvälitys. Juha Järvensivu juha.jarvensivu@tut.fi 2008 Windowsin sanomanvälitys Juha Järvensivu juha.jarvensivu@tut.fi 2008 Sisällys Windowsin sanomat ja Sanomanvälitysmekanismi Ikkunan kahva ja Sanomien lähettäminen Windows API ohjelmointi Resurssit Sanomat

Lisätiedot

PERUSLASKUJA. Kirjoita muuten sama, mutta ota välilyönti 4:n jälkeen 3/4 +5^2

PERUSLASKUJA. Kirjoita muuten sama, mutta ota välilyönti 4:n jälkeen 3/4 +5^2 PERUSLASKUJA Matemaattisten lausekkeiden syöttäminen: Kirjoita ilman välilyöntejä /+^2 Kirjoita muuten sama, mutta ota välilyönti :n jälkeen / +^2 Kopioi molemmat matematiikka-alueet ja liiku alueen sisällä

Lisätiedot

Luento 3: 3D katselu. Sisältö

Luento 3: 3D katselu. Sisältö Tietokonegrafiikan perusteet T-.43 3 op Luento 3: 3D katselu Lauri Savioja Janne Kontkanen /27 3D katselu / Sisältö Kertaus: koordinaattimuunnokset ja homogeeniset koordinaatit Näkymänmuodostus Kameran

Lisätiedot

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti

Luku 6. Dynaaminen ohjelmointi. 6.1 Funktion muisti Luku 6 Dynaaminen ohjelmointi Dynaamisessa ohjelmoinnissa on ideana jakaa ongelman ratkaisu pienempiin osaongelmiin, jotka voidaan ratkaista toisistaan riippumattomasti. Jokaisen osaongelman ratkaisu tallennetaan

Lisätiedot

BM20A5800 Funktiot, lineaarialgebra ja vektorit Harjoitus 4, Syksy 2016

BM20A5800 Funktiot, lineaarialgebra ja vektorit Harjoitus 4, Syksy 2016 BM20A5800 Funktiot, lineaarialgebra ja vektorit Harjoitus 4, Syksy 2016 1. Hahmottele karkeasti funktion f : R R 2 piirtämällä sen arvoja muutamilla eri muuttujan arvoilla kaksiulotteiseen koordinaatistoon

Lisätiedot

Esimerkkejä. OpenGL ohjelma. OpenGL tilakone. Geometriset primitiivit. Hyvät ja huonot polygonit. OpenGL Pipeline. Rasterointi

Esimerkkejä. OpenGL ohjelma. OpenGL tilakone. Geometriset primitiivit. Hyvät ja huonot polygonit. OpenGL Pipeline. Rasterointi Tietokonegrafiikka / perusteet Ako/T-111.300/301 4 ov / 2 ov OpenGL 1 Yleistä harjoituksista OpenGL:n toiminta Primitiivit Kuvapuskurit Koordinaatistot ja projisointi Transformaatiot ja matriisit Valaistus

Lisätiedot

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta 5. 1. Toteuta Pythonilla seuraava ohjelma:

Kerta 2. Kerta 2 Kerta 3 Kerta 4 Kerta 5. 1. Toteuta Pythonilla seuraava ohjelma: Kerta 2 Kerta 3 Kerta 4 Kerta 5 Kerta 2 1. Toteuta Pythonilla seuraava ohjelma: 2. Tulosta Pythonilla seuraavat luvut allekkain a. 0 10 (eli, näyttää tältä: 0 1 2 3 4 5 6 7 8 9 10 b. 0 100 c. 50 100 3.

Lisätiedot

Luento 6: Piilopinnat ja Näkyvyys

Luento 6: Piilopinnat ja Näkyvyys Tietokonegrafiikan perusteet T-111.4300 3 op Luento 6: Piilopinnat ja Näkyvyys Janne Kontkanen Geometrinen mallinnus / 1 Johdanto Piilopintojen poisto-ongelma Syntyy kuvattaessa 3-ulotteista maailmaa 2-ulotteisella

Lisätiedot

Demokoodaus Linuxilla, tapaus Eternity

Demokoodaus Linuxilla, tapaus Eternity Demokoodaus Linuxilla, tapaus Eternity Tuomo Sipola tuomo.sipola@iki.fi Linkin lanit 9.4.2010 Tuomo Sipola tuomo.sipola@iki.fi () Demokoodaus Linuxilla, tapaus Eternity Linkin lanit 9.4.2010 1 / 17 Sisältö

Lisätiedot

PERUSLASKUJA. Kirjoita muuten sama, mutta ota KAKSI välilyöntiä (SEURAA ALUEMERKINTÄÄ) 4:n jälkeen 3/4 +5^2

PERUSLASKUJA. Kirjoita muuten sama, mutta ota KAKSI välilyöntiä (SEURAA ALUEMERKINTÄÄ) 4:n jälkeen 3/4 +5^2 PERUSLASKUJA Matemaattisten lausekkeiden syöttäminen: Kirjoita ilman välilyöntejä 3/4+^2 3 4+ 2 Kirjoita muuten sama, mutta ota KAKSI välilyöntiä (SEURAA ALUEMERKINTÄÄ) 4:n jälkeen 3/4 +^2 3 + 4 2 Kopioi

Lisätiedot

9. Vektorit. 9.1 Skalaarit ja vektorit. 9.2 Vektorit tasossa

9. Vektorit. 9.1 Skalaarit ja vektorit. 9.2 Vektorit tasossa 9. Vektorit 9.1 Skalaarit ja vektorit Skalaari on koon tai määrän mitta. Tyypillinen esimerkki skalaarista on massa. Lukumäärä on toinen hyvä esimerkki skalaarista. Vektorilla on taas suuruus ja suunta.

Lisätiedot

Pong-peli, vaihe Koordinaatistosta. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 2/7. Tämän vaiheen aikana

Pong-peli, vaihe Koordinaatistosta. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 2/7. Tämän vaiheen aikana Muilla kielillä: English Suomi Pong-peli, vaihe 2 Tämä on Pong-pelin tutoriaalin osa 2/7. Tämän vaiheen aikana Laitetaan pallo liikkeelle Tehdään kentälle reunat Vaihdetaan kentän taustaväri Zoomataan

Lisätiedot

Visualisoinnin perusteet

Visualisoinnin perusteet 1 / 12 Digitaalisen arkkitehtuurin yksikkö Aalto-yliopisto Visualisoinnin perusteet Mitä on renderöinti? 2 / 12 3D-mallista voidaan generoida näkymiä tietokoneen avulla. Yleensä perspektiivikuva Valon

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 3 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 3 vastaukset Harjoituksen aiheena ovat imperatiivisten kielten muuttujiin liittyvät kysymykset. Tehtävä 1. Määritä muuttujien max_num, lista,

Lisätiedot

10.2. Säteenjäljitys ja radiositeettialgoritmi. Säteenjäljitys

10.2. Säteenjäljitys ja radiositeettialgoritmi. Säteenjäljitys 10.2. Säteenjäljitys ja radiositeettialgoritmi Säteenjäljitys Säteenjäljityksessä (T. Whitted 1980) valonsäteiden kulkema reitti etsitään käänteisessä järjestyksessä katsojan silmästä takaisin kuvaan valolähteeseen

Lisätiedot

= 2 L L. f (x)dx. coshx dx = 1 L. sinhx nπ. sin. sin L + 2 L. a n. L 2 + n 2 cos. tehdään approksimoinnissa virhe, jota voidaan arvioida integraalin

= 2 L L. f (x)dx. coshx dx = 1 L. sinhx nπ. sin. sin L + 2 L. a n. L 2 + n 2 cos. tehdään approksimoinnissa virhe, jota voidaan arvioida integraalin BMA7 - Integraalimuunnokset Harjoitus 9. Määritä -jaksollisen funktion f x = coshx, < x < Fourier-sarja. Funktion on parillinen, joten b n = kun n =,,3,... Parillisuudesta johtuen kertoimet a ja a n saadaan

Lisätiedot

Luku 8. Aluekyselyt. 8.1 Summataulukko

Luku 8. Aluekyselyt. 8.1 Summataulukko Luku 8 Aluekyselyt Aluekysely on tiettyä taulukon väliä koskeva kysely. Tyypillisiä aluekyselyitä ovat, mikä on taulukon välin lukujen summa tai pienin luku välillä. Esimerkiksi seuraavassa taulukossa

Lisätiedot

MS-A0003/A0005 Matriisilaskenta Malliratkaisut 5 / vko 48

MS-A0003/A0005 Matriisilaskenta Malliratkaisut 5 / vko 48 MS-A3/A5 Matriisilaskenta Malliratkaisut 5 / vko 48 Tehtävä (L): a) Onko 4 3 sitä vastaava ominaisarvo? b) Onko λ = 3 matriisin matriisin 2 2 3 2 3 7 9 4 5 2 4 4 ominaisvektori? Jos on, mikä on ominaisarvo?

Lisätiedot

Tietotekniikan valintakoe

Tietotekniikan valintakoe Jyväskylän yliopisto Tietotekniikan laitos Tietotekniikan valintakoe 2..22 Vastaa kahteen seuraavista kolmesta tehtävästä. Kukin tehtävä arvostellaan kokonaislukuasteikolla - 25. Jos vastaat useampaan

Lisätiedot

Matematiikan tukikurssi

Matematiikan tukikurssi Matematiikan tukikurssi Kurssikerta 9 1 Implisiittinen derivointi Tarkastellaan nyt yhtälöä F(x, y) = c, jossa x ja y ovat muuttujia ja c on vakio Esimerkki tällaisesta yhtälöstä on x 2 y 5 + 5xy = 14

Lisätiedot

811312A Tietorakenteet ja algoritmit , Harjoitus 2 ratkaisu

811312A Tietorakenteet ja algoritmit , Harjoitus 2 ratkaisu 811312A Tietorakenteet ja algoritmit 2017-2018, Harjoitus 2 ratkaisu Harjoituksen aiheena on algoritmien oikeellisuus. Tehtävä 2.1 Kahvipurkkiongelma. Kahvipurkissa P on valkoisia ja mustia kahvipapuja,

Lisätiedot

Luento 4: Näkyvyystarkastelut ja varjot

Luento 4: Näkyvyystarkastelut ja varjot Tietokonegrafiikan jatkokurssi T-111.5300 4 op Luento 4: Näkyvyystarkastelut ja varjot Lauri Savioja 02/07 Näkyvyystarkastelut ja varjot / 1 Näkyvyystarkastelu Solurenderöinti Portaalirenderöinti Quad-/Octtree

Lisätiedot

766320A SOVELTAVA SÄHKÖMAGNETIIKKA, ohjeita tenttiin ja muutamia teoriavinkkejä sekä pari esimerkkilaskua

766320A SOVELTAVA SÄHKÖMAGNETIIKKA, ohjeita tenttiin ja muutamia teoriavinkkejä sekä pari esimerkkilaskua 7663A OVLTAVA ÄHKÖMAGNTIIKKA, ohjeita tenttiin ja muutamia teoriavinkkejä sekä pari esimerkkilaskua 1. Lue tenttitehtävä huolellisesti. Tehtävä saattaa näyttää tutulta, mutta siinä saatetaan kysyä eri

Lisätiedot

Matematiikan tukikurssi, kurssikerta 3

Matematiikan tukikurssi, kurssikerta 3 Matematiikan tukikurssi, kurssikerta 3 1 Epäyhtälöitä Aivan aluksi lienee syytä esittää luvun itseisarvon määritelmä: { x kun x 0 x = x kun x < 0 Siispä esimerkiksi 10 = 10 ja 10 = 10. Seuraavaksi listaus

Lisätiedot

12. Javan toistorakenteet 12.1

12. Javan toistorakenteet 12.1 12. Javan toistorakenteet 12.1 Sisällys Yleistä toistorakenteista. Laskurimuuttujat. While-, do-while- ja for-lauseet. Laskuri- ja lippumuuttujat. Tyypillisiä ohjelmointivirheitä. Silmukan rajat asetettu

Lisätiedot

Osoitin ja viittaus C++:ssa

Osoitin ja viittaus C++:ssa Osoitin ja viittaus C++:ssa Osoitin yksinkertaiseen tietotyyppiin Osoitin on muuttuja, joka sisältää jonkin toisen samantyyppisen muuttujan osoitteen. Ohessa on esimerkkiohjelma, jossa määritellään kokonaislukumuuttuja

Lisätiedot

(1) refleksiivinen, (2) symmetrinen ja (3) transitiivinen.

(1) refleksiivinen, (2) symmetrinen ja (3) transitiivinen. Matematiikassa ja muuallakin joudutaan usein tekemisiin sellaisten relaatioiden kanssa, joiden lakina on tietyn ominaisuuden samuus. Tietyn ominaisuuden samuus -relaatio on ekvivalenssi; se on (1) refleksiivinen,

Lisätiedot

Vektorien pistetulo on aina reaaliluku. Esimerkiksi vektorien v = (3, 2, 0) ja w = (1, 2, 3) pistetulo on

Vektorien pistetulo on aina reaaliluku. Esimerkiksi vektorien v = (3, 2, 0) ja w = (1, 2, 3) pistetulo on 13 Pistetulo Avaruuksissa R 2 ja R 3 on totuttu puhumaan vektorien pituuksista ja vektoreiden välisistä kulmista. Kuten tavallista, näiden käsitteiden yleistäminen korkeampiulotteisiin avaruuksiin ei onnistu

Lisätiedot

Matematiikassa ja muuallakin joudutaan usein tekemisiin sellaisten relaatioiden kanssa, joiden lakina on tietyn ominaisuuden samuus.

Matematiikassa ja muuallakin joudutaan usein tekemisiin sellaisten relaatioiden kanssa, joiden lakina on tietyn ominaisuuden samuus. Matematiikassa ja muuallakin joudutaan usein tekemisiin sellaisten relaatioiden kanssa, joiden lakina on tietyn ominaisuuden samuus. Matematiikassa ja muuallakin joudutaan usein tekemisiin sellaisten relaatioiden

Lisätiedot

Matriisit ovat matlabin perustietotyyppejä. Yksinkertaisimmillaan voimme esitellä ja tallentaa 1x1 vektorin seuraavasti: >> a = 9.81 a = 9.

Matriisit ovat matlabin perustietotyyppejä. Yksinkertaisimmillaan voimme esitellä ja tallentaa 1x1 vektorin seuraavasti: >> a = 9.81 a = 9. Python linkit: Python tutoriaali: http://docs.python.org/2/tutorial/ Numpy&Scipy ohjeet: http://docs.scipy.org/doc/ Matlabin alkeet (Pääasiassa Deni Seitzin tekstiä) Matriisit ovat matlabin perustietotyyppejä.

Lisätiedot

Excel syventävät harjoitukset 31.8.2015

Excel syventävät harjoitukset 31.8.2015 Yleistä Excel on taulukkolaskentaohjelma. Tämä tarkoittaa sitä että sillä voi laskea laajoja, paljon laskentatehoa vaativia asioita, esimerkiksi fysiikan laboratoriotöiden koetuloksia. Excel-ohjelmalla

Lisätiedot

Harjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti:

Harjoitus 7. 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: Harjoitus 7 1. Olkoon olemassa luokat Lintu ja Pelikaani seuraavasti: class Lintu //Kentät private int _siivenpituus; protected double _aivojenkoko; private bool _osaakolentaa; //Ominaisuudet public int

Lisätiedot

Tietorakenteet ja algoritmit

Tietorakenteet ja algoritmit Tietorakenteet ja algoritmit Rekursio Rekursion käyttötapauksia Rekursio määritelmissä Rekursio ongelmanratkaisussa ja ohjelmointitekniikkana Esimerkkejä taulukolla Esimerkkejä linkatulla listalla Hanoin

Lisätiedot

Matematiikan tukikurssi

Matematiikan tukikurssi Matematiikan tukikurssi Kurssikerta 8 1 Suunnattu derivaatta Aluksi tarkastelemme vektoreita, koska ymmärrys vektoreista helpottaa alla olevien asioiden omaksumista. Kun liikutaan tasossa eli avaruudessa

Lisätiedot

Algoritmit 1. Demot Timo Männikkö

Algoritmit 1. Demot Timo Männikkö Algoritmit 1 Demot 1 31.1.-1.2.2018 Timo Männikkö Tehtävä 1 (a) Algoritmi, joka tutkii onko kokonaisluku tasan jaollinen jollain toisella kokonaisluvulla siten, että ei käytetä lainkaan jakolaskuja Jaettava

Lisätiedot

2.3 Voiman jakaminen komponentteihin

2.3 Voiman jakaminen komponentteihin Seuraavissa kappaleissa tarvitaan aina silloin tällöin taitoa jakaa voima komponentteihin sekä myös taitoa suorittaa sille vastakkainen operaatio eli voimien resultantin eli kokonaisvoiman laskeminen.

Lisätiedot

A ja B pelaavat sarjan pelejä. Sarjan voittaja on se, joka ensin voittaa n peliä.

A ja B pelaavat sarjan pelejä. Sarjan voittaja on se, joka ensin voittaa n peliä. Esimerkki otteluvoiton todennäköisyys A ja B pelaavat sarjan pelejä. Sarjan voittaja on se, joka ensin voittaa n peliä. Yksittäisessä pelissä A voittaa todennäköisyydellä p ja B todennäköisyydellä q =

Lisätiedot

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan.

Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Osoittimet Ohjelmassa muuttujalla on nimi ja arvo. Kääntäjä ja linkkeri varaavat muistilohkon, jonne muuttujan arvo talletetaan. Muistilohkon koko riippuu muuttujan tyypistä, eli kuinka suuria arvoja muuttujan

Lisätiedot

Liite 1. Laajennettu Eukleideen algoritmi suoraviivainen tapa

Liite 1. Laajennettu Eukleideen algoritmi suoraviivainen tapa Liite 1. Laajennettu Eukleideen algoritmi suoraviivainen tapa - johdanto - matemaattinen induktiotodistus - matriisien kertolaskun käyttömahdollisuus - käsinlaskuesimerkkejä - kaikki välivaiheet esittävä

Lisätiedot

Reaalifunktioista 1 / 17. Reaalifunktioista

Reaalifunktioista 1 / 17. Reaalifunktioista säilyy 1 / 17 säilyy Jos A, B R, niin funktiota f : A B sanotaan (yhden muuttujan) reaalifunktioksi. Tällöin karteesinen tulo A B on (aiempia esimerkkejä luonnollisemmalla tavalla) xy-tason osajoukko,

Lisätiedot

Matikkaa KA1-kurssilaisille, osa 3: suoran piirtäminen koordinaatistoon

Matikkaa KA1-kurssilaisille, osa 3: suoran piirtäminen koordinaatistoon Matikkaa KA1-kurssilaisille, osa 3: suoran piirtäminen koordinaatistoon KA1-kurssi on ehkä mahdollista läpäistä, vaikkei osaisikaan piirtää suoraa yhtälön perusteella. Mutta muut kansiksen kurssit, no

Lisätiedot

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op Assembly ja konekieli Tietokoneen ja ohjelmiston rakenne Loogisilla piireillä ja komponenteilla rakennetaan prosessori ja muistit Prosessorin rakenne

Lisätiedot

1 Funktiot, suurin (max), pienin (min) ja keskiarvo

1 Funktiot, suurin (max), pienin (min) ja keskiarvo 1 Funktiot, suurin (max), pienin (min) ja keskiarvo 1. Avaa uusi työkirja 2. Tallenna työkirja nimellä perusfunktiot. 3. Kirjoita seuraava taulukko 4. Muista taulukon kirjoitusjärjestys - Ensin kirjoitetaan

Lisätiedot

Öljysäiliö maan alla

Öljysäiliö maan alla Kaigasniemen koulu Öljysäiliö maan alla Yläkoulun ketaava ja syventävä matematiikan tehtävä Vesa Maanselkä 009 Ostat talon jossa on öljylämmitys. Takapihalle on kaivettu maahan sylintein muotoinen öljysäiliö

Lisätiedot

Tutoriaaliläsnäoloista

Tutoriaaliläsnäoloista Tutoriaaliläsnäoloista Tutoriaaliläsnäolokierroksella voi nyt täyttää anomuksen läsnäolon merkitsemisestä Esim. tagi ei toiminut, korvavaltimon leikkaus, yms. Hyväksyn näitä omaa harkintaa käyttäen Tarkoitus

Lisätiedot

Ohjelmointiharjoituksia Arduino-ympäristössä

Ohjelmointiharjoituksia Arduino-ympäristössä Ohjelmointiharjoituksia Arduino-ympäristössä Yleistä Arduino-sovelluksen rakenne Syntaksi ja käytännöt Esimerkki ohjelman rakenteesta Muuttujat ja tietotyypit Tietotyypit Esimerkkejä tietotyypeistä Ehtolauseet

Lisätiedot

Tilanhallintatekniikat

Tilanhallintatekniikat Tilanhallintatekniikat 3D grafiikkamoottoreissa Moottori on projektin osa joka vastaa tiettyjen toiminnallisuuksien hallinnasta hallitsee kaikki vastuualueen datat suorittaa kaikki tehtäväalueen toiminnot

Lisätiedot

12. Javan toistorakenteet 12.1

12. Javan toistorakenteet 12.1 12. Javan toistorakenteet 12.1 Sisällys Yleistä toistorakenteista. Laskurimuuttujat. While-, do-while- ja for-lauseet. Laskuri- ja lippumuuttujat. Tyypillisiä ohjelmointivirheitä. Silmukan rajat asetettu

Lisätiedot

Ohjelmoinnin peruskurssi Y1

Ohjelmoinnin peruskurssi Y1 Ohjelmoinnin peruskurssi Y1 CSE-A1111 30.9.2015 CSE-A1111 Ohjelmoinnin peruskurssi Y1 30.9.2015 1 / 27 Mahdollisuus antaa luentopalautetta Goblinissa vasemmassa reunassa olevassa valikossa on valinta Luentopalaute.

Lisätiedot

MAB3 - Harjoitustehtävien ratkaisut:

MAB3 - Harjoitustehtävien ratkaisut: MAB - Harjoitustehtävien ratkaisut: Funktio. Piirretään koordinaatistoakselit ja sijoitetaan pisteet:. a) Funktioiden nollakohdat löydetään etsimällä kuvaajien ja - akselin leikkauspisteitä. Funktiolla

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 3.2.2010 T-106.1208 Ohjelmoinnin perusteet Y 3.2.2010 1 / 36 Esimerkki: asunnon välityspalkkio Kirjoitetaan ohjelma, joka laskee kiinteistönvälittäjän asunnon

Lisätiedot

Matematiikan tukikurssi

Matematiikan tukikurssi Matematiikan tukikurssi Kurssikerta 4 Jatkuvuus Jatkuvan funktion määritelmä Tarkastellaan funktiota f x) jossakin tietyssä pisteessä x 0. Tämä funktio on tässä pisteessä joko jatkuva tai epäjatkuva. Jatkuvuuden

Lisätiedot

Toinen harjoitustyö. ASCII-grafiikkaa

Toinen harjoitustyö. ASCII-grafiikkaa Toinen harjoitustyö ASCII-grafiikkaa Yleistä Tehtävä: tee Javalla ASCII-merkkeinä esitettyä grafiikkaa käsittelevä ASCIIArt-ohjelma omia operaatioita ja taulukoita käyttäen. Työ tehdään pääosin itse. Ideoita

Lisätiedot

Harjoitustyö: virtuaalikone

Harjoitustyö: virtuaalikone Harjoitustyö: virtuaalikone Toteuta alla kuvattu virtuaalikone yksinkertaiselle olio-orientoituneelle skriptauskielelle. Paketissa on testaamista varten mukana kaksi lyhyttä ohjelmaa. Ohjeita Noudata ohjelman

Lisätiedot

Ohjelmoinnin perusteet Y Python

Ohjelmoinnin perusteet Y Python Ohjelmoinnin perusteet Y Python T-106.1208 2.2.2011 T-106.1208 Ohjelmoinnin perusteet Y 2.2.2011 1 / 37 Kännykkäpalautetteen antajia kaivataan edelleen! Ilmoittaudu mukaan lähettämällä ilmainen tekstiviesti

Lisätiedot

PRELIMINÄÄRIKOE PITKÄ MATEMATIIKKA 9.2.2011

PRELIMINÄÄRIKOE PITKÄ MATEMATIIKKA 9.2.2011 PRELIMINÄÄRIKOE PITKÄ MATEMATIIKKA 9..0 Kokeessa saa vastata enintään kymmeneen tehtävään.. Sievennä a) 9 x x 6x + 9, b) 5 9 009 a a, c) log 7 + lne 7. Muovailuvahasta tehty säännöllinen tetraedri muovataan

Lisätiedot

Algoritmit 1. Demot Timo Männikkö

Algoritmit 1. Demot Timo Männikkö Algoritmit 1 Demot 1 25.-26.1.2017 Timo Männikkö Tehtävä 1 (a) Algoritmi, joka laskee kahden kokonaisluvun välisen jakojäännöksen käyttämättä lainkaan jakolaskuja Jaettava m, jakaja n Vähennetään luku

Lisätiedot

Monipuolinen esimerkki

Monipuolinen esimerkki Monipuolinen esimerkki Lopuksi monipuolinen esimerkki, jossa ohjelmisto koostuu pääohjelmasta ja kahdesta aliohjelmasta, joista toinen on proseduuri ja toinen funktio. Funktio Sqrt(int n): int Sqrt(int

Lisätiedot

MATEMATIIKKA. Matematiikkaa pintakäsittelijöille. Ongelmanratkaisu. Isto Jokinen 2017

MATEMATIIKKA. Matematiikkaa pintakäsittelijöille. Ongelmanratkaisu. Isto Jokinen 2017 MATEMATIIKKA Matematiikkaa pintakäsittelijöille Ongelmanratkaisu Isto Jokinen 2017 SISÄLTÖ 1. Matemaattisten ongelmien ratkaisu laskukaavoilla 2. Tekijäyhtälöt 3. Laskukaavojen yhdistäminen 4. Yhtälöiden

Lisätiedot

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä

Rekursiolause. Laskennan teorian opintopiiri. Sebastian Björkqvist. 23. helmikuuta Tiivistelmä Rekursiolause Laskennan teorian opintopiiri Sebastian Björkqvist 23. helmikuuta 2014 Tiivistelmä Työssä käydään läpi itsereplikoituvien ohjelmien toimintaa sekä esitetään ja todistetaan rekursiolause,

Lisätiedot

Sisältö. 2. Taulukot. Yleistä. Yleistä

Sisältö. 2. Taulukot. Yleistä. Yleistä Sisältö 2. Taulukot Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.1 2.2 Yleistä

Lisätiedot

ITKP102 Ohjelmointi 1 (6 op)

ITKP102 Ohjelmointi 1 (6 op) ITKP102 Ohjelmointi 1 (6 op) Tentaattori: Antti-Jussi Lakanen 7. huhtikuuta 2017 Vastaa kaikkiin tehtäviin. Tee jokainen tehtävä erilliselle konseptiarkille. Kirjoittamasi luokat, funktiot ja aliohjelmat

Lisätiedot

Avaruuden kolme sellaista pistettä, jotka eivät sijaitse samalla suoralla, määräävät

Avaruuden kolme sellaista pistettä, jotka eivät sijaitse samalla suoralla, määräävät 11 Taso Avaruuden kolme sellaista pistettä, jotka eivät sijaitse samalla suoralla, määräävät tason. Olkoot nämä pisteet P, B ja C. Merkitään vaikkapa P B r ja PC s. Tällöin voidaan sanoa, että vektorit

Lisätiedot

58131 Tietorakenteet ja algoritmit (kevät 2014) Uusinta- ja erilliskoe, , vastauksia

58131 Tietorakenteet ja algoritmit (kevät 2014) Uusinta- ja erilliskoe, , vastauksia 58131 Tietorakenteet ja algoritmit (kevät 2014) Uusinta- ja erilliskoe, 10..2014, vastauksia 1. [9 pistettä] (a) Todistetaan 2n 2 + n + 5 = O(n 2 ): Kun n 1 on 2n 2 + n + 5 2n 2 + n 2 +5n 2 = 8n 2. Eli

Lisätiedot

Matematiikan tukikurssi

Matematiikan tukikurssi Matematiikan tukikurssi Kurssikerta 4 Supremum ja inmum Tarkastellaan aluksi avointa väliä, Tämä on joukko, johon kuuluvat kaikki reaaliluvut miinus yhdestä yhteen Kuitenkaan päätepisteet eli luvut ja

Lisätiedot

58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut

58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut 58131 Tietorakenteet ja algoritmit (kevät 2016) Ensimmäinen välikoe, malliratkaisut 1. Palautetaan vielä mieleen O-notaation määritelmä. Olkoon f ja g funktioita luonnollisilta luvuilta positiivisille

Lisätiedot

Luento 7: Lokaalit valaistusmallit

Luento 7: Lokaalit valaistusmallit Tietokonegrafiikan perusteet T-111.4300 3 op Luento 7: Lokaalit valaistusmallit Lauri Savioja 11/07 Lokaalit valaistusmallit / 1 Sävytys Interpolointi Sisältö Lokaalit valaistusmallit / 2 1 Varjostustekniikat

Lisätiedot

Tietokonegrafiikka. Jyry Suvilehto T Johdatus tietoliikenteeseen ja multimediatekniikkaan kevät 2014

Tietokonegrafiikka. Jyry Suvilehto T Johdatus tietoliikenteeseen ja multimediatekniikkaan kevät 2014 Tietokonegrafiikka Jyry Suvilehto T-110.1100 Johdatus tietoliikenteeseen ja multimediatekniikkaan kevät 2014 1. Sovellusalueita 2. Rasterigrafiikkaa 3. Vektorigrafiikkaa 4. 3D-grafiikkaa 1. Säteenheitto

Lisätiedot

Lieriö ja särmiö Tarkastellaan pintaa, joka syntyy, kun tasoa T leikkaava suora s liikkuu suuntansa

Lieriö ja särmiö Tarkastellaan pintaa, joka syntyy, kun tasoa T leikkaava suora s liikkuu suuntansa Lieriö ja särmiö Tarkastellaan pintaa, joka syntyy, kun tasoa T leikkaava suora s liikkuu suuntansa säilyttäen pitkin tason T suljettua käyrää (käyrä ei leikkaa itseään). Tällöin suora s piirtää avaruuteen

Lisätiedot

Pong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana

Pong-peli, vaihe Aliohjelman tekeminen. Muilla kielillä: English Suomi. Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana Muilla kielillä: English Suomi Pong-peli, vaihe 3 Tämä on Pong-pelin tutoriaalin osa 3/7. Tämän vaiheen aikana Jaetaan ohjelma pienempiin palasiin (aliohjelmiin) Lisätään peliin maila (jota ei voi vielä

Lisätiedot

Tampereen yliopisto Tietokonegrafiikka 2013 Tietojenkäsittelytiede Harjoitus

Tampereen yliopisto Tietokonegrafiikka 2013 Tietojenkäsittelytiede Harjoitus Tampereen yliopisto Tietokonegrafiikka 2013 Tietojenkäsittelytiede Harjoitus 2 7.2.2013 1. Matematiikan lukiokurssissa on esitetty, että ylöspäin aukeavan paraabelin f(x) = ax 2 +bx+c,a > 0,minimikohtasaadaan,kunf

Lisätiedot

Reaaliaikaiset varjoalgoritmit. Atso Kauppinen

Reaaliaikaiset varjoalgoritmit. Atso Kauppinen Reaaliaikaiset varjoalgoritmit Atso Kauppinen Tampereen yliopisto Tietojenkäsittelytieteiden laitos Tietojenkäsittelyoppi Pro gradu -tutkielma Maaliskuu 2008 Tampereen yliopisto Tietojenkäsittelytieteiden

Lisätiedot

VEKTORIANALYYSIN HARJOITUKSET: VIIKKO 4

VEKTORIANALYYSIN HARJOITUKSET: VIIKKO 4 VEKTORIANALYYSIN HARJOITUKSET: VIIKKO 4 Jokaisen tehtävän jälkeen on pieni kommentti tehtävään liittyen Nämä eivät sisällä mitään kovin kriittistä tietoa tehtävään liittyen, joten niistä ei tarvitse välittää

Lisätiedot

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli

TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op. Assembly ja konekieli TIEP114 Tietokoneen rakenne ja arkkitehtuuri, 3 op Assembly ja konekieli Tietokoneen ja ohjelmiston rakenne Loogisilla piireillä ja komponenteilla rakennetaan prosessori ja muistit Prosessorin rakenne

Lisätiedot

MAB3 - Harjoitustehtävien ratkaisut:

MAB3 - Harjoitustehtävien ratkaisut: MAB3 - Harjoitustehtävien ratkaisut: 1 Funktio 1.1 Piirretään koordinaatistoakselit ja sijoitetaan pisteet: 1 1. a) Funktioiden nollakohdat löydetään etsimällä kuvaajien ja - akselin leikkauspisteitä.

Lisätiedot

Digikuvan peruskäsittelyn. sittelyn työnkulku. Soukan Kamerat 22.1.2007. Soukan Kamerat/SV

Digikuvan peruskäsittelyn. sittelyn työnkulku. Soukan Kamerat 22.1.2007. Soukan Kamerat/SV Digikuvan peruskäsittelyn sittelyn työnkulku Soukan Kamerat 22.1.2007 Sisält ltö Digikuvan siirtäminen kamerasta tietokoneelle Skannaus Kuvan kääntäminen Värien säätö Sävyjen säätö Kuvan koko ja resoluutio

Lisätiedot

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset

815338A Ohjelmointikielten periaatteet Harjoitus 2 vastaukset 815338A Ohjelmointikielten periaatteet 2015-2016. Harjoitus 2 vastaukset Harjoituksen aiheena on BNF-merkinnän käyttö ja yhteys rekursiivisesti etenevään jäsentäjään. Tehtävä 1. Mitkä ilmaukset seuraava

Lisätiedot

Demo 1: Simplex-menetelmä

Demo 1: Simplex-menetelmä MS-C2105 Optimoinnin perusteet Malliratkaisut 3 Ehtamo Demo 1: Simplex-menetelmä Muodosta lineaarisen tehtävän standardimuoto ja ratkaise tehtävä taulukkomuotoisella Simplex-algoritmilla. max 5x 1 + 4x

Lisätiedot

Helsingin seitsemäsluokkalaisten matematiikkakilpailu 7.2.2013 Ratkaisuita

Helsingin seitsemäsluokkalaisten matematiikkakilpailu 7.2.2013 Ratkaisuita Helsingin seitsemäsluokkalaisten matematiikkakilpailu..013 Ratkaisuita 1. Eräs kirjakauppa myy pokkareita yhdeksällä eurolla kappale, ja siellä on meneillään mainoskampanja, jossa seitsemän sellaista ostettuaan

Lisätiedot

LIITE 1 1. Tehtävänä on mallintaa kitara ohjeiden mukaan käyttäen Edit Poly-tekniikkaa.

LIITE 1 1. Tehtävänä on mallintaa kitara ohjeiden mukaan käyttäen Edit Poly-tekniikkaa. LIITE 1 1 HARJOITUS 1 Kitara Tehtävänä on mallintaa kitara ohjeiden mukaan käyttäen Edit Poly-tekniikkaa. Käsiteltävät asiat Edit Poly Muokkaus kuvan mukaan TurboSmooth Extrude 1. Tarkistetaan että mittayksiköt

Lisätiedot

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma.

Yleistä. Nyt käsitellään vain taulukko (array), joka on saman tyyppisten muuttujien eli alkioiden (element) kokoelma. 2. Taulukot 2.1 Sisältö Yleistä. Esittely ja luominen. Alkioiden käsittely. Kaksiulotteinen taulukko. Taulukko operaation parametrina. Taulukko ja HelloWorld-ohjelma. Taulukko paluuarvona. 2.2 Yleistä

Lisätiedot

Ratkaisu: Maksimivalovoiman lauseke koostuu heijastimen maksimivalovoimasta ja valonlähteestä suoraan (ilman heijastumista) tulevasta valovoimasta:

Ratkaisu: Maksimivalovoiman lauseke koostuu heijastimen maksimivalovoimasta ja valonlähteestä suoraan (ilman heijastumista) tulevasta valovoimasta: LASKUHARJOITUS 1 VALAISIMIEN OPTIIKKA Tehtävä 1 Pistemäinen valonlähde (Φ = 1000 lm, valokappaleen luminanssi L = 2500 kcd/m 2 ) sijoitetaan 15 cm suuruisen pyörähdysparaboloidin muotoisen peiliheijastimen

Lisätiedot

Matematiikan tukikurssi

Matematiikan tukikurssi Matematiikan tukikurssi Kurssikerta 2 Lisää osamurtoja Tutkitaan jälleen rationaalifunktion P(x)/Q(x) integrointia. Aiemmin käsittelimme tapauksen, jossa nimittäjä voidaan esittää muodossa Q(x) = a(x x

Lisätiedot

Pong-peli, vaihe Aliohjelmakutsu laskureita varten. 2. Laskurin luominen. Muilla kielillä: English Suomi

Pong-peli, vaihe Aliohjelmakutsu laskureita varten. 2. Laskurin luominen. Muilla kielillä: English Suomi Muilla kielillä: English Suomi Pong-peli, vaihe 7 Tässä vaiheessa lisäämme peliin pistelaskun. Pong-pelissä pelaaja saa pisteen kun pallo ohittaa toisen pelaajan mailan. 1. Aliohjelmakutsu laskureita varten

Lisätiedot

Käyttöliittymän muokkaus

Käyttöliittymän muokkaus Käyttöliittymän muokkaus Ohjelman pitkän kehityshistorian takia asetukset ovat jakaantuneet useampaan eri kohtaan ohjelmassa. Ohessa yhteenveto nykyisistä asetuksista (versio 6.4.1, 2/2018). Ylä- ja sivupalkkien

Lisätiedot

Matopeli C#:lla. Aram Abdulla Hassan. Ammattiopisto Tavastia. Opinnäytetyö

Matopeli C#:lla. Aram Abdulla Hassan. Ammattiopisto Tavastia. Opinnäytetyö Matopeli C#:lla Aram Abdulla Hassan Ammattiopisto Tavastia Opinnäytetyö Syksy 2014 1 Sisällysluettelo 1. Johdanto... 3 2. Projektin aihe: Matopeli C#:lla... 3 3. Projektissa käytetyt menetelmät ja työkalut

Lisätiedot

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille:

Merkkijono määritellään kuten muutkin taulukot, mutta tilaa on varattava yksi ylimääräinen paikka lopetusmerkille: Merkkijonot C-kielessä merkkijono on taulukko, jonka alkiot ovat char -tyyppiä. Taulukon viimeiseksi merkiksi tulee merkki '\0', joka ilmaisee merkkijonon loppumisen. Merkkijono määritellään kuten muutkin

Lisätiedot

Zeon PDF Driver Trial

Zeon PDF Driver Trial Matlab-harjoitus 2: Kuvaajien piirto, skriptit ja funktiot. Matlabohjelmoinnin perusteita Numeerinen integrointi trapezoidaalimenetelmällä voidaan tehdä komennolla trapz. Esimerkki: Vaimenevan eksponentiaalin

Lisätiedot

2.1. Tehtävänä on osoittaa induktiolla, että kaikille n N pätee n = 1 n(n + 1). (1)

2.1. Tehtävänä on osoittaa induktiolla, että kaikille n N pätee n = 1 n(n + 1). (1) Approbatur 3, demo, ratkaisut Sovitaan, että 0 ei ole luonnollinen luku. Tällöin oletusta n 0 ei tarvitse toistaa alla olevissa ratkaisuissa. Se, pidetäänkö nollaa luonnollisena lukuna vai ei, vaihtelee

Lisätiedot