<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-8771189832108270235</id><updated>2009-10-17T14:32:10.940-07:00</updated><title type='text'>xcx's blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-3450221399998634993</id><published>2009-04-07T10:31:00.000-07:00</published><updated>2009-04-07T10:33:42.421-07:00</updated><title type='text'>Blogi vaihtuu</title><content type='html'>Tämä blogi vaihtuu uuteen. Uusi blogi löytyy osoitteesta&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.verajankorva.com/openblog/"&gt;http://www.verajankorva.com/openblog/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Tämän blogin artikkelit löytyvät myös uudelta blogilta.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-3450221399998634993?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/3450221399998634993/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=3450221399998634993' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/3450221399998634993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/3450221399998634993'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2009/04/blogi-vaihtuu.html' title='Blogi vaihtuu'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-1838481357002458649</id><published>2009-04-06T05:19:00.000-07:00</published><updated>2009-04-06T05:40:11.806-07:00</updated><title type='text'>Lisää custom dataa .NET ListViewItem olioon.</title><content type='html'>Usein tulee vastaan tilanne, että ListViewItem tai TreeViewItem pitäisi sisältää dataa, joka ei näy itse komponentissa esim. jokin tunnisteguid.&lt;br /&gt;&lt;br /&gt;Oman tiedon kirjoittaminen ListViewItemiin ei ole lainkaan vaikeaa. Näin se käy.&lt;br /&gt;&lt;br /&gt;Luodaan luokka, joka perii ListViewItem luokan.&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; public class MyListViewItem : ListViewItem&lt;br /&gt; {&lt;br /&gt;     private Guid m_guid;&lt;br /&gt;&lt;br /&gt;     public MyListViewItem()&lt;br /&gt;     {&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     public Guid Guid&lt;br /&gt;     {&lt;br /&gt;         set&lt;br /&gt;         {&lt;br /&gt;             m_guid = value;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         get&lt;br /&gt;         {&lt;br /&gt;             return m_guid;&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;Ja nyt voit käyttää luokkaasi ihan normaalisti.&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;MyListViewItem mlvi = MyListViewItem();&lt;br /&gt;mlvi.Text = "TEST TEXT";&lt;br /&gt;mlvi.Guid = Guid.NewGuid();&lt;br /&gt;&lt;br /&gt;this.listView1.Items.Add( mlvi );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;Ja kun nyt haluat päästä käsiksi omaan dataasi.&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;MyListViewItem mlvi = (MyListViewItem)this.listView1.Items[0];&lt;br /&gt;Console.Out.WriteLine( mlvi.Guid.ToString() );&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/span&gt;Siinä se. Helppoa, nopeaa ja käytännöllistä.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-1838481357002458649?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/1838481357002458649/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=1838481357002458649' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/1838481357002458649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/1838481357002458649'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2009/04/lisaa-custom-dataa-net-listviewitem.html' title='Lisää custom dataa .NET ListViewItem olioon.'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-3088530324395948436</id><published>2009-03-30T01:49:00.000-07:00</published><updated>2009-04-06T00:23:14.796-07:00</updated><title type='text'>Scanline rendaaja Flashille</title><content type='html'>Pitkään on pitänyt tätä kokeilla ja loputakin löysin aikaa tämän tekemiseen.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.verajankorva.com/temp/flash/GnosisENGINE9/bin/"&gt;Katso esimerkki&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Eli scanline rendaaja Flash 10:lle. Tärkeintä tässä on se, että enginessä on oikea zbuffer. Eli joka pikselillä on z arvo jota vasten voidaan tarkistaa mikä pikseli on minkäkin pikselin etu- vai takapuolella. &lt;br /&gt;Tavallisesti Flash 3d-enginet eivät tee näin, koska polygonien rasterointi on flashilla hidasta, puhumattakaa pikselin piirtämisestä. Kuitenkin nykyisin alkaa vaikuttaa siltä, että pikselin piirto alkaa olla sen verran nopeaa, että jonkinlaiseen käyttöön sitä voisi jo käyttää. Edelleen olisi nopeampaa tehdä, kuten Papervision, Sandy3d tai Away3d eli käyttää Flashin omaa polygonin piirtoapia ja sorttaa polyt esim zsortilla. Ongelma kuitenkin on, että polyt voivat joissain tilanteissa piirtyä väärässä järjestyksessä, koska z arvot lasketaan vain polyn keskipisteen mukaan, jolloin tulos ei ole aina oikein. Lisäksi zsort ei voi piirtää leikkaavia polygoneja okein. Pikselipohjainen zbuffer on melkoisesti hitaampi, mutta polyt piirtyy aina oikein myös silloin jos polyt leikaavat toisiaan.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.verajankorva.com/temp/flash/GnosisENGINE9/Engine.zip"&gt;Lähdekoodit&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-3088530324395948436?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/3088530324395948436/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=3088530324395948436' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/3088530324395948436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/3088530324395948436'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2009/03/scanline-renderer-flashille.html' title='Scanline rendaaja Flashille'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-945957532555864247</id><published>2008-11-28T10:05:00.000-08:00</published><updated>2008-12-01T00:02:12.525-08:00</updated><title type='text'>XNA</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Microsoft XNA&lt;/span&gt; on ilmainen "peliohjelmointikirjasto", jonka tarkoitus on olla helppokäyttöinen Direct X rajapinnan päälle rakennettu Framework. XNA ei kuitenkaan eroa kovinkaan paljoa Direct X:stä. Se on kuitenkin selkeämpi ja siitä on poistettu epäolennaisia osia. XNA ohjelmia voidaan ohjelmoida .NET kielillä ja tässä käytetämme C# kieltä, mutta voisit käyttää muitakin .NET kieliä oman valintasi mukaan.&lt;br /&gt;&lt;br /&gt;XNA käytännössä korvaa Managed Direct X:n.&lt;br /&gt;&lt;br /&gt;XNA on melko pieni paketti, jonka voi ladata täältä http://creators.xna.com/en-US/downloads&lt;br /&gt;&lt;br /&gt;Tarvitset kuitenkin myös DirectX SDK:n ja Visual Studion tai &lt;span class="XnaCgp_Global_Large_Subtitle"&gt;Visual C# 2008 Express Edition.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Kolmio&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Värillinen kolmio on melkein "Hello world" ohjelma, kun aloitetaan opiskelemaan 3d-grafiikkaohjelmointia. Tällä kertaa aionkin esitellä miten kolmio luodaan XNA:lla.&lt;br /&gt;&lt;br /&gt;Käynnistä Visual C# ja luo uusi XNA projekti. XNA projekti on hämäävästi nimetty Windows Game ja XBox360 Game.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_OL7dnwBevhY/STF9ioikOrI/AAAAAAAAAEQ/G4tPfdVSCm8/s1600-h/projcreate01.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 230px;" src="http://2.bp.blogspot.com/_OL7dnwBevhY/STF9ioikOrI/AAAAAAAAAEQ/G4tPfdVSCm8/s320/projcreate01.jpg" alt="" id="BLOGGER_PHOTO_ID_5274134672578984626" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Tämä luo sinulle projektin, jossa on valmiiksi tehtynä pari perusjuttua peliä tehdessä, kuten ikkuna ja pääsilmukka. Nämä mm. ovat asioita, jotka teet aina likimain samalla tavalla. On siis varsin mukavaa, että XNA projekti tekee nämä valmiiksi.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;#region Using Statements&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using Microsoft.Xna.Framework;&lt;br /&gt;using Microsoft.Xna.Framework.Audio;&lt;br /&gt;using Microsoft.Xna.Framework.Content;&lt;br /&gt;using Microsoft.Xna.Framework.Graphics;&lt;br /&gt;using Microsoft.Xna.Framework.Input;&lt;br /&gt;using Microsoft.Xna.Framework.Storage;&lt;br /&gt;#endregion&lt;br /&gt;&lt;br /&gt;namespace BlogExample01&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;public class Game1 : Microsoft.Xna.Framework.Game&lt;br /&gt;{&lt;br /&gt; GraphicsDeviceManager graphics;&lt;br /&gt; ContentManager content;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; public Game1()&lt;br /&gt; {&lt;br /&gt;     graphics = new GraphicsDeviceManager(this);&lt;br /&gt;     content = new ContentManager(Services);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected override void Initialize()&lt;br /&gt; {&lt;br /&gt;     base.Initialize();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected override void LoadGraphicsContent(&lt;br /&gt;     bool loadAllContent)&lt;br /&gt; {&lt;br /&gt;     if (loadAllContent)&lt;br /&gt;     {         &lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected override void UnloadGraphicsContent(&lt;br /&gt;     bool unloadAllContent)&lt;br /&gt; {&lt;br /&gt;     if (unloadAllContent)&lt;br /&gt;     {&lt;br /&gt;         content.Unload();&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected override void Update(GameTime gameTime)&lt;br /&gt; {&lt;br /&gt;     base.Update(gameTime);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected override void Draw(GameTime gameTime)&lt;br /&gt; {&lt;br /&gt;     graphics.GraphicsDevice.Clear(Color.CornflowerBlue); &lt;br /&gt;&lt;br /&gt;     base.Draw(gameTime);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Jos käännät koodin saat eteesi ikkunan sinisellä pohjalla.&lt;br /&gt;&lt;br /&gt;Haluamme kuitenkin sen kolmion ruudulle, joten meidän pitää kertoa millaisista pisteistä kolmio koostuu. Näitä pisteitä sanotaan vertekseiksi. XNA:ssa verteksit voivat sisältää paljonkin tietoa. Se mitä tietoa verteksillä on kerrotaan verteksiformaatissa. Näitä formaatteja voi tehdä itse tai käyttää XNA:n valmiita formaatteja, kuten tässä.&lt;br /&gt;Käytämme verteksiformaattia VertexPositionColor, johon voidaan siis kirjoittaa paikka- ja väridata. Luodaan siis luokalle uusi member muuttuja (kaamea suomennos "jäsenmuuttuja") private VertexPositionColor[] m_vertices.&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;...&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;public class Game1 : Microsoft.Xna.Framework.Game&lt;br /&gt;{&lt;br /&gt; GraphicsDeviceManager graphics;&lt;br /&gt; ContentManager content;&lt;br /&gt;&lt;br /&gt; &lt;b&gt;private VertexPositionColor[] m_vertices;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt; public Game1()&lt;br /&gt; {&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Seuraavaksi luodaan taulukkoon ne verteksit.&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;...&lt;br /&gt; protected override void LoadGraphicsContent(&lt;br /&gt;     bool loadAllContent)&lt;br /&gt; {&lt;br /&gt;     if (loadAllContent)&lt;br /&gt;     {&lt;br /&gt;         &lt;b&gt;m_vertices = new VertexPositionColor[3];&lt;br /&gt;&lt;br /&gt;         m_vertices[0].Position = new Vector3(&lt;br /&gt;             -0.5f, -0.5f, 0f);&lt;br /&gt;         m_vertices[0].Color = Color.Red;&lt;br /&gt;         m_vertices[1].Position = new Vector3(&lt;br /&gt;             0, 0.5f, 0f);&lt;br /&gt;         m_vertices[1].Color = Color.Green;&lt;br /&gt;         m_vertices[2].Position = new Vector3(&lt;br /&gt;             0.5f, -0.5f, 0f);&lt;br /&gt;         m_vertices[2].Color = Color.Yellow;&lt;/b&gt;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Nyt meillä on verteksit, joilla voidaan piirtää kolmio, mutta näytönohjaimelle on kerrottava millaista vertexdataa on tulossa ja XNA:ssa se tehdään luomalla VertexDeclaration olio. VertexDeclaration tarvitsee myös pääsyn näytönohjaimeen, joka onnistuu XNA:n GraphicsDevice luokan kautta. Meidän pitää siis luoda oliot VertexDeclaration ja GraphicsDevice.&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;...&lt;br /&gt;public class Game1 : Microsoft.Xna.Framework.Game&lt;br /&gt;{&lt;br /&gt; GraphicsDeviceManager m_graphics;&lt;br /&gt; ContentManager m_content;&lt;br /&gt; &lt;b&gt;GraphicsDevice m_device;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt; private VertexPositionColor[] m_vertices;&lt;br /&gt; &lt;b&gt;private VertexDeclaration m_vd;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt; public Game1()&lt;br /&gt; {&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt; protected override void LoadGraphicsContent(&lt;br /&gt;     bool loadAllContent)&lt;br /&gt; {&lt;br /&gt;     if (loadAllContent)&lt;br /&gt;     {&lt;br /&gt;         &lt;b&gt;m_device = m_graphics.GraphicsDevice;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;         m_vertices = new VertexPositionColor[3];&lt;br /&gt;&lt;br /&gt;         m_vertices[0].Position = new Vector3(&lt;br /&gt;             -0.5f, -0.5f, 0f);&lt;br /&gt;         m_vertices[0].Color = Color.Red;&lt;br /&gt;         m_vertices[1].Position = new Vector3(&lt;br /&gt;             0, 0.5f, 0f);&lt;br /&gt;         m_vertices[1].Color = Color.Green;&lt;br /&gt;         m_vertices[2].Position = new Vector3(&lt;br /&gt;             0.5f, -0.5f, 0f);&lt;br /&gt;         m_vertices[2].Color = Color.Yellow;&lt;br /&gt;&lt;br /&gt;         &lt;b&gt;m_vd = new VertexDeclaration(m_device, VertexPositionColor.VertexElements);&lt;/b&gt;&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;Emme ole vieläkään valmiit piirtämään mitään :(, mutta olemme jo puolivälissä :).&lt;br /&gt;XNA piirtää kaiken kaman ruudulle shaderien kautta. Eli meidän kirjoitettava Vertex- ja PixelShader voidaksemme piirtää jotain. Niiden kirjoittaminen on kuitenkin oma asiansa ja voimme tässä vaiheessa aivan hyvin tyytyä käyttämään jotain valmista shaderia ja murehtia niiden tekemisestä sitten joskus myöhemmin. Halutessasi voit lukea shadereistä lisää Direct X SDK:n dokuista tai vaikka Riemersin tutoriaaleista, joista meidän käyttämämme shader on otettu &lt;a href="http://www.riemers.net/eng/Tutorials/XNA/Csharp/series3.php"&gt;linkki&lt;/a&gt;. Tässä vaiheessa on kuitenkin tarpeen tietää miten shadereitä käytetään.&lt;br /&gt;Shadereitä hallitaan Effect luokan kautta. Eli luomme Effect olion, johon ladataan HLSL tiedosto. Itse lataaminen suoritetaan Content luokan avulla, jonka XNA projekti on jo valmiiksi alustanut ohjelman käytettäväksi.&lt;br /&gt;Shader tiedosto on normaali tekstitiedosto, jonka pääte tavallisesti on .fx. Tässä ohjeessa käytän &lt;a href="http://www.verajankorva.com/blog/simpleshader.fx"&gt;simpleshader.fx&lt;/a&gt; shaderia. Se on äärimmäisen yksinkertainen shaderi, mutta se riittää meidän tarpeisiimme.&lt;br /&gt;Lisää shader tiedosto projektiisi ja lataa shader Content luokan avulla käyttäen Visual C#:pin shaderille antamaa Asset Name nimeä. Se on yleensä tiedoston nimi ilman päätettä.&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;...&lt;br /&gt;public class Game1 : Microsoft.Xna.Framework.Game&lt;br /&gt;{&lt;br /&gt; GraphicsDeviceManager m_graphics;&lt;br /&gt; ContentManager m_content;&lt;br /&gt; GraphicsDevice m_device;&lt;br /&gt;&lt;br /&gt; &lt;b&gt;private Effect m_effect;&lt;/b&gt;&lt;br /&gt; private VertexPositionColor[] m_vertices;&lt;br /&gt; private VertexDeclaration m_vd;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;protected override void LoadGraphicsContent(&lt;br /&gt;bool loadAllContent)&lt;br /&gt; {&lt;br /&gt;     if (loadAllContent)&lt;br /&gt;     {&lt;br /&gt;         m_device = m_graphics.GraphicsDevice;&lt;br /&gt;         &lt;b&gt;m_effect = m_content.Load&lt;effect&gt;("simpleshader");&lt;/effect&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;         m_vertices = new VertexPositionColor[3];&lt;br /&gt;...&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nyt meillä on kolmion verteksit, verteksiformaatti ja shaderi, jolla piirtää. Mitä vielä tarvitaan? Matriisi tai oikeastaan matriisit. Matriisi on taulukko numeroita, joiden selittäminen ei ole tässä juuri nyt tarpeen. Oikeastaan ne ovat melkoisen yksinkertaisia ja selkiintyvät kuin itsestään. Voimme kuitenkin käyttää niitä aivan hyvin vaikka emme niiden toimintaa ymmärtäisikään. Tarvitsemme kaksi matriisia. Näkymämatriisin ja projektiomatriisin. Yleensä tarvitaan matriiseja enemmänkin, mutta juuri nyt nuo kaksi riittävät. Näkymämatriisi on matriisi, joka kertoo XNA:lle missä ja missä asennossa katsojan silmä, eli kamera, on. Projektiomatriisi kertoo millainen kamera. Eli minkälainen FOV, lähi -ja kaukoleikkaus ja millainen aspect ratio näkymässä on.&lt;br /&gt;Tarvitsemme kaksi uutta memberiä luokkaamme.&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;...&lt;br /&gt;public class Game1 : Microsoft.Xna.Framework.Game&lt;br /&gt;{&lt;br /&gt; GraphicsDeviceManager m_graphics;&lt;br /&gt; ContentManager m_content;&lt;br /&gt; GraphicsDevice m_device;&lt;br /&gt;&lt;br /&gt; private Effect m_effect;&lt;br /&gt; private VertexPositionColor[] m_vertices;&lt;br /&gt; private VertexDeclaration m_vd;&lt;br /&gt;&lt;br /&gt; &lt;b&gt;private Matrix m_matView;&lt;br /&gt; private Matrix m_matProj;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt; public Game1()&lt;br /&gt;...&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Ja asetamme näille asetukset, jotka sopivat ko. tilanteeseen.&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;...&lt;br /&gt; protected override void LoadGraphicsContent(&lt;br /&gt;     bool loadAllContent)&lt;br /&gt; {&lt;br /&gt;     if (loadAllContent)&lt;br /&gt;     {&lt;br /&gt;         m_device = m_graphics.GraphicsDevice;&lt;br /&gt;         m_effect = m_content.Load&lt;effect&gt;("simpleshader");&lt;br /&gt;&lt;br /&gt;         m_vertices = new VertexPositionColor[3];&lt;br /&gt;&lt;br /&gt;         m_vertices[0].Position = new Vector3(&lt;br /&gt;              -0.5f, -0.5f, 0f);&lt;br /&gt;         m_vertices[0].Color = Color.Red;&lt;br /&gt;         m_vertices[1].Position = new Vector3(&lt;br /&gt;             0, 0.5f, 0f);&lt;br /&gt;         m_vertices[1].Color = Color.Green;&lt;br /&gt;         m_vertices[2].Position = new Vector3(&lt;br /&gt;             0.5f, -0.5f, 0f);&lt;br /&gt;         m_vertices[2].Color = Color.Yellow;&lt;br /&gt;&lt;br /&gt;         m_vd = new VertexDeclaration(&lt;br /&gt;              m_device,&lt;br /&gt;              VertexPositionColor.VertexElements);&lt;br /&gt;&lt;br /&gt;         &lt;b&gt;m_matView = Matrix.CreateLookAt(new Vector3(&lt;br /&gt;                0.0f, 0.0f, 2.0f),&lt;br /&gt;                new Vector3(0.0f, 0.0f, 0.0f),&lt;br /&gt;                new Vector3(0.0f, 1.0f, 0.0f));&lt;br /&gt;         m_matProj = Matrix.CreatePerspectiveFieldOfView(&lt;br /&gt;             MathHelper.PiOver4,&lt;br /&gt;             (float)m_device.Viewport.Width /&lt;br /&gt;             (float)m_device.Viewport.Height,&lt;br /&gt;             1.0f, 100.0f);&lt;/b&gt;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;...&lt;br /&gt;&lt;/effect&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;Ja lopultakin olemme valmiit piirtämään!&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;...&lt;br /&gt; protected override void Draw(GameTime gameTime)&lt;br /&gt; {&lt;br /&gt;     m_graphics.GraphicsDevice.Clear(Color.CornflowerBlue);&lt;br /&gt;&lt;b&gt;&lt;br /&gt;     m_device.RenderState.CullMode = CullMode.None;&lt;br /&gt;     m_device.RenderState.FillMode = FillMode.Solid;&lt;/b&gt;&lt;br /&gt;...&lt;/span&gt;&lt;/pre&gt;Asetetaan piilopintojen poisto pois päältä, jotta kolmio näkyy vaikka se olisi "väärin päin" ja asetetaan kolmion piirto fill moodiin. Eli kolmiot täytetään eikä piirretä niistä vain reunoja tai kärkipisteitä.&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;...&lt;br /&gt;     &lt;b&gt;m_effect.CurrentTechnique = m_effect.Techniques["Simplest"];&lt;br /&gt;     m_effect.Parameters["xViewProjection"].SetValue(&lt;br /&gt;         m_matView * m_matProj);&lt;br /&gt;     m_effect.Begin();&lt;/b&gt;&lt;br /&gt;...&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Otetaan shaderista käyttöön Simplest tekniikka. Eli tämä on shaderiin kirjoitettu efekti, joka voi olla melkin mitä tahansa. Tällä kertaa se on hyvin yksinkertainen värien interpolointi verteksien välillä.&lt;br /&gt;Shader myös sisältää muuttujan, joka on xViewProjection matriisi. Sinun tulee antaa tämä matriisi jotta shader osaa projisoida verteksit oikein.&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;...&lt;br /&gt;     &lt;b&gt;foreach (EffectPass pass in&lt;br /&gt;         m_effect.CurrentTechnique.Passes)&lt;br /&gt;     {&lt;br /&gt;         pass.Begin();&lt;/b&gt;&lt;br /&gt;...&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Koodi käy kaikki shaderin "passit" läpi. Tässä shaderissa passeja on vain yksi, mutta niitä voi olla enemmänkin.&lt;br /&gt;&lt;pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;...&lt;br /&gt;         &lt;b&gt;m_device.VertexDeclaration = m_vd;         &lt;br /&gt;         m_device.DrawUserPrimitives(&lt;br /&gt;             PrimitiveType.TriangleList,&lt;br /&gt;             m_vertices, 0, 1);&lt;br /&gt;&lt;br /&gt;         pass.End();&lt;br /&gt;     }&lt;br /&gt;     m_effect.End();&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;     base.Draw(gameTime);&lt;br /&gt; }&lt;br /&gt;...&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Kerrotaan näyttökortille, millaista verteksidataa olemme lähettämässä. Lähetetään polygoni kortille ja lopuksi piirretään näyttökortin muistissa oleva data. Ja tulos näyttää tältä.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_OL7dnwBevhY/STMg2dKINqI/AAAAAAAAAEY/iVzvNnJr388/s1600-h/app01.jpg"&gt;&lt;img style="cursor: pointer; width: 320px; height: 250px;" src="http://3.bp.blogspot.com/_OL7dnwBevhY/STMg2dKINqI/AAAAAAAAAEY/iVzvNnJr388/s320/app01.jpg" alt="" id="BLOGGER_PHOTO_ID_5274595708493117090" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.verajankorva.com/blog/BlogExample.cs"&gt;Imuroi lähdekoodi&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-945957532555864247?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/945957532555864247/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=945957532555864247' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/945957532555864247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/945957532555864247'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/11/xna.html' title='XNA'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_OL7dnwBevhY/STF9ioikOrI/AAAAAAAAAEQ/G4tPfdVSCm8/s72-c/projcreate01.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-4610779092984425736</id><published>2008-11-16T02:48:00.000-08:00</published><updated>2008-11-16T23:55:50.629-08:00</updated><title type='text'>C# ja JavaScript</title><content type='html'>Usein tulee vastaan tilanteita jolloin selainohjelman tekeminen esim. yrityksen sisäiseen käyttöön tuntuu järkevältä. Selaimet ovat mm. erittäin hyviä käsittelemään isoja määriä kuvia. Ne mukavasti lataavat kuvat streamaamalla ja pysyvät interaktiivisina isojenkin kuva määrien kanssa.&lt;br /&gt;&lt;br /&gt;Nettiselain on kuitenkin tehty turvalliseksi ja niistä ei ole pääsyä asiakaskoneeseen. Paikallisessa käytössä se on kuitenkin usein toivottua ja tarpaallista.&lt;br /&gt;Internet Explorer kylläkin tarjoaa ActiveX:n kautta pääsyn Windowsiin, mutta siihen on myös toinenkin keino.&lt;br /&gt;&lt;br /&gt;C# tai ylipäätään kaikki .NET kielet tarjoavat WebBrowser komponentin, jolla voidaan omaan .NET ohjelmaan upottaa webbiselain ja kirjottaa sen päälle omaa koodia. Kuitenkin on lievästi hankalaa saada HTML sivulta tietoa .NET ohjelmaasi. Usein varmasti haluaisit saada tiedon esim. siitä onko käyttäjä painanut nappia ja mitä asetuksia hän on sivulle laittanut.&lt;br /&gt;&lt;br /&gt;Eli voidaksemme käyttää .NET:iä laajentamaan selaimen toimintaa pitää meidän kirjoittaa oma .NET ohjelma. Ohjelman pitää sisältää WebBrowser komponentti, joka löytyy System.Windows.Forms.WebBrowser&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.aspx"&gt;http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;C# koodia&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Drawing;&lt;br /&gt;using System.Windows.Forms;&lt;br /&gt;&lt;br /&gt;namespace WebpageTest&lt;br /&gt;{&lt;br /&gt; public partial class MainForm : Form&lt;br /&gt; {  &lt;br /&gt;  WebBrowser m_wb = new WebBrowser();&lt;br /&gt;  &lt;br /&gt;  public MainForm()&lt;br /&gt;  {&lt;br /&gt;   InitializeComponent();&lt;br /&gt;      &lt;br /&gt;   m_wb.DocumentCompleted += &lt;br /&gt;      new WebBrowserDocumentCompletedEventHandler( &lt;br /&gt;          this.wb_OnDocumentComplete );&lt;br /&gt;   m_wb.ObjectForScripting = new JavaScript();&lt;br /&gt;   m_wb.Dock = DockStyle.Fill;  &lt;br /&gt;   this.Controls.Add( m_wb );&lt;br /&gt;   &lt;br /&gt;   try&lt;br /&gt;   {    &lt;br /&gt;    m_wb.Url = new Uri( Application.StartupPath + &lt;br /&gt;        "/example.html");    &lt;br /&gt;   }&lt;br /&gt;   catch ( Exception e )&lt;br /&gt;   {&lt;br /&gt;    MessageBox.Show ( e.Message );&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public void wb_OnDocumentComplete(object sender, &lt;br /&gt;      System.EventArgs e)&lt;br /&gt;  {&lt;br /&gt;   m_wb.Document.InvokeScript ("testDotNet", null );&lt;br /&gt;  }  &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ohjelma on yksinkertainen, mutta käydään silti joitain kohtia läpi.&lt;br /&gt;&lt;pre&gt;m_wb.DocumentCompleted += &lt;br /&gt;    new WebBrowserDocumentCompletedEventHandler( &lt;br /&gt;        this.wb_OnDocumentComplete );&lt;/pre&gt;&lt;br /&gt;Kun HTML tiedosto on ladattu siitä lähetetään DocumentCompleted tapahtuma. Tämä rivi kertoo ohjelmalle, että haluamme tapahtuman käsiteltävän funktiossa wb_OnDocumentComplete(). Tämä on tärkeää, koska emme halua yrittää kutsua JavaScript funktioita ennen, kuin sivu on ladattu.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;m_wb.ObjectForScripting = new JavaScript();&lt;/pre&gt;&lt;br /&gt;Rivi kertoo WebBrowser komponentille, että mihin olioon internet sivulla oleva scripti voi päästä käsiksi.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;m_wb.Document.InvokeScript ("testDotNet", null );&lt;/pre&gt;&lt;br /&gt;DocumentComplete tapahtuman käsittelevässä funktiossa oleva rivi. Komentaa WebBrowseria ajamaan scriptiä. Tässä tapaauksessa ajamme testDotNet() funktion ilman funktioparametreja.&lt;br /&gt;&lt;br /&gt;.NET ohjelma tarvitsee vielä JavaScript olion. Eli olion, joka näkyy nettisivulla olevalle JavaScriptille. Olion nimi voi olla mitä vain, mutta itse käytän nimeä JavaScript.&lt;br /&gt;&lt;br /&gt;C# koodia&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Windows.Forms;&lt;br /&gt;&lt;br /&gt;namespace WebpageTest&lt;br /&gt;{&lt;br /&gt; [System.Runtime.InteropServices.ComVisible(true)]&lt;br /&gt; public class JavaScript&lt;br /&gt; {&lt;br /&gt;  public JavaScript()&lt;br /&gt;  {&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public void testJS( int iId )&lt;br /&gt;  {&lt;br /&gt;   MessageBox.Show( iId.ToString() );&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Luokka on simppeli, jossa on vain yksi methodi testJS( int id ). Tätä methodia voidaan kutsua nettisivulta. Huomaa, että luokan pitää olla näkyvissä COM:lle.&lt;br /&gt;&lt;pre&gt;[System.Runtime.InteropServices.ComVisible(true)]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Lopuksi vielä pieni nettisivu, joka osaa käyttää .NET koodia. Huomaa, että sivu on ajettava .NET ohjelmasi kautta, jotta oma koodisi toimii.&lt;br /&gt;&lt;br /&gt;HTML koodia&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;#60;html&amp;#62;&lt;br /&gt; &amp;#60;head&amp;#62;&lt;br /&gt;  &amp;#60;title&amp;#62;.NET example&amp;#60;/title&amp;#62;&lt;br /&gt;  &amp;#60;style type="text/css"&amp;#62;&lt;br /&gt;  p.option &lt;br /&gt;  { &lt;br /&gt;   cursor:pointer;&lt;br /&gt;  }&lt;br /&gt;  &amp;#60;/style&amp;#62;&lt;br /&gt;  &amp;#60;script type="text/javascript"&amp;#62;&lt;br /&gt;  function testDotNet()&lt;br /&gt;  {&lt;br /&gt;   alert ("Dot net made this function call.");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  function OnClick(id)&lt;br /&gt;  {&lt;br /&gt;   window.external.testJS( id )&lt;br /&gt;  }&lt;br /&gt;  &amp;#60;/script&amp;#62;  &lt;br /&gt; &amp;#60;/head&amp;#62;&lt;br /&gt; &amp;#60;body&amp;#62;&lt;br /&gt;  &amp;#60;p class="option" onClick="OnClick(1);"&amp;#62;Option 1&amp;#60;/p&amp;#62;&lt;br /&gt;  &amp;#60;p class="option" onClick="OnClick(2);"&amp;#62;Option 2&amp;#60;/p&amp;#62;&lt;br /&gt;  &amp;#60;p class="option" onClick="OnClick(3);"&amp;#62;Option 3&amp;#60;/p&amp;#62;&lt;br /&gt; &amp;#60;/body&amp;#62;&lt;br /&gt;&amp;#60;/html&amp;#62;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-4610779092984425736?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/4610779092984425736/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=4610779092984425736' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/4610779092984425736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/4610779092984425736'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/11/c-ja-javascript.html' title='C# ja JavaScript'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-6181197347734737653</id><published>2008-05-18T12:48:00.000-07:00</published><updated>2008-05-19T14:13:43.534-07:00</updated><title type='text'>Flash 10 beta</title><content type='html'>Flash 10:nen ei vielä ole virallisesti julkaistu, mutta nyt jo hätäisemmät pääsevät sitä kokeilemaan. Tätä varten tarvitaan Flex3 Nightly Build Thu May 15, 2008 tai uudempi &lt;a href="http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3"&gt;linkki&lt;/a&gt;. Muista myös ennen asennusta poistaa vanha flash koneestasi &lt;a href="http://labs.adobe.com/technologies/flashplayer10/releasenotes.html#install"&gt;linkki&lt;/a&gt;. Asenna vanhan poistamisen jälkeen uusi Flash 10 beta player &lt;a href="http://labs.adobe.com/downloads/flashplayer10.html"&gt;linkki&lt;/a&gt;. Pura sdk paketti haluamaasi hakemistoon ja varmista, että sieltä löytyy seuraavaa filu FLEX_SDK/frameworks/libs/player/10/playerglobal.swc.&lt;br /&gt;&lt;br /&gt;Sitten vaikeampi osuus :).&lt;br /&gt;&lt;br /&gt;Sinun pitää käsin muuttaa flex-config.xml tiedostoa. Se löytyy [flex_root]\frameworks\flex-config.xml. Tee tiedostosta varmuuskopio ja avaa alkuperäinen xml tiedosto johonkin tekstieditoriin.&lt;br /&gt;Muuta tiedostoa seuraavasti.&lt;br /&gt;&lt;br /&gt;Muuta target-player tagi arvoon 10.0.0. Muuta viittaukset playeriin 9 arvoon {targetPlayerMajorVersion}. Eli libs/player/9/playerglobal.swc rivi libs/player/{targetPlayerMajorVersion}/playerglobal.swc. Näitä kohtia on tiedostossa kaksi external-library-path ja library-path.&lt;br /&gt;&lt;br /&gt;Nyt Flex on valmis kääntämään Flash 10 sälää. Jos haluat käyttää Flash Developia tarvitset uuden FD buildin &lt;a href="http://flashdevelop.org/downloads/builds/FD3_Debug_rev2297.rar"&gt;FlashDevelop 3 SVN build from rev. 2297&lt;/a&gt;. Aseta se käyttämään uutta Flexiä ja lisää projektin External Libraries listaan [flex_root]\frameworks\libs\player\10\playerglobal.swc tiedosto. Tarvitset enää Flash 10 playerin IE:lle ja voit tehdä Flash 10 ohjelmia Flash Developilla.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flashdevelop.org/community/viewtopic.php?t=3039"&gt;Ohje englanniksi Flash Developin foorumilla.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-6181197347734737653?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/6181197347734737653/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=6181197347734737653' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/6181197347734737653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/6181197347734737653'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/05/flash-10-beta.html' title='Flash 10 beta'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-7938372704683963986</id><published>2008-05-12T14:09:00.000-07:00</published><updated>2008-05-12T14:33:59.343-07:00</updated><title type='text'>PaperVision 3D</title><content type='html'>Koska rasterointi pikseli pikseliltä on Flashilla erittäin hidasta pitää Flashin kanssa kikkailla, jotta pystytään renderoimaan 3d kamaa ruudulle. Tähän tarkoitukseen on olemassa useita 3d-moottoreita, jotka suoriutuvat tehtävästä jotakuinkin. Yksi näistä on suosittu PV3D, joka on ns. "skew rendaaja". Useimmat Flash 3d-enginet ovat skew rendaajia. Tämä on matemaattisesti oikeaa 3d:tä, mutta se on silti "huijausta". Mitään ei oikeasti rasteroida, joten emme tiedä pikselien 3d koordinaatteja paitsi verteksien kohdalla. Tästä johtuen emme voi mm. perspektiivikorjata tekstuureita. Syvyysdatan puute aiheuttaa myös paljon muitakin rajoituksia joita tosin joitain voidaan kiertää. Skew nimitys tulee tavasta jolla tekstuurit rendataan. Flash ei tue perspektiivitekstuureja, mutta spritejä voidaan skewata. Eli rotaatoimme ja skewaamme spriten sopivaan asentoon ja leikkaamme siitä polyn tarvitsevan osan ja piirrämme tämän polyn kohdalle. Näin saadaan aikaan tektuurit, mutta ilman perspektiivikorjausta, joka näkyy isoissa polyissa teksturen vääristymisenä. Jotkut enginet tosin dynaamisesti tesselloi polyja jolloin vääristyminen vähenee, mutta ei kuitenkaan kokonaan katoa. Oikea tapa tehdä 3d-moottori olisi rasterointi, josta olemmekin tässä blogissa puhuneet, mutta flashin tehot eivät siihen vielä riitä. Tässä kuitenkin tulevaisuuden varalle open source 3d rasteroija &lt;a href="http://drawlogic.com/2008/04/11/as3-swfz-source-code-goes-open-source/"&gt;http://drawlogic.com/2008/04/11/as3-swfz-source-code-goes-open-source/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Tällä kertaa kuitenkin on tarkoitus kokeilla PaperVisionia. Teemme sillä upean pyörivän laatikon :). Olen varma, että tulette hämmästymään lopputuloksen upeutta, mutta tarkoitus on kokeilla miten PV3D saadaan käyttökuntoon ei pörhistellä graafisilla hienouksilla.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.verajankorva.com/blog/HelloCube.swf"&gt;http://www.verajankorva.com/blog/HelloCube.swf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Kuten huomaatte tekstuurit vääristyvät laatikon pyöriessä. Tämä johtuu juuri mainituista syistä ja laatikkoa ei dynaamisesti tesselloida pienempiin polyihin niin vääristyminen näkyy hyvin selvästi.&lt;br /&gt;&lt;br /&gt;Koodi tähän on erittäin simppeliä ja suurempi haaste on saada PV3D sorsat donattua :).&lt;br /&gt;&lt;br /&gt;Lähdekoodi &lt;a href="http://www.verajankorva.com/blog/HelloCube.as"&gt;http://www.verajankorva.com/blog/HelloCube.as&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-7938372704683963986?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/7938372704683963986/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=7938372704683963986' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/7938372704683963986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/7938372704683963986'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/05/papervision-3d.html' title='PaperVision 3D'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-3977366027202281842</id><published>2008-05-07T03:07:00.000-07:00</published><updated>2008-05-08T04:24:39.783-07:00</updated><title type='text'>Flashin suorituskyky</title><content type='html'>AS3 on sanottu olevan nopemapi kuin AS2. Se on totta, mutta AS3 ei silti tee Flashista nopeaa. Se on edelleen hidas ja jää pahasti jalkoihin vaikka Javalle. Tästä huolimatta Flash tuntuu olevan suositumpi (jumala yksin tietää miksi). No kun kerran Flashia halutaan niin koodataan sitten sitä. Ensin on kuitenkin syytä tietää missä pullonkaulat ovat.&lt;br /&gt;&lt;br /&gt;Kokeilin ensin perus matikkakamat. Laskutoimitukset tehty 10 000 000 kertaa ja katsottu miten kauan meni. Tuloksia.&lt;br /&gt;&lt;br /&gt;Kertolasku: 858ms&lt;br /&gt;Jakolasku: 809ms&lt;br /&gt;Potenssilasku: 931ms&lt;br /&gt;Bittien siirto: 932ms&lt;br /&gt;Miinuslasku: 821ms&lt;br /&gt;Pluslasku: 817ms&lt;br /&gt;Pluslasku integer: 815ms&lt;br /&gt;&lt;br /&gt;Tulokset ovat varsin hämmentäviä ja varsinkin jakolaskun nopeus. Tämä ei vertaa mittaa toimitusten nopeutta esim. verrattuna Javaan tai C++:aan, mutta tämä kertoo mikä on hidasta ja nopeaa Flashin sisällä. Yleisesti jakolasku on hidas, mutta Flashissa se tuntuu olevan nopein. Samoin myös bittien siirto ja pontessilasku on liki samalla viivalla mikä on myös melko erikoista. Flash tekee selvästi jotain hyvin  eri tavalla kuin useimmat ohjelmointikielet, mutta tämän testin valossa plus, miinus, kerto ja jakolasku ovat kaikki yhtä kalliita flashille. Bittien siirtely ei myöskään tuo lisänopeutta potenssilaskuun nähden. Erityisen harmillista koska nyt koodin optimointi on taas vähän vaikeampaa. Oikeastaan tämän testin valossa pitäisi suosia jakolaskua, joka kuulostaa hyvin väärältä, mutta siltä se vaikuttaisi :).&lt;br /&gt;&lt;br /&gt;Sanotaan selvyyden ja pahan olon vuoksi, että kertolasku testi kestää C#:lla 16ms ja Flashilla siis 858ms. Eli C# on tässä noin 53 kertaa nopeampi. Voisi tuon perusteella sanoa, että esim. peli joka pyörii 20fps flashilla pyörisi noin 1060fps C#:lla. Ei ole yhtään kivaa, että Flash on niin suosittu :(.&lt;br /&gt;&lt;br /&gt;Nopeuksia ehtolauseiden käytöstä. Tässä sama juttu kuin yllä eli operaatiot on tehty 10 000 000 kertaa ja mitattu niiden viemä aika.&lt;br /&gt;&lt;br /&gt;1 kierron mittainen for lause: 905ms&lt;br /&gt;If lause: 822ms&lt;br /&gt;Switch/Case lause: 1271ms&lt;br /&gt;&lt;br /&gt;Dynaaminen muistin varaus. Mitattu samalla tavalla kuin aikaisemminkin.&lt;br /&gt;&lt;br /&gt;2 muuttujan luominen: 1199ms&lt;br /&gt;2 muuttujan arvon vaihtaminen: 1193ms&lt;br /&gt;Luokan luominen, jossa 2 muuttujaa: 9586ms&lt;br /&gt;&lt;br /&gt;Tässä kohtaa on erityisen tärkeää huomata, että luokan luonti on todella runsaasti hitaampaa. Eli jos olet ajatellut tehdä vaikka XY luokan, jota käytät joka pikselissä niin se on todella huono idea :). Kannattaa enemmin tehdä kaksi muuttujaa X ja Y. Eli vältä pieniä luokkia aina kun se on mahdollista. Ei kuitenkaan kannata mennä liiallisuuksiin ja tehdä koodista epäselvää vain siksi, että yrittää välttää luokkia. Muuttujan luomisella tai muuttujan arvon asettamisella ei tunnu olevan juuri eroja.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-3977366027202281842?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/3977366027202281842/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=3977366027202281842' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/3977366027202281842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/3977366027202281842'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/05/flashin-suorituskyky.html' title='Flashin suorituskyky'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-1666927074878059352</id><published>2008-05-06T13:09:00.000-07:00</published><updated>2008-12-10T17:26:58.814-08:00</updated><title type='text'>Kolmion rasterointi</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_OL7dnwBevhY/SCFP0d_w_cI/AAAAAAAAACU/y94Mh7qXD8I/s1600-h/tri01.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_OL7dnwBevhY/SCFP0d_w_cI/AAAAAAAAACU/y94Mh7qXD8I/s320/tri01.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5197523207786134978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Kuvan mukaisen kolmion täyttäminen yhdellä värillä ei ole niin helppoa miltä se kuulostaa. Toki Flash tarjoaa tähän valmiin funktion, mutta se funktio ei kelpaa meille enää siinä vaiheessa kun haluamme täyttää polygonin tekstuurilla perspektiivikorjattuna. Tästä syystä meidän on kirjoitettava oma poly filleri, jota voimme kehittää eteenpäin.&lt;br /&gt;Tähän on monia tapoja, mutta tässä esittelen tavallisemman tavan, jossa polygoni täytetään vetämällä polygonin reunasta reunaan vaakaviivoja (scanline). En oikeastaan tiedä millä nimellä tätä algoritmia kutsutaan, mutta sanon sitä nyt vaikka scanline rasteriksi.&lt;br /&gt;Eli kolmio on muoto jossa on kolme sivua (edge) ja kolme kärkipistettä (vertex).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_OL7dnwBevhY/SCFQIt_w_dI/AAAAAAAAACc/07q14xn9-4k/s1600-h/tri02.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_OL7dnwBevhY/SCFQIt_w_dI/AAAAAAAAACc/07q14xn9-4k/s320/tri02.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5197523555678485970" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Homma toimii siten, että interpoloimme A-&gt;B välin jolloin saamme AB reunan ja interpoloimme A-&gt;C välin jolloin saamme AC reunan ja interpoloimme B-&gt;C ja saadaan BC reuna. Sitten vedellään vaakaviivoja AB ja AC reunojen välille ja saadaan täytetty yläosa.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_OL7dnwBevhY/SCFQm9_w_eI/AAAAAAAAACk/tydJismuUcA/s1600-h/tri03.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_OL7dnwBevhY/SCFQm9_w_eI/AAAAAAAAACk/tydJismuUcA/s320/tri03.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5197524075369528802" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sama BC ja AC välille ja saadaan myös fillattu alaosa. Näin koko kolmio on täytetty.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_OL7dnwBevhY/SCFQ49_w_fI/AAAAAAAAACs/teYkIN39-K0/s1600-h/tri04.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_OL7dnwBevhY/SCFQ49_w_fI/AAAAAAAAACs/teYkIN39-K0/s320/tri04.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5197524384607174130" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Tämän toiminnallisuuden kirjoittaminen koodilla ei ole aivan triviaalia, mutta se ennemminkin hiukan työlästä ja ikävää kuin vaikeaa.&lt;br /&gt;Kolmio siis rasteroidaan kahdessa osassa. Tämä siksi että haluamme kolmion yhden sivun olevan suora, joka helpottaa vaakaviivojen piirtoa ja ennen kaikkea nopeuttaa niiden piirtoa. Vaakaviivahan on hyvin helppo piirtää. Meidän pitää vain kasvattaa X arvoa yhdellä kunnes ollaan loppupisteessä. Tämä on siis yksinkertainen plus lasku.&lt;br /&gt;Eli aloitetaan kolmion halkaisusta. Tässä ei oikeastaan ole mitään hankalaa. Meidän pitää vain varmistaa, että verteksit ovat y suunnassa laskevassa järjestyksessä eli A on ylin piste ja C alin piste. Itse halkaisu käy ikään kuin itsestään.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var t:Point = null;&lt;br /&gt;if (A.y &gt; B.y)&lt;br /&gt;{&lt;br /&gt; t = A;&lt;br /&gt; A = B;&lt;br /&gt; B = t;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (B.y &gt; C.y)&lt;br /&gt;{&lt;br /&gt; t = B;&lt;br /&gt; B = C;&lt;br /&gt; C = t;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if (A.y &gt; C.y)&lt;br /&gt;{&lt;br /&gt; t = A;&lt;br /&gt; A = C;&lt;br /&gt; C = t;&lt;br /&gt;}   &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Kun tiedämme, että pisteet ovat oikeassa järjestyksessä voimme laskea polyn yläosan.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if (t.A.y != t.B.y)&lt;br /&gt;{&lt;br /&gt; var aex:Number = t.A.x;&lt;br /&gt; var aed:Point = new Point(t.B.x - t.A.x, t.B.y - t.A.y);&lt;br /&gt; var aes:Number = aed.x / aed.y;&lt;br /&gt; &lt;br /&gt; for (var i:int = t.A.y; i &lt; t.B.y; i++)&lt;br /&gt; {&lt;br /&gt;  aex += aes;&lt;br /&gt;  cex += ces;&lt;br /&gt;  &lt;br /&gt;  var x1:int = aex;&lt;br /&gt;  var x2:int = cex;&lt;br /&gt;  drawScanline(new Point(x1, i), new Point(x2, i), _bmp);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Loogisesti jatkamme tästä piirtämällä myös alaosan.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if (t.B.y != t.C.y)&lt;br /&gt;{&lt;br /&gt; var bex:Number = t.B.x;&lt;br /&gt; var bed:Point = new Point(t.C.x - t.B.x, t.C.y - t.B.y);&lt;br /&gt; var bes:Number = bed.x / bed.y;&lt;br /&gt; &lt;br /&gt; for (i = t.B.y; i &lt; t.C.y; i++)&lt;br /&gt; {&lt;br /&gt;  bex += bes;&lt;br /&gt;  cex += ces;&lt;br /&gt;  &lt;br /&gt;  x1 = bex;&lt;br /&gt;  x2 = cex;&lt;br /&gt;  drawScanline(new Point(x1, i), new Point(x2, i), _bmp);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ja tässä koko koodi, joka näyttää kaikki tarpeelliset yksityiskohdat.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.verajankorva.com/blog/polyraster.rar"&gt;Lataa lähdekoodi&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-1666927074878059352?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/1666927074878059352/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=1666927074878059352' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/1666927074878059352'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/1666927074878059352'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/05/kolmion-rasterointi.html' title='Kolmion rasterointi'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_OL7dnwBevhY/SCFP0d_w_cI/AAAAAAAAACU/y94Mh7qXD8I/s72-c/tri01.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-7578036631918889438</id><published>2008-01-25T09:32:00.000-08:00</published><updated>2008-12-10T17:26:59.130-08:00</updated><title type='text'>Pikselin piirtoa</title><content type='html'>Kun nyt olemme alkaneet puhua 3d:stä niin meidän pitää puhua myös pikseleistä, koska ilman niitä emme saa aikaan kunnon 3d:tä. Toki jonkinlaista saadaan rendattua ilman pikseleitäkin, mutta ongelmia tulee. Varsinkin teksturoidessa ja Z-bufferin kanssa. Teksturointi vielä joten kuten onnistuu, mutta Z-Buffer on mahdoton ilman pikseleitä ja vaihtoehdoksi jää Z-Sort, joka ei toimi kunnolla. Tästä syystä Sandyn ja Papervisionin polyt napsahtelee eikä piirry aina oikein.&lt;br /&gt;&lt;br /&gt;Ongelma kuitenkin on, että flash on hidas tuhertamaan pikseleitä. Nyt kuitenkin meillä on AS3 ja sen kehuttu huima nopeus käytössämme, joten testataan millä vahudilla pikseliä ruutuun saadaan ja millä tavalla saadaan niitä sinne nopeitein.&lt;br /&gt;&lt;br /&gt;Tässä siis testiä parista eri tavasta piirtää pikseleitä. Testit piirtää kuvan mukaisen kuvan 10 kertaa ja laskee keskiarvon kokonaispiirtoajasta. Testikoneena Intel dual core 1.86GHz, 2GB ja GeForce 7600 GT.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_OL7dnwBevhY/R5pUJtghAUI/AAAAAAAAABM/loN8t9mkco0/s1600-h/pixelBench.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer;" src="http://4.bp.blogspot.com/_OL7dnwBevhY/R5pUJtghAUI/AAAAAAAAABM/loN8t9mkco0/s320/pixelBench.jpg" alt="" id="BLOGGER_PHOTO_ID_5159528848917856578" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Testi 1:&lt;/span&gt; Pikselin piirtoa joka pikselille setPixel() methodilla.&lt;br /&gt;&lt;a href="http://www.verajankorva.com/blog/pixelbench1.swf" target="blank"&gt;pixelBench1.swf&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.verajankorva.com/blog/pixelbench1.fla" target="blank"&gt;pixelBench1.fla&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Keskimääräinen piirtoaika: 24.4ms&lt;br /&gt;FPS: 40.98&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Testi 2:&lt;/span&gt; Pikselit kirjoitetaan ensin byteArray objektiin josta se piirretään kerralla bitmapData objektiin ja näytetään ruudulla.&lt;br /&gt;&lt;a href="http://www.verajankorva.com/blog/pixelbench2.swf" target="blank"&gt;pixelBench2.swf&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.verajankorva.com/blog/pixelbench2.fla" target="blank"&gt;pixelBench2.fla&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Keskimääräinen piirtoaika: 22.6ms&lt;br /&gt;FPS: 44.25&lt;br /&gt;Parannusta testiin 1: 7.38%&lt;br /&gt;Tämä testi koossa 640*480 vei aikaa 92ms eli fps oli 10.87.&lt;br /&gt;Jos poistamme jakolaskut for-looppien sisältä saamme nipistettyä piirtoajan 68.6ms fps 14.58.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Testi 3:&lt;/span&gt; Sama kuin testi 2, mutta tällä kertaa emme luo bytearrayta joka kerta uudestaan vaan käytämme samaa arrayta. Tämä ei yllättäen nopeuttanut mitään. Tosin matikkaa tarvittiin vähän lisää, josta johtunee tuo hidastuminen. Yleensä kuitenkin muistin varaaminen dynaamisesti on hidasta ja jota pitäisi välttää, mutta tässä kohtaa ei niin näytä olevan. Kenties flash sisäisesti käsittelee bytearrayta niin ettei tästä ole hyötyä.&lt;br /&gt;&lt;a href="http://www.verajankorva.com/blog/pixelbench3.swf" target="blank"&gt;pixelBench3.swf&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.verajankorva.com/blog/pixelbench3.fla" target="blank"&gt;pixelBench3.fla&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Keskimääräinen piirtoaika: 28.6ms&lt;br /&gt;FPS: 34.97&lt;br /&gt;&lt;br /&gt;Huomaamme että versio 2 on nopein, mutta sekin on kuitenkin todella hidas ja aivan liian hidas jotta voisimme piirtää sillä oikeaa 3d grafiikka reaaliaikaisesti. Eli joudumme edelleen AS3 ajallakin välttelemään pikselin piirtoa ainakin minun koneellani :(.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-7578036631918889438?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/7578036631918889438/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=7578036631918889438' title='2 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/7578036631918889438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/7578036631918889438'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/01/pikselin-piirtoa.html' title='Pikselin piirtoa'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_OL7dnwBevhY/R5pUJtghAUI/AAAAAAAAABM/loN8t9mkco0/s72-c/pixelBench.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-3825255594461952665</id><published>2008-01-18T11:21:00.000-08:00</published><updated>2008-01-25T03:51:31.749-08:00</updated><title type='text'>3D-grafiikkaohjelmointia Flashilla.</title><content type='html'>Tämä on varsinainen mammuttiaihe, joten tulemme puhumaan tästä osissa aika ajoin tällä blogilla.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;Oletan että kaikki lukijat tietävät mitä on 3d, joten ei juuri yritä selittää mikä on kolmiuloitteinen avaruus tai -malli. Myös perustieto 3d grafiikasta on erittäin suositeltavaa.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;3D&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;Tietokoneen monitori on 2d-taso eli siihen ei voi piirtää 3d-pistettä. Tästä syystä 3d-piste on ensin projisoitava 2d-tasolle, jotta voit piirtää sen ruudulle. Piste pitää kuitenkin ensin transformoida eli siirtää oikeaan paikkaan ennen projisointia. Tämä projisointi tehdään 3d-mallin jokaiselle geometria verteksille, jonka jälkeen saisimme aikaan mallin josta osaamme piirtää verteksit.&lt;br /&gt;&lt;br /&gt;Jos yhdistät pisteet viivalla oikeassa järjestyksessä saat aikaan wireframe mallin eli rautalankamallin.&lt;br /&gt;&lt;br /&gt;Jos täytät viivojen rajaamat alueet saat solidface mallin. Tällöin mallisi olisi kuitenkin tasaisen yksi värinen.&lt;br /&gt;&lt;br /&gt;Jos lisäät ohjelmaasi varjostuslaskentaa saat aikaan varjostetun 3d-mallin. Varjostustapoja onkin sitten monia, mutta alkuun kannattaa opetella joku yksinkertainen kuten esim. Z-Flat.&lt;br /&gt;&lt;br /&gt;Varjostuksesta on luonnollista siirtyä tekstuureihin, joka on Flashilla hankala toteuttaa. Se on kuitenkin mahdollista rotailemalla ja skewaamalla kuvaa sopivasti. Tästä tulee kuitenkin ongelmia isojen polygonien kanssa johon palaamme myöhemmin. Sanotaan kuitenkin, että ongelmana on ettei tekstuureja ole perspektiivikorjattu. Ongelmaa voidaan vähentää tesseloimalla polygonia, mutta tämä on kuitenkin vain purkkaviritelmä, joka ei oikeasti kunnolla toimi, mutta korjaa kyllä ongelmaa jonkin verran. Palataan tähän aiheeseen kun oikeasti asiaa käsittelemme.&lt;br /&gt;&lt;br /&gt;Kun olemme käsitelleet yllä olevat asiat alkaa sinulla ollakin jo melko hyvä pohja 3d-ohjelmoinnissa. Paljon kuitenkin jää asioita opittaviksi tämänkin jälkeen, mutta aloitetaan ensin aivan alusta.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Pisteen projisointi&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;Pisteen projisointi 2d-tasolle on helppoa. Se vaatii vain kaksi yksinkertaista laskukaavaa.&lt;br /&gt;sx = x*256/z&lt;br /&gt;sy = y*256/z&lt;br /&gt;&lt;br /&gt;Näin siis projisoimme 3d pisteen 2d pisteeksi. Luku 256 on katselupisteen etäisyys projisoitavasta pinnasta.&lt;br /&gt;&lt;br /&gt;Nyt periaatteessa osaisit tehdä 3d starfieldin. :)&lt;br /&gt;&lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="320" height="240" id="starfield" align="middle"&gt;&lt;br /&gt;&lt;param name="allowScriptAccess" value="sameDomain" /&gt;&lt;br /&gt;&lt;param name="allowFullScreen" value="false" /&gt;&lt;br /&gt;&lt;param name="movie" value="http://www.verajankorva.com/blog/starfield.swf" /&gt;&lt;param name="quality" value="high" /&gt;&lt;param name="bgcolor" value="#000000" /&gt; &lt;embed src="http://www.verajankorva.com/blog/starfield.swf" quality="high" bgcolor="#000000" width="320" height="240" name="starfield" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.verajankorva.com/blog/starfield.fla"&gt;Starfield.fla&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Starfield on varmasti yksinkertaisin 3d-ohjelma mitä on, mutta siinä tulee projisio hyvin tutuksi. Jatketaan tästä seuraavalla kerralla.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-3825255594461952665?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/3825255594461952665/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=3825255594461952665' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/3825255594461952665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/3825255594461952665'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/01/3d-grafiikkaohjelmintia-flashilla.html' title='3D-grafiikkaohjelmointia Flashilla.'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-6044570423059638124</id><published>2008-01-16T23:08:00.001-08:00</published><updated>2008-01-16T23:58:21.533-08:00</updated><title type='text'>Binääritiedostojen lukeminen Flashilla.</title><content type='html'>Jatketaan binääritiedostoilla. Virheellisesti viime postauksessa väitin ettei binääritiedostoja voi lukea Flashilla. Kyllähän niitä voikin ja se helpottaa taas kummasti elämää.&lt;br /&gt;&lt;br /&gt;Binääritiedoston lukeminen on jonkin verran vaikeampaa, kuin normaalin ascii muotoisen tiedoston lukeminen, joita ovat mm. tekstitiedostot ja xml-tiedostot. Tekstitiedostoissa ei sinänsä ole mitään vikaa, mutta ne alkavat viedä melkoisesti tilaa, jos niihin tallennetaan paljon dataa. Binääritiedostot on taas mahdollista saada paljon pienempään tilaan ja sitä pidän erityisen tärkeänä varsinkin internetissä.&lt;br /&gt;&lt;br /&gt;Binääritiedostoa ei kuitenkaan voi lukea, jos et tiedä tiedostoformaattia. Tässä tapauksessa teemme formaatin itse joten tietysti myös tiedämme millainen se on. En käy tässä varsinaisesti läpi miten hoidamme homman UV rendaajassa vaan käydään läpi ihan perustasolla miten nämä binääritiedostot toimivat Flashissa. Palaamme UV rendaajaan vielä myöhemmin tässä blogissa.&lt;br /&gt;&lt;br /&gt;Tein scriptin 3dsmaxissa, joka kirjoittaa yksinkertaisen binääritiedoston.&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;00h&lt;/span&gt; 4 byte integer&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;04h&lt;/span&gt; 4 byte integer&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;08h&lt;/span&gt; 4 byte float&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;0Ch&lt;/span&gt; 4 byte float&lt;br /&gt;Tällaisen binääritiedoston lukeminen Flashilla ei ole erityisen vaikeaa.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;// ActionScript 3.0&lt;br /&gt;&lt;br /&gt;import flash.net.URLLoader;&lt;br /&gt;import flash.net.URLRequest;&lt;br /&gt;import flash.utils.ByteArray;&lt;br /&gt;&lt;br /&gt;var cURLLoader:URLLoader = new URLLoader(null);&lt;br /&gt;var cURLRequest:URLRequest = new URLRequest(null);&lt;br /&gt;&lt;br /&gt;cURLLoader.addEventListener(Event.COMPLETE, cURLLoader_onComplete);&lt;br /&gt;&lt;br /&gt;cURLLoader.dataFormat = URLLoaderDataFormat.BINARY;&lt;br /&gt;cURLRequest.url = "test.bin";&lt;br /&gt;&lt;br /&gt;cURLLoader.load(cURLRequest);&lt;br /&gt;&lt;br /&gt;function cURLLoader_onComplete(event:Event):void&lt;br /&gt;{&lt;br /&gt;    var byteArray:ByteArray = cURLLoader.data;&lt;br /&gt;    byteArray.endian = Endian.LITTLE_ENDIAN;&lt;br /&gt;    byteArray.position = 0;&lt;br /&gt;    trace (byteArray.readInt());&lt;br /&gt;    trace (byteArray.readInt());&lt;br /&gt;    trace (byteArray.readFloat());&lt;br /&gt;    trace (byteArray.readFloat());     &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Ellet kuitenkaan ole tutustunut juurikaan binääritiedostojen lukemiseen flashilla niin tuo voi näyttää vähän mystiseltä. Eli käydään koodi läpi.&lt;br /&gt;&lt;br /&gt;Importoidaan tarvittavat kirjastot.&lt;br /&gt;&lt;pre&gt;import flash.net.URLLoader;&lt;br /&gt;import flash.net.URLRequest;&lt;br /&gt;import flash.utils.ByteArray;&lt;/pre&gt;&lt;br /&gt;Luodaan URLLoader -ja URLRequest oliot, jota käytämme tiedostomme lataamiseen. URLLoader osaa ladata tiedostot binäärimuotoisena. URLRequest on URLLoaderin vaatima luokka, jolla määritellään URL osoite. Alustamme kummankin luokan muodostimen parameterin arvolla null.&lt;br /&gt;&lt;pre&gt;var cURLLoader:URLLoader = new URLLoader(null);&lt;br /&gt;var cURLRequest:URLRequest = new URLRequest(null);&lt;/pre&gt;&lt;br /&gt;Lisätään cURLLoader oliolle tapahtumakuuntelija tapahtumaan COMPLETE, joka lähetetään kun tiedosto on ladattu.&lt;br /&gt;&lt;pre&gt;cURLLoader.addEventListener(Event.COMPLETE, cURLLoader_onComplete);&lt;/pre&gt;&lt;br /&gt;Asetetaan cURLLoader olion data tyypiksi tai formaatiksi binääri ja cURLRequest oliolle kerrotaan URL, josta ladattava tiedosto löytyy.&lt;br /&gt;&lt;pre&gt;cURLLoader.dataFormat = URLLoaderDataFormat.BINARY;&lt;br /&gt;cURLRequest.url = "test.bin";&lt;/pre&gt;&lt;br /&gt;Ladataan tiedosto cURLLoader oliolla.&lt;br /&gt;&lt;pre&gt;cURLLoader.load(cURLRequest);&lt;/pre&gt;&lt;br /&gt;Function cURLLoader_onCompelete määrittely. Tätä funktiota kutsutaan kun tiedosto on ladattu muistiin.&lt;br /&gt;&lt;pre&gt;function cURLLoader_onComplete(event:Event):void&lt;/pre&gt;&lt;br /&gt;Pyydetään cURLLoader luokalta sen ByteArray olio, joka sisältää tiedoston datan binäärimuodossa. Asetetaan endian vastaamaan tiedoston endiania, joka tässä tapauksessa on little endian. Lopuksi varmistetaan, että ollaan datan alussa.&lt;br /&gt;&lt;pre&gt;var byteArray:ByteArray = cURLLoader.data;&lt;br /&gt;byteArray.endian = Endian.LITTLE_ENDIAN;&lt;br /&gt;byteArray.position = 0;&lt;/pre&gt;&lt;br /&gt;Sitten luetaan tiedostoformaatin mukaisesti ensin kaksi 4 tavuista inttiä ja sitten kaksi 4 tavuista floattia.&lt;br /&gt;&lt;pre&gt;trace (byteArray.readInt());&lt;br /&gt;trace (byteArray.readInt());&lt;br /&gt;trace (byteArray.readFloat());&lt;br /&gt;trace (byteArray.readFloat());&lt;/pre&gt;&lt;br /&gt;Siinäpä se olikin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-6044570423059638124?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/6044570423059638124/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=6044570423059638124' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/6044570423059638124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/6044570423059638124'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/01/binritiedostot.html' title='Binääritiedostojen lukeminen Flashilla.'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-3446306286540638636</id><published>2008-01-08T12:54:00.001-08:00</published><updated>2008-12-10T17:27:00.033-08:00</updated><title type='text'>UV datan pakkaaminen kuvaan</title><content type='html'>Haluaisitko flash ohjelman jossa 3d-animaation pintatekstuureja voisi muuttaa. Voisit esim. tehdä renderoidun kuvan huoneesta ja muuttaa huoneen seinien tapetit ja vaihtaa lattian. Mikä olisi erityisen hienoa voisit laittaa seinälle minkä tahansa tapettikuva tai vaikka oman naamasi jos siltä jostain syystä tuntuu :).&lt;br /&gt;&lt;br /&gt;Koska flashin tehot eivät riitä "kunnolliseen" oikeaan 3d-renderointiin (joka olisi tietysti ideaalista) olisi erityisen mieluisaa saada edes 3d-mallin tai scenen UV-koordinaatit flashiin per pikseli. Tämä mahdollistaisi 3d-mallien tekstuurien vaihtamisen ilman, että 3d-mallia tarvitsee oikeasti renderoida ja vieläpä perspektiivi korjattuna. Lisäksi tällä tavalla 3d-mallin polygonimäärällä ei ole merkitystä, joten 3d-malli voi sisältää miljoonia polygoneja, jos niin tahdot.&lt;br /&gt;&lt;br /&gt;Niinpä tein 3D Studio Maxilla scriptin, joka tallensi renderoidun kuvan jokaisen pikselin UV-koordinaatit ja kirjoitti ne tekstitiedostoon. Ongelmaksi tuli hyvin nopeasti tekstitiedoston kasvava koko, joten aloin kirjoittaa data binäärimuotoisena. Tämä korjasi koko ongelmaa jossain määrin, mutta yllätyin melkoisesti huomatessani ettei flashilla voinut lukea binäärimuotoisia tiedostoja. Niinpä päätin pakata UV-datan kuvaan, joita flash lukee kiltisti eikä minun edes tarvitse kirjoittaa omaa tiedostoformaattia.&lt;br /&gt;&lt;br /&gt;Itse UV-koordinaattien pakkaaminen kuvaan ei ole kovin hankalaa. Periaatteessa normaaliin PNG kuvaan voi tallentaa mitä tahansa 32 bittistä tietoa, koska jokainen neljä kanavaa (ARGB) on 8 bittisiä. ARGB kuvat kuitenkin alkavat viedä ikävästi tilaa ja kestävät ladata palvelimelta, joten päätin tyytyä 24 bittiseen tarkkuuteen eli R, G ja B kanaviin.&lt;br /&gt;&lt;br /&gt;Ajatellaan UV-koordinaatistoa 24bit 2d-matriisina jolloin sen koko on 256^3 = 16777216.  Koska haluamme matriisista yhtä leveän kuin korkeankin saamme leveyden laskettua seuraavasti Math.sqrt(16777216) = 4096. Tämän perusteella voimme sanoa, että maksimi tektuuriresoluutio on 4096*4096 pikseliä. Toki sen kokoinen tekstuuri veisi melkoisesti tilaa, mutta se on tällä systeemillä maksimi koko.&lt;br /&gt;Meillä on siis 4096*4096 kokoinen matriisi eli 4096 numeroa U koordinaatille ja 4096 numeroa V koordinaatille. UV:t on kuitenkin usein yksikkövektoreita joten ne pitää skaalata meidän rangellemme U*4096 ja V*4096. Lopuksi vielä pyöristämme U:n ja V:n kokonaisluvuksi. Näin meillä on kaksi kokonaislukua jotka voimme pakata yhdeksi luvuksi näin V*4096+U. Nyt meillä on yksi luku jonka voimme jo kirjoittaa kuvaan. Kuvaformaattien lukijat tietysti luulevat, että numero tarkoittaa RGB arvoa ja piirtää siksi melko erikoisia kuvia.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_OL7dnwBevhY/R4xdihNBkYI/AAAAAAAAAAs/No4Osvn5_vc/s1600-h/uv02.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://2.bp.blogspot.com/_OL7dnwBevhY/R4xdihNBkYI/AAAAAAAAAAs/No4Osvn5_vc/s320/uv02.jpg" alt="" id="BLOGGER_PHOTO_ID_5155598521042309506" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;UV koordinaatit pakattuna kuvaan.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Meitä ei kuitenkaan kiinnosta miltä kuva näyttää vaan data jota kuvassa on. Lukemalla pikselin arvon voimme purkaa siitä UV:t seuraavasti.&lt;br /&gt;V = Math.floor(pikselin_arvo / 4096.0)&lt;br /&gt;U = (pikselin_arvo / 4096.0) - V&lt;br /&gt;V = V / 4096.0&lt;br /&gt;Näin meillä on jälleen samat UV:t (pienin pyöristyseroin), kuin alussa niitä kuvaan pakattaessa. Ja nyt voimme piirtää tekstuurin haluamastamme kuvasta.&lt;br /&gt;X = U*tekstuurikuvan_leveys&lt;br /&gt;Y = V*tekstuurikuvan_korkeus&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_OL7dnwBevhY/R4xgMBNBkZI/AAAAAAAAAA0/3uQ9uTNMk9M/s1600-h/laketexture.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://4.bp.blogspot.com/_OL7dnwBevhY/R4xgMBNBkZI/AAAAAAAAAA0/3uQ9uTNMk9M/s320/laketexture.jpg" alt="" id="BLOGGER_PHOTO_ID_5155601433030136210" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;Tekstuurikuva&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ja tein vielä ohjelman joka lukee UV arvot kuvasta piirtää kuvan teksturoimalla sen tekstuurikuvalla.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_OL7dnwBevhY/R4xg6hNBkaI/AAAAAAAAAA8/KgsIAkAQczA/s1600-h/rend01.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://2.bp.blogspot.com/_OL7dnwBevhY/R4xg6hNBkaI/AAAAAAAAAA8/KgsIAkAQczA/s320/rend01.jpg" alt="" id="BLOGGER_PHOTO_ID_5155602231894053282" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;font-size:85%;" &gt;Pakatun UV datan mukaan piiretty kuva.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Koska itse renderointi on lineaarista tulee kuvaan pientä epätarkuutta, mutta ajatus kuitenkin näyttää toimivan. Seuraavaksi sitten on vuorossa enemmän itse koodia niin flashin kuin 3dsmax scriptinkin osalta. Tällä kertaa kuitenkin pysytellään näin teoriassa.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-3446306286540638636?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/3446306286540638636/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=3446306286540638636' title='4 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/3446306286540638636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/3446306286540638636'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/01/uv-datan-pakkaaminen-kuvaan.html' title='UV datan pakkaaminen kuvaan'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_OL7dnwBevhY/R4xdihNBkYI/AAAAAAAAAAs/No4Osvn5_vc/s72-c/uv02.jpg' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8771189832108270235.post-6894276923517498625</id><published>2008-01-08T12:46:00.000-08:00</published><updated>2008-01-08T12:53:26.840-08:00</updated><title type='text'>Blogi avattu</title><content type='html'>Tarkoitus tällä blogilla ei ole keskittyä yhteen tarkasti rajattuun alueeseen vaan tarkoitus on puhua laajemmalta alueelta vastaan tulevista ongelmista ja niiden ratkomisesta. Mikään tässä blogissa esitetty ratkaisutapa ei välttämättä ole oikea tai paras tapa, mutta se on eräs vaihtoehto kyseisen asian tekemiseen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8771189832108270235-6894276923517498625?l=xcxsblog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xcxsblog.blogspot.com/feeds/6894276923517498625/comments/default' title='Lähetä kommentteja'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8771189832108270235&amp;postID=6894276923517498625' title='0 kommenttia'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/6894276923517498625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8771189832108270235/posts/default/6894276923517498625'/><link rel='alternate' type='text/html' href='http://xcxsblog.blogspot.com/2008/01/blogi-avattu.html' title='Blogi avattu'/><author><name>xcx</name><uri>http://www.blogger.com/profile/09985321968378660916</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='07905616883482046357'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry></feed>