tag:blogger.com,1999:blog-53580093553831195122024-02-06T21:51:27.275-08:00XNA-UK: Randomchaos ArchiveCharles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.comBlogger198125tag:blogger.com,1999:blog-5358009355383119512.post-8041248467047648952016-06-08T12:28:00.000-07:002016-06-08T12:28:45.220-07:00Source Example 6 - Fog SM 1.1 to 2<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/NdPEhjL9ufo?feature=player_embedded' frameborder='0'></iframe></div>
<br />
This example shows the use of shader model 1.1 - 2 methodology for fog by
using the render states.<br />
<br />
<b>Controls</b><br />
Mouse to rotate camera.<br />
Arrow Keys to translate
camera.<br />
F1 Switch Fog On.<br />
F2 Switch Fog Off.<br />
<br />
<a href="http://www.randomchaos.co.uk/tutorials/xna/archive/RC3DEFogSample1.zip">RC3DEFogSample1.zip</a><a href="http://xna-uk.net/files/folders/randomchaos/entry1073.aspx"></a>Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com2tag:blogger.com,1999:blog-5358009355383119512.post-82936955243050775372016-06-08T12:26:00.000-07:002016-06-08T12:26:41.233-07:00Source Example 4 - Terrain<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/WDzWlKpa07o?feature=player_embedded' frameborder='0'></iframe></div>
<br />
So onto terrain, this example uses a height map 128X128 and is configured to
use Riemers origional terrain shader (modified for the engine). Also included in
this example are my terrain shaders along with the modified bump maped versions
of these shaders and the associated textures.<br />
<br />
It also gives an example of the terrain picking and collision, again this
is quite basic.<br />
<br />
<b>Controls</b><br />
Mouse to rotate the camera.<br />
Arrow keys to translate
the camera.<br />
Right click to drop the terrains height and left to raise
it.<br />
Keys 1-4 select a terrain shader<br />
<br />
<li>1 - Reimers Terrain Shader
</li>
<li>2 - My Terrain Shader
</li>
<li>3 - Reimers Terrain Shader with Bump Mapping
</li>
<li>4 - My Terrain Shader with Bump Mapping</li>
Escape to exit.<br />
<br />
<a href="http://www.randomchaos.co.uk/tutorials/xna/archive/RC3DETerrainExample1.zip">RC3DETerrainExample1.zip</a>Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com2tag:blogger.com,1999:blog-5358009355383119512.post-77403854456822230162016-06-08T12:25:00.000-07:002016-06-08T12:25:32.433-07:00Source Example 2 - Scene Picking & Targets<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/m2qyoLI598k?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<blockquote>
Moving on from example 1 but sticking with the Model and Scene class, this
example shows how to apply picking objects from the scene and also how to apply
a targeting reticle to a model using the Get2DCoors method.<br />
<br />
For this to be done I have added the RandomchaosContentPipelineManager to
the project, this gives the model class the ability to use the bounding box
data.<br />
<br />
You will see in the example screen above that the target reticle is not
in the center of the model, this is because the skullocc.x file has it's center
at the bottom of the model. I have also noticed a bug with the targeting code,
if you target a model then rotate the camera 180 degrees away, you get the
target reticle behind you.<br />
<br />
Again to ensure the download works, you will have to reference the
Randomchaos3Engine.dll and the RandomchaosContentPipelineManager.dll, the later
is done by right clicking the project name in the project explorer, select
properties, select the Content Pipeline tab remove the current setting and
replace with the path you have for the dll on your system.<br />
<br />
<a href="http://www.randomchaos.co.uk/tutorials/xna/archive/RC3DEModelExample2.zip">RC3DEModelExample2.zip</a><br />
<br />
If you have any comments or issues with this example, please post them
here :)<br />
<h5>
</h5>
<a href="http://xna-uk.net/blogs/randomchaos/archive/2007/10/15/source-example-1-basic-model.aspx#"></a></blockquote>
Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com2tag:blogger.com,1999:blog-5358009355383119512.post-30684876722883320352012-10-04T07:53:00.001-07:002012-10-04T07:53:23.424-07:00Fancy playing with C++ and DirectX 11<p>Well I am starting out down that road too, my C++ is rusty, I know little about DX11, but what the hell, you have to start somewhere right? So if you fancy trying your hand at it to, check out my first post on the <a href="http://randomchaosdx11adventures.blogspot.co.uk/2012/06/lets-go.html">subject</a>.</p> Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-31826138328628707202012-10-04T07:52:00.003-07:002012-10-04T07:52:57.372-07:00Heads up!<p>As we have seen over the past few days, the future of this site seems uncertain, and so I have decided to archive my historical posts I have here; and have started to move them to a new blogspot blog which you can find <a href="http://xnauk-randomchaosblogarchive.blogspot.co.uk/">here</a> should this site go. <p>I am also starting to take a look at DirectX11 with C++, and have started a new blog <a href="http://randomchaosdx11adventures.blogspot.co.uk/">here</a>, so if you are interested in this area of development, then please feel free to pop by, take a look at what I am up to and comment as much as you like :) <p>I would also like to keep bloging about XNA as I love it so much, so I am intending to continue that <a href="http://randomchaosxnaadventures.blogspot.co.uk/">here</a>. <p>To all of you that have followed, commented and helped my out over my time here and with XNA, I thank you so very, very much, without you guys I would not have discovered so much, and to all the people I have met at events and user group meets, it has been a pleasure to have known such an enthusiastic and nice bunch of guys. <p>Thanks, <p>Charles.</p> Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-5245898007273894842012-10-04T07:52:00.001-07:002012-10-17T12:25:29.358-07:002D Crepuscular (God) RaysIf you follow my blog, you know I have already covered this as a 3D implementation, well while having a nose on twitter, I spotted that <a href="https://twitter.com/#!/x35mm">x35mm</a> (another XNA developer from the midlands :D) was writing what looked like a pretty cool hack and slash Ronin game for DBP, and I thought, that would look nice with some God rays to give it some more lighting details, so sent x35mm my 2D implementation of the God ray post process, and this is what he did with it: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://s8.postimage.org/7e8xjn9gl/rays002.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="166" src="http://s8.postimage.org/7e8xjn9gl/rays002.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://s8.postimage.org/vgpreiq3p/rays001.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="166" src="http://s8.postimage.org/vgpreiq3p/rays001.jpg" width="320" /></a></div>
<br />
<br />
Pretty cool eh :D <br />
So, I am going to post here this 2D implementation. Keep in mind that this effect will not work on the WP7 device as it uses custom shaders to do what it needs to do, might have a look at a CPU implementation, but I reckon it will suck. <br />
<strong>Overview</strong> <br />
If you refer back to my <a href="http://xna-uk.net/blogs/randomchaos/archive/2011/09/15/crepuscular-god-rays-and-web-ui-sample.aspx">post</a> on this for 3D you will see all the same shaders, the difference in this 2D sample is the way the light mask is built. Effectively you need to render your light source, over that render the elements in your scene that are obscuring that source over the top in black to create the light mask, then apply the Crepuscular post processing effect. Then render the scene as you would normaly and then using an additive blend apply the god ray’s over the top. <br />
<strong>1. Draw Light Source</strong> <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_mAFEQR3RbJ-qiV9mmBCZBQeRxjjB1AB9wW535LiFIuXfXz5JdZ17vUYIQ-13pAfEntg0lGk-GGYCLR676a7vaU21UjZXwBnoLcgAKZxgu7r6476WxlY1UXXndit8fj_Z0444yutm6S8I/s1600/7444.image_3CED382F.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="163" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_mAFEQR3RbJ-qiV9mmBCZBQeRxjjB1AB9wW535LiFIuXfXz5JdZ17vUYIQ-13pAfEntg0lGk-GGYCLR676a7vaU21UjZXwBnoLcgAKZxgu7r6476WxlY1UXXndit8fj_Z0444yutm6S8I/s320/7444.image_3CED382F.png" width="320" /></a></div>
<br />
Here the post processor is rendering the light mask at the position we want on the screen, as you can see I have put up a few keyboard controls you can use to alter the parameters to the effect, so you can move the light source around, alter the exposure, stuff like that. <br />
<strong>2. Draw Light Mask</strong> <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGlgcxXgNwa7QUPudLluGZ7LyhAtyh22mHJ4AuEfzMj_t27Tai7o9-MgJjvNO-ZxrpTP1ZQB-q1DAYcPkDAlgjM1R0jbHS7XkSXAjO687d3O84nhDOZunsf1lDUQ63xj3PaSaATFPSSoGD/s1600/7357.image_61DDFB04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="163" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGlgcxXgNwa7QUPudLluGZ7LyhAtyh22mHJ4AuEfzMj_t27Tai7o9-MgJjvNO-ZxrpTP1ZQB-q1DAYcPkDAlgjM1R0jbHS7XkSXAjO687d3O84nhDOZunsf1lDUQ63xj3PaSaATFPSSoGD/s320/7357.image_61DDFB04.png" width="320" /></a></div>
<br />
There are a few items in this scene, a number of “mountain” images which are just wrap able textures and a samurai head icon for my mouse pointer, all png’s so we can use the alpha channel on them to allow light to bleed through. The post process is then applied to this to make the light bleed past the edges of the mask to give the god ray effect. <br />
<strong>3. Draw Scene</strong> <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBoblG_KGHdOXw9mlolwgooRaUg3r7xo3sgTzUdcUkuiBEUwdUZHGCvvlnOExqDYXSK3BwrSqtYEwo9N4h4Pp7MXUOICMZuj59V5hd1e77DPSar81hhLMcrX7o3MMHedaNopU4AljQ-5_a/s1600/0511.image_79453710.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="163" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBoblG_KGHdOXw9mlolwgooRaUg3r7xo3sgTzUdcUkuiBEUwdUZHGCvvlnOExqDYXSK3BwrSqtYEwo9N4h4Pp7MXUOICMZuj59V5hd1e77DPSar81hhLMcrX7o3MMHedaNopU4AljQ-5_a/s320/0511.image_79453710.png" width="320" /></a></div>
<br />
The scene is then drawn ready to be blended with the processed mask. <br />
<strong>4. Combine Scene and Ray Images</strong> <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTobMFceQCByiz8-XaOfIh6d2LbhlRPObORoqBkbqgjGU0GydY42uNCQV7_diz4A97bxvKuzxP4rn9suMzcinAGvlrpbo_SxWGaMLXQe0EgvK1x6nO4YLESeHiMNkUZwcriCvSVrhmpC0d/s1600/7853.image_07DFBD29.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="163" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTobMFceQCByiz8-XaOfIh6d2LbhlRPObORoqBkbqgjGU0GydY42uNCQV7_diz4A97bxvKuzxP4rn9suMzcinAGvlrpbo_SxWGaMLXQe0EgvK1x6nO4YLESeHiMNkUZwcriCvSVrhmpC0d/s320/7853.image_07DFBD29.png" width="320" /></a></div>
<br />
Finally it’s all brought together to give the overall effect. <br />
<strong>5. Animate It</strong> <br />
<div class="wlWriterEditableSmartContent" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:2cef3834-5be0-4f96-9388-b30a03cebc35" style="display: block; float: none; margin-left: auto; margin-right: auto; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; width: 425px;">
<embed height="350" src="http://www.youtube.com/v/w_VYUhIsvlE" type="application/x-shockwave-flash" width="425" wmode="transparent"></embed></div>
So I am scrolling the mountains at different speeds to give the sense of movement over the terrain and moving the mouse icon to obscure the light showing how dynamic this technique is. Also at the same time altering the parameters as I go. <br />
As you can see it renders at a good frame rate, 60fps, and this is at 900x1440 on my laptop. I have not personally ran this sample on my 360, buy x35mm has I believe. <br />
Check out Dawn of the Ronin (pre god rays) <a href="http://www.youtube.com/watch?v=JB9ECirVkuI">here</a>. <br />
The solution for this sample can be found <a href="http://www.randomchaos.co.uk/Tutorials/XNA/Archive/Randomchaos2DGodRaysOrg.zip">here</a>.<br />
I have also made an update to this so that the effect takes screen resolution into account <a href="http://www.randomchaos.co.uk/Tutorials/XNA/Archive/Randomchaos2DGodRays.zip">here</a>.<br />
If you use this technique in your work, please let me know, be cool to see it used in the real world, just like x35mm has done in his game.Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com42tag:blogger.com,1999:blog-5358009355383119512.post-56357263390522557332012-10-04T07:48:00.003-07:002012-10-04T07:48:51.481-07:00XNA with BulletSharp Physics Engine<p>Did a quick clip to show the progress of my current engine as I have started to put a third party physics engine in. For years I have struggles and struggled with writing my own, with some success, but to be honest, I never could quite get it right. So I have took it on the chin and decided to go with a third party engine. I chose BulletSharp as it’s the physics engine used in <a href="http://www.stexcalibur.com/">ST Excalibur</a>. In this clip I have the engine with a load of cubes, a sphere and terrain. As expected the lighting is deferred, with a single shadow casting light source.</p> <div style="padding-bottom: 0px; padding-left: 0px; width: 425px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:d7862ef5-c03f-4a06-b88a-5db7790218f7" class="wlWriterEditableSmartContent"><embed src="http://www.youtube.com/v/yCL_EpB46BA" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></div> Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-72055262017355616972012-10-04T07:48:00.001-07:002012-10-05T06:17:02.330-07:00Simple Active Tiles using XNA on WP7So another quick post I want to do is on using active tiles in XNA, or rather how you instantiate them in you WP7 application using XNA, like in the last post we have to have the assets in the project rather than the content project. <br />
So, simply enough I created a method called SetTile, this will create the active tile for you, so when your game is pinned it will display the tile and the information you want on it. I used the same sample I did last time to implement this so it’s all rolled in with the ringtone source.<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1eda79b4-d10e-4056-92bb-f7b80c8b703f" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: blue;">void</span> SetTile(<span style="color: blue;">string</span> title, <span style="color: blue;">string</span> data, <span style="color: blue;">string</span> tileAsset)<br />
{<br />
<span style="color: #2b91af;">ShellTile</span> tile = <span style="color: #2b91af;">ShellTile</span>.ActiveTiles.First();<br />
<br />
<span style="color: blue;">if</span> (tile != <span style="color: blue;">null</span>)<br />
{<br />
<span style="color: #2b91af;">StandardTileData</span> tileUpdate = <span style="color: blue;">new</span> <span style="color: #2b91af;">StandardTileData</span><br />
{<br />
BackTitle = title,<br />
BackContent = data,<br />
BackBackgroundImage = <span style="color: blue;">new</span> <span style="color: #2b91af;">Uri</span>(tileAsset, <span style="color: #2b91af;">UriKind</span>.Relative)<br />
};<br />
<br />
tile.Update(tileUpdate);<br />
}<br />
}</div>
</div>
</div>
So you could call the method like this:<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b1a687fd-b87e-4504-bf4b-2798342b1080" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px;">
SetTile(<span style="color: #a31515;">"Ringtones"</span>, <span style="color: #a31515;">"Play them or save them"</span>, <span style="color: #a31515;">"Tile.jpg"</span>);</div>
</div>
</div>
So, now when you pin your application you can get something like this when the tile flips: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1Wv20xXkeqm8DrW4K6YHPIBAsi6j_48cPmHae6uXawPU5SAQwP8KcEkPcRW_2xWv8Z3vmsWPg091o44C1rPHO6lzik1vK5meAmjXxSnIByP8DINV6BDJAiyYDKGJtNrQy99Wh_yOKi0yM/s1600/8015.image_1E743ECD.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1Wv20xXkeqm8DrW4K6YHPIBAsi6j_48cPmHae6uXawPU5SAQwP8KcEkPcRW_2xWv8Z3vmsWPg091o44C1rPHO6lzik1vK5meAmjXxSnIByP8DINV6BDJAiyYDKGJtNrQy99Wh_yOKi0yM/s320/8015.image_1E743ECD.png" width="170" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrjmgeyk30u1iLur_gtvlff8nwAk7LDl2mQwDfSykGn8lsfZOkCEIzAMELceN1qHYQK1L1A5UqP6JCVmsUFj1_trVKdl7vVmYVjygmm9yfPYQDLwQr6kSgwrYjaTWAkARSNbcmOyZMHsRu/s1600/0508.image_4EF6D511.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrjmgeyk30u1iLur_gtvlff8nwAk7LDl2mQwDfSykGn8lsfZOkCEIzAMELceN1qHYQK1L1A5UqP6JCVmsUFj1_trVKdl7vVmYVjygmm9yfPYQDLwQr6kSgwrYjaTWAkARSNbcmOyZMHsRu/s320/0508.image_4EF6D511.png" width="170" /></a></div>
<br />
<br />
<br />
Naturally you would have much better icons and messages on your tiles, but you could use this to show the players last high score, or there current progress in a currently saved game etc.. <br />
Source can be found <a href="http://xna-uk.net/media/p/8577.aspx">here</a> <strong><span style="color: red;">[Not Yet Uploaded]</span></strong> <br />
<br />
<br />
<br />
Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-28750322844096703752012-10-04T07:45:00.001-07:002012-10-05T06:20:14.728-07:00Ringtones on WP7 using XNASo, I did a sample for a friend a while back on how to add ringtones to a WP7 title that has been written in XNA. As we all know if you are writing it in Silverlight, there are plenty of samples out there, but I never spotted one for XNA. So I wrote this, as ever I may well be going about it in a cack handed manner, so please feel free to comment and/or correct anything you see in this post by adding a comment below. Thanks. <br />
For this sample, the first thing I did was create some ring tones, now I did this in a very simplistic manor, I got a copy of <a href="http://www.threechords.com/hammerhead/">Hammerhead</a> and just used a few samples off that, 4 ring tones. <br />
Now in XNA, we normally just throw our assets into the content pipeline and it sorts it all out for us, but due to the way MS have implemented ringtones we can’t just do that in XNA, we have to have them in the content pipeline as wav’s and as they are intended to be in the game project it’s self as mp3’s. This is all due to the lack of control XNA has compared with the Silverlight implementation over the MediaPlayer, read into that what you will… <br />
[EDIT]Just found <a href="http://mommysbest.blogspot.co.uk/2011/11/add-ringtones-to-xna-games-for-windows.html">this</a> post, which will get around this :S [/EDIT] <br />
So, with my 4 new super duper ring tones my project(s) look like this: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT_GFOMBqiQUzGmq_2JG7Z23BZOTi6m55OgC80IRm5By6JV22YyVMYZFnz8BKkSoKxhyJvfK63qY-V3WNo1BW2sBw21vo6EgyaM7Fq4zcq8lHkXL03AsG8r03y-2BL2C8iDrf0mPrPMfRe/s1600/3632.image_4ECAC55B.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT_GFOMBqiQUzGmq_2JG7Z23BZOTi6m55OgC80IRm5By6JV22YyVMYZFnz8BKkSoKxhyJvfK63qY-V3WNo1BW2sBw21vo6EgyaM7Fq4zcq8lHkXL03AsG8r03y-2BL2C8iDrf0mPrPMfRe/s320/3632.image_4ECAC55B.png" width="204" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<br />
Here is a quick shot of the code in my Update method<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2b970c5a-84a0-4d13-97b9-57c8f085ded8" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: green;">// Allows the game to exit</span><br />
<span style="color: blue;">if</span> (<span style="color: #2b91af;">GamePad</span>.GetState(<span style="color: #2b91af;">PlayerIndex</span>.One).Buttons.Back == <span style="color: #2b91af;">ButtonState</span>.Pressed)<br />
{<br />
<span style="color: green;">// If it's paused, start it back up again...</span><br />
<span style="color: blue;">if</span> (<span style="color: #2b91af;">MediaPlayer</span>.State == <span style="color: #2b91af;">MediaState</span>.Paused)<br />
<span style="color: #2b91af;">MediaPlayer</span>.Resume();<br />
<br />
<span style="color: blue;">this</span>.Exit();<br />
}<br />
<br />
<span style="color: green;">// First of all, and this is probably the only situation you can do this</span><br />
<span style="color: green;">// Pause the media player if it is playing, this will also pause the </span><br />
<span style="color: green;">// users own music, might be work you wanrning them before you enter</span><br />
<span style="color: green;">// your ring tone screen</span><br />
<span style="color: blue;">if</span> (<span style="color: #2b91af;">MediaPlayer</span>.State == <span style="color: #2b91af;">MediaState</span>.Playing)<br />
{<br />
<span style="color: #2b91af;">MediaPlayer</span>.Pause();<br />
}</div>
</div>
</div>
When playing your ring tones, you don’t want the media player playing at the same time, this situation is probably the only time you can just pause the media player… <br />
I am not going to go over the code that renders the ringtone options, just show you the method used to play and to save the ringtones to the device. <br />
<strong>Play a Ringtone</strong><br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:663173ea-d9a6-452a-906d-22ab2d6bddfe" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">class</span> <span style="color: #2b91af;">ScreenSprite</span> { }<br />
<span style="color: blue;">public</span> <span style="color: blue;">void</span> playThisRingTone(<span style="color: blue;">object</span> sender)<br />
{<br />
<span style="color: #2b91af;">ScreenSprite</span> thisRT = (<span style="color: #2b91af;">ScreenSprite</span>)sender;<br />
<br />
<span style="color: blue;">if</span> (playingRTNo != -1)<br />
{<br />
ringTonesText[playingRTNo].Shadow = <span style="color: blue;">true</span>;<br />
ringTonesText[playingRTNo].Color = <span style="color: #2b91af;">Color</span>.Red;<br />
}<br />
<br />
<span style="color: blue;">int</span> rt = <span style="color: blue;">int</span>.Parse(thisRT.Tag);<br />
playingRTNo = rt;<br />
<br />
<span style="color: green;">// Play the RT.</span><br />
<span style="color: blue;">if</span> (playingRT != <span style="color: blue;">null</span> && playingRT.State == <span style="color: #2b91af;">SoundState</span>.Playing)<br />
playingRT.Stop();<br />
<br />
playingRT = Content.Load<<span style="color: #2b91af;">SoundEffect</span>>(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"Audio/Ringtones/RingTone {0}"</span>, rt + 1)).CreateInstance();<br />
<br />
ringTonesText[rt].Shadow = <span style="color: blue;">false</span>;<br />
ringTonesText[rt].Color = <span style="color: #2b91af;">Color</span>.DarkRed;<br />
<br />
playingRT.Play();<br />
}</div>
</div>
</div>
The sender is the object that has been taped, so the play button for a given ring tone, this has a tag with the ring tone number to be played, you could put the full ring tone name in there if you liked. I then get that into a SoundEffect object and play it, this is a global SoundEffect object as I only want to play 1 at any given time and may want to stop it mid play.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAnfQpgTC1yUXCv4bpkryWh8ltd60VLA6H5K1kA1pARL3tC2HB5dTjcKXlJ2JCxCJ2Sw4NaXTZntJU-QQqX4Qj2NCzvbaHbiDmiUgAcLlryob-1Gth3Ihu5vnBElYbT9ogUplZqtWFlw8g/s1600/6303.image_0A5AAE4F.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAnfQpgTC1yUXCv4bpkryWh8ltd60VLA6H5K1kA1pARL3tC2HB5dTjcKXlJ2JCxCJ2Sw4NaXTZntJU-QQqX4Qj2NCzvbaHbiDmiUgAcLlryob-1Gth3Ihu5vnBElYbT9ogUplZqtWFlw8g/s320/6303.image_0A5AAE4F.png" width="320" /></a></div>
<br />
<br />
<strong>Save a Ringtone</strong><br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1475d415-a535-4613-a805-e2c07e6cb726" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: blue;">void</span> SaveRingTone(<span style="color: blue;">string</span> ringtone)<br />
{<br />
<span style="color: blue;">try</span><br />
{<br />
<span style="color: blue;">if</span> (!<span style="color: #2b91af;">Guide</span>.IsTrialMode)<br />
{<br />
SaveRingtoneTask srt = <span style="color: blue;">new</span> SaveRingtoneTask();<br />
srt.Completed += <span style="color: blue;">new</span> <span style="color: #2b91af;">EventHandler</span><TaskEventArgs>(srt_Completed);<br />
<br />
srt.Source = <span style="color: blue;">new</span> <span style="color: #2b91af;">Uri</span>(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"appdata:/{0}"</span>, ringtone));<br />
srt.DisplayName = <span style="color: #a31515;">""</span>;<br />
srt.IsShareable = <span style="color: blue;">true</span>;<br />
srt.Show();<br />
}<br />
<span style="color: blue;">else</span><br />
{<br />
dialogButtons.Clear();<br />
dialogButtons.Add(<span style="color: #a31515;">"OK"</span>);<br />
<br />
<span style="color: #2b91af;">Guide</span>.BeginShowMessageBox(<span style="color: #a31515;">"Trial Mode"</span>,<br />
<span style="color: #a31515;">"Purchase the full game to get the ringtones"</span>,<br />
dialogButtons, 0, <span style="color: #2b91af;">MessageBoxIcon</span>.Alert, <span style="color: blue;">null</span>, <span style="color: blue;">null</span>);<br />
}<br />
}<br />
<span style="color: blue;">catch</span> (<span style="color: #2b91af;">Exception</span> e)<br />
{<br />
dialogButtons.Clear();<br />
dialogButtons.Add(<span style="color: #a31515;">"OK"</span>);<br />
<br />
<span style="color: #2b91af;">Guide</span>.BeginShowMessageBox(<span style="color: #a31515;">"Error"</span>,<br />
e.Message,<br />
dialogButtons, 0, <span style="color: #2b91af;">MessageBoxIcon</span>.Alert, <span style="color: blue;">null</span>, <span style="color: blue;">null</span>);<br />
}<br />
}<br />
<br />
<span style="color: blue;">void</span> srt_Completed(<span style="color: blue;">object</span> sender, TaskEventArgs e)<br />
{<br />
<span style="color: blue;">switch</span> (e.TaskResult)<br />
{<br />
<span style="color: green;">//Logic for when the ringtone was saved successfully</span><br />
<span style="color: blue;">case</span> TaskResult.OK:<br />
dialogButtons.Clear();<br />
dialogButtons.Add(<span style="color: #a31515;">"OK"</span>);<br />
<br />
<span style="color: #2b91af;">Guide</span>.BeginShowMessageBox(<span style="color: #a31515;">"Ringtone Saved"</span>,<br />
<span style="color: #a31515;">"The ringtone was saved successfully"</span>,<br />
dialogButtons, 0, <span style="color: #2b91af;">MessageBoxIcon</span>.Alert, <span style="color: blue;">null</span>, <span style="color: blue;">null</span>);<br />
<br />
<span style="color: blue;">break</span>;<br />
<br />
<span style="color: green;">//Logic for when the task was cancelled by the user</span><br />
<span style="color: blue;">case</span> TaskResult.Cancel:<br />
<span style="color: blue;">break</span>;<br />
<br />
<span style="color: green;">//Logic for when the ringtone could not be saved</span><br />
<span style="color: blue;">case</span> TaskResult.None:<br />
dialogButtons.Clear();<br />
dialogButtons.Add(<span style="color: #a31515;">"OK"</span>);<br />
<br />
<span style="color: #2b91af;">Guide</span>.BeginShowMessageBox(<span style="color: #a31515;">"Can't Save.."</span>,<br />
<span style="color: #a31515;">"Can't save this ringtone"</span>,<br />
dialogButtons, 0, <span style="color: #2b91af;">MessageBoxIcon</span>.Alert, <span style="color: blue;">null</span>, <span style="color: blue;">null</span>);<br />
<span style="color: blue;">break</span>;<br />
}<br />
}</div>
</div>
</div>
The method to save a ring tone, first checks we are not in trial, and if not then allows the user to save the ringtone, this is why I put the mp3’s in the game project so they are accessible from “appdata:/”. The SaveRingToneTask Show method is then called: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY1aloCgUc6YP3tvZlLazipOV4tXVnWK39wO8ZU6ExbYX1EeHdMq3EZFrnfno1h07b5-P02ruggW0fdZsKOmFOEMtKkGqxullQNmdnQ4Wsz3ygAch1OL06k9fgqMBPzVnbAgEkTLGFS7nh/s1600/7853.image_62745C97.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="172" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY1aloCgUc6YP3tvZlLazipOV4tXVnWK39wO8ZU6ExbYX1EeHdMq3EZFrnfno1h07b5-P02ruggW0fdZsKOmFOEMtKkGqxullQNmdnQ4Wsz3ygAch1OL06k9fgqMBPzVnbAgEkTLGFS7nh/s320/7853.image_62745C97.png" width="320" /></a></div>
<br />
<br />
The srt_Completed call back method then informs the user if it’s all gone well. <br />
So that’s about it, my way of saving/playing ringtones on WP7 in XNA. As ever, comments are more than welcome… <br />
Source code can be found <a href="http://xna-uk.net/media/p/8577.aspx">here</a> <strong><span style="color: red;">[Not yet uloaded]</span></strong><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-78008135545104879332012-10-04T07:38:00.001-07:002012-10-05T06:21:41.842-07:00Android NDK Beginner’s Guide <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.packtpub.com/sites/default/files/1529EXP_Android%20NDK_cov.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://www.packtpub.com/sites/default/files/1529EXP_Android%20NDK_cov.jpg" width="259" /></a></div>
<br />
First thing that got me about this book was the comprehensive installation instructions, covering the installation of the JDK (Java Development Kit), Android SDK (Software Development Kit), Android NDK (Native Development Kit) and the IDE (Eclipse) across a number of platforms, Windows PC, Mac OS X and Linux PC. Now this it great as it’s sure to cover all those wanting to develop on this platform, but does lead to a lot of page skipping, but I guess that can’t be helped. <br />
Having already played with Eclipse and the Android SDK, I only had to install the NDK and refresh what I already had installed (indigo upgrade), but still it’s a lot of work to get this all lined up for Android development, really makes you appreciate Visual Studio and all it’s quirks. Another draw back as a VS developer is all the command line compilation, but once you are all set up you can then get into the book samples. <br />
Anyway, back to the book and it’s content, from the off you get to command line compile some samples and see them running on the Android, then into the IDE (Eclipse) and creating your first simple project in eight pretty simple steps. Then onto the C/C++ integration, now, it may well have been me but I found an issue when trying to set javah.exe up as described in the book, just in case you also have the same issue, here is the arguments string that I ended up using to generate my header file:<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:11e96aa9-e407-4237-9827-237ded015a9c" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px;">
-jni -verbose -d ${workspace_loc:/MyProject/jni} -classpath ${workspace_loc:/MyProject/bin/classes/} com.myproject.MyActivity</div>
</div>
</div>
Other than my own issues with Eclipse and the odd typo, I quite enjoyed playing with native code on the Android plat form, the book will show you how to pass data to and from your hybrid Java/C++ code, to creating a fully native application, rendering with OpenGL ES (which i am playing with now) as well as handling devices and sensors and even has a chapter for porting existing libraries to the Android platform. <br />
I think the only other suggestion I would have would be how the code is rendered, it may well be different in a physical book (I have an ebook) but it would have been nice if tabulation and syntax highlighting was used. Other than that I have enjoyed it :) <br />
<br />
<br />
<br />
Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com1tag:blogger.com,1999:blog-5358009355383119512.post-40133573881168412722012-10-04T07:36:00.003-07:002012-10-05T06:24:47.302-07:00Development Book ReviewI have recently come across a number of books that are published by <a href="http://www.packtpub.com/">Packt Publishing</a>, a couple related to XNA and one for the Android platform. All three perked my interest, the later as I have done a small amount of Android development for work in Java, but I started out as a C/C++ programmer so I thought it would be cool to check this book out as it covers Android development using C/C++ <br />
Here are the books I am going to cover in the next three posts. <br />
<h5>
<a href="http://www.packtpub.com/microsoft-xna-4-0-game-development-by-example-beginners-guide/book">XNA 4.0 Game Development by Example: Beginner's Guide – Visual Basic Edition</a></h5>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.packtpub.com/microsoft-xna-4-0-game-development-by-example-beginners-guide/book"><img border="0" src="http://cdn3.cf.packtpub.com/sites/default/files/imagecache/productview/2403EXP_XNA%204.0%20Game%20Developement%20by%20Example1.jpg" /></a></div>
<div>
<br /></div>
<br />
<h5>
<a href="http://www.packtpub.com/windows-phone-7-xna-game-cookbook/book">Windows Phone 7 XNA Cookbook</a></h5>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.packtpub.com/windows-phone-7-xna-game-cookbook/book"><img border="0" src="http://cdn1.cf.packtpub.com/sites/default/files/imagecache/productview/1208_Windows%20Phone%207%20XNA%20cookbook_cov.jpg" /></a></div>
<br />
<h5>
<a href="http://www.packtpub.com/android-ndk-beginners-guide/book">Android NDK Beginner’s Guide</a></h5>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.packtpub.com/android-ndk-beginners-guide/book"><img border="0" src="http://cdn2.cf.packtpub.com/sites/default/files/imagecache/productview/1529EXP_Android%20NDK_cov.jpg" /></a></div>
<div>
<br /></div>
<br />
Hope you find the reviews useful :) <br />
<br />
<br />
<br />
<br />
Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-80110330196846272242012-10-04T07:36:00.001-07:002012-10-04T07:36:18.659-07:00SSAO & Water as a Post Process: My worst video ever?<div style="padding-bottom: 0px; padding-left: 0px; width: 425px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:564c53de-905e-407d-a9c9-b7c84ab09953" class="wlWriterEditableSmartContent"><embed src="http://www.youtube.com/v/x4ZBGwhpvJg" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></div> <p>Possibly my worst video :S SSAO may not be right, water not finished and bad model port. But, it's where I am with these shaders. Would like to thank Ed for the model port so i could export it from Blender and Manzo for the music :) <p>As ever let me know what you think of it Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-36954471469968806092012-10-04T07:35:00.001-07:002012-10-04T07:35:17.253-07:00A Quick Note On Binary Serialization<p>So was playing about with Binary serialization, and think I have a nice base class you might want to use if you ever want serialize your classes. This is the base class</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7ab27393-a0fb-4b1f-b458-00292cfcbcb5" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">using</span> System;<br> <span style="color:#0000ff">using</span> System.Collections.Generic;<br> <span style="color:#0000ff">using</span> System.Linq;<br> <span style="color:#0000ff">using</span> System.Text;<br> <span style="color:#0000ff">using</span> System.Reflection;<br> <span style="color:#0000ff">using</span> System.Runtime.Serialization;<br> <span style="color:#0000ff">using</span> System.Runtime.Serialization.Formatters.Binary;<br> <span style="color:#0000ff">using</span> System.IO;<br> <br> <span style="color:#0000ff">namespace</span> SerializationXNA<br> {<br>     [<span style="color:#2b91af">Serializable</span>]<br>     <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">SerializableBase</span><T> : <span style="color:#2b91af">ISerializable</span><br>     {<br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> ctor</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"></summary></span><br>         <span style="color:#0000ff">public</span> SerializableBase() { }<br> <br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> ctor</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"></summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><param name="info"></span><span style="color:#008000">Data to be serialized</span><span style="color:#808080"></param></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><param name="context"></span><span style="color:#008000">Streaming context</span><span style="color:#808080"></param></span><span style="color:#008000">  </span><br>         <span style="color:#0000ff">public</span> SerializableBase(<span style="color:#2b91af">SerializationInfo</span> info, <span style="color:#2b91af">StreamingContext</span> ctxt)<br>             : <span style="color:#0000ff">this</span>()<br>         {<br>             <span style="color:#2b91af">PropertyInfo</span>[] properties = <span style="color:#0000ff">this</span>.GetType().GetProperties();<br> <br>             <span style="color:#0000ff">int</span> propertyCount = properties.Length;<br> <br>             <span style="color:#0000ff">for</span> (<span style="color:#0000ff">int</span> p = 0; p < propertyCount; p++)<br>                 properties[p].SetValue(<span style="color:#0000ff">this</span>, info.GetValue(properties[p].Name, properties[p].PropertyType), <span style="color:#0000ff">null</span>);<br>         }<br> <br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> Method to serialize the object</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"></summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><returns></returns></span><br>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">byte</span>[] Serialize(T objectInsatnce)<br>         {<br>             <span style="color:#2b91af">BinaryFormatter</span> formatter = <span style="color:#0000ff">new</span> <span style="color:#2b91af">BinaryFormatter</span>();<br> <br>             <span style="color:#2b91af">MemoryStream</span> memStream = <span style="color:#0000ff">new</span> <span style="color:#2b91af">MemoryStream</span>();<br>             formatter.Serialize(memStream, objectInsatnce);<br> <br>             <span style="color:#0000ff">byte</span>[] buffer = memStream.ToArray();<br>             memStream.Close();<br> <br>             <br> <br>             <span style="color:#0000ff">return</span> buffer;<br> <br>         }<br> <br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> Method to deserialize the object from a byte array</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"></summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><param name="buffer"></span><span style="color:#008000">byte array holding the serialized object</span><span style="color:#808080"></param></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><returns></span><span style="color:#008000">Deserialized instance of the object</span><span style="color:#808080"></returns></span><br>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> T Deserialize(<span style="color:#0000ff">byte</span>[] buffer)<br>         {<br>             <span style="color:#2b91af">BinaryFormatter</span> formatter = <span style="color:#0000ff">new</span> <span style="color:#2b91af">BinaryFormatter</span>();<br>             <span style="color:#2b91af">MemoryStream</span> memStream = <span style="color:#0000ff">new</span> <span style="color:#2b91af">MemoryStream</span>(buffer);<br> <br>             T retVal = (T)formatter.Deserialize(memStream);<br>             <br>             memStream.Close();<br> <br>             <span style="color:#0000ff">return</span> retVal;<br>         }<br> <br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> Needed to do binary serailization of this object</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"></summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><param name="info"></span><span style="color:#008000">Data to be serialized</span><span style="color:#808080"></param></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><param name="context"></span><span style="color:#008000">Streaming context</span><span style="color:#808080"></param></span><span style="color:#008000">  </span><br>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">virtual</span> <span style="color:#0000ff">void</span> GetObjectData(<span style="color:#2b91af">SerializationInfo</span> info, <span style="color:#2b91af">StreamingContext</span> context)<br>         {<br>             <span style="color:#2b91af">PropertyInfo</span>[] properties = <span style="color:#0000ff">this</span>.GetType().GetProperties();<br> <br>             <span style="color:#0000ff">int</span> propertyCount = properties.Length;<br> <br>             <span style="color:#0000ff">for</span> (<span style="color:#0000ff">int</span> p = 0; p < propertyCount; p++)<br>                 info.AddValue(properties[p].Name, properties[p].GetValue(<span style="color:#0000ff">this</span>, <span style="color:#0000ff">null</span>));<br>         }<br>     }<br> }</div> </div> </div> <p>Not a great deal in there other than it has to have the Serializable class attribute and implement the ISerializable interface and uses a generic in it’s definition, there are two constructors, the second needed for de-serialization. We then have Serialize and Deserialize statics, both methods do exactly what they say and then finally we implement the ISerializable method GetObjectData. <p>So pretty simple stuff, this is how you can then derive from this to then use all the lovely serialization stuff in the base class</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1e9d90c5-9f1a-4909-843e-f86153fd1692" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">using</span> System;<br> <span style="color:#0000ff">using</span> System.Collections.Generic;<br> <span style="color:#0000ff">using</span> System.Linq;<br> <span style="color:#0000ff">using</span> System.Text;<br> <span style="color:#0000ff">using</span> System.Runtime.Serialization;<br> <br> <span style="color:#0000ff">namespace</span> SerializationXNA<br> {<br>     [<span style="color:#2b91af">Serializable</span>]<br>     <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">SerializableClass</span> : SerializableBase<<span style="color:#2b91af">SerializableClass</span>><br>     {<br>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">bool</span> IsDirty { <span style="color:#0000ff">get</span>; <span style="color:#0000ff">set</span>; }<br>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">string</span> Name { <span style="color:#0000ff">get</span>; <span style="color:#0000ff">set</span>; }<br>         <span style="color:#0000ff">public</span> <span style="color:#2b91af">Dictionary</span><<span style="color:#0000ff">string</span>, <span style="color:#0000ff">object</span>> ObjDictionary { <span style="color:#0000ff">get</span>; <span style="color:#0000ff">set</span>; }<br>         <span style="color:#0000ff">public</span> <span style="color:#2b91af">List</span><<span style="color:#0000ff">string</span>> StringList { <span style="color:#0000ff">get</span>; <span style="color:#0000ff">set</span>; }<br> <br>         <span style="color:#0000ff">public</span> SerializableClass() <br>         {<br>             IsDirty = <span style="color:#0000ff">false</span>;<br>             Name = <span style="color:#0000ff">string</span>.Empty;<br>             ObjDictionary = <span style="color:#0000ff">new</span> <span style="color:#2b91af">Dictionary</span><<span style="color:#0000ff">string</span>, <span style="color:#0000ff">object</span>>();<br>             StringList = <span style="color:#0000ff">new</span> <span style="color:#2b91af">List</span><<span style="color:#0000ff">string</span>>();<br>         }<br> <br>         <span style="color:#0000ff">public</span> SerializableClass(<span style="color:#2b91af">SerializationInfo</span> info, <span style="color:#2b91af">StreamingContext</span> ctxt)<br>             : <span style="color:#0000ff">base</span>(info, ctxt)<br>         { }<br>     }<br> }</div> </div> </div> <p>As you can see a pretty simple class, has 4 properties and a couple of constructors, but as we have derived from SerializableBase class we get all the serializable goodness, so this is how you could implement it</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:45ceee83-7077-4af2-bb43-085a66fd6b82" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap">            <span style="color:#2b91af">SerializableClass</span> classToSerialize = <span style="color:#0000ff">new</span> <span style="color:#2b91af">SerializableClass</span>();<br> <br>             classToSerialize.IsDirty = <span style="color:#0000ff">true</span>;<br>             classToSerialize.Name = <span style="color:#a31515">"Date To serialize"</span>;<br>             classToSerialize.ObjDictionary.Add(<span style="color:#a31515">"One"</span>, <span style="color:#a31515">"One"</span>);<br>             classToSerialize.ObjDictionary.Add(<span style="color:#a31515">"Two"</span>, 3);<br>             classToSerialize.StringList.Add(<span style="color:#a31515">"Hello"</span>);<br>             classToSerialize.StringList.Add(<span style="color:#a31515">"World"</span>);<br> <br>             <span style="color:#0000ff">byte</span>[] buffer = <span style="color:#2b91af">SerializableClass</span>.Serialize(classToSerialize);<br> <br>             <span style="color:#2b91af">SerializableClass</span> deserializedClass = <span style="color:#2b91af">SerializableClass</span>.Deserialize(buffer);<br> <br>             deserializedClass.Name = <span style="color:#a31515">"Deserialized data"</span>;</div> </div> </div> <p>The great thing about this is that you can go and add as many properties as you like and you wont have to change any of the serialization code as it will automatically pick up the new properties :) <p><strong>EDIT</strong> <p>Just altered the base class so it’s now WP7 friendly, I guess you could go 100% with the DataContractSerializer though…</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:dcb244a1-62ea-431e-be5c-d5653d04cfe1" class="wlWriterEditableSmartContent"> <div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"> <div style="background-color: #ffffff; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap"><span style="color:#0000ff">using</span> System;<br> <span style="color:#0000ff">using</span> System.Collections.Generic;<br> <span style="color:#0000ff">using</span> System.Linq;<br> <span style="color:#0000ff">using</span> System.Text;<br> <span style="color:#0000ff">using</span> System.Reflection;<br> <span style="color:#0000ff">using</span> System.Runtime.Serialization;<br> <span style="color:#0000ff">#if</span> WINDOWS<br> <span style="color:#0000ff">using</span> System.Runtime.Serialization.Formatters.Binary;<br> <span style="color:#0000ff">#endif</span><br> <span style="color:#0000ff">using</span> System.IO;<br> <br> <span style="color:#0000ff">namespace</span> SerializationXNA<br> {<br> <span style="color:#0000ff">#if</span> WINDOWS<br>     [<span style="color:#2b91af">Serializable</span>]<br> <span style="color:#0000ff">#endif</span><br>     <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> <span style="color:#2b91af">SerializableBase</span><T> <br> <span style="color:#0000ff">#if</span> WINDOWS<br>         : <span style="color:#2b91af">ISerializable</span><br> <span style="color:#0000ff">#endif</span><br>     {<br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> ctor</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"></summary></span><br>         <span style="color:#0000ff">public</span> SerializableBase() { }<br> <br> <span style="color:#0000ff">#if</span> WINDOWS<br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> ctor</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"></summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><param name="info"></span><span style="color:#008000">Data to be serialized</span><span style="color:#808080"></param></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><param name="context"></span><span style="color:#008000">Streaming context</span><span style="color:#808080"></param></span><span style="color:#008000">  </span><br>         <span style="color:#0000ff">public</span> SerializableBase(<span style="color:#2b91af">SerializationInfo</span> info, <span style="color:#2b91af">StreamingContext</span> ctxt)<br>             : <span style="color:#0000ff">this</span>()<br>         {<br>             <span style="color:#2b91af">PropertyInfo</span>[] properties = <span style="color:#0000ff">this</span>.GetType().GetProperties();<br> <br>             <span style="color:#0000ff">int</span> propertyCount = properties.Length;<br> <br>             <span style="color:#0000ff">for</span> (<span style="color:#0000ff">int</span> p = 0; p < propertyCount; p++)<br>                 properties[p].SetValue(<span style="color:#0000ff">this</span>, info.GetValue(properties[p].Name, properties[p].PropertyType), <span style="color:#0000ff">null</span>);<br>         }<br> <span style="color:#0000ff">#endif</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> Method to serialize the object</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"></summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><returns></returns></span><br>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> <span style="color:#0000ff">byte</span>[] Serialize(T objectInsatnce)<br>         {<br> <span style="color:#0000ff">#if</span> WINDOWS<br>             <span style="color:#2b91af">BinaryFormatter</span> formatter = <span style="color:#0000ff">new</span> <span style="color:#2b91af">BinaryFormatter</span>();<br> <span style="color:#0000ff">#else</span><br> <span style="color:#808080">            DataContractSerializer formatter = new DataContractSerializer(typeof(T));</span><br> <span style="color:#0000ff">#endif</span><br> <br>             <span style="color:#2b91af">MemoryStream</span> memStream = <span style="color:#0000ff">new</span> <span style="color:#2b91af">MemoryStream</span>();<br> <span style="color:#0000ff">#if</span> WINDOWS<br>             formatter.Serialize(memStream, objectInsatnce);<br> <span style="color:#0000ff">#else</span><br> <span style="color:#808080">            formatter.WriteObject(memStream, objectInsatnce);</span><br> <span style="color:#0000ff">#endif</span><br>             <span style="color:#0000ff">byte</span>[] buffer = memStream.ToArray();<br>             memStream.Close();<br> <br>             <br> <br>             <span style="color:#0000ff">return</span> buffer;<br> <br>         }<br> <br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> Method to deserialize the object from a byte array</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"></summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><param name="buffer"></span><span style="color:#008000">byte array holding the serialized object</span><span style="color:#808080"></param></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><returns></span><span style="color:#008000">Deserialized instance of the object</span><span style="color:#808080"></returns></span><br>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">static</span> T Deserialize(<span style="color:#0000ff">byte</span>[] buffer)<br>         {<br> <span style="color:#0000ff">#if</span> WINDOWS<br>             <span style="color:#2b91af">BinaryFormatter</span> formatter = <span style="color:#0000ff">new</span> <span style="color:#2b91af">BinaryFormatter</span>();<br> <span style="color:#0000ff">#else</span><br> <span style="color:#808080">            DataContractSerializer fomratter = new DataContractSerializer(typeof(T));</span><br> <span style="color:#0000ff">#endif</span><br>             <span style="color:#2b91af">MemoryStream</span> memStream = <span style="color:#0000ff">new</span> <span style="color:#2b91af">MemoryStream</span>(buffer);<br> <br> <span style="color:#0000ff">#if</span> WINDOWS<br>             T retVal = (T)formatter.Deserialize(memStream);<br> <span style="color:#0000ff">#else</span><br> <span style="color:#808080">            T retVal = (T)fomratter.ReadObject(memStream);</span><br> <br> <span style="color:#0000ff">#endif</span> <br>             memStream.Close();<br> <br>             <span style="color:#0000ff">return</span> retVal;<br>         }<br> <span style="color:#0000ff">#if</span> WINDOWS<br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> Needed to do binary serailization of this object</span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"></summary></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><param name="info"></span><span style="color:#008000">Data to be serialized</span><span style="color:#808080"></param></span><br>         <span style="color:#808080">///</span><span style="color:#008000"> </span><span style="color:#808080"><param name="context"></span><span style="color:#008000">Streaming context</span><span style="color:#808080"></param></span><span style="color:#008000">  </span><br>         <span style="color:#0000ff">public</span> <span style="color:#0000ff">virtual</span> <span style="color:#0000ff">void</span> GetObjectData(<span style="color:#2b91af">SerializationInfo</span> info, <span style="color:#2b91af">StreamingContext</span> context)<br>         {<br>             <span style="color:#2b91af">PropertyInfo</span>[] properties = <span style="color:#0000ff">this</span>.GetType().GetProperties();<br> <br>             <span style="color:#0000ff">int</span> propertyCount = properties.Length;<br> <br>             <span style="color:#0000ff">for</span> (<span style="color:#0000ff">int</span> p = 0; p < propertyCount; p++)<br>                 info.AddValue(properties[p].Name, properties[p].GetValue(<span style="color:#0000ff">this</span>, <span style="color:#0000ff">null</span>));<br>         }<br> <span style="color:#0000ff">#endif</span> <br>     }<br> }</div> </div> </div> Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-39007893838660220112012-10-04T07:27:00.001-07:002012-10-05T06:43:15.854-07:00WP7 game/app talking to WCF Web ServicesThis post is taken from the discussion we had on the forum <a href="http://xna-uk.net/forums/t/1544.aspx">here</a>. So, the OP was asking about WCF web services and I replied with my 2 peneth and said I would write a blog post about it, and this is where I will start. <br />
<strong>Stuff You Will Need (Other than the dev tools)</strong> <br />
<ol>
<li>A host to serve your service </li>
<li>A registered domain with said host </li>
<li>An FTP client</li>
</ol>
<strong>Get a ASP.NET Host</strong> <br />
I use <a href="http://www.tsohost.co.uk/">TSOHost</a> for all my web hosting, have my domain registered with them and they also serve my <a href="http://www.randomchaos.co.uk/">web site</a> there. I chose these guys as at the time they gave all I needed in there <a href="http://www.tsohost.co.uk/windows_webhosting.php">basic package</a> for ASP.NET and must say I have not a bad word to say about them. Any tech issues I have had; they have responded and resolved in no time at all. Now if I was you, I wouldn’t just take these guys up, I would have a good look round first, make sure you get a good deal. <br />
<strong>Create Database</strong> <br />
So once you are registered, have your domain up and running, you will want to set up a DB on the server, now I can only show you how I do it with the host I use, it will differ if you use another company to host your site. <br />
From the dashboard the host provide me with I can get to my MySQL DB stuff and set up a new DB <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8zpXGGEoin6RPHmUdjtD1iiVw3rgikL28hUiOb1_ph3MGYxp5SpFe08gCw0JDgR8dg7AsnmquZOS92XqiTc_4xu7fsrF5ePXZwn01xebZEO26hjjkQsvIok2w8XqQ2EOJqzwzf8fxT_ab/s1600/6765.image_7A19BA07.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="37" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8zpXGGEoin6RPHmUdjtD1iiVw3rgikL28hUiOb1_ph3MGYxp5SpFe08gCw0JDgR8dg7AsnmquZOS92XqiTc_4xu7fsrF5ePXZwn01xebZEO26hjjkQsvIok2w8XqQ2EOJqzwzf8fxT_ab/s320/6765.image_7A19BA07.png" width="320" /></a></div>
<br />
<br />
This then gives me the server side IP address for the database so I can then connect to it from my service, we will need this later, don’t worry about it for now, just know we will need it later. <br />
I now need to set up a user for this DB, again from the control panel the host has provided I can do this. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuJD00O6CorruHsaQcpZqWMe8hOX9UFp9xLV2GFmHAq9-LrMLw6XMfgi5kTFqpxDm6s6eUpuxCB7YYlwQQciw4_gl-SqSmDtZNiGYrJ8GenSPgyj5kKGzoMFtFuPyGQha2gDBXMWPsEj10/s1600/8037.image41_thumb_7A75C72F.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="77" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuJD00O6CorruHsaQcpZqWMe8hOX9UFp9xLV2GFmHAq9-LrMLw6XMfgi5kTFqpxDm6s6eUpuxCB7YYlwQQciw4_gl-SqSmDtZNiGYrJ8GenSPgyj5kKGzoMFtFuPyGQha2gDBXMWPsEj10/s320/8037.image41_thumb_7A75C72F.png" width="320" /></a></div>
<br />
<br />
Now we have a database and a user that can access it, what we now need is a table that can be used to store data. Again from the hosts dashboard I can go and create a table in my new DB <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidPZvsxN8AT-N9SAgptXYDa08XqsfOZnL-f8IaNLR2VYAMA8_rraY2VCBoq1dnTOQyPPHIqIfcR5Tui0asf3qkRAnXQQRRhrmlO4m3A04KdvMMF6H-1yhLBDoHiYRkROI9Ow1Gysl13Dgv/s1600/6283.image23_thumb_5FC92B16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="40" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidPZvsxN8AT-N9SAgptXYDa08XqsfOZnL-f8IaNLR2VYAMA8_rraY2VCBoq1dnTOQyPPHIqIfcR5Tui0asf3qkRAnXQQRRhrmlO4m3A04KdvMMF6H-1yhLBDoHiYRkROI9Ow1Gysl13Dgv/s320/6283.image23_thumb_5FC92B16.png" width="320" /></a></div>
<br />
<br />
Now with the table created I need to create the columns that will be in it. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBthZiMogrKSqeCYh71M2i2cwNteRb9keRj2Kl8HiW0wVdk0LDjPqkU9rVulyqhERFyAi0PQzYt9wcCvojMDT2lO7B-ul7l3jD3ZP8f1UTrAxP2b76o6KdB1v3QIlxXmxcaWgMnfMDOsqx/s1600/5314.image35_thumb_71398BEE.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBthZiMogrKSqeCYh71M2i2cwNteRb9keRj2Kl8HiW0wVdk0LDjPqkU9rVulyqhERFyAi0PQzYt9wcCvojMDT2lO7B-ul7l3jD3ZP8f1UTrAxP2b76o6KdB1v3QIlxXmxcaWgMnfMDOsqx/s320/5314.image35_thumb_71398BEE.png" width="320" /></a></div>
<br />
<br />
So, my two columns are Country and Count. So we now have a table set up which will look something like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXjSCfjn8XHFntHyIgm2voV7yRZAbGIjfbWa2Ed_Grs4hR9QwOKBjt_fcwht_wkkNqFw1grifzVgSq3mxkszTYz3I85pSVwlTojNANcC93wmofniaa1ynMdL-bMI-jHsxfFaAuc1RtXabv/s1600/1588.image39_thumb_193C1541.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXjSCfjn8XHFntHyIgm2voV7yRZAbGIjfbWa2Ed_Grs4hR9QwOKBjt_fcwht_wkkNqFw1grifzVgSq3mxkszTYz3I85pSVwlTojNANcC93wmofniaa1ynMdL-bMI-jHsxfFaAuc1RtXabv/s320/1588.image39_thumb_193C1541.png" width="320" /></a></div>
<br />
<br />
<strong>Service Creation</strong> <br />
Now we need to create a web service to be hosted from our site and have access to the new DB and it’s table(s). We will also have to get some assemblies so we can connect and use a MySQL database, but lets get the basic service project going for now. <br />
Open up VS2010 and create a new Web Site, <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEReSoQojs35ywt0FPQfy4ks7CFdBj3WsDQy5c6cQwLaoFa3E146bYeWKbFpcldjbHvNxByRrvrPUrq57xSI5_6LEuLZ1uck_VoIGuKxqeWBgZX4IOeHn-N-_9_XD7qmvBJBOsPbgE58_a/s1600/6787.image26_thumb_0EAB1B54.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEReSoQojs35ywt0FPQfy4ks7CFdBj3WsDQy5c6cQwLaoFa3E146bYeWKbFpcldjbHvNxByRrvrPUrq57xSI5_6LEuLZ1uck_VoIGuKxqeWBgZX4IOeHn-N-_9_XD7qmvBJBOsPbgE58_a/s320/6787.image26_thumb_0EAB1B54.png" width="320" /></a></div>
<br />
<br />
As far as creating a WCF web service, you have just done it; it wont do what you want it to yet, but the default project comes with basic stubs so you could run it as it stands and it would run the service. But we don’t want that… <br />
<strong>Creating Web Methods</strong> <br />
So, we now want to give the service some methods so we can act on the database. First thing I am going to do is rename the source files to reflect this service better. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhytnPpXMCqE8b12AoETwaTXKKF51ufIktRYj5NjuOOw9HnXzgIEp0uGp32BItLqZQwncd8WOLd_P-PTrum2Is8NM3Cbz9eyBleiZ_60hg6v3wwfvTMAJ42sBSJAJIxyKDPThTKu5Tb3xZg/s1600/7851.image11_thumb_005C7C97.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="49" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhytnPpXMCqE8b12AoETwaTXKKF51ufIktRYj5NjuOOw9HnXzgIEp0uGp32BItLqZQwncd8WOLd_P-PTrum2Is8NM3Cbz9eyBleiZ_60hg6v3wwfvTMAJ42sBSJAJIxyKDPThTKu5Tb3xZg/s320/7851.image11_thumb_005C7C97.png" width="320" /></a></div>
<br />
<br />
I am also going to clear out all the stuff we don’t need from this project, all the template code can go really, so in the IRCTestService.cs (was IService.cs) I am removing everything from line 23 on wards, we wont be needing that data contract, we will create our own ones in a moment. I am also going to remove ALL the operational contracts from the interface in this file too, we now have a pretty naked looking file<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2b46cbed-8a41-42b8-be55-196b4da00641" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">using</span> System;<br />
<span style="color: blue;">using</span> System.Collections.Generic;<br />
<span style="color: blue;">using</span> System.Linq;<br />
<span style="color: blue;">using</span> System.Runtime.Serialization;<br />
<span style="color: blue;">using</span> System.ServiceModel;<br />
<span style="color: blue;">using</span> System.ServiceModel.Web;<br />
<span style="color: blue;">using</span> System.Text;<br />
<br />
<span style="color: green;">// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService" in both code and config file together.</span><br />
[ServiceContract]<br />
<span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: #2b91af;">IRCTestService</span><br />
{<br />
<br />
}</div>
</div>
</div>
But that’s how we want it, ready for us to put our functionality in it. Just so we have all our ducks in a row, clean out the RCTestService.cs file to so it looks like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:08fbac5d-6490-40dd-ae9c-91cf4ae68b1c" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">using</span> System;<br />
<span style="color: blue;">using</span> System.Collections.Generic;<br />
<span style="color: blue;">using</span> System.Linq;<br />
<span style="color: blue;">using</span> System.Runtime.Serialization;<br />
<span style="color: blue;">using</span> System.ServiceModel;<br />
<span style="color: blue;">using</span> System.ServiceModel.Web;<br />
<span style="color: blue;">using</span> System.Text;<br />
<br />
<span style="color: green;">// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service" in code, svc and config file together.</span><br />
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">RCTestService</span> : <span style="color: #2b91af;">IRCTestService</span><br />
{<br />
<br />
}</div>
</div>
</div>
Now, make sure that the RCTestService.svc (was Service.svc) file is using the right class now we have renamed it, like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5e94d10c-c021-45b3-b65e-bbd241996bd5" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px;">
<span style="background: #ffff00;"><%</span><span style="color: blue;">@</span> <span style="color: red;">ServiceHost</span> <span style="color: red;">Language</span><span style="color: blue;">="C#"</span> <span style="color: red;">Debug</span><span style="color: blue;">="true"</span> <span style="color: red;">Service</span><span style="color: blue;">="RCTestService"</span> <span style="color: red;">CodeBehind</span><span style="color: blue;">="~/App_Code/RCTestService.cs"</span> <span style="background: #ffff00;">%></span></div>
</div>
</div>
Before we can write our first web method we need to understand how we are going to package the data and send it to and from the client, this is done with data contracts, so the first data contract we want will have information in it that we want to have stored on the server. More importantly for me I like to have a base class for all my requests and responses, so lets first create a BaseRequest data contract. Create a new folder file in the App_Code folder and call it DataContracts (nice to keep tidy), then in there create a new class called RequestBase , make sure you specify that the class is a data contract (you have to type it in above the class definition) like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIjGT6VTtYsl2y9bXDhfCuyKb_UrGEsYX34Zzy5yNULwhrXKEqRfAFILPgjggkBqjGCE9YSm03yyZUOX3TB86j0jRcTB5Nv2msm4OHxbypRGGcn5NzIstQTxofIr4aOwuW54jSCdnsMhvx/s1600/1184.image15_thumb_7DD34AD8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="80" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIjGT6VTtYsl2y9bXDhfCuyKb_UrGEsYX34Zzy5yNULwhrXKEqRfAFILPgjggkBqjGCE9YSm03yyZUOX3TB86j0jRcTB5Nv2msm4OHxbypRGGcn5NzIstQTxofIr4aOwuW54jSCdnsMhvx/s320/1184.image15_thumb_7DD34AD8.png" width="320" /></a></div>
<br />
<br />
In this class I am going to have it store a user name and password, we won’t really be doing much validation as this is a simple project, but just to show you how you might want to set it up. So your RequestBase class should now look like this, note you have to specify that the members are Data Members<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a5e330d7-1c12-4ce9-88db-1ab9ca533086" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
[<span style="color: #2b91af;">DataContract</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">RequestBase</span><br />
{<br />
[<span style="color: #2b91af;">DataMember</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">string</span> UserName { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }<br />
<br />
[<span style="color: #2b91af;">DataMember</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">string</span> Password { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }<br />
<br />
<span style="color: blue;">public</span> RequestBase()<br />
{<br />
<span style="color: green;">//</span><br />
<span style="color: green;">// TODO: Add constructor logic here</span><br />
<span style="color: green;">//</span><br />
}<br />
}</div>
</div>
</div>
We now have a base request object, we are now going to create an UpdateRequest data contract, so we can send the client data to the service and it can be stored in the database. In the same folder as the RequestBase.cs file, create another new class called UpdateRequest.cs, derive from RequestBase and add in the fields we want to store in the DB, it should look something like this when you are done<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:d6d118cb-f75e-4393-b25e-1d1408deefaa" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
[<span style="color: #2b91af;">DataContract</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">UpdateRequest</span> : <span style="color: #2b91af;">RequestBase</span><br />
{<br />
[<span style="color: #2b91af;">DataMember</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">string</span> Country { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }<br />
<br />
<span style="color: blue;">public</span> UpdateRequest()<br />
{<br />
<span style="color: green;">//</span><br />
<span style="color: green;">// TODO: Add constructor logic here</span><br />
<span style="color: green;">//</span><br />
}<br />
}</div>
</div>
</div>
Now we need to add our first web method, in the interface (IRCTestService.cs) we are going to create our first method like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a4e91e26-0f66-46dc-b43a-ca6aefe4b5ba" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
[<span style="color: #2b91af;">ServiceContract</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: #2b91af;">IRCTestService</span><br />
{<br />
[<span style="color: #2b91af;">OperationContract</span>]<br />
<span style="color: blue;">void</span> UpdateServer(<span style="color: #2b91af;">UpdateRequest</span> request);<br />
}</div>
</div>
</div>
We then need to implement this in the service. I am also going to add in some very simple validation, naturally you would be a lot more exhaustive on a real server. Your RCTestService.cs should now look something like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:008aa714-00f1-4a91-82a0-bba4a8f2fbd6" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">RCTestService</span> : <span style="color: #2b91af;">IRCTestService</span><br />
{<br />
<span style="color: blue;">public</span> <span style="color: blue;">void</span> UpdateServer(<span style="color: #2b91af;">UpdateRequest</span> request)<br />
{<br />
<span style="color: blue;">if</span> (ValidRequest(request))<br />
{<br />
<span style="color: green;">// Do what we need to do</span><br />
}<br />
}<br />
<br />
<span style="color: blue;">private</span> <span style="color: blue;">bool</span> ValidRequest(<span style="color: #2b91af;">RequestBase</span> request)<br />
{<br />
<span style="color: blue;">return</span> <span style="color: blue;">true</span>;<br />
}<br />
}</div>
</div>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWuMfUZ6p6kruI57qxVafE0J9LpKYJbTddQUf2LGLxU7SlTxos5mvfB3wHyQWxoR-HD0-m9Cflg1L_4ot9sS2_0T7BHVwkDpPNu6dgR4xs0YHVvq2qTb7_RiA5nxf1AGrvMoJ55cWstcJ8/s1600/5488.image7_thumb_2DCD768D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="149" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWuMfUZ6p6kruI57qxVafE0J9LpKYJbTddQUf2LGLxU7SlTxos5mvfB3wHyQWxoR-HD0-m9Cflg1L_4ot9sS2_0T7BHVwkDpPNu6dgR4xs0YHVvq2qTb7_RiA5nxf1AGrvMoJ55cWstcJ8/s320/5488.image7_thumb_2DCD768D.png" width="320" /></a></div>
<br />
Hit OK, it’s so we can debug the service, we can remove this later, it just adds a setting to the web.config file. So you should then get a screen a little like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuDM7XhfFYVMUGWYO3Sh3ocKStXHR7TicVi7Hg3FvLYoysfG7DQjCCoO2dk5d7IjKkFIHQG_eIYMVVC74lPmA6YwLWNkcF6r7S5RHwhl_StyB_7s8SwnRKHtF_PiZKyESB9j7W2JDjwmHy/s1600/2664.image43_thumb_39BF40F4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="202" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuDM7XhfFYVMUGWYO3Sh3ocKStXHR7TicVi7Hg3FvLYoysfG7DQjCCoO2dk5d7IjKkFIHQG_eIYMVVC74lPmA6YwLWNkcF6r7S5RHwhl_StyB_7s8SwnRKHtF_PiZKyESB9j7W2JDjwmHy/s320/2664.image43_thumb_39BF40F4.png" width="320" /></a></div>
<br />
<br />
If you get a screen like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX_v0C5nDnPCcwKtJ8tz41sqa8T8jDVRycDz69UoEGTTjkxOONBmaWvHTYrTSnB1e9JqOEuI2SjClflWQ_FYbclW8ybLQUUGMWpIUvR5cTTKR7owVbakvCe80pdBOC1mbI69u7CbzJsYXo/s1600/3225.image11_thumb_68E106BE.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="142" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX_v0C5nDnPCcwKtJ8tz41sqa8T8jDVRycDz69UoEGTTjkxOONBmaWvHTYrTSnB1e9JqOEuI2SjClflWQ_FYbclW8ybLQUUGMWpIUvR5cTTKR7owVbakvCe80pdBOC1mbI69u7CbzJsYXo/s320/3225.image11_thumb_68E106BE.png" width="320" /></a></div>
<br />
<br />
Click the RDTestService.svc file, this is the actual service we want to make sure runs. <br />
Congratulations you have just written your own WCF service!! Still does not do all we need though, and now we will look at how we will interact with the database :) <br />
<strong>MySQL</strong> <br />
So, we now need to get the MySQL assemblies so we can connect to the DB, you can find the download you need<a href="http://www.mysql.com/downloads/connector/net/">here</a>. Download and install the msi, I had to uninstall an older version, you may need to do the same. <br />
Once installed you can then reference the MySQL assemblies in your project, right click on the project and select Add Reference like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlpCY7GYFVrA2odRhnoJKWHi2rGokeWqkbHJv80xT8TDKBac9MGHOlE7qYME5bUNJ8GYoAiB-oZzuwEbGjlh3H8q3Jzs3sBdyAW-LQLPzRDWpAQ6E8AF56aTzESjajtIITcliz3fZE9tdZ/s1600/8030.image1_thumb_5D1B99BF.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlpCY7GYFVrA2odRhnoJKWHi2rGokeWqkbHJv80xT8TDKBac9MGHOlE7qYME5bUNJ8GYoAiB-oZzuwEbGjlh3H8q3Jzs3sBdyAW-LQLPzRDWpAQ6E8AF56aTzESjajtIITcliz3fZE9tdZ/s320/8030.image1_thumb_5D1B99BF.png" width="320" /></a></div>
<br />
<br />
In the Add Reference popup, select the .NET tab, wait about 9 hours (not that long really :P) then go find the MySQL.Data reference and add that to your project like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA7o1U2a9UYGVg9f0MrprxmYng5vEIMuC_cjPxISMXFzvh3LrEz8IfRmd2sy6GVg0J4u5cKm0P-3c0A2OEDQ_wnzPNYO5v3Mhbj6F-Oj6-M1Wz78DivY7cEv7P7xqPOkyVhElGiKFRVnm-/s1600/0511.image5_thumb_168E83EA.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA7o1U2a9UYGVg9f0MrprxmYng5vEIMuC_cjPxISMXFzvh3LrEz8IfRmd2sy6GVg0J4u5cKm0P-3c0A2OEDQ_wnzPNYO5v3Mhbj6F-Oj6-M1Wz78DivY7cEv7P7xqPOkyVhElGiKFRVnm-/s320/0511.image5_thumb_168E83EA.png" width="320" /></a></div>
<br />
<br />
Now we have registered the MySQL assemblies we can go on to create a class that will handle all our communications with the database. In the App_Code folder create a Utilities folder, in there create a class called DBUtility and add using statements for System.Data, MySql.Data and MySql.Data.MySqlClient like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7c4800e3-3c8f-4fe4-bf9c-86400052837b" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">using</span> System;<br />
<span style="color: blue;">using</span> System.Collections.Generic;<br />
<span style="color: blue;">using</span> System.Linq;<br />
<span style="color: blue;">using</span> System.Web;<br />
<span style="color: blue;">using</span> System.Data;<br />
<br />
<span style="color: blue;">using</span> MySql.Data;<br />
<span style="color: blue;">using</span> MySql.Data.MySqlClient;<br />
<br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span><br />
<span style="color: grey;">///</span><span style="color: green;"> Summary description for DBUtility</span><br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span><br />
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">DBUtility</span><br />
{<br />
<span style="color: blue;">public</span> DBUtility()<br />
{<br />
<span style="color: green;">//</span><br />
<span style="color: green;">// TODO: Add constructor logic here</span><br />
<span style="color: green;">//</span><br />
}<br />
}</div>
</div>
</div>
Now we are going to add a database connection object, alter the constructor to initialize it and add a method to use it like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e792dd00-93dd-4f90-8b67-e3db5ff17b60" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">DBUtility</span><br />
{<br />
<span style="color: blue;">public</span> <span style="color: #2b91af;">IDbConnection</span> CNN;<br />
<br />
<span style="color: blue;">public</span> DBUtility(<span style="color: blue;">string</span> server,<span style="color: blue;">string</span> port, <span style="color: blue;">string</span> database,<span style="color: blue;">string</span> userID,<span style="color: blue;">string</span> password)<br />
{<br />
CNN = <span style="color: blue;">new</span> MySqlConnection(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"Data Source={0};Port={1};Database={2};User ID={3};Password={4}"</span>, server, port, database, userID, password)); <br />
}<br />
<br />
<span style="color: blue;">public</span> <span style="color: #2b91af;">DataSet</span> GetDataSet(<span style="color: blue;">string</span> sql)<br />
{<br />
<span style="color: #2b91af;">DataSet</span> ds = <span style="color: blue;">new</span> <span style="color: #2b91af;">DataSet</span>();<br />
<span style="color: #2b91af;">IDbDataAdapter</span> da;<br />
<br />
da = <span style="color: blue;">new</span> MySqlDataAdapter(sql, (MySqlConnection)CNN);<br />
<br />
da.Fill(ds);<br />
<br />
<span style="color: blue;">return</span> ds;<br />
}<br />
}</div>
</div>
</div>
As you can see in this sample I am using IDbConnection interface rather than a MySQLConnection, this is so later (if I get around to it) we will expand this class so it can connect to databases of other types like MSSql, Oracle and other OleDB types. <br />
So, now we have all this set up we can code up our web method to update the table for us. To the RCTestService.cs we are going to add an instance of DBUtility, in the service constructor, initiate it and then use it in our web method to update the database. In order to do this we are going to set up some values in the web.config file, we are going to add an appSettings section and give it two keys, Server and Port like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:bab44ed3-be86-42ed-bf7c-e0f0be485e60" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;"><?</span><span style="color: #a31515;">xml</span><span style="color: blue;"> </span><span style="color: red;">version</span><span style="color: blue;">=</span>"<span style="color: blue;">1.0</span>"<span style="color: blue;">?></span><br />
<span style="color: blue;"><</span><span style="color: #a31515;">configuration</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">appSettings</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">add</span><span style="color: blue;"> </span><span style="color: red;">key</span><span style="color: blue;">=</span>"<span style="color: blue;">Server</span>"<span style="color: blue;"> </span><span style="color: red;">value</span><span style="color: blue;">=</span>""<span style="color: blue;">/></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">add</span><span style="color: blue;"> </span><span style="color: red;">key</span><span style="color: blue;">=</span>"<span style="color: blue;">Port</span>"<span style="color: blue;"> </span><span style="color: red;">value</span><span style="color: blue;">=</span>""<span style="color: blue;">/> </span><br />
<span style="color: blue;"> </</span><span style="color: #a31515;">appSettings</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">system.web</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">compilation</span><span style="color: blue;"> </span><span style="color: red;">debug</span><span style="color: blue;">=</span>"<span style="color: blue;">true</span>"<span style="color: blue;"> </span><span style="color: red;">targetFramework</span><span style="color: blue;">=</span>"<span style="color: blue;">4.0</span>"<span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">assemblies</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">add</span><span style="color: blue;"> </span><span style="color: red;">assembly</span><span style="color: blue;">=</span>"<span style="color: blue;">MySql.Data, Version=6.4.4.0, Culture=neutral, PublicKeyToken=C5687FC88969C44D</span>"<span style="color: blue;">/></span><br />
<span style="color: blue;"> </</span><span style="color: #a31515;">assemblies</span><span style="color: blue;">></span><br />
<span style="color: blue;"> </</span><span style="color: #a31515;">compilation</span><span style="color: blue;">></span><br />
<span style="color: blue;"> </</span><span style="color: #a31515;">system.web</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">system.serviceModel</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">behaviors</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">serviceBehaviors</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">behavior</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <!--</span><span style="color: green;"> To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment </span><span style="color: blue;">--></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">serviceMetadata</span><span style="color: blue;"> </span><span style="color: red;">httpGetEnabled</span><span style="color: blue;">=</span>"<span style="color: blue;">true</span>"<span style="color: blue;">/></span><br />
<span style="color: blue;"> <!--</span><span style="color: green;"> To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information </span><span style="color: blue;">--></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">serviceDebug</span><span style="color: blue;"> </span><span style="color: red;">includeExceptionDetailInFaults</span><span style="color: blue;">=</span>"<span style="color: blue;">false</span>"<span style="color: blue;">/></span><br />
<span style="color: blue;"> </</span><span style="color: #a31515;">behavior</span><span style="color: blue;">></span><br />
<span style="color: blue;"> </</span><span style="color: #a31515;">serviceBehaviors</span><span style="color: blue;">></span><br />
<span style="color: blue;"> </</span><span style="color: #a31515;">behaviors</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">serviceHostingEnvironment</span><span style="color: blue;"> </span><span style="color: red;">multipleSiteBindingsEnabled</span><span style="color: blue;">=</span>"<span style="color: blue;">true</span>"<span style="color: blue;">/></span><br />
<span style="color: blue;"> </</span><span style="color: #a31515;">system.serviceModel</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">system.webServer</span><span style="color: blue;">></span><br />
<span style="color: blue;"> <</span><span style="color: #a31515;">modules</span><span style="color: blue;"> </span><span style="color: red;">runAllManagedModulesForAllRequests</span><span style="color: blue;">=</span>"<span style="color: blue;">true</span>"<span style="color: blue;">/></span><br />
<span style="color: blue;"> </</span><span style="color: #a31515;">system.webServer</span><span style="color: blue;">></span><br />
<span style="color: blue;"></</span><span style="color: #a31515;">configuration</span><span style="color: blue;">></span></div>
</div>
</div>
These values will be populated with the server and port number your data base is on, you can find this value in the MySQL Databases tab on your hosted control panel. I do this as you can test your service while running from your home machine, but you will need to swap the server and port numbers for those used for remote access, you will also need to set up your IP address so it will be allowed to talk to the server during testing, all this is pretty simple on my hosts control panel, just goto the MySQL Remote Access tab. <br />
So, now we have our server and port configured we can set up the connection object in the service constructr like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c8266981-d0a9-4877-a4ac-4a4e688739e4" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">RCTestService</span> : <span style="color: #2b91af;">IRCTestService</span><br />
{<br />
<span style="color: blue;">protected</span> DBUtility dbUtil;<br />
<br />
<span style="color: blue;">public</span> RCTestService()<br />
{<br />
dbUtil = <span style="color: blue;">new</span> DBUtility(<span style="color: #2b91af;">ConfigurationManager</span>.AppSettings[<span style="color: #a31515;">"Server"</span>], <span style="color: #2b91af;">ConfigurationManager</span>.AppSettings[<span style="color: #a31515;">"Port"</span>], <span style="color: #a31515;">"randomch_testdb"</span>, <span style="color: #a31515;">"randomch_test"</span>, <span style="color: #a31515;">"test"</span>);<br />
}</div>
</div>
</div>
And we can then update our UpdateServer web method like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f27b4992-aec3-49bb-b7d5-fdea96f2a7db" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: blue;">void</span> UpdateServer(<span style="color: #2b91af;">UpdateRequest</span> request)<br />
{<br />
<span style="color: blue;">if</span> (ValidRequest(request))<br />
{<br />
<span style="color: green;">// Do we have any of this country?</span><br />
<span style="color: blue;">string</span> sql = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"SELECT * FROM TestTable WHERE Country = '{0}'"</span>, request.Country);<br />
<span style="color: #2b91af;">DataSet</span> ds = dbUtil.GetDataSet(sql);<br />
<br />
<span style="color: green;">// Update DB</span><br />
<span style="color: blue;">if</span> (ds != <span style="color: blue;">null</span> && ds.Tables != <span style="color: blue;">null</span> && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)<br />
sql = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"UPDATE TestTable SET Count = {1} WHERE Country = '{0}'"</span>, request.Country, <span style="color: blue;">int</span>.Parse(ds.Tables[0].Rows[0][<span style="color: #a31515;">"Count"</span>].ToString()) + 1);<br />
<span style="color: blue;">else</span><br />
sql = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"INSERT INTO TestTable VALUES('{0}',{1})"</span>, request.Country, 1);<br />
<br />
dbUtil.GetDataSet(sql);<br />
}<br />
}</div>
</div>
</div>
So, what I am doing here, is first checking if we have any records for this country type, if we have then we update that row with a new count value, if we don’t then we insert a new row. <br />
We can also add a new web method now to get us all the data in the table so we ca display it on our client. Before we do this we need to create a decent response object so we can bundle all that data up and pass it back to the client in a nice tidy manner. We do this with another data contract, but first we will create a ResponseBase and then derive from that. <br />
As before in the DataContracts folder create a new class, but this time call it ResponseBase like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1c4c9df9-14a5-4d19-8417-747c624c6871" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">using</span> System;<br />
<span style="color: blue;">using</span> System.Collections.Generic;<br />
<span style="color: blue;">using</span> System.Linq;<br />
<span style="color: blue;">using</span> System.Runtime.Serialization;<br />
<span style="color: blue;">using</span> System.ServiceModel;<br />
<span style="color: blue;">using</span> System.ServiceModel.Web;<br />
<span style="color: blue;">using</span> System.Text;<br />
<br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span><br />
<span style="color: grey;">///</span><span style="color: green;"> Summary description for ResponseBase</span><br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span><br />
[<span style="color: #2b91af;">DataContract</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">ResponseBase</span><br />
{<br />
[<span style="color: #2b91af;">DataMember</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> Success { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }<br />
<br />
[<span style="color: #2b91af;">DataMember</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">string</span> Message { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }<br />
<br />
<span style="color: blue;">public</span> ResponseBase()<br />
{<br />
Success = <span style="color: blue;">true</span>;<br />
}<br />
}</div>
</div>
</div>
We can use this response object in our existing web method, so we can inform the client if all went well or if there was an issue, first we update the service interface so it looks like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c72b5b36-4fc4-4d0f-b7a3-5d487f439eff" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">using</span> System;<br />
<span style="color: blue;">using</span> System.Collections.Generic;<br />
<span style="color: blue;">using</span> System.Linq;<br />
<span style="color: blue;">using</span> System.Runtime.Serialization;<br />
<span style="color: blue;">using</span> System.ServiceModel;<br />
<span style="color: blue;">using</span> System.ServiceModel.Web;<br />
<span style="color: blue;">using</span> System.Text;<br />
<br />
<span style="color: green;">// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService" in both code and config file together.</span><br />
[<span style="color: #2b91af;">ServiceContract</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">interface</span> <span style="color: #2b91af;">IRCTestService</span><br />
{<br />
[<span style="color: #2b91af;">OperationContract</span>]<br />
<span style="color: #2b91af;">ResponseBase</span> UpdateServer(<span style="color: #2b91af;">UpdateRequest</span> request);<br />
}</div>
</div>
</div>
Then alter the web method like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:03867ca4-d80a-47d8-934c-c4c89ab4f024" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: #2b91af;">ResponseBase</span> UpdateServer(<span style="color: #2b91af;">UpdateRequest</span> request)<br />
{<br />
<span style="color: #2b91af;">ResponseBase</span> retVal = <span style="color: blue;">new</span> <span style="color: #2b91af;">ResponseBase</span>();<br />
<br />
<span style="color: blue;">try</span><br />
{<br />
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Exception</span>(<span style="color: #a31515;">"oops"</span>);<br />
<span style="color: blue;">if</span> (ValidRequest(request))<br />
{<br />
<span style="color: green;">// Do we have any of this country?</span><br />
<span style="color: blue;">string</span> sql = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"SELECT * FROM TestTable WHERE Country = '{0}'"</span>, request.Country);<br />
<span style="color: #2b91af;">DataSet</span> ds = dbUtil.GetDataSet(sql);<br />
<br />
<span style="color: green;">// Update DB</span><br />
<span style="color: blue;">if</span> (ds != <span style="color: blue;">null</span> && ds.Tables != <span style="color: blue;">null</span> && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)<br />
sql = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"UPDATE TestTable SET Count = {1} WHERE Country = '{0}'"</span>, request.Country, <span style="color: blue;">int</span>.Parse(ds.Tables[0].Rows[0][<span style="color: #a31515;">"Count"</span>].ToString()) + 1);<br />
<span style="color: blue;">else</span><br />
sql = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"INSERT INTO TestTable VALUES('{0}',{1})"</span>, request.Country, 1);<br />
<br />
dbUtil.GetDataSet(sql);<br />
}<br />
<span style="color: blue;">else</span><br />
{<br />
retVal.Success = <span style="color: blue;">false</span>;<br />
retVal.Message = <span style="color: #a31515;">"Invalid Request Credentials!"</span>;<br />
}<br />
}<br />
<span style="color: blue;">catch</span> (<span style="color: #2b91af;">Exception</span> e)<br />
{<br />
retVal.Success = <span style="color: blue;">false</span>;<br />
retVal.Message = e.Message;<br />
}<br />
<br />
<span style="color: blue;">return</span> retVal;<br />
}</div>
</div>
</div>
Now onto our new web method, GetAll, this will need a specific response object, but first we need a class to store our data. <br />
Create a new folder called DataObjects, in there create a class called TableData like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:a3cc5ae0-1449-441e-9c9a-f34f0b738705" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">using</span> System;<br />
<span style="color: blue;">using</span> System.Collections.Generic;<br />
<span style="color: blue;">using</span> System.Linq;<br />
<span style="color: blue;">using</span> System.Web;<br />
<span style="color: blue;">using</span> System.Data;<br />
<br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span><br />
<span style="color: grey;">///</span><span style="color: green;"> Summary description for TableData</span><br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span><br />
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">TableData</span><br />
{<br />
<span style="color: blue;">public</span> <span style="color: blue;">string</span> Country { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }<br />
<span style="color: blue;">public</span> <span style="color: blue;">int</span> Count { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }<br />
<br />
<span style="color: blue;">public</span> TableData()<br />
{ }<br />
<br />
<span style="color: blue;">public</span> TableData(<span style="color: blue;">string</span> country, <span style="color: blue;">int</span> count)<br />
{<br />
Country = country;<br />
Count = count;<br />
}<br />
<span style="color: blue;">public</span> TableData(<span style="color: #2b91af;">DataRow</span> row)<br />
{<br />
Country = row[<span style="color: #a31515;">"Country"</span>].ToString();<br />
<br />
<span style="color: blue;">int</span> c = 0;<br />
<span style="color: blue;">int</span>.TryParse(row[<span style="color: #a31515;">"Count"</span>].ToString(), <span style="color: blue;">out</span> c);<br />
<br />
Count = c;<br />
}<br />
}</div>
</div>
</div>
This class will store the two columns we need for each record, I have given it 3 constructors so I can be lazy when creating the objects, but you can define yours how ever you need to. <br />
Now again, create a new class in the DataContracts folder called GetAllResponse deriving from ResponseBase like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:4bc78148-8e92-4a96-809d-7de3cc556cf9" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">using</span> System;<br />
<span style="color: blue;">using</span> System.Collections.Generic;<br />
<span style="color: blue;">using</span> System.Linq;<br />
<span style="color: blue;">using</span> System.Runtime.Serialization;<br />
<span style="color: blue;">using</span> System.ServiceModel;<br />
<span style="color: blue;">using</span> System.ServiceModel.Web;<br />
<span style="color: blue;">using</span> System.Text;<br />
<span style="color: blue;">using</span> System.Data;<br />
<br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span><br />
<span style="color: grey;">///</span><span style="color: green;"> Summary description for GetAllResponse</span><br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span><br />
[<span style="color: #2b91af;">DataContract</span>]<br />
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">GetAllResponse</span> : <span style="color: #2b91af;">ResponseBase</span><br />
{<br />
[<span style="color: #2b91af;">DataMember</span>]<br />
<span style="color: #2b91af;">IList</span><TableData> Data { <span style="color: blue;">get</span>; <span style="color: blue;">set</span>; }<br />
<br />
<span style="color: blue;">public</span> GetAllResponse()<br />
{ }<br />
<br />
<span style="color: blue;">public</span> GetAllResponse(<span style="color: #2b91af;">DataRowCollection</span> rows)<br />
{<br />
Data = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><TableData>();<br />
<br />
<span style="color: blue;">foreach</span> (<span style="color: #2b91af;">DataRow</span> row <span style="color: blue;">in</span> rows)<br />
Data.Add(<span style="color: blue;">new</span> TableData(row));<br />
}<br />
}</div>
</div>
</div>
In here we have a list of TableData and a constructor that will populate the object from a DataRowCollection, again so I can be lazy and just pass in the rows from the dataset :) <br />
Now we can create our new Web method to get it all for us, in the interface, set up the call like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:228fd14b-a30b-4d47-87e2-918e0affc720" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
[<span style="color: #2b91af;">OperationContract</span>]<br />
<span style="color: #2b91af;">GetAllResponse</span> GetAll(<span style="color: #2b91af;">RequestBase</span> request);</div>
</div>
</div>
We can then write the web method in the service located in the RCTestService.cs file like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9b2ec4ab-ceac-423a-98a7-7dbd3bb62dd0" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: #2b91af;">GetAllResponse</span> GetAll(<span style="color: #2b91af;">RequestBase</span> request)<br />
{<br />
<span style="color: #2b91af;">GetAllResponse</span> retVal = <span style="color: blue;">new</span> <span style="color: #2b91af;">GetAllResponse</span>();<br />
<span style="color: blue;">try</span><br />
{<br />
<span style="color: blue;">if</span> (ValidRequest(request))<br />
{<br />
<span style="color: green;">// Do our SQL stuff here</span><br />
}<br />
<span style="color: blue;">else</span><br />
{<br />
retVal.Success = <span style="color: blue;">false</span>;<br />
retVal.Message = <span style="color: #a31515;">"Invalid Request Credentials!"</span>;<br />
}<br />
}<br />
<span style="color: blue;">catch</span> (<span style="color: #2b91af;">Exception</span> e)<br />
{<br />
retVal.Success = <span style="color: blue;">false</span>;<br />
retVal.Message = e.Message;<br />
}<br />
<br />
<span style="color: blue;">return</span> retVal;<br />
}</div>
</div>
</div>
Now we can add the logic like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:05d826c3-1583-4d36-a337-927c9f14b591" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: #2b91af;">GetAllResponse</span> GetAll(<span style="color: #2b91af;">RequestBase</span> request)<br />
{<br />
<span style="color: #2b91af;">GetAllResponse</span> retVal = <span style="color: blue;">new</span> <span style="color: #2b91af;">GetAllResponse</span>();<br />
<span style="color: blue;">try</span><br />
{<br />
<span style="color: blue;">if</span> (ValidRequest(request))<br />
{<br />
<span style="color: blue;">string</span> sql = <span style="color: #a31515;">"SELECT * FROM TestTable"</span>;<br />
<span style="color: #2b91af;">DataSet</span> ds = dbUtil.GetDataSet(sql);<br />
<br />
<span style="color: blue;">if</span> (ds != <span style="color: blue;">null</span> && ds.Tables != <span style="color: blue;">null</span> && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)<br />
retVal = <span style="color: blue;">new</span> <span style="color: #2b91af;">GetAllResponse</span>(ds.Tables[0].Rows);<br />
<span style="color: blue;">else</span><br />
{<br />
retVal.Message = <span style="color: #a31515;">"There is no data in the table..."</span>;<br />
}<br />
}<br />
<span style="color: blue;">else</span><br />
{<br />
retVal.Success = <span style="color: blue;">false</span>;<br />
retVal.Message = <span style="color: #a31515;">"Invalid Request Credentials!"</span>;<br />
}<br />
}<br />
<span style="color: blue;">catch</span> (<span style="color: #2b91af;">Exception</span> e)<br />
{<br />
retVal.Success = <span style="color: blue;">false</span>;<br />
retVal.Message = e.Message;<br />
}<br />
<br />
<span style="color: blue;">return</span> retVal;<br />
}</div>
</div>
</div>
<strong>Publish the Web Service</strong> <br />
So, now we are going to put the service up on the interwebz so your applications can access it. First of all, if you did use the debug/remote access server address and port in your web.config file, switch it to the live IP and port now, if you forget, most FTP clients will let you edit files on the server, so it’s no big issue, just makes it a bit easier if you do it now. <br />
Once you are all compiled and ready to go, you need to locate the MySql.Data.dll as this wont be present on the server, it will be in the GAC, so I found mine here “C:\Windows\Microsoft.NET\assembly\GAC_MSIL”, once you have located the assembly, create an ASP.NET Bin folder in the project ad copy the assembly across so it’s ready to go on the server, your solution should now look something like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEriAEFo6akZpxByMhDYYGLLyWYQA_voPB_Sdrs6LQMHyP0NRkeY-snNLxHK0Bap-Hpg_THF7eBJlGR9dO5BrW4LWLZ_NGADVdjbHnn1-GgcYnY4MAExE2WTxQcpryvK9PhbIsEIW0_tYR/s1600/8446.image_thumb_5F54D023.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEriAEFo6akZpxByMhDYYGLLyWYQA_voPB_Sdrs6LQMHyP0NRkeY-snNLxHK0Bap-Hpg_THF7eBJlGR9dO5BrW4LWLZ_NGADVdjbHnn1-GgcYnY4MAExE2WTxQcpryvK9PhbIsEIW0_tYR/s320/8446.image_thumb_5F54D023.png" width="223" /></a></div>
<br />
<br />
Now, I had a few issues setting mine up on my server as I had other web applications using an older version of the MySQL.Data.dll, to get round this I altered the reference to the assembly so it looked like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:c54f4f12-b97f-4513-842b-da5ff02d77b3" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;"> <</span><span style="color: #a31515;">add</span><span style="color: blue;"> </span><span style="color: red;">assembly</span><span style="color: blue;">=</span>"<span style="color: blue;">MySql.Data, Culture=neutral</span>"<span style="color: blue;">/></span></div>
</div>
</div>
This means it won’t look for a specific version of the assembly, I also have a Bin folder at a higher level to this service on my server, so I ended up having to use the older version. Also my host does not have Front Page Publishing enabled (probably because I didn’t ask for it) so I have had to set it all up manually rather than using the Publish Web site option in VS2010. <br />
So, we have the project all lined up and ready to be served on our server, fire up your FTP client and connect to your host, create a folder to hold the service, I just used the folder name my project is in RCTestWCFService, then just copy it all up. We are still not done, we need to now go over to our control panel and set up the folder as a virtual directory. With my host it’s a pretty simple thing to do, go into the Virtual Directories option off the main menu screen, select the Add New Virtual Directory tab and enter the names you want as the alias and the name you just transferred the service to and click Create virtual directory. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGMmyt1B2NoTHK2irm4PDMCudRSx-IjM_nv0uu3LhEapXYP-yx67zFpUf63wUcnktNcqDShneK5Z2GNZlwbUcERbkTK3ZEnZINxVsniQz6y9x2XmuoVcQdpIb8QtT91KM1w3vy22ikyTLW/s1600/4237.image_thumb_5323302F.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGMmyt1B2NoTHK2irm4PDMCudRSx-IjM_nv0uu3LhEapXYP-yx67zFpUf63wUcnktNcqDShneK5Z2GNZlwbUcERbkTK3ZEnZINxVsniQz6y9x2XmuoVcQdpIb8QtT91KM1w3vy22ikyTLW/s320/4237.image_thumb_5323302F.png" width="320" /></a></div>
<br />
<br />
One more step and we will have our service up and running and that’s to refresh your application pool, I think that by default on my host your site is in a shared application pool, but from the dashboard you can switch to an isolated one, then simply hit the refresh application pool button. <br />
So, now (if I have not took it down yet) you should be able to go and see my version of this test service running from my site here <a href="http://www.randomchaos.co.uk/RCTestWCFService/RCTestService.svc">http://www.randomchaos.co.uk/RCTestWCFService/RCTestService.svc</a> which should look something like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUd8V4h62hFMc6MBdLFC-QdZSEMjnZkfw4rQ48p6R-A_bO0oCNtDPrs6Zpf7hG88Dt5yhaSHqYvHJzWj1LMpm5CzSCwXfArSQl4Jr3CLx9vIGT-2EXuy7hCpJSoK-J68jnxu2WeD8Rx9RZ/s1600/8446.image_thumb_1F6A9E04.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUd8V4h62hFMc6MBdLFC-QdZSEMjnZkfw4rQ48p6R-A_bO0oCNtDPrs6Zpf7hG88Dt5yhaSHqYvHJzWj1LMpm5CzSCwXfArSQl4Jr3CLx9vIGT-2EXuy7hCpJSoK-J68jnxu2WeD8Rx9RZ/s320/8446.image_thumb_1F6A9E04.png" width="320" /></a></div>
<br />
<br />
And if you click the link at the top you will get to see the WSDL for the service, which will look like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtwFA3gj3xsSs0rhusP5r73EE-atrsVFph1VSkHy5bUUNvoWzUazwEUo5JcbA-6YdOhyphenhyphenPS0KS8pcN-Wu8o2voVCZccSuseT_iwp8tJgO3VwkeTedd1AFXWozI6bkkMUGh1xzhFACB2_hk9/s1600/2063.image_thumb_556BCAB9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="156" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtwFA3gj3xsSs0rhusP5r73EE-atrsVFph1VSkHy5bUUNvoWzUazwEUo5JcbA-6YdOhyphenhyphenPS0KS8pcN-Wu8o2voVCZccSuseT_iwp8tJgO3VwkeTedd1AFXWozI6bkkMUGh1xzhFACB2_hk9/s320/2063.image_thumb_556BCAB9.png" width="320" /></a></div>
<br />
<br />
So that’s that, you have created a simple WCF Web service, now to look at setting up a WP7 Client to access this service. <br />
<strong>XNA WP7 Client</strong> <br />
So as I hope you by know, I am pretty much 100% XNA on this blog, so I am going to create the WP7 client in pure XNA. So, create your XNA WP7 project as you normally would, we then need to add a service reference, right click on the project and click Add Service Reference <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9KzYBUbM8dQkSzSSLLxLkZgM9JsRwE0PKnKU7yDDvThQIapyon5h5H-ae3-hYKvFbJH8AW7EOP1F9AEh4iUwZH67lhLuDPows22aIlGA-3MW8S7xGqzuv6SzgRZdFgciB5FoDuVXPVF-m/s1600/4621.image_thumb_233454A2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9KzYBUbM8dQkSzSSLLxLkZgM9JsRwE0PKnKU7yDDvThQIapyon5h5H-ae3-hYKvFbJH8AW7EOP1F9AEh4iUwZH67lhLuDPows22aIlGA-3MW8S7xGqzuv6SzgRZdFgciB5FoDuVXPVF-m/s320/4621.image_thumb_233454A2.png" width="248" /></a></div>
<br />
<br />
In the Address paste the address of your service and hit the Go button, once the service has been discovered you can change the namespace that will be used in your project, I named mine RCTestService, then click OK <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpmXC_uO0zxQU6Oi2tuW8Ire6amg2xXd5cZ1jTAf8hr9HUOR2ujPEKQxkSSlXbI25rXutWZMK9q9s6oh1top7khLu5blUpZpACiYj5Pvee6Ov_Shzg6rwEOpkJmVfBJ43kikQQGu3QwU55/s1600/4705.image_thumb_5A1E0D0E.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="261" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpmXC_uO0zxQU6Oi2tuW8Ire6amg2xXd5cZ1jTAf8hr9HUOR2ujPEKQxkSSlXbI25rXutWZMK9q9s6oh1top7khLu5blUpZpACiYj5Pvee6Ov_Shzg6rwEOpkJmVfBJ43kikQQGu3QwU55/s320/4705.image_thumb_5A1E0D0E.png" width="320" /></a></div>
<br />
<br />
And that’s it, it’s now bound to the service and we can now make the web service calls from the client. <br />
In the Game1 class I create a reference to the service just above the constructor like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:8aa3a7ae-7896-4661-92f0-305350d758fd" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">namespace</span> RCTestWP7Client<br />
{<br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span><br />
<span style="color: grey;">///</span><span style="color: green;"> This is the main type for your game</span><br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span><br />
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">Game1</span> : Microsoft.Xna.Framework.Game<br />
{<br />
GraphicsDeviceManager graphics;<br />
SpriteBatch spriteBatch;<br />
<br />
RCTestService.RCTestServiceClient webService;<br />
<br />
<span style="color: blue;">public</span> Game1()<br />
{<br />
graphics = <span style="color: blue;">new</span> GraphicsDeviceManager(<span style="color: blue;">this</span>);<br />
Content.RootDirectory = <span style="color: #a31515;">"Content"</span>;</div>
</div>
</div>
Then in the Initialize method I am going to instantiate the service and bind callbacks to the asynchronous web methods we have. The methods appear as asynchronous as the WP7 uses the same Silverlight architecture (I am guessing) which forces the service calls to be asynchronous, if we were writing for a PC XNA game we could make synchronous calls. And if we were on the XBox, we could not bind to the service as the framework does not allow it for security reasons. <br />
So our Initialize method now looks something like this and we have two new methods<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:abfbe6e8-f1f6-44ee-be58-7bb22aff3d48" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">protected</span> <span style="color: blue;">override</span> <span style="color: blue;">void</span> Initialize()<br />
{<br />
<span style="color: green;">// TODO: Add your initialization logic here</span><br />
<br />
<span style="color: blue;">base</span>.Initialize();<br />
<br />
webService = <span style="color: blue;">new</span> RCTestService.RCTestServiceClient();<br />
webService.UpdateServerCompleted += <span style="color: blue;">new</span> <span style="color: #2b91af;">EventHandler</span><RCTestService.UpdateServerCompletedEventArgs>(webService_UpdateServerCompleted);<br />
webService.GetAllCompleted += <span style="color: blue;">new</span> <span style="color: #2b91af;">EventHandler</span><RCTestService.GetAllCompletedEventArgs>(webService_GetAllCompleted);<br />
}<br />
<br />
<span style="color: blue;">void</span> webService_GetAllCompleted(<span style="color: blue;">object</span> sender, RCTestService.GetAllCompletedEventArgs e)<br />
{<br />
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">NotImplementedException</span>();<br />
}<br />
<br />
<span style="color: blue;">void</span> webService_UpdateServerCompleted(<span style="color: blue;">object</span> sender, RCTestService.UpdateServerCompletedEventArgs e)<br />
{<br />
<span style="color: blue;">throw</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">NotImplementedException</span>();<br />
}</div>
</div>
</div>
I am going to create a bool so I know if I have updated the server and in the Update method if we have not done it, call the UpdateServer web method<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:3155f842-aa34-4ed7-a71e-5b8265a8112b" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">protected</span> <span style="color: blue;">override</span> <span style="color: blue;">void</span> Update(GameTime gameTime)<br />
{<br />
<span style="color: green;">// Allows the game to exit</span><br />
<span style="color: blue;">if</span> (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)<br />
<span style="color: blue;">this</span>.Exit();<br />
<br />
<span style="color: blue;">if</span> (!UpdatedServer)<br />
{<br />
UpdatedServer = <span style="color: blue;">true</span>;<br />
RCTestService.UpdateRequest req = <span style="color: blue;">new</span> RCTestService.UpdateRequest();<br />
req.UserName = <span style="color: #a31515;">"username"</span>;<br />
req.Password = <span style="color: #a31515;">"password"</span>;<br />
req.Country = System.Globalization.<span style="color: #2b91af;">CultureInfo</span>.CurrentCulture.Name;<br />
<br />
webService.UpdateServerAsync(req);<br />
}<br />
<br />
<span style="color: blue;">base</span>.Update(gameTime);<br />
}</div>
</div>
</div>
Now, what if something goes wrong, then we sort of need a pop up message box to display any issues, so here is a method we can use to do that<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:da5a5397-dda4-4d56-8bcc-dcf280cd2928" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: blue;">void</span> ShowMessageBox(<span style="color: blue;">string</span> title, <span style="color: blue;">string</span> message)<br />
{<br />
Guide.BeginShowMessageBox(title, message, <span style="color: blue;">new</span> <span style="color: blue;">string</span>[] { <span style="color: #a31515;">"OK"</span> }, 0, MessageBoxIcon.Alert, <span style="color: blue;">null</span>, <span style="color: blue;">null</span>);<br />
}</div>
</div>
</div>
So, with that we can then see how our call went and respond accordingly.<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b4c61325-ce70-4651-b5df-219ae5ab6211" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">void</span> webService_UpdateServerCompleted(<span style="color: blue;">object</span> sender, RCTestService.UpdateServerCompletedEventArgs e)<br />
{<br />
<span style="color: blue;">if</span> (e.Result.Success)<br />
ShowMessageBox(<span style="color: #a31515;">"All Good"</span>, <span style="color: #a31515;">"Server was updated."</span>);<br />
<span style="color: blue;">else</span><br />
ShowMessageBox(<span style="color: #a31515;">"Error"</span>, e.Result.Message);<br />
}</div>
</div>
</div>
Now we have that call all wired up we can then take on the next one, but first we need to add a font to the content folder so we can show the results, we are also going to call the method every minute and display the updated data and we will hold this data in a list of TableData. <br />
The variables we now have at the top of Game1 look like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:7673b055-12c2-4649-923a-602ca9585d5f" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
RCTestService.RCTestServiceClient webService;<br />
<span style="color: #2b91af;">List</span><RCTestService.TableData> getAllResponse = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><RCTestService.TableData>();<br />
<span style="color: #2b91af;">TimeSpan</span> checkTimeSpan = <span style="color: blue;">new</span> <span style="color: #2b91af;">TimeSpan</span>(0, 1, 0);<br />
<span style="color: #2b91af;">TimeSpan</span> lastCheck = <span style="color: #2b91af;">DateTime</span>.Now.TimeOfDay;<br />
<span style="color: blue;">bool</span> UpdatedServer = <span style="color: blue;">false</span>;</div>
</div>
</div>
and our list of data is populated when the service returns like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b5aede70-813f-4a1b-a57d-f70406153bb6" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">void</span> webService_GetAllCompleted(<span style="color: blue;">object</span> sender, RCTestService.GetAllCompletedEventArgs e)<br />
{<br />
<span style="color: blue;">if</span> (e.Result.Success)<br />
{<br />
getAllResponse = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><RCTestService.TableData>(e.Result.Data);<br />
}<br />
<span style="color: blue;">else</span><br />
ShowMessageBox(<span style="color: #a31515;">"Error"</span>, e.Result.Message);<br />
}</div>
</div>
</div>
Now in the Update method we are going to set up the call to the service like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:be34fc7b-060d-4726-8198-e682d788ad16" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">protected</span> <span style="color: blue;">override</span> <span style="color: blue;">void</span> Update(GameTime gameTime)<br />
{<br />
<span style="color: green;">// Allows the game to exit</span><br />
<span style="color: blue;">if</span> (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)<br />
<span style="color: blue;">this</span>.Exit();<br />
<br />
<span style="color: blue;">if</span> (!UpdatedServer)<br />
{<br />
UpdatedServer = <span style="color: blue;">true</span>;<br />
RCTestService.UpdateRequest req = <span style="color: blue;">new</span> RCTestService.UpdateRequest();<br />
req.UserName = <span style="color: #a31515;">"username"</span>;<br />
req.Password = <span style="color: #a31515;">"password"</span>;<br />
req.Country = System.Globalization.<span style="color: #2b91af;">CultureInfo</span>.CurrentCulture.Name;<br />
<br />
webService.UpdateServerAsync(req);<br />
}<br />
<span style="color: blue;">else</span><br />
{<br />
<span style="color: blue;">if</span> (<span style="color: #2b91af;">DateTime</span>.Now.TimeOfDay - lastCheck > checkTimeSpan)<br />
{<br />
lastCheck = <span style="color: #2b91af;">DateTime</span>.Now.TimeOfDay;<br />
<br />
RCTestService.RequestBase req = <span style="color: blue;">new</span> RCTestService.RequestBase();<br />
req.UserName = <span style="color: #a31515;">"username"</span>;<br />
req.Password = <span style="color: #a31515;">"password"</span>;<br />
<br />
webService.GetAllAsync(req);<br />
}<br />
}<br />
<br />
<span style="color: blue;">base</span>.Update(gameTime);<br />
}</div>
</div>
</div>
So, now we are going to display on the screen the time till next check and the current data we have, so our draw call will now look like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9eb1c75e-58b8-41a5-88c1-46a759d8fed9" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">protected</span> <span style="color: blue;">override</span> <span style="color: blue;">void</span> Draw(GameTime gameTime)<br />
{<br />
GraphicsDevice.Clear(Color.Black);<br />
<br />
spriteBatch.Begin();<br />
<br />
spriteBatch.DrawString(Content.Load<SpriteFont>(<span style="color: #a31515;">"Fonts/font"</span>), <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"Next Check in {0} seconds"</span>, (checkTimeSpan - (<span style="color: #2b91af;">DateTime</span>.Now.TimeOfDay - lastCheck)).Seconds), Vector2.Zero, Color.Gold);<br />
<br />
<span style="color: blue;">int</span> cnt = getAllResponse.Count;<br />
<span style="color: blue;">for</span> (<span style="color: blue;">int</span> l = 0; l < cnt; l++)<br />
spriteBatch.DrawString(Content.Load<SpriteFont>(<span style="color: #a31515;">"Fonts/font"</span>), <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"{0} {1}"</span>, getAllResponse[l].Country, getAllResponse[l].Count), <span style="color: blue;">new</span> Vector2(0, Content.Load<SpriteFont>(<span style="color: #a31515;">"Fonts/font"</span>).LineSpacing * (l + 1)), Color.White);<br />
<br />
spriteBatch.End();<br />
<br />
<span style="color: blue;">base</span>.Draw(gameTime);<br />
}</div>
</div>
</div>
So, when our WP7 app connects to the service we get this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhChMp2emW28ReUUPKBH8zYdpFhBeh2mqoA1zBsXRF-IjS9z2mqgg9uJecLy6K5wcJm8P-fYLu01w2zuIZUxqCc4JYLtLzJW7jEpJfhUOrFfgpTWonqJiE9YK_HkXn5-IvG8cpTbYCwUmug/s1600/4237.image_thumb_2BB46194.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhChMp2emW28ReUUPKBH8zYdpFhBeh2mqoA1zBsXRF-IjS9z2mqgg9uJecLy6K5wcJm8P-fYLu01w2zuIZUxqCc4JYLtLzJW7jEpJfhUOrFfgpTWonqJiE9YK_HkXn5-IvG8cpTbYCwUmug/s320/4237.image_thumb_2BB46194.png" width="320" /></a></div>
<br />
<br />
And once it has gone and got all, looks something like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikQMhSvZSSUJDQaXmS2Cyu_d-BfB4w9MyVb5hbdEnZBV3QtbZKj93kupUZof1K81CcblMDw1EsotlorLSxwT91PlMY26SAUvLe7oHVeb3dM1krQuTCj0aqWGlzLOGO3-55DSDXjjZWtwp6/s1600/7853.image_thumb_7868025D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikQMhSvZSSUJDQaXmS2Cyu_d-BfB4w9MyVb5hbdEnZBV3QtbZKj93kupUZof1K81CcblMDw1EsotlorLSxwT91PlMY26SAUvLe7oHVeb3dM1krQuTCj0aqWGlzLOGO3-55DSDXjjZWtwp6/s320/7853.image_thumb_7868025D.png" width="320" /></a></div>
<br />
<br />
<strong>Silverlight WP7 Client</strong> <br />
So, I am updating this post to include the silver light client code, I am new to Silverlight on the WP7, so please forgive how crude I have been writing this client. It’s pretty much the same steps as the XNA client, we add a reference to the service, just as before, but we set the service up in code in the MainPage constructor like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:5422815e-f5cb-456a-9792-d3e935823fa4" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> MainPage()<br />
{<br />
InitializeComponent();<br />
<br />
webService = <span style="color: blue;">new</span> RCTestService.RCTestServiceClient();<br />
webService.UpdateServerCompleted += <span style="color: blue;">new</span> <span style="color: #2b91af;">EventHandler</span><RCTestService.UpdateServerCompletedEventArgs>(webService_UpdateServerCompleted);<br />
webService.GetAllCompleted += <span style="color: blue;">new</span> <span style="color: #2b91af;">EventHandler</span><RCTestService.GetAllCompletedEventArgs>(webService_GetAllCompleted);<br />
<br />
RCTestService.UpdateRequest request = <span style="color: blue;">new</span> RCTestService.UpdateRequest();<br />
request.UserName = <span style="color: #a31515;">"username"</span>;<br />
request.Password = <span style="color: #a31515;">"password"</span>;<br />
request.Country = System.Globalization.<span style="color: #2b91af;">CultureInfo</span>.CurrentCulture.Name;<br />
<br />
webService.UpdateServerAsync(request);<br />
<br />
runThread = <span style="color: blue;">true</span>;<br />
timer.Start();<br />
<br />
txtCounter.Text = <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"Data will be updated every {0} seconds."</span>, checkTimeSpan.Seconds);<br />
}</div>
</div>
</div>
And the callback methods are also pretty much the same<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:6adc43a3-9adc-4a70-bfb9-6778eed6856a" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">void</span> webService_GetAllCompleted(<span style="color: blue;">object</span> sender, RCTestService.GetAllCompletedEventArgs e)<br />
{<br />
<span style="color: blue;">if</span> (e.Result.Success)<br />
{<br />
getAllResponse = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><RCTestService.TableData>(e.Result.Data);<br />
<br />
RunAsCrossThreadSafeCode(<br />
<span style="color: blue;">delegate</span><br />
{<br />
txtData.Text = <span style="color: blue;">string</span>.Empty;<br />
<span style="color: blue;">foreach</span> (RCTestService.TableData data <span style="color: blue;">in</span> getAllResponse)<br />
{<br />
txtData.Text += <span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"{0} {1}\n"</span>, data.Country, data.Count);<br />
}<br />
});<br />
<br />
<br />
}<br />
<span style="color: blue;">else</span><br />
MessageBox.Show(<span style="color: #a31515;">"Error"</span>, e.Result.Message, MessageBoxButton.OK);<br />
}<br />
<br />
<span style="color: blue;">void</span> webService_UpdateServerCompleted(<span style="color: blue;">object</span> sender, RCTestService.UpdateServerCompletedEventArgs e)<br />
{<br />
<span style="color: blue;">if</span> (e.Result.Success)<br />
{<br />
MessageBox.Show(<span style="color: #a31515;">"All Good"</span>, <span style="color: #a31515;">"Server was updated."</span>, MessageBoxButton.OK);<br />
}<br />
<span style="color: blue;">else</span><br />
MessageBox.Show(<span style="color: #a31515;">"Error"</span>, e.Result.Message, MessageBoxButton.OK);<br />
}</div>
</div>
</div>
But as you can see I have had to do some extra work to be able to populate the TextBlock control from the callback. This is because the code calling the service method is being called from another thread. I am doing this as in Silverlight I don’t have a game loop, so as in XNA we can just up a check in the Update method, here I have fired off a new thread and do they check in there, the tread looks like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:9adb8b3f-8c63-41db-84c6-b3ada902c820" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">static</span> <span style="color: blue;">void</span> callTimer()<br />
{<br />
<span style="color: blue;">while</span> (runThread)<br />
{<br />
<span style="color: blue;">if</span> (<span style="color: #2b91af;">DateTime</span>.Now.TimeOfDay - lastCheck > checkTimeSpan)<br />
{<br />
lastCheck = <span style="color: #2b91af;">DateTime</span>.Now.TimeOfDay;<br />
<br />
RCTestService.RequestBase req = <span style="color: blue;">new</span> RCTestService.RequestBase();<br />
req.UserName = <span style="color: #a31515;">"username"</span>;<br />
req.Password = <span style="color: #a31515;">"password"</span>;<br />
<br />
webService.GetAllAsync(req);<br />
}<br />
Thread.Sleep(1);<br />
}<br />
}</div>
</div>
</div>
Also the RunAsCrossThreadSafeCode is mine (well after I used Google to find out how to do it) and that method looks like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2194b540-ff23-4313-b919-73b56b030d1b" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span><br />
<span style="color: grey;">///</span><span style="color: green;"> Method to run a delegate as cross thread safe code</span><br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span><br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><param name="code"></span><span style="color: green;">Code to be ran</span><span style="color: grey;"></param></span><br />
<span style="color: blue;">protected</span> <span style="color: blue;">static</span> <span style="color: blue;">void</span> RunAsCrossThreadSafeCode(CrossThreadCode code)<br />
{<br />
<span style="color: blue;">using</span> (AutoResetEvent are = <span style="color: blue;">new</span> AutoResetEvent(<span style="color: blue;">false</span>))<br />
{<br />
System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =><br />
{<br />
<span style="color: green;">// Code here</span><br />
code();<br />
<br />
are.Set();<br />
});<br />
are.WaitOne();<br />
}<br />
}</div>
</div>
</div>
As you can see it takes a CrossThreadCode delegate, again created at the top of the class like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:21314ca9-dad8-4632-9ea4-4796cf2b0f62" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"><summary></span><br />
<span style="color: grey;">///</span><span style="color: green;"> Delegate used to run none cross thread safe code in a cross thread safe manor.</span><br />
<span style="color: grey;">///</span><span style="color: green;"> </span><span style="color: grey;"></summary></span><br />
<span style="color: blue;">protected</span> <span style="color: blue;">delegate</span> <span style="color: blue;">void</span> <span style="color: #2b91af;">CrossThreadCode</span>();</div>
</div>
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgr5QsH1reD99CrILfOsKq3WylqF7pkWPIVPSF2QO65Q7HXKQU9EhkIs3ALFzXJq40LhUT2z-3Jmbl4Kh_xs3hHVNYsj_SYVCihwdt_D_e1cj7cRzi8lIAJk3mb_whkC36N7fpFeoAVjIHt/s1600/0820.image_thumb_2D476267.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgr5QsH1reD99CrILfOsKq3WylqF7pkWPIVPSF2QO65Q7HXKQU9EhkIs3ALFzXJq40LhUT2z-3Jmbl4Kh_xs3hHVNYsj_SYVCihwdt_D_e1cj7cRzi8lIAJk3mb_whkC36N7fpFeoAVjIHt/s320/0820.image_thumb_2D476267.png" width="171" /></a></div>
<br />
And that’s pretty much it really. I know it seems like a lot to sort out and to take in at first, but once you have written a few services you will love it, I do :) I know I may go around the houses and do stuff the long winded way, so if you read this and have any advice or tips to add then please feel free to comment and let us all know how you stream line the process. Or you know of a great host for ASP.NET, share that too. If you have any issues creating your WCF service then let us know, you never know we might be able to help :P <br />
Hope I have not scared you off of confused you when it comes to creating services for your game, and I hope this post helps you realize the potential you have in your game with web services. <br />
ALL the source is available <a href="http://xna-uk.net/media/p/8437.aspx">here</a> <span style="color: red;"><strong>[Not yet uploaded]</strong></span>Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com2tag:blogger.com,1999:blog-5358009355383119512.post-87685577079590866372012-10-04T06:59:00.001-07:002012-10-04T06:59:26.763-07:00Reason for Recent Radio Silence…<p>Hello to anyone still following this blog. I just thought I should explain my (more than usual) silence over the last few months. In November we found out that my Mother is terminally ill with cancer. This has made it difficult for me to get into writing posts and helping out as much as I normally do on the site and around the community. As you can imagine this blog and other none family related things have been low on my list of priorities. My mother is still with us, but very ill now. <p>With that said, I do have some items I want to start writing up and posting, it’s just a matter of me getting time and motivation to do that. I have a few bits to write on WP7 development, I have been doing some Silverlight at work and have a few things to share about that as well as some more GPU postings, from ST:Excalibur to DX10/11. <p>I hope I have not ruined your day with my sad news, but I just wanted to let those that do follow the blog what’s going on.</p> Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-75363200626753622332012-10-04T06:57:00.001-07:002012-10-05T06:44:37.793-07:00XNA a Kinect ComponentSo, I have been playing about with the <a href="http://research.microsoft.com/en-us/um/redmond/projects/kinectsdk/">Kinect Beta</a>, having finally got a power supply for my Kinect sensor (I got a Slim XBox). I am not doing a great deal with this post, just thought if you have a sensor you might want to start playing with it in XNA, so I have created a component you can use to get the video, depth and skeletal data back from the device. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRJQ0p8Q3oWQaGGoevucaOCHuM6IHtIjbyVgbZlJQaW7qQXBIXSYZbh4IZaMmoIrO04lxEzLgx3IggLEDRvS66N4-Hflv801nug0tegmNbC-uEjxiGtJWmSHLVDxArsHnv3AEBH2RTGYye/s1600/4237.Kinect1_5BA6628A.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="96" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRJQ0p8Q3oWQaGGoevucaOCHuM6IHtIjbyVgbZlJQaW7qQXBIXSYZbh4IZaMmoIrO04lxEzLgx3IggLEDRvS66N4-Hflv801nug0tegmNbC-uEjxiGtJWmSHLVDxArsHnv3AEBH2RTGYye/s320/4237.Kinect1_5BA6628A.jpg" width="320" /></a></div>
<br />
<br />
Forgive the state of my living room, but this shows the video and depth data being retrieved from the device, notice the FPS is at 30, the project will run at 60, but the sensor runs at 30, so it gets a bit jittery if you are running at 60 FPS, so I have restricted it to 30. <br />
So here is the simple component you can use to get data back from the device.<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:f9762259-450e-4836-9eca-03b9dd566076" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">using</span> System;<br />
<span style="color: blue;">using</span> System.Collections.Generic;<br />
<span style="color: blue;">using</span> System.Linq;<br />
<span style="color: blue;">using</span> System.Text;<br />
<br />
<span style="color: blue;">using</span> Microsoft.Xna.Framework;<br />
<span style="color: blue;">using</span> Microsoft.Xna.Framework.Graphics;<br />
<br />
<span style="color: blue;">using</span> Microsoft.Research.Kinect.Nui;<br />
<span style="color: blue;">using</span> Microsoft.Research.Kinect.Audio;<br />
<br />
<span style="color: blue;">namespace</span> KinectXNA<br />
{<br />
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">KinectXNAComponent</span> : GameComponent<br />
{<br />
<span style="color: blue;">public</span> Runtime nui;<br />
<span style="color: blue;">public</span> Texture2D colorMap;<br />
<span style="color: blue;">public</span> Texture2D depthMap;<br />
<span style="color: blue;">public</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">Point</span>> renderJoints = <span style="color: blue;">new</span> <span style="color: #2b91af;">List</span><<span style="color: #2b91af;">Point</span>>();<br />
<br />
<span style="color: blue;">const</span> <span style="color: blue;">int</span> RED_IDX = 2;<br />
<span style="color: blue;">const</span> <span style="color: blue;">int</span> GREEN_IDX = 1;<br />
<span style="color: blue;">const</span> <span style="color: blue;">int</span> BLUE_IDX = 0;<br />
<span style="color: blue;">byte</span>[] depthFrame32 = <span style="color: blue;">new</span> <span style="color: blue;">byte</span>[320 * 240 * 4];<br />
<br />
<span style="color: blue;">public</span> ImageResolution VideoStreamSize = ImageResolution.Resolution640x480;<br />
<span style="color: blue;">public</span> ImageResolution DepthStreamSize = ImageResolution.Resolution320x240; <br />
<br />
<span style="color: blue;">public</span> <span style="color: #2b91af;">Point</span> depthResolution = <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>();<br />
<span style="color: blue;">public</span> <span style="color: #2b91af;">Point</span> videoResolution = <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>();<br />
<br />
<span style="color: blue;">public</span> KinectXNAComponent(Game game)<br />
: <span style="color: blue;">base</span>(game)<br />
{<br />
game.Services.AddService(<span style="color: blue;">this</span>.GetType(), <span style="color: blue;">this</span>);<br />
game.Components.Add(<span style="color: blue;">this</span>);<br />
}<br />
<br />
<span style="color: blue;">public</span> <span style="color: blue;">override</span> <span style="color: blue;">void</span> Initialize()<br />
{<br />
<span style="color: blue;">base</span>.Initialize();<br />
<br />
nui = <span style="color: blue;">new</span> Runtime();<br />
nui.Initialize(RuntimeOptions.UseDepthAndPlayerIndex | RuntimeOptions.UseSkeletalTracking | RuntimeOptions.UseColor);<br />
<br />
nui.VideoStream.Open(ImageStreamType.Video, 2, VideoStreamSize, ImageType.Color);<br />
nui.DepthStream.Open(ImageStreamType.Depth, 2, DepthStreamSize, ImageType.DepthAndPlayerIndex);<br />
<br />
<span style="color: blue;">if</span> (depthResolution == <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>())<br />
{<br />
<span style="color: blue;">switch</span> (nui.DepthStream.Resolution)<br />
{<br />
<span style="color: blue;">case</span> ImageResolution.Resolution1280x1024:<br />
depthResolution = <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>(1280, 1024);<br />
depthFrame32 = <span style="color: blue;">new</span> <span style="color: blue;">byte</span>[1280 * 1024 * 4];<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> ImageResolution.Resolution320x240:<br />
depthResolution = <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>(320, 240);<br />
depthFrame32 = <span style="color: blue;">new</span> <span style="color: blue;">byte</span>[320 * 240 * 4];<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> ImageResolution.Resolution640x480:<br />
depthResolution = <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>(640, 480);<br />
depthFrame32 = <span style="color: blue;">new</span> <span style="color: blue;">byte</span>[640 * 480 * 4];<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> ImageResolution.Resolution80x60:<br />
depthResolution = <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>(80, 60);<br />
depthFrame32 = <span style="color: blue;">new</span> <span style="color: blue;">byte</span>[80 * 60 * 4];<br />
<span style="color: blue;">break</span>;<br />
}<br />
}<br />
<br />
<span style="color: blue;">if</span> (videoResolution == <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>())<br />
{<br />
<span style="color: blue;">switch</span> (nui.VideoStream.Resolution)<br />
{<br />
<span style="color: blue;">case</span> ImageResolution.Resolution1280x1024:<br />
videoResolution = <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>(1280, 1024);<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> ImageResolution.Resolution320x240:<br />
videoResolution = <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>(320, 240);<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> ImageResolution.Resolution640x480:<br />
videoResolution = <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>(640, 480);<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> ImageResolution.Resolution80x60:<br />
videoResolution = <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>(80, 60);<br />
<span style="color: blue;">break</span>;<br />
}<br />
}<br />
<br />
<br />
nui.DepthFrameReady += <span style="color: blue;">new</span> <span style="color: #2b91af;">EventHandler</span><ImageFrameReadyEventArgs>(nui_DepthFrameReady);<br />
nui.SkeletonFrameReady += <span style="color: blue;">new</span> <span style="color: #2b91af;">EventHandler</span><SkeletonFrameReadyEventArgs>(nui_SkeletonFrameReady);<br />
nui.VideoFrameReady += <span style="color: blue;">new</span> <span style="color: #2b91af;">EventHandler</span><ImageFrameReadyEventArgs>(nui_ColorFrameReady);<br />
}<br />
<br />
<span style="color: blue;">void</span> nui_ColorFrameReady(<span style="color: blue;">object</span> sender, ImageFrameReadyEventArgs e)<br />
{<br />
PlanarImage Image = e.ImageFrame.Image;<br />
<br />
<span style="color: blue;">if</span> (colorMap == <span style="color: blue;">null</span>)<br />
colorMap = <span style="color: blue;">new</span> Texture2D(Game.GraphicsDevice, Image.Width, Image.Height, <span style="color: blue;">false</span>, SurfaceFormat.Color);<br />
<br />
<span style="color: blue;">byte</span>[] data = Image.Bits;<br />
<br />
<span style="color: green;">// Flip the R with the B</span><br />
<span style="color: blue;">for</span> (<span style="color: blue;">int</span> b = 0; b < data.Length; b+=4)<br />
{<br />
<span style="color: blue;">byte</span> tmp = data[b];<br />
data[b] = data[b + 2];<br />
data[b + 2] = tmp;<br />
}<br />
<br />
colorMap.SetData<<span style="color: blue;">byte</span>>(data);<br />
}<br />
<br />
<span style="color: blue;">void</span> nui_DepthFrameReady(<span style="color: blue;">object</span> sender, ImageFrameReadyEventArgs e)<br />
{<br />
PlanarImage Image = e.ImageFrame.Image;<br />
<br />
<span style="color: blue;">if</span> (depthMap == <span style="color: blue;">null</span>)<br />
depthMap = <span style="color: blue;">new</span> Texture2D(Game.GraphicsDevice, Image.Width, Image.Height, <span style="color: blue;">false</span>, SurfaceFormat.Color);<br />
<br />
depthMap.SetData<<span style="color: blue;">byte</span>>(convertDepthFrame(Image.Bits)); <br />
}<br />
<br />
<span style="color: green;">// Converts a 16-bit grayscale depth frame which includes player indexes into a 32-bit frame</span><br />
<span style="color: green;">// that displays different players in different colors</span><br />
<span style="color: blue;">byte</span>[] convertDepthFrame(<span style="color: blue;">byte</span>[] depthFrame16)<br />
{<br />
<span style="color: blue;">for</span> (<span style="color: blue;">int</span> i16 = 0, i32 = 0; i16 < depthFrame16.Length && i32 < depthFrame32.Length; i16 += 2, i32 += 4)<br />
{<br />
<span style="color: blue;">int</span> player = depthFrame16[i16] & 0x07;<br />
<span style="color: blue;">int</span> realDepth = (depthFrame16[i16 + 1] << 5) | (depthFrame16[i16] >> 3);<br />
<span style="color: green;">// transform 13-bit depth information into an 8-bit intensity appropriate</span><br />
<span style="color: green;">// for display (we disregard information in most significant bit)</span><br />
<span style="color: blue;">byte</span> intensity = (<span style="color: blue;">byte</span>)(255 - (255 * realDepth / 0x0fff));<br />
<br />
depthFrame32[i32 + RED_IDX] = 0;<br />
depthFrame32[i32 + GREEN_IDX] = 0;<br />
depthFrame32[i32 + BLUE_IDX] = 0;<br />
<br />
<span style="color: green;">// choose different display colors based on player</span><br />
<span style="color: blue;">switch</span> (player)<br />
{<br />
<span style="color: blue;">case</span> 0:<br />
depthFrame32[i32 + RED_IDX] = (<span style="color: blue;">byte</span>)(intensity / 2);<br />
depthFrame32[i32 + GREEN_IDX] = (<span style="color: blue;">byte</span>)(intensity / 2);<br />
depthFrame32[i32 + BLUE_IDX] = (<span style="color: blue;">byte</span>)(intensity / 2);<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> 1:<br />
depthFrame32[i32 + RED_IDX] = intensity;<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> 2:<br />
depthFrame32[i32 + GREEN_IDX] = intensity;<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> 3:<br />
depthFrame32[i32 + RED_IDX] = (<span style="color: blue;">byte</span>)(intensity / 4);<br />
depthFrame32[i32 + GREEN_IDX] = (<span style="color: blue;">byte</span>)(intensity);<br />
depthFrame32[i32 + BLUE_IDX] = (<span style="color: blue;">byte</span>)(intensity);<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> 4:<br />
depthFrame32[i32 + RED_IDX] = (<span style="color: blue;">byte</span>)(intensity);<br />
depthFrame32[i32 + GREEN_IDX] = (<span style="color: blue;">byte</span>)(intensity);<br />
depthFrame32[i32 + BLUE_IDX] = (<span style="color: blue;">byte</span>)(intensity / 4);<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> 5:<br />
depthFrame32[i32 + RED_IDX] = (<span style="color: blue;">byte</span>)(intensity);<br />
depthFrame32[i32 + GREEN_IDX] = (<span style="color: blue;">byte</span>)(intensity / 4);<br />
depthFrame32[i32 + BLUE_IDX] = (<span style="color: blue;">byte</span>)(intensity);<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> 6:<br />
depthFrame32[i32 + RED_IDX] = (<span style="color: blue;">byte</span>)(intensity / 2);<br />
depthFrame32[i32 + GREEN_IDX] = (<span style="color: blue;">byte</span>)(intensity / 2);<br />
depthFrame32[i32 + BLUE_IDX] = (<span style="color: blue;">byte</span>)(intensity);<br />
<span style="color: blue;">break</span>;<br />
<span style="color: blue;">case</span> 7:<br />
depthFrame32[i32 + RED_IDX] = (<span style="color: blue;">byte</span>)(255 - intensity);<br />
depthFrame32[i32 + GREEN_IDX] = (<span style="color: blue;">byte</span>)(255 - intensity);<br />
depthFrame32[i32 + BLUE_IDX] = (<span style="color: blue;">byte</span>)(255 - intensity);<br />
<span style="color: blue;">break</span>;<br />
}<br />
}<br />
<span style="color: blue;">return</span> depthFrame32;<br />
}<br />
<br />
<span style="color: blue;">void</span> nui_SkeletonFrameReady(<span style="color: blue;">object</span> sender, SkeletonFrameReadyEventArgs e)<br />
{<br />
SkeletonFrame skeletonFrame = e.SkeletonFrame;<br />
<br />
renderJoints.Clear();<br />
<span style="color: blue;">foreach</span> (SkeletonData data <span style="color: blue;">in</span> skeletonFrame.Skeletons)<br />
{<br />
<span style="color: blue;">if</span> (SkeletonTrackingState.Tracked == data.TrackingState)<br />
{<br />
<span style="color: blue;">foreach</span> (Joint joint <span style="color: blue;">in</span> data.Joints)<br />
{<br />
renderJoints.Add(getDisplayPosition(joint));<br />
}<br />
}<br />
}<br />
}<br />
<br />
<span style="color: blue;">private</span> <span style="color: #2b91af;">Point</span> getDisplayPosition(Joint joint)<br />
{<br />
<span style="color: blue;">if</span> (depthResolution != <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>() && videoResolution != <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>())<br />
{<br />
<span style="color: blue;">float</span> depthX, depthY;<br />
nui.SkeletonEngine.SkeletonToDepthImage(joint.Position,<br />
<span style="color: blue;">out</span> depthX, <span style="color: blue;">out</span> depthY);<br />
<br />
depthX = <span style="color: #2b91af;">Math</span>.Max(0, <span style="color: #2b91af;">Math</span>.Min(depthX * depthResolution.X, depthResolution.X));<br />
depthY = <span style="color: #2b91af;">Math</span>.Max(0, <span style="color: #2b91af;">Math</span>.Min(depthY * depthResolution.Y, depthResolution.Y));<br />
<br />
<span style="color: blue;">int</span> colorX, colorY;<br />
ImageViewArea iv = <span style="color: blue;">new</span> ImageViewArea();<br />
<span style="color: green;">// only ImageResolution.Resolution640x480 is supported at this point</span><br />
nui.NuiCamera.GetColorPixelCoordinatesFromDepthPixel(nui.VideoStream.Resolution, iv, (<span style="color: blue;">int</span>)depthX, (<span style="color: blue;">int</span>)depthY, (<span style="color: blue;">short</span>)0, <span style="color: blue;">out</span> colorX, <span style="color: blue;">out</span> colorY);<br />
<br />
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>((<span style="color: blue;">int</span>)(Game.GraphicsDevice.Viewport.Width * colorX / videoResolution.X), (<span style="color: blue;">int</span>)(Game.GraphicsDevice.Viewport.Height * colorY / videoResolution.Y));<br />
}<br />
<span style="color: blue;">else</span><br />
<span style="color: blue;">return</span> <span style="color: blue;">new</span> <span style="color: #2b91af;">Point</span>();<br />
}<br />
}<br />
}</div>
</div>
</div>
So, provided you have a sensor and have the SDK installed you can instantiate the component like this:<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1ef03743-b08d-4c91-9e2a-0611c2091a83" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
kinect = <span style="color: blue;">new</span> <span style="color: #2b91af;">KinectXNAComponent</span>(<span style="color: blue;">this</span>);</div>
</div>
</div>
You can then render the texture data coming back from the sensor in your draw call like this:<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:044f507b-0279-4dc4-9dca-9a438319059f" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
spriteBatch.Begin(SpriteSortMode.Immediate,BlendState.Opaque);<br />
<br />
<span style="color: blue;">if</span> (kinect.depthMap != <span style="color: blue;">null</span>)<br />
{<br />
spriteBatch.Draw(kinect.depthMap, <span style="color: blue;">new</span> <span style="color: #2b91af;">Rectangle</span>(GraphicsDevice.Viewport.Width / 2, 0, GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2), <span style="color: #2b91af;">Color</span>.White);<br />
}<br />
<br />
<span style="color: blue;">if</span> (kinect.colorMap != <span style="color: blue;">null</span>)<br />
{<br />
GraphicsDevice.VertexSamplerStates[0] = SamplerState.LinearClamp;<br />
spriteBatch.Draw(kinect.colorMap, <span style="color: blue;">new</span> <span style="color: #2b91af;">Rectangle</span>(0, 0, GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2), <span style="color: #2b91af;">Color</span>.White);<br />
}<br />
<br />
<span style="color: blue;">if</span> (kinect.renderJoints != <span style="color: blue;">null</span>)<br />
{<br />
<span style="color: blue;">int</span> sc = kinect.renderJoints.Count;<br />
<span style="color: blue;">for</span> (<span style="color: blue;">int</span> s = 0; s < sc; s++)<br />
{<br />
spriteBatch.Draw(jointImage, <span style="color: blue;">new</span> <span style="color: #2b91af;">Rectangle</span>(kinect.renderJoints[s].X, kinect.renderJoints[s].Y, 8, 8), <span style="color: #2b91af;">Color</span>.Gold);<br />
}<br />
}<br />
<br />
spriteBatch.End();</div>
</div>
</div>
What I love about this, is when you look at the depth data output with two people in it is actually able to differentiate (thanks to the MS method I got of the SDK) between the two different people, it actually colors them different in the map!! ACE!! <br />
In that above sample I am also rendering the joints to the screen, but not to just the video out put but across the whole screen, you will see what I mean if you use it. <br />
I am loving playing with this device, so hope to do some more XNA/Kinect cross over posts :D I am also hoping to put up some sample projects like I have been with my pure XNA samples. Anyway, hope you find this little start useful.<br />
<br />
<br />
<br />
<br />
Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-67752607135294112092012-10-04T06:52:00.001-07:002012-10-04T06:52:39.139-07:00SSAO, a start<div style="padding-bottom: 0px; padding-left: 0px; width: 425px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:397f5702-8407-464f-8e4c-cdb7ebb5ae4d" class="wlWriterEditableSmartContent"><embed src="http://www.youtube.com/v/7mshXJNzI-o" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></div> <p>So, have now been playing with <a href="http://en.wikipedia.org/wiki/Screen_Space_Ambient_Occlusion">SSAO</a> (Screen Space Ambient Occlusion) after finding this great article on GameDev.net<br><a href="http://www.gamedev.net/page/resources/_/reference/programming/140/lighting-and-shading/a-simple-and-practical-approach-to-ssao-r2753">http://www.gamedev.net/page/resources/_/reference/programming/140/lighting-an...</a><br>I am sure it's still not 100% right, but it has me on the right road I think. <p>Also, thanks to <a href="http://xna-uk.net/members/manzanotti/default.aspx">manzanotti</a> for the music, it's a refreshing change :)</p> Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-86992817631458492832012-07-13T05:56:00.001-07:002016-02-29T13:39:36.253-08:00Crepuscular (God) Rays and Web UI Sample<div class="wlWriterEditableSmartContent" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:2bc84fcd-8e1e-4beb-af80-4f029702e2fd" style="display: block; float: none; margin-left: auto; margin-right: auto; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; width: 425px;">
<embed height="350" src="http://www.youtube.com/v/toS1n_VHLRI" type="application/x-shockwave-flash" width="425" wmode="transparent"></embed></div>
OK, this is two samples rolled into one, the first part of this sample will cover the post processing effect of Crepuscular rays I have created in XNA based on the GPU Gems 3 article <a href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch13.html">Volumetric Light Scattering as a Post-Process</a>. The second part of this post covers the Web UI that is used in the sample. I initially intended to give a short talk on it at the September 2011 XNA-UK meeting but we had a great talk from the guys over at <a href="http://indiecity.com/">IndieCity.com</a> and so I never got around to it. <br />
<strong>Crepuscular Rays Effect Overview</strong> <br />
So, after reading the GPU Gems article I thought it should be easy to get the effect working in my Post Processing framework, which, if you missed it, I posted the <a href="http://xna-uk.net/media/p/7486.aspx">source</a> for a while ago, have made a few changes in my latest version, but that framework should still fly. I also thought that I could use my existing sun post process, again, if you missed<a href="http://www.sgtconker.com/2010/04/article-sun-and-lens-flare-as-a-post-process/">that</a>, you can find it on stg conker, and incorporate it into the effect. So, the steps used to create this effect are, render the sun to a render target, black out any occluded pixels in that image by matching them against the depth buffer (created when you rendered the scene), pass this image onto the GPU Gems god ray pixel shader, use a bright pass pixel shader (taken from my Bloom shader) to brighten the rays, then render this final texture and blend it back with the scene image. <br />
All in all it’s a 5 pass effect, this could be reduced by having the occlusion pass in with the rendering of the original sun/light source pass, and negating the bright pass. So, lets get into the shaders, probably wont post any C# here as you have the March 2011 talk and code I gave to fall back on, a change you will notice is that I have moved away from using SpriteBatch to render the RT’s as this restricted the post processing framework to Shader model 2. <br />
<strong>LightSourceMask.fx (or the old Sun shader tidied up a bit)</strong><br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:b5fc0057-299b-4b02-9b19-e5d1d85e04e6" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
#include "PPVertexShader.fxh"<br />
float3 lightPosition;<br />
float4x4 matVP;<br />
float2 halfPixel;<br />
float SunSize = 1500;<br />
texture flare;<br />
sampler Flare = sampler_state<br />
{<br />
Texture = (flare);<br />
AddressU = CLAMP;<br />
AddressV = CLAMP;<br />
};<br />
float4 LightSourceMaskPS(float2 texCoord : TEXCOORD0 ) : COLOR0<br />
{<br />
texCoord -= halfPixel;<br />
// Get the scene<br />
float4 col = 0;<br />
// Find the suns position in the world and map it to the screen space.<br />
float4 ScreenPosition = mul(lightPosition,matVP);<br />
float scale = ScreenPosition.z;<br />
ScreenPosition.xyz /= ScreenPosition.w;<br />
ScreenPosition.x = ScreenPosition.x/2.0f+0.5f;<br />
ScreenPosition.y = (-ScreenPosition.y/2.0f+0.5f);<br />
// Are we lokoing in the direction of the sun?<br />
if(ScreenPosition.w > 0)<br />
{ <br />
float2 coord;<br />
float size = SunSize / scale;<br />
float2 center = ScreenPosition.xy;<br />
coord = .5 - (texCoord - center) / size * .5;<br />
col += (pow(tex2D(Flare,coord),2) * 1) * 2; <br />
}<br />
return col; <br />
}<br />
technique LightSourceMask<br />
{<br />
pass p0<br />
{<br />
VertexShader = compile vs_2_0 VertexShaderFunction();<br />
PixelShader = compile ps_2_0 LightSourceMaskPS();<br />
}<br />
}</div>
</div>
</div>
You can see at the top there a reference to aPPVertexShader.fxh, this is just a header that has the vertex shader in it, I do this so I don’t have to repeat the shader in shaders that share the same vertex shader. <br />
So, like in the sun shader, we find the point in world space of the light source and render the texture. <br />
So we end up with an image like this: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjckpIxtuMELyooLmGeMvA9mInZWeCtjMUJ3hHE2qPKRbi_GM8WHPa7GuNjgeuyvxQcS97TMWPyR0ifQBAnogAxJWE-pJWxuN2zCD0hJhCunhzPV9faIb1lu_bvbHMKGFk_xuFCEBwGakIK/s1600/2677.image_thumb_34AFABC3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjckpIxtuMELyooLmGeMvA9mInZWeCtjMUJ3hHE2qPKRbi_GM8WHPa7GuNjgeuyvxQcS97TMWPyR0ifQBAnogAxJWE-pJWxuN2zCD0hJhCunhzPV9faIb1lu_bvbHMKGFk_xuFCEBwGakIK/s320/2677.image_thumb_34AFABC3.png" width="320" /></a></div>
<br />
<br />
<strong>LightSceneMask.fx</strong><br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:ad4ce86f-794d-4ce8-b3da-48d15bb2bc29" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
#include "PPVertexShader.fxh"<br />
float3 lightPosition;<br />
float4x4 matVP;<br />
float4x4 matInvVP;<br />
float2 halfPixel;<br />
sampler2D Scene: register(s0){<br />
AddressU = Mirror;<br />
AddressV = Mirror;<br />
};<br />
texture depthMap;<br />
sampler2D DepthMap = sampler_state<br />
{<br />
Texture = <depthMap>;<br />
MinFilter = Point;<br />
MagFilter = Point;<br />
MipFilter = None;<br />
};<br />
float4 LightSourceSceneMaskPS(float2 texCoord : TEXCOORD0) : COLOR0<br />
{<br />
float depthVal = 1 - (tex2D(DepthMap, texCoord).r);<br />
float4 scene = tex2D(Scene,texCoord);<br />
float4 position;<br />
position.x = texCoord.x * 2.0f - 1.0f;<br />
position.y = -(texCoord.y * 2.0f - 1.0f);<br />
position.z = depthVal;<br />
position.w = 1.0f;<br />
// Pixel pos in the world<br />
float4 worldPos = mul(position, matInvVP);<br />
worldPos /= worldPos.w;<br />
// Find light pixel position<br />
float4 ScreenPosition = mul(lightPosition, matVP);<br />
ScreenPosition.xyz /= ScreenPosition.w;<br />
ScreenPosition.x = ScreenPosition.x/2.0f+0.5f;<br />
ScreenPosition.y = (-ScreenPosition.y/2.0f+0.5f);<br />
// If the pixel is infront of the light source, blank it out..<br />
if(depthVal < ScreenPosition.z - .00025)<br />
scene = 0;<br />
return scene;<br />
}<br />
technique LightSourceSceneMask<br />
{<br />
pass p0<br />
{<br />
VertexShader = compile vs_2_0 VertexShaderFunction();<br />
PixelShader = compile ps_2_0 LightSourceSceneMaskPS();<br />
}<br />
}</div>
</div>
</div>
In this shader we take the renderer light scene and then black out the pixels that are occluded by objects in the scene, which then gives us an image like this: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCDjeDkAeeuTX9P_58I_zT8pFO955f7QL_DN14ypYhyphenhyphensosT01CXbDtt7-YYN_M3wYMliuDRERJgSJVz3tfq2kqLZ0f2Pi0AxEpYGe5Bw2E5sNGm9B3IVRQBcclBix4_fyHBJ1RLRm4clSc/s1600/8446.image_thumb_52213B28.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCDjeDkAeeuTX9P_58I_zT8pFO955f7QL_DN14ypYhyphenhyphensosT01CXbDtt7-YYN_M3wYMliuDRERJgSJVz3tfq2kqLZ0f2Pi0AxEpYGe5Bw2E5sNGm9B3IVRQBcclBix4_fyHBJ1RLRm4clSc/s320/8446.image_thumb_52213B28.png" width="320" /></a></div>
<br />
<br />
<strong>LightRays.fx</strong><br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:1bbcf0fc-4516-4fe6-9e20-55d36fd80bff" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
#include "PPVertexShader.fxh"<br />
#define NUM_SAMPLES 128<br />
float3 lightPosition;<br />
float4x4 matVP;<br />
float2 halfPixel;<br />
float Density = .5f;<br />
float Decay = .95f;<br />
float Weight = 1.0f;<br />
float Exposure = .15f;<br />
sampler2D Scene: register(s0){<br />
AddressU = Clamp;<br />
AddressV = Clamp;<br />
};<br />
float4 lightRayPS( float2 texCoord : TEXCOORD0 ) : COLOR0<br />
{<br />
// Find light pixel position<br />
float4 ScreenPosition = mul(lightPosition, matVP);<br />
ScreenPosition.xyz /= ScreenPosition.w;<br />
ScreenPosition.x = ScreenPosition.x/2.0f+0.5f;<br />
ScreenPosition.y = (-ScreenPosition.y/2.0f+0.5f);<br />
float2 TexCoord = texCoord - halfPixel;<br />
float2 DeltaTexCoord = (TexCoord - ScreenPosition.xy);<br />
DeltaTexCoord *= (1.0f / NUM_SAMPLES * Density);<br />
DeltaTexCoord = DeltaTexCoord * clamp(ScreenPosition.w * ScreenPosition.z,0,.5f);<br />
float3 col = tex2D(Scene,TexCoord);<br />
float IlluminationDecay = 1.0;<br />
float3 Sample;<br />
for( int i = 0; i < NUM_SAMPLES; ++i )<br />
{<br />
TexCoord -= DeltaTexCoord;<br />
Sample = tex2D(Scene, TexCoord);<br />
Sample *= IlluminationDecay * Weight;<br />
col += Sample;<br />
IlluminationDecay *= Decay; <br />
}<br />
return float4(col * Exposure,1);<br />
if(ScreenPosition.w > 0)<br />
return float4(col * Exposure,1) * (ScreenPosition.w * .0025);<br />
else<br />
return 0;<br />
}<br />
technique LightRayFX<br />
{<br />
pass p0<br />
{<br />
VertexShader = compile vs_3_0 VertexShaderFunction();<br />
PixelShader = compile ps_3_0 lightRayPS();<br />
}<br />
}</div>
</div>
</div>
As you can see, this is pretty much the same shader in the GPU Gems article, but we calculate the onscreen light source position in the shader. This gives an image like this: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3dQHfkoaaT8PX5114uyNStXLO5LhgAYQuQE08og3yTEo_DyVLoI_T-PYIm2VX5vCT0lziV9JYMJruHXVHm-oS1tt_npLTq-CacAFdiTH2fseINPazf1q27UmLF1i4LqQ1VvN9xQR92qJK/s1600/0511.image_thumb_262075D2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3dQHfkoaaT8PX5114uyNStXLO5LhgAYQuQE08og3yTEo_DyVLoI_T-PYIm2VX5vCT0lziV9JYMJruHXVHm-oS1tt_npLTq-CacAFdiTH2fseINPazf1q27UmLF1i4LqQ1VvN9xQR92qJK/s320/0511.image_thumb_262075D2.png" width="320" /></a></div>
<br />
<br />
Pretty eh :D <br />
<strong>BrightPass.fx</strong><br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:0908a79a-2352-4293-a59e-6d12e5f44184" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
#include "PPVertexShader.fxh"<br />
uniform extern float BloomThreshold;<br />
float2 halfPixel;<br />
sampler TextureSampler : register(s0);<br />
float4 BrightPassPS(float2 texCoord : TEXCOORD0) : COLOR0<br />
{<br />
texCoord -= halfPixel;<br />
// Look up the original image color.<br />
float4 c = tex2D(TextureSampler, texCoord);<br />
// Adjust it to keep only values brighter than the specified threshold.<br />
return saturate((c - BloomThreshold) / (1 - BloomThreshold));<br />
}<br />
technique BloomExtract<br />
{<br />
pass P0<br />
{<br />
VertexShader = compile vs_2_0 VertexShaderFunction();<br />
PixelShader = compile ps_2_0 BrightPassPS();<br />
}<br />
}</div>
</div>
</div>
This shader just takes the scene and based on a threshold brightens it up like this: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJzrKxrx-q-p0oXkF8DlG3VSLFsj5q_PenXcUbjr7-SQXh4B4HCG01rAn23Xh3N1teqZZ0ATFPiqzPwwhBOg-tFZUcW_d0t18h7Ok2EFsTx0AiraeBjD_7coNIBWtXt9AM6kAINTTBP6AK/s1600/6303.image_thumb_332667B1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJzrKxrx-q-p0oXkF8DlG3VSLFsj5q_PenXcUbjr7-SQXh4B4HCG01rAn23Xh3N1teqZZ0ATFPiqzPwwhBOg-tFZUcW_d0t18h7Ok2EFsTx0AiraeBjD_7coNIBWtXt9AM6kAINTTBP6AK/s320/6303.image_thumb_332667B1.png" width="320" /></a></div>
<br />
<br />
<strong>SceneBlend.fx</strong><br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:2fcb6e9c-7579-4398-b34d-12380e9bcc3c" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
#include "PPVertexShader.fxh"<br />
float2 halfPixel;<br />
sampler2D Scene: register(s0){<br />
AddressU = Mirror;<br />
AddressV = Mirror;<br />
};<br />
texture OrgScene;<br />
sampler2D orgScene = sampler_state<br />
{<br />
Texture = <OrgScene>;<br />
AddressU = CLAMP;<br />
AddressV = CLAMP;<br />
};<br />
float4 BlendPS(float2 texCoord : TEXCOORD0 ) : COLOR0<br />
{<br />
texCoord -= halfPixel;<br />
float4 col = tex2D(orgScene,texCoord) * tex2D(Scene,texCoord);<br />
return col;<br />
}<br />
float4 AditivePS(float2 texCoord : TEXCOORD0 ) : COLOR0<br />
{<br />
texCoord -= halfPixel;<br />
float4 col = tex2D(orgScene,texCoord) + tex2D(Scene,texCoord);<br />
return col;<br />
}<br />
technique Blend<br />
{<br />
pass p0<br />
{<br />
VertexShader = compile vs_2_0 VertexShaderFunction();<br />
PixelShader = compile ps_2_0 BlendPS();<br />
}<br />
}<br />
technique Aditive<br />
{<br />
pass p0<br />
{<br />
VertexShader = compile vs_2_0 VertexShaderFunction();<br />
PixelShader = compile ps_2_0 AditivePS();<br />
}<br />
}</div>
</div>
</div>
And Finally we blend this with the original scene, the Additive technique is used in this sample, giving a final image like this: <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqSJ8Xg4W7hOuc0vAF0ybEfOJfWwU50B5VdGR-jikLAUdhm5ASky2pS3QhHbETHa4NsiAOUwwyw0Ec0KGOnVVy8tPT-8AojwVUOakGz-wOSoaWC4W09IsHHrlYfddXT96YTueK_B6vvoec/s1600/4721.image_thumb_1E70A6CC.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqSJ8Xg4W7hOuc0vAF0ybEfOJfWwU50B5VdGR-jikLAUdhm5ASky2pS3QhHbETHa4NsiAOUwwyw0Ec0KGOnVVy8tPT-8AojwVUOakGz-wOSoaWC4W09IsHHrlYfddXT96YTueK_B6vvoec/s320/4721.image_thumb_1E70A6CC.png" width="320" /></a></div>
<br />
<br />
So there you have the god ray post process. <br />
<strong>Web UI</strong> <br />
OK, so now onto the UI, I am using a third party library call <a href="http://awesomium.com/">Awesomium</a>, and it is indeed Awesome, well I think so. It is basically a web renderer, you give it a url, it renders it and spits out a texture, we can then render this texture. Now, if it just did that it would not be much use, thankfully we can wire up call backs to it and pass mouse and keyboard events to it. This means we can, through our game interact with the web page. It means you can create all your UI’s in HTML using great stuff like JQuery and any other web tech you can pile into your game. Now this sample has all it’s web UI local but you could serve the entire game UI from your site. <br />
I first came across this tool while working on <a href="http://stexcalibur.com/">ST:Excalibur</a> as we use it to drive the UI and was really impressed with it, so thought I would do a version for XNA. In order to use this tool you need to download the Awsomium source and compile the AwesmiumSharp project, once you have that there are a number of assemblies you will need from that build adding to your project, all the details on how to do this can be found in the ppt what comes with this sample. Once you have all that in place you can create a DrawableGameComponent like this one to handle your Web UI<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:e3329a5b-7212-4bee-8c9a-60d764c6f7b0" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">AwesomiumUIManager</span> : <span style="color: #2b91af;">DrawableGameComponent</span><br />
{<br />
<span style="color: blue;">public</span> <span style="color: blue;">int</span> thisWidth;<br />
<span style="color: blue;">public</span> <span style="color: blue;">int</span> thisHeight;<br />
<span style="color: blue;">protected</span> <span style="color: #2b91af;">Effect</span> webEffect;<br />
<span style="color: blue;">public</span> WebView webView;<br />
<span style="color: blue;">public</span> <span style="color: #2b91af;">Texture2D</span> webRender;<br />
<span style="color: blue;">protected</span> <span style="color: blue;">int</span>[] webData;<br />
<span style="color: blue;">public</span> <span style="color: blue;">bool</span> TransparentBackground = <span style="color: blue;">true</span>;<br />
<span style="color: blue;">protected</span> <span style="color: #2b91af;">SpriteBatch</span> spriteBatch<br />
{<br />
<span style="color: blue;">get</span> { <span style="color: blue;">return</span> (<span style="color: #2b91af;">SpriteBatch</span>)Game.Services.GetService(<span style="color: blue;">typeof</span>(<span style="color: #2b91af;">SpriteBatch</span>)); }<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">string</span> URL;<br />
<span style="color: blue;">public</span> AwesomiumUIManager(<span style="color: #2b91af;">Game</span> game, <span style="color: blue;">string</span> baseUrl)<br />
: <span style="color: blue;">base</span>(game)<br />
{<br />
URL = baseUrl;<br />
DrawOrder = <span style="color: blue;">int</span>.MaxValue;<br />
}<br />
<span style="color: blue;">protected</span> <span style="color: blue;">override</span> <span style="color: blue;">void</span> LoadContent()<br />
{<br />
WebCore.Config config = <span style="color: blue;">new</span> WebCore.Config();<br />
config.enableJavascript = <span style="color: blue;">true</span>;<br />
config.enablePlugins = <span style="color: blue;">true</span>;<br />
WebCore.Initialize(config);<br />
thisWidth = Game.GraphicsDevice.PresentationParameters.BackBufferWidth;<br />
thisHeight = Game.GraphicsDevice.PresentationParameters.BackBufferHeight;<br />
webView = WebCore.CreateWebview(thisWidth, thisHeight);<br />
webRender = <span style="color: blue;">new</span> <span style="color: #2b91af;">Texture2D</span>(GraphicsDevice, thisWidth, thisHeight, <span style="color: blue;">false</span>, <span style="color: #2b91af;">SurfaceFormat</span>.Color);<br />
webData = <span style="color: blue;">new</span> <span style="color: blue;">int</span>[thisWidth * thisHeight];<br />
webEffect = Game.Content.Load<<span style="color: #2b91af;">Effect</span>>(<span style="color: #a31515;">"Shaders/webEffect"</span>);<br />
ReLoad();<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">virtual</span> <span style="color: blue;">void</span> LoadFile(<span style="color: blue;">string</span> file)<br />
{<br />
LoadURL(<span style="color: blue;">string</span>.Format(<span style="color: #a31515;">"file:///{0}\\{1}"</span>, Directory.GetCurrentDirectory(), file).Replace(<span style="color: #a31515;">"\\"</span>, <span style="color: #a31515;">"/"</span>));<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">virtual</span> <span style="color: blue;">void</span> LoadURL(<span style="color: blue;">string</span> url)<br />
{<br />
URL = url;<br />
webView.LoadURL(url);<br />
webView.SetTransparent(TransparentBackground);<br />
webView.Focus();<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">virtual</span> <span style="color: blue;">void</span> ReLoad()<br />
{<br />
<span style="color: blue;">if</span> (URL.Contains(<span style="color: #a31515;">"http://"</span>) || URL.Contains(<span style="color: #a31515;">"file:///"</span>))<br />
LoadURL(URL);<br />
<span style="color: blue;">else</span><br />
LoadFile(URL);<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">virtual</span> <span style="color: blue;">void</span> CreateObject(<span style="color: blue;">string</span> name)<br />
{<br />
webView.CreateObject(name);<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">virtual</span> <span style="color: blue;">void</span> CreateObject(<span style="color: blue;">string</span> name, <span style="color: blue;">string</span> method, WebView.JSCallback callback)<br />
{<br />
CreateObject(name);<br />
webView.SetObjectCallback(name, method, callback);<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">virtual</span> <span style="color: blue;">void</span> PushData(<span style="color: blue;">string</span> name, <span style="color: blue;">string</span> method, <span style="color: blue;">params</span> JSValue[] args)<br />
{<br />
webView.CallJavascriptFunction(name, method, args);<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">void</span> LeftButtonDown()<br />
{<br />
webView.InjectMouseDown(MouseButton.Left);<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">void</span> LeftButtonUp()<br />
{<br />
webView.InjectMouseUp(MouseButton.Left);<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">void</span> MouseMoved(<span style="color: blue;">int</span> X, <span style="color: blue;">int</span> Y)<br />
{<br />
webView.InjectMouseMove(X, Y);<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">void</span> ScrollWheel(<span style="color: blue;">int</span> delta)<br />
{<br />
webView.InjectMouseWheel(delta);<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">void</span> KeyPressed(Keys key)<br />
{<br />
WebKeyboardEvent keyEvent = <span style="color: blue;">new</span> WebKeyboardEvent();<br />
keyEvent.type = WebKeyType.Char;<br />
keyEvent.text = <span style="color: blue;">new</span> <span style="color: blue;">ushort</span>[] { (<span style="color: blue;">ushort</span>)key, 0, 0, 0 };<br />
webView.InjectKeyboardEvent(keyEvent);<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">override</span> <span style="color: blue;">void</span> Update(<span style="color: #2b91af;">GameTime</span> gameTime)<br />
{<br />
WebCore.Update();<br />
<span style="color: blue;">if</span> (webView.IsDirty())<br />
{<br />
Marshal.Copy(webView.Render().GetBuffer(), webData, 0, webData.Length);<br />
webRender.SetData(webData);<br />
}<br />
<span style="color: blue;">base</span>.Update(gameTime);<br />
}<br />
<span style="color: blue;">public</span> <span style="color: blue;">override</span> <span style="color: blue;">void</span> Draw(<span style="color: #2b91af;">GameTime</span> gameTime)<br />
{<br />
<span style="color: blue;">if</span> (webRender != <span style="color: blue;">null</span>)<br />
{<br />
spriteBatch.Begin(<span style="color: #2b91af;">SpriteSortMode</span>.Immediate, <span style="color: #2b91af;">BlendState</span>.AlphaBlend, <span style="color: #2b91af;">SamplerState</span>.PointClamp, <span style="color: #2b91af;">DepthStencilState</span>.Default, <span style="color: #2b91af;">RasterizerState</span>.CullCounterClockwise);<br />
webEffect.CurrentTechnique.Passes[0].Apply();<br />
spriteBatch.Draw(webRender, <span style="color: blue;">new</span> <span style="color: #2b91af;">Rectangle</span>(0, 0, Game.GraphicsDevice.Viewport.Width, Game.GraphicsDevice.Viewport.Height), <span style="color: #2b91af;">Color</span>.White);<br />
spriteBatch.End();<br />
Game.GraphicsDevice.Textures[0] = <span style="color: blue;">null</span>;<br />
}<br />
}<br />
<span style="color: blue;">protected</span> <span style="color: blue;">void</span> SaveTarget()<br />
{<br />
FileStream s = <span style="color: blue;">new</span> FileStream(<span style="color: #a31515;">"UI.jpg"</span>, FileMode.Create);<br />
webRender.SaveAsJpeg(s, webRender.Width, webRender.Height);<br />
s.Close();<br />
}<br />
}</div>
</div>
</div>
So, this call enables you to use the Awesomium WebView object, create objects that reside on the UI that can then call back into our C# code as well as access functions on the UI that we can call from our C# code. Again, the set up of these elements are described in the ppt and accompanying solution. <br />
Effectively, i have created a html page in the Content project, made sure all it’s elements are not compiled and are copied over if newer, I can then tell my AwesomiumUIManager to go and get that html page in the constructor like this <br />
HUD = new AwesomiumUIManager(this, "Content\\UI\\MyUI.html"); <br />
In this sample I am not adding it to the Components list as I don’t want it included in the post processing, so I have to initialize, update and draw it my self in the respective Game methods. <br />
In the Game.LoadContent method I set up two script objects in the HUD, these can then be called from the html to pass data back to my C# code, one for click events and one for the slider events. <br />
HUD.CreateObject("UIEventmanager", "click", webEventManager);<br />
HUD.CreateObject("UIEventmanager", "slide", webEventManager); <br />
In my Game.Update I can push data back to the UI, the push method calls the two methods passing the param to them <br />
HUD.PushData("", "ShowSunPosition", new JSValue(sunPosition.X), new JSValue(sunPosition.Y), new JSValue(sunPosition.Z));<br />
HUD.PushData("", "SetVars", new JSValue(GodRays.BrightThreshold), new JSValue(GodRays.Decay), new JSValue(GodRays.Density), new JSValue(GodRays.Exposure), new JSValue(GodRays.Weight)); <br />
Also in the Game.Update method I have to ensure the WebView is getting the mouse and keyboard events<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:59a8c4ba-e848-496e-92b7-ab4d39280c34" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
<span style="color: green;">// Manage the mouse and keyboard for the UI</span><br />
<span style="color: blue;">if</span> (thisMouseState.LeftButton == ButtonState.Pressed)<br />
HUD.LeftButtonDown();<br />
<span style="color: blue;">if</span> (thisMouseState.LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed)<br />
HUD.LeftButtonUp();<br />
HUD.MouseMoved(thisMouseState.X, thisMouseState.Y);<br />
HUD.ScrollWheel(thisMouseState.ScrollWheelValue - lastMouseState.ScrollWheelValue);<br />
<span style="color: blue;">if</span> (thisKBState.GetPressedKeys().Length > 0)<br />
HUD.KeyPressed(thisKBState.GetPressedKeys()[0]);</div>
</div>
</div>
You may also notice in the Draw call of the AwesomiumUIManager I am using a shader, this is because the texture returned from the WebView is in bgra format so I have to switch the channels around in a shader like this<br />
<div class="wlWriterEditableSmartContent" id="scid:9ce6104f-a9aa-4a17-a79f-3a39532ebf7c:cd77d747-31f0-4dfb-bfb7-8ab1bf0d4ec3" style="display: inline; float: none; margin: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;">
<div style="border: #000080 1px solid; color: black; font-family: 'Courier New', Courier, Monospace; font-size: 10pt;">
<div style="background-color: white; max-height: 300px; overflow: auto; padding: 2px 5px; white-space: nowrap;">
uniform extern texture sceneMap;<br />
sampler screen = sampler_state<br />
{<br />
texture = <sceneMap>; <br />
};<br />
struct PS_INPUT<br />
{<br />
float2 TexCoord : TEXCOORD0;<br />
};<br />
float4 Render(PS_INPUT Input) : COLOR0<br />
{<br />
float4 col = tex2D(screen, Input.TexCoord).bgra; <br />
return col;<br />
}<br />
technique PostInvert<br />
{<br />
pass P0<br />
{<br />
PixelShader = compile ps_2_0 Render();<br />
}<br />
}</div>
</div>
</div>
So, that’s the end of this mammoth post, hope you find the content useful, as ever, let me know if you have any questions or issues. Oh, and before anyone else points it out, I know my web skill’s ain’t all that :P <br />
The code samples for both this post, and the talk I was to give can be found <a href="http://www.randomchaos.co.uk/Tutorials/XNA/Archive/CrepuscularRays_PostProcess.zip">here</a>. <br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com22tag:blogger.com,1999:blog-5358009355383119512.post-76066838053163174832012-07-13T05:48:00.001-07:002012-07-13T05:48:03.229-07:00Crepuscular Rays Post Process<div style="padding-bottom: 0px; padding-left: 0px; width: 425px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:5e7e4ad1-2539-4baf-be7f-1df82156ec4e" class="wlWriterEditableSmartContent"><embed src="http://www.youtube.com/v/1hpdLHsU_Zs" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></div> <p>So, I have been meaning to do god rays for ages and while doing the <a href="http://stexcalibur.com/">ST Excalibur</a> post processing framework in SlimDX, thought I would give them a go.<br>This clip is of my XNA engine, I still have an issue or two with the render in SlimDX, but I am sure, once I have time, I'll write up an XNA blog post about how I did this and the references I used.<br>Sorry the clip is a bit messy, and forgive my jerky camera work, hope you like how it looks. Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-57357500867324629692012-07-13T05:46:00.003-07:002012-10-05T06:50:23.973-07:00September 2011 Talk PreviewOK, so the next XNA UK meeting will be on the 7th of September and I will be giving a short talk on using Web UI's in XNA, I thought I would put up a quick post with a picture to show the sort of thing you will be able to do. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI8lCohsgs3rpfviWKoiMELwmU9OPoCDWi79bn8mRVtGx1_Yt3buVt5G1UAK9oogJV8puPkXxpPh20I3y-Y4pV_sGYPdnggqmzO7IY_RDMi1VbJaIc4LrdDAD0oV6DAXhMZ-DRskkRppKW/s1600/4621.376486711.jpg-550x0.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="190" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI8lCohsgs3rpfviWKoiMELwmU9OPoCDWi79bn8mRVtGx1_Yt3buVt5G1UAK9oogJV8puPkXxpPh20I3y-Y4pV_sGYPdnggqmzO7IY_RDMi1VbJaIc4LrdDAD0oV6DAXhMZ-DRskkRppKW/s320/4621.376486711.jpg-550x0.jpg" width="320" /></a></div>
<br />
<br />
See you in September :D <br />
<br />
Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-25320719358249873582012-07-13T05:46:00.001-07:002012-07-13T05:46:06.377-07:00XNA UK UG April 2011 Talk<p>I have finally got the source and ppt up for the talk I gave on the 6th of April. <p>It was just covering the UI I created for the talk the month before, have expanded on it slightly so that you can skin it. <p>You can find the down load <a href="http://xna-uk.net/media/p/8115.aspx">here</a>.</p> Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-54494690758168619662012-07-13T05:45:00.001-07:002012-07-13T05:45:10.159-07:00And now for something completely different….<p>Now, some of you, especially the XNAUK-UG admins will have noticed I have been a bit quieter than normal here, well that’s because, as well as working on <a href="http://www.ghostscapegame.com/">Ghostscape</a> for the WP7, and giving the odd talk or two for the user group<a href="http://xna-uk.net/groups/xna_uk_user_group_meetings/default.aspx">meetings</a>, I am now involved with this truly awesome project, <a href="http://www.stexcalibur.com/">ST Excalibur</a>. <p>I helped out on the project last year but now I have become a member of the dev team, hoping to help out as best I can. Now, this doesn’t mean that I have stopped working with XNA, the contrary, I will be taking some of the samples I have created and hope to be using them in the project. I’ll also still be doing my best to attend the monthly user group meetings and give talks, also I intend to keep my blog going and to help you guys out as and when I can. <p>So, in the mean time, take a look at a few clips the team have already put together, I am sure you will agree it is a truly stunning achievement so far and I hope my contributions only improve an already stunning project.</p> <div style="padding-bottom: 0px; padding-left: 0px; width: 425px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:f5347cbd-c810-43a4-98d1-b384bfeaa210" class="wlWriterEditableSmartContent"><embed src="http://www.youtube.com/v/g5EDVA6VO24" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></div> <div style="padding-bottom: 0px; padding-left: 0px; width: 425px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:2cf44688-a60f-4cdb-a9c4-cb925b5fc202" class="wlWriterEditableSmartContent"><embed src="http://www.youtube.com/v/Elp6hyjzal0" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></div> <div style="padding-bottom: 0px; padding-left: 0px; width: 425px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:bf292340-b281-4bd9-956c-6cd0a1f38efb" class="wlWriterEditableSmartContent"><embed src="http://www.youtube.com/v/gLVZcVw5LlU" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></div> <p>So, I am going to be busy to say the least, but I am not going away, I will always be here ready to bore you with shaders :D Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-68155703640489535612012-07-13T05:31:00.001-07:002012-07-13T05:31:50.702-07:00Bit More Terrain<div style="padding-bottom: 0px; padding-left: 0px; width: 425px; padding-right: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-top: 0px" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:825e9789-333a-4d7f-b40e-63fc3bf6f7d2" class="wlWriterEditableSmartContent"><embed src="http://www.youtube.com/v/szgHZ0IL6To" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></div> <p>Well I say Geo Clip Map, but it's my take on the GPU Gems 2 Articles on terrain. So, since the last clip I have added some lighting to the shader, I did a GPU terrain render before and so just took the code from that to generate the normals and lighting from the height map. <p>Still have issues I want to iron out and a load of performance changes to make, but I think it's getting there. <p>As ever comments welcome :) Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-52031102677278440222012-07-13T05:29:00.001-07:002012-07-13T05:29:40.726-07:00Terrain: Geo Clip Mapping<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:53357c8b-5919-4e32-8c25-305d27c17a37:98301251-5683-4341-a3ee-ca0c07359ff1" class="wlWriterEditableSmartContent"><embed src="http://www.youtube.com/v/u95cln5yYIY" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></div> <p>So I decided to have a play with Geo Clip Mapping. I always wanted a decent terrain render and I think this could be a good start. Not much of a render I know, but that will come, need to get the mechanics working first.</p> <p><br>As you can see I still have a few issues that need ironing out, but it's a good start I think for a couple of evenings..</p> <p><br>OOPS! Forgot to credit the music, track is a bg track Psionic did over at PsionicGames.com, thanks Psi :D</p> Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com0tag:blogger.com,1999:blog-5358009355383119512.post-57801388021206751792012-07-13T05:19:00.001-07:002012-10-05T08:09:46.262-07:00Blender 2.57b & XNA 4.0 Part III<a href="http://xnauk-randomchaosblogarchive.blogspot.co.uk/2012/07/blender-257b-xna-40-part-ii.html"><< Prev</a> | Next >> <br />
OK, so still not much in the way of XNA, I guess I should have just called this set of posts Blender 2.57b, but all this stuff I am using form my own XNA projects, so I guess if you are using XNA and want to use Blender, then this shows what can be done, well if nothing else, what I am doing… <br />
In this post I am going to look at creating normal maps for our cube mesh, we will UV map it as before, and this time I am going to create a six sided dice, but before we paint our texture onto our dice we are going to create a high poly (really detailed) version of our cube and add the number markers to it. We can then use this high poly mesh to generate a normal map that we can then use to render against our low poly model and give the impression that there are dips on the surface of the dice. <br />
So, we are going to start off with a UV mapped cube, like we had in the previous post, like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidTawTSJ1uwG4-99yCEkQGCW5YlV_a7a6_vUbQVTSq4ZQbDRbLnXDxM7157GubPBbmfrEme8DFaoGIOccsnOLIyZWJcroo5BxfF6OE-37uGKoFGCGZPws0IgCJkZoUuQ6idA89NR1Y3TVs/s1600/4721.image_thumb_5506C7C0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidTawTSJ1uwG4-99yCEkQGCW5YlV_a7a6_vUbQVTSq4ZQbDRbLnXDxM7157GubPBbmfrEme8DFaoGIOccsnOLIyZWJcroo5BxfF6OE-37uGKoFGCGZPws0IgCJkZoUuQ6idA89NR1Y3TVs/s320/4721.image_thumb_5506C7C0.png" width="320" /></a></div>
<br />
<br />
We have a 3D view window and a UV/Image Editor window in our Blender session. We now need to create a high poly version of our mesh, to do this go into Object mode in the 3D view and hit Shift-D to duplicate our mesh, the mesh’s edges will turn white, this is our copy of the mesh, hit enter to keep the mesh where it is. Now we want to move this duplicated mesh to another layer. Layers in blender are handy for separating your scene, for this we are going to use it as a holding bay for our high poly mesh. With the mesh selected in Object mode, hit the M key, this tells blender we want to move the selected item to another layer and we will get the layer selection box pop up like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiFcnhtRfetoOlxtl8rp4YO0O08d4x16EaQYGO6RT9xK61NC7BFHKm836uMqSHOE14I9U_S8CxYkdITsRdtawuCTR0ANXrv9DJVJqTxKhrGe0u9iTQ-We1uTq2C2fhsBm2W9dHLEOGmX2z/s1600/1581.image_thumb_3FC89C4B.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiFcnhtRfetoOlxtl8rp4YO0O08d4x16EaQYGO6RT9xK61NC7BFHKm836uMqSHOE14I9U_S8CxYkdITsRdtawuCTR0ANXrv9DJVJqTxKhrGe0u9iTQ-We1uTq2C2fhsBm2W9dHLEOGmX2z/s320/1581.image_thumb_3FC89C4B.png" width="320" /></a></div>
<br />
<br />
You can see the box at the top left is in dark grey, this is the layer we are in now, click the box next to it (does not have to be that one, you can pick any layer you like really) and the new mesh will be moved to that layer. You can see what layer you are in and if you have anything in a layer and indeed if you have a selected object in that layer by looking at the bottom of the 3D view window, there is the layers icon(s) <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2HY0IAtDVizUPzS4-p5_9R4v2Cy9IdzJwwjxToFbP9qSBxGugSUIJDguOddkfOtrCe2-O7RltSdPRUEY7xOVknrl9vAJOBSCcVo2-qj2gbwyFE3ys0CW_cTtCSUdY6d1yRF9s0ud4CWpc/s1600/2654.image_thumb_6A34CD68.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2HY0IAtDVizUPzS4-p5_9R4v2Cy9IdzJwwjxToFbP9qSBxGugSUIJDguOddkfOtrCe2-O7RltSdPRUEY7xOVknrl9vAJOBSCcVo2-qj2gbwyFE3ys0CW_cTtCSUdY6d1yRF9s0ud4CWpc/s1600/2654.image_thumb_6A34CD68.png" /></a></div>
<br />
<br />
As can be seen in the image above, we now have 2 layers with objects in, the second layer has our active object in it. You can quickly move from layer to layer by simply clicking the layer icon you want to switch to, or while the mouse is over the 3D view, with the 3D view in Object Mode you can key the layers number (not from the number pad though.) <br />
So we want to be in the second layer with the new duplicated mesh selected. We are now going to make our high poly mesh, go into edit mode, as we have in the previous posts, and now, on the panel to the left in the 3D view, find the Add panel <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK46eDMz0_wv-ucNC1b5YqrcbvG81_B6f45n0PoQgFADwJWeJAoTg4lZd5E2dseUNYQyFtGdFvrwx3Hb8V0FkktoKBgk3NNp__36ip4VqbSwayv10Ym9tdaRJ2KBPmdTq2f5N7GrH7fisr/s1600/7357.image_thumb_779AE06E.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK46eDMz0_wv-ucNC1b5YqrcbvG81_B6f45n0PoQgFADwJWeJAoTg4lZd5E2dseUNYQyFtGdFvrwx3Hb8V0FkktoKBgk3NNp__36ip4VqbSwayv10Ym9tdaRJ2KBPmdTq2f5N7GrH7fisr/s1600/7357.image_thumb_779AE06E.png" /></a></div>
<br />
<br />
In here is an option called Subdivide, this will take all the selected elements and, well divide them in two, so, with all our vertices selected click the subdivide button about five or six times, this will give us a fair few faces to play with, you should have something like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOknkkqS9igUu7UEsxrgeXOTrNyTcR31Oo5l9d4FWxC8qYqIYtt57Qs_7gJPEHjBH_0S9i3TxDoFDu_RNVVuYCKw9G4jl9KAXQS0g2IwkX7TfJ5krGOMSABuXXM_8URfash3c78dxV8b8-/s1600/5707.image_thumb_28BA1B0F.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="224" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOknkkqS9igUu7UEsxrgeXOTrNyTcR31Oo5l9d4FWxC8qYqIYtt57Qs_7gJPEHjBH_0S9i3TxDoFDu_RNVVuYCKw9G4jl9KAXQS0g2IwkX7TfJ5krGOMSABuXXM_8URfash3c78dxV8b8-/s320/5707.image_thumb_28BA1B0F.png" width="320" /></a></div>
<br />
<br />
Now we have a high poly version of our cube, we ca now start to add a bit of detail, to do this I am going to use the Sculpt mode, so, select sculpt mode in the 3D view <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZKYd_QqIGiIgNbxIUel6-31aWhQjsbE75o5rSD986-gHxSi87LdSKqO3m55jZ4XrNyMcggNzA2vXp_VfJuCUJtzEzCqusPc5zsWoMA7lXWWHi9SDiM9XoNjcW8_wljhhmTAKRLUVQyXT7/s1600/8037.image_thumb_6D863F43.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZKYd_QqIGiIgNbxIUel6-31aWhQjsbE75o5rSD986-gHxSi87LdSKqO3m55jZ4XrNyMcggNzA2vXp_VfJuCUJtzEzCqusPc5zsWoMA7lXWWHi9SDiM9XoNjcW8_wljhhmTAKRLUVQyXT7/s1600/8037.image_thumb_6D863F43.png" /></a></div>
<br />
<br />
We now need to set up out sculpt brush on the left of the 3D view window, I am going to set my radius to 40, strength to 1 and to subtract like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitlo4B4O9-qYbMZVpPo2vBniOmUj3f5rZxd28akBtV3IZmXL3lWFr7w5Q4nbwJnWhpM0TOKyl3RvjzjLkijYc2g9I_qP5S_f3wz_nMVqBd7GqOEVSVZlMk-xnQ6-3mTECxWpdZoz4yx9Z-/s1600/6378.image_thumb_644A0402.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitlo4B4O9-qYbMZVpPo2vBniOmUj3f5rZxd28akBtV3IZmXL3lWFr7w5Q4nbwJnWhpM0TOKyl3RvjzjLkijYc2g9I_qP5S_f3wz_nMVqBd7GqOEVSVZlMk-xnQ6-3mTECxWpdZoz4yx9Z-/s320/6378.image_thumb_644A0402.png" width="134" /></a></div>
<br />
<br />
I am now going to put the number dimples on the mesh, remember the opposite sides of a six sided dice add up to seven, ill start with four dots on the first face I do, then using the * key on the number pad, rotate over the top to the other side to mark another three dots. Now, as you do this, check out and if you like use the Symmetry tools on the brush panel, it will save you doing ALL the dots your self :D Oh, and be aware of the axis you are in when using it :P <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzazv20XTv-FYwN931XzkxrMz9SapoC12tW33YnrPViJzM6OjRzLZ1MGvV0F2sr75uZkHlOH4uH7_SGLXUtQYKNDbT8XIo51d1fS3Uh8HsnHo28zJzG4HeI0wYZveKCeXVn2-ijA90-I5V/s1600/5126.image_thumb_1B43E23C.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzazv20XTv-FYwN931XzkxrMz9SapoC12tW33YnrPViJzM6OjRzLZ1MGvV0F2sr75uZkHlOH4uH7_SGLXUtQYKNDbT8XIo51d1fS3Uh8HsnHo28zJzG4HeI0wYZveKCeXVn2-ijA90-I5V/s320/5126.image_thumb_1B43E23C.png" width="320" /></a></div>
<br />
<br />
So now we have a high poly mesh with lots of detail in it, how do we now create a normal map from it? First thing we need to do is create a texture so we can write the normal data to it. In the UV/Image Editor create a new image by clicking the +New option at the bottom <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAvtUztg0x9RIPVf1cJBaPm3dfWeGohfJLouDtfSkJYiAskOWNaeP1VsRxk4UBHwFPFU9JE9IxDFCyZoZTFH9NivcelnHavVjcD_4KNaPo-WoH90Gw1ZkgwFAWBWlwnbCgFDIcFKZ1Uq_r/s1600/6378.image_thumb_2BFB671D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAvtUztg0x9RIPVf1cJBaPm3dfWeGohfJLouDtfSkJYiAskOWNaeP1VsRxk4UBHwFPFU9JE9IxDFCyZoZTFH9NivcelnHavVjcD_4KNaPo-WoH90Gw1ZkgwFAWBWlwnbCgFDIcFKZ1Uq_r/s1600/6378.image_thumb_2BFB671D.png" /></a></div>
<br />
<br />
Now name the texture NormalMap and keep the defaults and click OK. Now, in Object Mode, select the high poly mesh, hit 1 to go to our low poly mesh and with Shift held down select our low poly mesh, we now have both mesh’s selected, with Shift still held down, select the high poly mesh layer from the layer icons, we now have both our mesh’s and both our layers selected and your screen should look something like this (I have circles in red what the layer icon should look like at this point) <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6LpxHPJDiFQXRxIOBDvZYWQpuIszbY2SJgN_frINeokPilWZ78EW8MoBDYJsxzufKAw1Dp_BgvM_LF8F1VA-ytessnJpo24-afs26zA4OHT6o7C0XGdc3j2-Er-2CVfuB5NZZOzZ6SstF/s1600/6303.image_thumb_6A80B4C3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6LpxHPJDiFQXRxIOBDvZYWQpuIszbY2SJgN_frINeokPilWZ78EW8MoBDYJsxzufKAw1Dp_BgvM_LF8F1VA-ytessnJpo24-afs26zA4OHT6o7C0XGdc3j2-Er-2CVfuB5NZZOzZ6SstF/s320/6303.image_thumb_6A80B4C3.png" width="320" /></a></div>
<br />
<br />
We now have our mesh’s and layers selected and a texture set up ready to accept our normal data. To now write the high poly normal data to the texture we will need to use the Properties window<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCynUxad4qfvD8u_-di2K0FPwNKw6ndkj1SYxy1vYrtJfsxe8x3ikshWSKMss_53nh59_BDa3Xttc7rtZlBtkPJKI-2pAfkM6djEny3XD03bdF4kXAjcSIHZxi0837e1jKTcCN5SeSoXe/s1600/8037.image_thumb_53DE667C.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCCynUxad4qfvD8u_-di2K0FPwNKw6ndkj1SYxy1vYrtJfsxe8x3ikshWSKMss_53nh59_BDa3Xttc7rtZlBtkPJKI-2pAfkM6djEny3XD03bdF4kXAjcSIHZxi0837e1jKTcCN5SeSoXe/s1600/8037.image_thumb_53DE667C.png" /></a></div>
<br />
At the very bottom of this window is the Bake panel and this is what we will use to generate the normal data in the NormalMap texture, configure your Bake panel so that it looks like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirdQHU-rcsMEaL-BIc1QBUh56UTqu6sV-MwftrrSM5Mrq7YLRGs2h6Kvdt-u9zrNPLYEChhInevfBTTcSniFmLTPtaFYel86F2ykGYIJpfDnEXnnIncPiTKSzvsPR2dX5r6GawT1dUNj0O/s1600/7532.image_thumb_61447982.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirdQHU-rcsMEaL-BIc1QBUh56UTqu6sV-MwftrrSM5Mrq7YLRGs2h6Kvdt-u9zrNPLYEChhInevfBTTcSniFmLTPtaFYel86F2ykGYIJpfDnEXnnIncPiTKSzvsPR2dX5r6GawT1dUNj0O/s1600/7532.image_thumb_61447982.png" /></a></div>
<br />
<br />
So you have the Bake Mode set to Normals and Selected to Act is selected. Now, hit the Bake button, the one at the top of the Bake panel with the camera on it. After a moment or two you should have a screen that looks like this <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw_EwUJk4Nz09F89OYMcpZMnxrEEkpJGoIgh9elphVqTpy1DQymd7B5OJmMaTpagoXbd4qn0706hc822_TapIQ5O22aH3QMDahF9Z8R0b6u8SITehJNnTh-LU1TWQn625ctF0xyvabP3jO/s1600/4721.image_thumb_014F6073.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhw_EwUJk4Nz09F89OYMcpZMnxrEEkpJGoIgh9elphVqTpy1DQymd7B5OJmMaTpagoXbd4qn0706hc822_TapIQ5O22aH3QMDahF9Z8R0b6u8SITehJNnTh-LU1TWQn625ctF0xyvabP3jO/s320/4721.image_thumb_014F6073.png" width="320" /></a></div>
<br />
<br />
Now we have a normal map we can save the texture, exactly like we did in the last post with our color map. <br />
<strong>How can I see what my normal map will look like on the mesh?</strong> <br />
In the Properties panel select the texture option as we did in the post before, name the first texture NormalMap, type to Image or Movie, then in the preview panel below, select Both, and below that, in the Image panel select the image icon next to +New and choose the NormalMap texture we just generated and saved. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCYGIZ_ptjcDl0GXJn9LskObuWpRrZ09LMoshwpSJBKQ2VZC2EK17pkWrLGM5YrTgytvOsmof3gwUjY7ISznBNPAjW81eTZ-AIMitYWb737H29LLpXcgLRWTQeKbnC5Q-J6rJaLbFykjzt/s1600/0508.image_thumb_60B7FAF3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="311" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCYGIZ_ptjcDl0GXJn9LskObuWpRrZ09LMoshwpSJBKQ2VZC2EK17pkWrLGM5YrTgytvOsmof3gwUjY7ISznBNPAjW81eTZ-AIMitYWb737H29LLpXcgLRWTQeKbnC5Q-J6rJaLbFykjzt/s320/0508.image_thumb_60B7FAF3.png" width="320" /></a></div>
<br />
<br />
We now need to tell blender to use this texture as a normal map. In the Image Sampling panel set the Normal Map option, under the Mapping panel set the Coordinates to UV so it uses the UV map we have for the mesh. In the Influence panel below un select the color option and select the Normal option under Geometry. Now hit F12 to render the cube in blender and you will see the cube rendered with the normal map we have just created. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje5ZGLVLxfQttOE2pYjlhkE7ZlnyShNHAcHlImpZahSV4Hgl7oZFtYi75OKFYVmpRb8EopIkKl87Iq-9cHewnlbzx2XEhVb4zjdyCjIQvmefvLjNBNW_yPaR5UV_Ka6dPG3bolq6f4y76I/s1600/2654.image_thumb_37BCC01D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEje5ZGLVLxfQttOE2pYjlhkE7ZlnyShNHAcHlImpZahSV4Hgl7oZFtYi75OKFYVmpRb8EopIkKl87Iq-9cHewnlbzx2XEhVb4zjdyCjIQvmefvLjNBNW_yPaR5UV_Ka6dPG3bolq6f4y76I/s320/2654.image_thumb_37BCC01D.png" width="320" /></a></div>
<br />
<br />
I am now going to texture my cube just as we did in the last post. So here is my dice rendered in Blender (I know, not the best dice ever, but you can see the effect, also on the face with 2 dots, think I have a modeling error there :P) <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3SnZJmLvm3VXD3PbxBF3EqFJGcgzCwcCBWEGvv8tShLSnOTUZVNdEX6XdJrVB3vaUN6l3xyl3NwuVhffZbDBk_1jGXV0ot1vEnI2AC-Gn9G_ZdEMudww25UAdJePSaoWhcxJflnnPI1Wu/s1600/2577.image_thumb_3B4AB52D.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3SnZJmLvm3VXD3PbxBF3EqFJGcgzCwcCBWEGvv8tShLSnOTUZVNdEX6XdJrVB3vaUN6l3xyl3NwuVhffZbDBk_1jGXV0ot1vEnI2AC-Gn9G_ZdEMudww25UAdJePSaoWhcxJflnnPI1Wu/s320/2577.image_thumb_3B4AB52D.png" width="320" /></a></div>
<br />
<br />
So to do this we need to let blender know to use our color map in the render. Just as we did with the Normal map, we have to set the texture up in the Properties window, create a new texture, call it ColorMap under the Image panel, select your color map image, under Mapping panel, set to Coordinates to UV, hit F12 and see it render :D <br />
Here is the mesh, it’s color map and normal map rendered in my deferred lighting engine. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR5JlZTjAZa-4OUHCS5SUezr56MH_6ObMK4ui5F3h6CJJHgsRbUdAxZDamCsyNrzfTL8c11-ivgo8do8pxNbM5uZaUiTtGywGdSqeMdu59x9-5RhvmIroK5fFNxqWusaz5s7Vp8MZAkI4M/s1600/6765.image_thumb_74414695.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR5JlZTjAZa-4OUHCS5SUezr56MH_6ObMK4ui5F3h6CJJHgsRbUdAxZDamCsyNrzfTL8c11-ivgo8do8pxNbM5uZaUiTtGywGdSqeMdu59x9-5RhvmIroK5fFNxqWusaz5s7Vp8MZAkI4M/s320/6765.image_thumb_74414695.png" width="320" /></a></div>
<br />
<br />
As ever, comments are welcome :) <br />
<a href="http://xnauk-randomchaosblogarchive.blogspot.co.uk/2012/07/blender-257b-xna-40-part-ii.html"><< Prev</a> | Next >>Charles Humphreyhttp://www.blogger.com/profile/10935746329039730399noreply@blogger.com1