<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sgt. Conker &#187; Uncategorized</title>
	<atom:link href="http://www.sgtconker.com/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sgtconker.com</link>
	<description>We are &#34;absolutely fine&#34;</description>
	<lastBuildDate>Wed, 06 Jul 2011 13:29:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Indiefreaks Game Framework 0.1.0.0 released</title>
		<link>http://www.sgtconker.com/2011/01/indiefreaks-game-framework-0-1-0-0-released/</link>
		<comments>http://www.sgtconker.com/2011/01/indiefreaks-game-framework-0-1-0-0-released/#comments</comments>
		<pubDate>Sat, 22 Jan 2011 20:13:53 +0000</pubDate>
		<dc:creator>Captain ZSquare</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[0.1.0.0]]></category>
		<category><![CDATA[Camera]]></category>
		<category><![CDATA[Content]]></category>
		<category><![CDATA[Indiefreaks]]></category>
		<category><![CDATA[Input]]></category>
		<category><![CDATA[Philippe Da Silva]]></category>
		<category><![CDATA[Sunburn]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1944</guid>
		<description><![CDATA[This just in!
Philippe Da Silva announced the availability of the Indifreaks Game Framework, v 0.1.0.0
The Indiefreaks Game Framework is a set of .Net libraries compiling a  few years of experimenting and prototyping design patterns developing  games for Microsoft Xna Framework using the SynapseGaming SunBurn  graphics engine.
The goal here is to share with [...]]]></description>
			<content:encoded><![CDATA[<p>This just in!</p>
<p>Philippe Da Silva announced the availability of the <a href="http://indiefreaks.com/indiefreaks-game-framework/">Indifreaks Game Framework, v 0.1.0.0</a></p>
<blockquote><p>The Indiefreaks Game Framework is a set of .Net libraries compiling a  few years of experimenting and prototyping design patterns developing  games for Microsoft Xna Framework using the SynapseGaming SunBurn  graphics engine.</p>
<p>The goal here is to share with the community what I consider as best  practices so they can avoid going through the same steps as I did. The  Indiefreaks Game Framework is totally free (like in free beer) to use  but it still requires you to acquire a SunBurn engine license.</p></blockquote>
<p>Looking at the framework's <a href="http://indiefreaks.com/indiefreaks-game-framework/">official page</a>, you can see some pretty interesting stuff that's in the framework, including</p>
<ul>
<li>Smart Content Management</li>
<li>Smart Input Management</li>
<li>Cameras</li>
<li>Alpha Blended Rendering</li>
</ul>
<p>Go and <a href="http://indiefreaks.com/indiefreaks-game-framework/">take a look for yourself</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2011/01/indiefreaks-game-framework-0-1-0-0-released/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>XBuilder v0.2 released a while ago</title>
		<link>http://www.sgtconker.com/2011/01/xbuilder-v0-2-released-a-while-ago/</link>
		<comments>http://www.sgtconker.com/2011/01/xbuilder-v0-2-released-a-while-ago/#comments</comments>
		<pubDate>Sat, 15 Jan 2011 07:46:51 +0000</pubDate>
		<dc:creator>Captain ZSquare</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Content Preview]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[RoastedAmoeba]]></category>
		<category><![CDATA[Tim Jones]]></category>
		<category><![CDATA[XBuilder]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1937</guid>
		<description><![CDATA[My timing is extremely bad, but I finally managed to get this info out here.
Version 0.2 of XBuilder, made by Tim Jones, is now available. For those who wonder, Xbuilder is "an extension for Visual Studio 2010 which lets you preview your XNA  assets (models, effects and textures) right inside Visual Studio.".
You can read [...]]]></description>
			<content:encoded><![CDATA[<p>My timing is extremely bad, but I finally managed to get this info out here.</p>
<p>Version 0.2 of XBuilder, made by Tim Jones, is now available. For those who wonder, Xbuilder is "an extension for Visual Studio 2010 which lets you preview your XNA  assets (models, effects and textures) right inside Visual Studio.".</p>
<p>You can read the announcement for v0.2 <a href="http://www.roastedamoeba.com/blog/archive/2010/12/09/xbuilder-v-released">here</a>.</p>
<p><img class="alignnone" title="XBuilder" src="http://www.roastedamoeba.com/assets/images/blog/xbuilder8.jpg" alt="XBuilder" width="450" height="450" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2011/01/xbuilder-v0-2-released-a-while-ago/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Voting is now closed!</title>
		<link>http://www.sgtconker.com/2010/10/voting-is-now-closed/</link>
		<comments>http://www.sgtconker.com/2010/10/voting-is-now-closed/#comments</comments>
		<pubDate>Fri, 01 Oct 2010 06:37:59 +0000</pubDate>
		<dc:creator>Captain ZSquare</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[End]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/2010/10/voting-is-now-closed/</guid>
		<description><![CDATA[As the title says, voting is now closed for the tutorial contest!
We will judge/evaluate all the entries and all the votes, and announce the winners next week!
Thanks to everybody that took part in the contest, both by sending in their entries, and by voting!
]]></description>
			<content:encoded><![CDATA[<p>As the title says, voting is now closed for the tutorial contest!<br />
We will judge/evaluate all the entries and all the votes, and announce the winners next week!</p>
<p>Thanks to everybody that took part in the contest, both by sending in their entries, and by voting!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/10/voting-is-now-closed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Article: Vacant Skies &#8211; Action RPG Tutorial Series</title>
		<link>http://www.sgtconker.com/2010/09/article-vacant-skies-action-rpg-tutorial-series/</link>
		<comments>http://www.sgtconker.com/2010/09/article-vacant-skies-action-rpg-tutorial-series/#comments</comments>
		<pubDate>Sat, 18 Sep 2010 20:51:57 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Aaron T Foley]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Action]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Day Night Cycle]]></category>
		<category><![CDATA[GameStateManagement]]></category>
		<category><![CDATA[RPG]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Vacant Skies]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1764</guid>
		<description><![CDATA[by Aaron T Foley

Welcome to the Vacant Skies – Action RPG Tutorial Series.  My name is Aaron Foley and I’ll be your host throughout this series.  The primary purpose of the series is to document a route on how to make a complete action RPG using XNA and various resources throughout the internet. [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="mailto:slyprid@roadrunner.com">Aaron T Foley</a></h4>
<p style="text-align: center;"><img class="aligncenter" title="Day Night Cycle" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part4/4.png" alt="" width="768" height="432" /></p>
<p>Welcome to the Vacant Skies – Action RPG Tutorial Series.  My name is Aaron Foley and I’ll be your host throughout this series.  The primary purpose of the series is to document a route on how to make a complete action RPG using XNA and various resources throughout the internet.  There are so many amazing resources out there now for XNA that it is pointless to keep reinventing the wheel when writing a game.  So I’m going to collect various tutorials, code, and libraries and utilize them all to create a game.  So let’s get this show on the road.</p>
<p><span id="more-1764"></span></p>
<p>First off we need to determine some of our base resources we will be using.  Most will already have these, but if you don’t there are links that can direct you to where you can get them.  I’ll be linking to the Express editions of Visual C#, but will be using Visual Studio for the tutorials. I also will be using XNA Game Studio 3.1 for now until XNA Game Studio 4.0 comes out.  Once 4.0 comes out, these will be switched over to using XNA 4.0 and Visual Studio 2010.</p>
<h2>Resources</h2>
<ul>
<li><a href="http://www.microsoft.com/express/Downloads/#Visual_Studio_2008_Express_Downloads">Visual C# Express Edition</a></li>
<li> <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=80782277-d584-42d2-8024-893fcd9d3e82&amp;displaylang=en">XNA Game Studio 3.1</a></li>
<li><a href="http://www.getpaint.net/">Paint .NET</a></li>
</ul>
<p>Once we have all these installed, we can begin.</p>
<p><strong>Download: <a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/Part1_Resources.zip">Part1_Resources.zip</a></strong></p>
<p>To start we will need to create a new project using the Windows Game (3.1) template.<br />
<a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/1.png"><img class="alignnone" title="New Project" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/1.png" alt="" width="100%" /></a></p>
<p>I like to use my <a href="http://dropbox.com">Dropbox </a>for storing my projects, but you can store them where ever you feel like.  So once that is created we will have our base application.</p>
<p>Next we will need to add another project to our solution.  This will be our helper library and will store code and classes we will use throughout our game. So add a new project to our solution and select Windows Game Library (3.1) from our Templates and name it.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/2.png"><img class="alignnone" title="New Game Library" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/2.png" alt="" width="100%" /></a></p>
<p>Now in our main application we need to add the library reference to references and in the content references.</p>
<p>So now we have our base project ready.  So let’s get our hands dirty.</p>
<p>For our first resource we need some way of managing what state our game is in.  There is a wonderful sample on the XNA Creators Club site that handles this great.  So let’s go get that and implement it into our game.</p>
<p><a href="http://creators.xna.com/en-us/samples/gamestatemanagement"><strong> </strong></a><strong><a>Game State Management Sample</a> </strong></p>
<p>To start we will be using the graphics and content from the sample as filler graphics until we get a chance to work on some more.  So copy the content from the sample over to our main application.  I broke them out into their own folders (i.e. Textures and Fonts) to start some basic organization of our content.</p>
<p>So our first task is to add the ScreenManager component to our library.  So create a folder in our library called Screens and add in the three class files GameScreen.cs, and ScreenManager.cs.  These will need some tweaking to work so let’s see what we have.</p>
<p>First go through and change the namespaces in each file to the corresponding namespaces of your library (i.e. VacantSkies.Lib.Screens).  I also created a new class file and moved the ScreenState enumeration over too it, but that’s more of a personal preference and is not necessary.</p>
<p>Next we will create another folder in our Library and name it Input.  Here we will copy over the InputState class file and change its namespace to what we need. (i.e. VacantSkies.Lib.Input)</p>
<p>So now if we try to compile we will probably get a couple errors stating that some namespaces couldn’t be found.  So you can either add those in by hand, or resolve them however you choose.  Once those are resolved they should compile.</p>
<p>Now let’s add in our title screen.  In our main application add a new folder called Screens. Next add in all the screens from the Game State Management sample.  Once again go through and change all our namespaces over and resolve any namespaces that are missing.</p>
<p>Next in our constructor for our game application add in the following lines of code.</p>
<pre class="brush: csharp; title: ;">
   	  public Game1()
        {
            graphics = new GraphicsDeviceManager(this)
            {
                PreferredBackBufferWidth = 1280,
                PreferredBackBufferHeight = 720
            };

            Content.RootDirectory = &quot;Content&quot;;

            screenManager = new ScreenManager(this);

            Components.Add(screenManager);

            screenManager.AddScreen(new BackgroundScreen(), null);
            screenManager.AddScreen(new MainMenuScreen(), null);
        }
</pre>
<p>Make sure you change the paths to our content also in ScreenManager, BackgroundScreen, GameplayScreen,  and MessageBoxScreen to reflect any folder changes in our Content folder.  Once that is complete you can run your application and should get a fully navigable menu system.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/3.png"><img class="alignnone" title="Menu" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/3.png" alt="" width="100%" /></a></p>
<p>It isn’t anything spectacular yet, but we can edit it to whatever we need now.</p>
<p>So let’s start doing some changes to our game screens now.  First let’s make the title screen really show our game instead of the filler graphics.  So add in the following to our textures content, VacantSkies-Title, and VacantSkies-TitleText.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/4.png"><img class="alignnone" title="VacantSkies-TitleText" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/4.png" alt="" /></a></p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/5.png"><img class="alignnone" title="VacantSkies-Title" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/5.png" alt="" width="100%" /></a></p>
<p>First lets open BackgroundScreen.  This screen will sit behind all of our other screens, so we want it to be something rather basic instead of the sample background. So in the LoadContent change the backgroundTexture to “Textures\\gradient”.</p>
<p>Next lets open up our MainMenuScreen.  There are going to be some significant changes need to be made here.  So before we dive into this lets determine what we want our main menu to actually reflect.</p>
<ul>
<li>Main Menu
<ul>
<li> New Story</li>
<li> Continue Story</li>
<li> Options</li>
<li> Credits</li>
<li> Exit</li>
</ul>
</li>
</ul>
<p>So you can see there is some changes we need to make to the menu.  So in the constructor of our MainMenuScreen add in some new menu entries and change other entries to reflect this menu structure.  So our constructor should look like this.</p>
<pre class="brush: csharp; title: ;">
   	public MainMenuScreen() : base(&quot;&quot;)
        {
            // Create our menu entries.
            MenuEntry playGameMenuEntry = new MenuEntry(&quot;New Game&quot;);
            MenuEntry continueGameMenuEntry = new MenuEntry(&quot;Continue Story&quot;);
            MenuEntry optionsMenuEntry = new MenuEntry(&quot;Options&quot;);
            MenuEntry creditsMenuEntry = new MenuEntry(&quot;Credits&quot;);
            MenuEntry exitMenuEntry = new MenuEntry(&quot;Exit&quot;);

            // Hook up menu event handlers.
            playGameMenuEntry.Selected += PlayGameMenuEntrySelected;
            continueGameMenuEntry.Selected += ContinueGameMenuEntrySelected;
            optionsMenuEntry.Selected += OptionsMenuEntrySelected;
            creditsMenuEntry.Selected += CreditsGameMenuEntrySelected;
            exitMenuEntry.Selected += OnCancel;

            // Add entries to the menu.
            MenuEntries.Add(playGameMenuEntry);
            MenuEntries.Add(continueGameMenuEntry);
            MenuEntries.Add(optionsMenuEntry);
            MenuEntries.Add(creditsMenuEntry);
            MenuEntries.Add(exitMenuEntry);

		MenuPosition = new Vector2(100, 300);
        }
</pre>
<p>And the two new event hooks should look like this for now.</p>
<pre class="brush: csharp; title: ;">
  /// &lt;summary&gt;
        /// Event handler for when the Continue Game menu entry is selected.
        /// &lt;/summary&gt;
        void ContinueGameMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {

        }
	  /// &lt;summary&gt;
        /// Event handler for when the Credits menu entry is selected.
        /// &lt;/summary&gt;
        void CreditsGameMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {

        }
</pre>
<p>Now in order to continue we need to change some things in MenuScreen.  First add in a property Vector2 MenuPosition {get; set;}  This will allow us to move our menu to wherever we choose on the screen.  Now in the constructor of MenuScreen set MenuPosition = new Vector2(100, 150) and then change our draw methods to use MenuPosition instead of position.<br />
Now jump back over to our MainMenuScreen and add in the following fields.</p>
<pre class="brush: csharp; title: ;">
        ContentManager content;
        Texture2D background;
        Texture2D title;
</pre>
<p>Then add in the LoadContent method.</p>
<pre class="brush: csharp; title: ;">
    public override void LoadContent()
        {
            if (content == null) content = new ContentManager(ScreenManager.Game.Services, &quot;Content&quot;);
            background = content.Load&lt;Texture2D&gt;(&quot;Textures\\VacantSkies-Title&quot;);
            title = content.Load&lt;Texture2D&gt;(&quot;Textures\\VacantSkies-TitleText&quot;);
        }
Then finally our Draw method.
    public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
            Rectangle fullscreen = new Rectangle(0, 0, viewport.Width, viewport.Height);
            byte fade = TransitionAlpha;

            Color transitionColor = new Color(fade, fade, fade);

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

                spriteBatch.Draw(background, fullscreen, transitionColor);
                spriteBatch.Draw(title, new Vector2(100f, 50f), transitionColor);

            spriteBatch.End();

            base.Draw(gameTime);
        }
</pre>
<p>So now when we run it, our game is starting to take on shape.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/6.png"><img class="alignnone" title="Menu" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/6.png" alt="" width="100%" /></a></p>
<p>Now that we have our base menu in place, let’s change the other menu screens to what we need.  Let’s work with the Options screen first.  There are not going to be a bunch of options to set, but this leaves it open to you if you want to add in some more options for your game.  There are going to be two options that can be set, Main Volume and SFX Volume.  These will be stored in a static class that will contain global information for the game, and when the player saves, it will save to that players save slot.<br />
So in our library let’s add a new class called Settings. This will be a static class so we have access to it throughout our library.</p>
<pre class="brush: csharp; title: ;">
	public static class Settings
	{
		public static int MainVolume = 75;
		public static int SFXVolume = 75;
	}
</pre>
<p>Now let’s go take a look at the OptionsMenuScreen.  Most of the sample code here can be gotten rid of, but lets first add in some backgrounds for screens other than the Title Screen.  We will add in another texture called Background001 to our Content folder in our main application.  Than we will create our fields and add in our LoadContent method to load the background.<br />
Our new fields:</p>
<pre class="brush: csharp; title: ;">

		ContentManager content;
		Texture2D background;
</pre>
<p>Our LoadContent method:</p>
<pre class="brush: csharp; title: ;">
#region Load Content

		public override void LoadContent()
		{
			if (content == null) content = new ContentManager(ScreenManager.Game.Services, &quot;Content&quot;);
			background = content.Load&lt;Texture2D&gt;(&quot;Textures\\Background001&quot;);
		}

		#endregion
</pre>
<p>Then our Draw method:</p>
<pre class="brush: csharp; title: ;">
	#region Drawing

		public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
            Rectangle fullscreen = new Rectangle(0, 0, viewport.Width, viewport.Height);
            byte fade = TransitionAlpha;

            Color transitionColor = new Color(fade, fade, fade);

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

                spriteBatch.Draw(background, fullscreen, transitionColor);

            spriteBatch.End();

            base.Draw(gameTime);
        }

        #endregion
</pre>
<p>So now, if you run our application and go to the options menu you will see a nice wood background.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/7.png"><img class="alignnone" title="Menu Background" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/7.png" alt="" width="100%" /></a></p>
<p>Next, we are going to add another tweak to the MenuScreen to allow us to set the position of the Menu Title, so if we need to we can move it to wherever we wish.  We are also going to have it default to center horizontally on the screen.  So open MenuScreen.cs and add in the property</p>
<pre class="brush: csharp; title: ;">
public Vector2 TitlePosition { get; set; }
</pre>
<p>Then in our constructor set TitlePosition to whatever.  The original default is TitlePosition = new Vector2(426, 80);  Now in our Draw method change our code to use the new TitlePosition, and then add a new method to center the title when we load the screen.</p>
<pre class="brush: csharp; title: ;">
	public void CenterTitle()
		{
			if (ScreenManager != null)
			{
				TitlePosition = new Vector2((ScreenManager.GraphicsDevice.Viewport.Width / 2) - (ScreenManager.Font.MeasureString(menuTitle).X / 2), 80);
			}
		}
</pre>
<p>Now we can go back to our OptionsMenuScreen.LoadContent and add the line CenterTitle() so our title centers when we load the screen.<br />
So next we need to create our menu items for Main Volume and SFX Volume.  Lets create two new MenuEntries for our menu items in the constructor, and then hook them in.  So this is what our OptionsMenuScreen constructor should now look like.</p>
<pre class="brush: csharp; title: ;">
  public OptionsMenuScreen() : base(&quot;Options&quot;)
        {
			// Create our menu entries.
			mainVolume = new MenuEntry(string.Empty);
			sfxVolume = new MenuEntry(string.Empty);

            SetMenuEntryText();

            MenuEntry backMenuEntry = new MenuEntry(&quot;Back&quot;);

            // Hook up menu event handlers.
			mainVolume.Selected += MainVolumeEntrySelected;
			sfxVolume.Selected += SFXVolumeEntrySelected;
            backMenuEntry.Selected += OnCancel;

            // Add entries to the menu.
			MenuEntries.Add(mainVolume);
			MenuEntries.Add(sfxVolume);
            MenuEntries.Add(backMenuEntry);
        }
</pre>
<p>As you can see we created two more fields mainVolume, and sfxVolume, and added a new method SetMenuEntryText().</p>
<pre class="brush: csharp; title: ;">
/// &lt;summary&gt;
        /// Fills in the latest values for the options screen menu text.
        /// &lt;/summary&gt;
        void SetMenuEntryText()
        {
			mainVolume.Text = String.Format(&quot;Main Volume: {0} %&quot;, Settings.MainVolume);
			sfxVolume.Text = String.Format(&quot;SFX Volume: {0} %&quot;, Settings.SFXVolume);
        }
</pre>
<p>Then we need to setup our event hooks for when the items are selected.</p>
<pre class="brush: csharp; title: ;">
/// &lt;summary&gt;
		/// Event handler for when the Main Volume menu entry is selected.
		/// &lt;/summary&gt;
		void MainVolumeEntrySelected(object sender, PlayerIndexEventArgs e)
		{
			Settings.MainVolume += 5;
			if (Settings.MainVolume &gt; 100) Settings.MainVolume = 0;

			SetMenuEntryText();
		}

		/// &lt;summary&gt;
		/// Event handler for when the SFX Volume menu entry is selected.
		/// &lt;/summary&gt;
		void SFXVolumeEntrySelected(object sender, PlayerIndexEventArgs e)
		{
			Settings.SFXVolume += 5;
			if (Settings.SFXVolume &gt; 100) Settings.SFXVolume = 0;

			SetMenuEntryText();
		}
</pre>
<p>So now, when we run it we should have something like this.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/8.png"><img class="alignnone" title="Options" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/8.png" alt="" width="100%" /></a></p>
<p>When we select each item, the volume increases 5% and will wrap around to 0%.  In addition, it saves it to our Settings class.<br />
Next, we will add in a Credits screen.  This will be straightforward and will only have one menu item. So on our Screens folder add a new class and name it CreditsScreen.</p>
<pre class="brush: csharp; title: ;">
    class CreditsScreen: MenuScreen
    {
        #region Fields

		ContentManager content;
		Texture2D background;

        #endregion

        #region Initialization

        /// &lt;summary&gt;
        /// Constructor.
        /// &lt;/summary&gt;
		public CreditsScreen() : base(&quot;Credits&quot;)
        {
			MenuEntry backMenuEntry = new MenuEntry(&quot;Back&quot;);
            backMenuEntry.Selected += OnCancel;
            MenuEntries.Add(backMenuEntry);
        }

        #endregion

		#region Load Content

		public override void LoadContent()
		{
			if (content == null) content = new ContentManager(ScreenManager.Game.Services, &quot;Content&quot;);
			background = content.Load&lt;Texture2D&gt;(&quot;Textures\\Background001&quot;);
			CenterTitle();
			if (ScreenManager != null)
			{
				MenuPosition = new Vector2(100f, ScreenManager.GraphicsDevice.Viewport.Height - (ScreenManager.GraphicsDevice.Viewport.Height * 0.1f));
			}
		}

		#endregion

       	#region Drawing

		public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
            Rectangle fullscreen = new Rectangle(0, 0, viewport.Width, viewport.Height);
            byte fade = TransitionAlpha;

            Color transitionColor = new Color(fade, fade, fade);

			Vector2 position = new Vector2(100, 150);

			float transitionOffset = (float)Math.Pow(TransitionPosition, 2);

			if (ScreenState == ScreenState.TransitionOn)
				position.X -= transitionOffset * 256;
			else
				position.X += transitionOffset * 512;

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

                spriteBatch.Draw(background, fullscreen, transitionColor);

				spriteBatch.DrawString(ScreenManager.Font, &quot;[ Design / Concept / Programming / Art ] - Aaron T Foley&quot;, position, Color.White);
				spriteBatch.DrawString(ScreenManager.Font, &quot;[ Design / Testing ] - Ginger Foley&quot;, position + new Vector2(0f, ScreenManager.Font.LineSpacing * 2), Color.White);
				spriteBatch.DrawString(ScreenManager.Font, &quot;[ Music ] - Neil Lynn&quot;, position + new Vector2(0f, ScreenManager.Font.LineSpacing * 4), Color.White);

            spriteBatch.End();

            base.Draw(gameTime);
        }

        #endregion
    }
</pre>
<p>As you can see there is nothing special about this screen, but it can be molded into whatever you want.<br />
Our next section will deal with our Continue Story screen and loading from storage.<br />
So our first thing we need to do is create the new screen ContinueGameScreen.  Once again, this will be roughly the same as the Credits screen and the Options screen.</p>
<pre class="brush: csharp; title: ;">
	class ContinueGameScreen : MenuScreen
    {
        #region Fields

		ContentManager content;
		Texture2D background;

        #endregion

        #region Initialization

        /// &lt;summary&gt;
        /// Constructor.
        /// &lt;/summary&gt;
		public ContinueGameScreen() : base(&quot;Continue Game&quot;)
        {
			MenuEntry backMenuEntry = new MenuEntry(&quot;Back&quot;);
            backMenuEntry.Selected += OnCancel;
            MenuEntries.Add(backMenuEntry);
        }

        #endregion

		#region Load Content

		public override void LoadContent()
		{
			if (content == null) content = new ContentManager(ScreenManager.Game.Services, &quot;Content&quot;);
			background = content.Load&lt;Texture2D&gt;(&quot;Textures\\Background001&quot;);
			CenterTitle();
		}

		#endregion

        #region Handle Input

        #endregion

		#region Drawing

		public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
            Rectangle fullscreen = new Rectangle(0, 0, viewport.Width, viewport.Height);
            byte fade = TransitionAlpha;

            Color transitionColor = new Color(fade, fade, fade);

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

                spriteBatch.Draw(background, fullscreen, transitionColor);

            spriteBatch.End();

            base.Draw(gameTime);
        }

        #endregion
    }
</pre>
<p>So this is pretty basic, but we will flesh it out.  Also don’t forget to add in your event hook in your MainMenuScreen to transition to the continue screen.</p>
<pre class="brush: csharp; title: ;">
/// &lt;summary&gt;
        /// Event handler for when the Continue Game menu entry is selected.
        /// &lt;/summary&gt;
        void ContinueGameMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
			ScreenManager.AddScreen(new ContinueGameScreen(), e.PlayerIndex);
        }
</pre>
<p>Now that we have the screen loading, let’s get even more dirty.  We will be using a library to handle the storage device for us.  It is a nice library called EasyStorage.</p>
<p><a href="http://easystorage.codeplex.com/"><strong><span style="text-decoration: underline;">EasyStorage</span></strong></a></p>
<p>So download this and in the DLL’s to our solution.  I created a new folder in my solution called EasyStorage and added in the DLL and resource files it uses there.  Then I added the reference to it.</p>
<p>Now we need to determine what we want to see on our Continue Game screen.</p>
<p>My original concept will use 5 slots that display some information about the save that’s currently within that slot.  So we need to create a SaveGameDescription that holds the information we want to display in each slot.</p>
<pre class="brush: csharp; title: ;">
[Serializable]
	public class SaveGameDescription
	{
		public string Filename { get; set; }
		public string PlayerName { get; set; }
		public string PlayerLevel { get; set; }
		public string PlayerClass { get; set; }
		public string Region { get; set; }
		public string Description { get; set; }

		public SaveGameDescription()
		{
			Filename = &quot;&quot;;
			PlayerName = &quot;&quot;;
			PlayerLevel = &quot;0&quot;;
			PlayerClass = &quot;Unknown&quot;;
			Region = &quot;Unknown&quot;;
			Description = &quot;Empty&quot;;
		}
	}
</pre>
<p>Now that we have defined what our SaveGameDescriptions will be, we need somewhere to store them globally.  So we will create a static class called Global that will store data we will need throughout the game such as this.</p>
<pre class="brush: csharp; title: ;">
	public static class Global
	{

		public static List&lt;SaveGameDescription&gt; SaveGameDescriptions { get; set; }

		static Global()
		{
			SaveGameDescriptions = new List&lt;SaveGameDescription&gt;();
		}
	}
</pre>
<p>So now we have some data to work with to create our 5 slots for our continue screen.  So back in our continue game screen we will modify our screen to handle the five slots.<br />
I’m wanting to use the MenuEntry system to do this, but each item has a default of the Fonts Line Spacing to space the items out on the screen.  So we will have to modify MenuScreen again to have an adjustable LineSpacing.<br />
So in MenuScreen.cs add the property,</p>
<pre class="brush: csharp; title: ;">
public float LineSpacing { get; set; }
</pre>
<p>and in the constructor set it to 0.  This will be the amount each item will space in addition to the default Font.LineSpacing. Then in the Draw method modify the following line.</p>
<pre class="brush: csharp; title: ;">
position.Y += menuEntry.GetHeight(this) + LineSpacing;
</pre>
<p>So now we can set our additional line spacing in our screens to whatever we choose.<br />
So here is the final ContinueGameScreen.cs.  Right now it doesn’t actually load any save data, but it provides the shell for doing it.  It does load save descriptions, and if one doesn’t exist it creates a blank one so it can display information on the slot.</p>
<pre class="brush: csharp; title: ;">
	class ContinueGameScreen : MenuScreen
    {
        #region Fields

		ISaveDevice saveDevice;

		ContentManager content;
		Texture2D background;

		MenuEntry slot1;
        MenuEntry slot2;
        MenuEntry slot3;
        MenuEntry slot4;
        MenuEntry slot5;

		private SaveGameDescription loadedSaveGameDescription;
		private SaveGameDescription savedSaveGameDescription;

		public string StorageContainerName = &quot;Vacant Skies&quot;;

		private readonly XmlSerializer serializer = new XmlSerializer(typeof(SaveGameDescription));

        #endregion

		#region Initialization

		/// &lt;summary&gt;
        /// Constructor.
        /// &lt;/summary&gt;
		public ContinueGameScreen() : base(&quot;Continue Game&quot;)
        {
			MenuEntry backMenuEntry = new MenuEntry(&quot;Back&quot;);
            backMenuEntry.Selected += OnCancel;

			slot1 = new MenuEntry(&quot;Slot 1&quot;);
			slot2 = new MenuEntry(&quot;Slot 2&quot;);
			slot3 = new MenuEntry(&quot;Slot 3&quot;);
			slot4 = new MenuEntry(&quot;Slot 4&quot;);
			slot5 = new MenuEntry(&quot;Slot 5&quot;);

			SetMenuText();

			slot1.Selected += Slot1Selected;
			slot2.Selected += Slot2Selected;
			slot3.Selected += Slot3Selected;
			slot4.Selected += Slot4Selected;
			slot5.Selected += Slot5Selected;

			MenuEntries.Add(slot1);
			MenuEntries.Add(slot2);
			MenuEntries.Add(slot3);
			MenuEntries.Add(slot4);
			MenuEntries.Add(slot5);
			MenuEntries.Add(backMenuEntry);
        }

        #endregion

		#region Load Content

		public override void LoadContent()
		{
			if (content == null) content = new ContentManager(ScreenManager.Game.Services, &quot;Content&quot;);
			background = content.Load&lt;Texture2D&gt;(&quot;Textures\\Background001&quot;);
			CenterTitle();
			LineSpacing = ScreenManager.Font.LineSpacing * 1.25f;

			LoadStorageDevice();
		}

		#endregion

        #region Handle Input

		void Slot1Selected(object sender, PlayerIndexEventArgs e)
		{
			SetMenuText();
		}

		void Slot2Selected(object sender, PlayerIndexEventArgs e)
		{
			SetMenuText();
		}

		void Slot3Selected(object sender, PlayerIndexEventArgs e)
		{
			SetMenuText();
		}

		void Slot4Selected(object sender, PlayerIndexEventArgs e)
		{
			SetMenuText();
		}

		void Slot5Selected(object sender, PlayerIndexEventArgs e)
		{
			SetMenuText();
		}

        #endregion

		#region Drawing

		public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
            Rectangle fullscreen = new Rectangle(0, 0, viewport.Width, viewport.Height);
            byte fade = TransitionAlpha;

            Color transitionColor = new Color(fade, fade, fade);

            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

                spriteBatch.Draw(background, fullscreen, transitionColor);

            spriteBatch.End();

            base.Draw(gameTime);
        }

		#endregion

		void SetMenuText()
		{
			if (Global.SaveGameDescriptions.Count &gt; 1)
			{
				SaveGameDescription save = Global.SaveGameDescriptions[0];
				slot1.Text = string.Format(&quot;Slot 1 | Name: {0} Class: {1} Level: {2} Region: {3}\r\n       | {4}&quot;, save.PlayerName, save.PlayerClass, save.PlayerLevel, save.Region, save.Description);
			}
			if (Global.SaveGameDescriptions.Count &gt; 2)
			{
				SaveGameDescription save = Global.SaveGameDescriptions[1];
				slot2.Text = string.Format(&quot;Slot 2 | Name: {0} Class: {1} Level: {2} Region: {3}\r\n       | {4}&quot;, save.PlayerName, save.PlayerClass, save.PlayerLevel, save.Region, save.Description);
			}
			if (Global.SaveGameDescriptions.Count &gt; 3)
			{
				SaveGameDescription save = Global.SaveGameDescriptions[2];
				slot3.Text = string.Format(&quot;Slot 3 | Name: {0} Class: {1} Level: {2} Region: {3}\r\n       | {4}&quot;, save.PlayerName, save.PlayerClass, save.PlayerLevel, save.Region, save.Description);
			}
			if (Global.SaveGameDescriptions.Count &gt; 4)
			{
				SaveGameDescription save = Global.SaveGameDescriptions[3];
				slot4.Text = string.Format(&quot;Slot 4 | Name: {0} Class: {1} Level: {2} Region: {3}\r\n       | {4}&quot;, save.PlayerName, save.PlayerClass, save.PlayerLevel, save.Region, save.Description);
			}
			if (Global.SaveGameDescriptions.Count &gt; 1)
			{
				SaveGameDescription save = Global.SaveGameDescriptions[4];
				slot5.Text = string.Format(&quot;Slot 5 | Name: {0} Class: {1} Level: {2} Region: {3}\r\n       | {4}&quot;, save.PlayerName, save.PlayerClass, save.PlayerLevel, save.Region, save.Description);
			}
		}

		void LoadStorageDevice()
		{
#if WINDOWS
			saveDevice = new PCSaveDevice(StorageContainerName);
			ReadSaves();
#else
			// add the GamerServicesComponent
			Components.Add(new GamerServicesComponent(this));

			// create and add our SaveDevice
			SharedSaveDevice sharedSaveDevice = new SharedSaveDevice(StorageContainerName);
			Components.Add(sharedSaveDevice);

			// hook an event for when the device is selected to run our test
			sharedSaveDevice.DeviceSelected += (s, e) =&gt; ReadSaves();

			// hook two event handlers to force the user to choose a new device if they cancel the
			// device selector or if they disconnect the storage device after selecting it
			sharedSaveDevice.DeviceSelectorCanceled += (s, e) =&gt; e.Response = SaveDeviceEventResponse.Force;
			sharedSaveDevice.DeviceDisconnected += (s, e) =&gt; e.Response = SaveDeviceEventResponse.Force;

			// prompt for a device on the first Update we can
			sharedSaveDevice.PromptForDevice();

			// make sure we hold on to the device
			saveDevice = sharedSaveDevice;
#endif

			SetMenuText();
		}

		private void ReadSaves()
		{
			Global.SaveGameDescriptions.Clear();
			for (int i = 1; i &lt;= 5; i++)
			{
				string filename = String.Format(&quot;SaveSlot{0}-Description.xml&quot;, i);
				if (!saveDevice.FileExists(filename))
				{
					Trace.WriteLine(String.Format(&quot;Failed to find file {0}.&quot;, filename));
					savedSaveGameDescription = new SaveGameDescription();
					if (!saveDevice.Save(filename, SerializeSave))
					{
						Trace.WriteLine(string.Format(&quot;Failed to save file {0}.&quot;, filename));
					}
				}
				else
				{
					if (!saveDevice.Load(filename, DeserializeSave))
					{
						Trace.WriteLine(String.Format(&quot;Failed to load file {0}.&quot;, filename));
					}
					Global.SaveGameDescriptions.Add(loadedSaveGameDescription);
				}
			}
		}

		private void DeserializeSave(Stream stream)
		{
			loadedSaveGameDescription = serializer.Deserialize(stream) as SaveGameDescription;
			Trace.WriteLine(&quot;Save Game Description Loaded: &quot; + loadedSaveGameDescription);
		}

		private void SerializeSave(Stream stream)
		{
			Trace.WriteLine(&quot;Game Description Saved: &quot; + savedSaveGameDescription);
			serializer.Serialize(stream, savedSaveGameDescription);
		}
    }
</pre>
<p>So now if you run our application you should see something like this in the continue screen.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/9.png"><img class="alignnone" title="Continue Screen" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/9.png" alt="" width="100%" /></a></p>
<p>So this concludes part one of the Action RPG Tutorial Series.  In our next part we will be diving into creating the game world and populating it.</p>
<p><strong>Download: <a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rpg/part1/Part1_Source.zip">Part1_Source.zip</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-vacant-skies-action-rpg-tutorial-series/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Article: Rolling World Tutorial</title>
		<link>http://www.sgtconker.com/2010/09/article-rolling-world-tutorial/</link>
		<comments>http://www.sgtconker.com/2010/09/article-rolling-world-tutorial/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 21:01:46 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[2D]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Christian Schlager]]></category>
		<category><![CDATA[Content Creation]]></category>
		<category><![CDATA[Rolling World]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1745</guid>
		<description><![CDATA[by Christian Schlager



When you look around the XBox Indie Games Channel, there aren't a lot of  3D games around. Most XNA games only feature 2D graphics. I hope to  contribute with this tutorial to making 3D graphics a bit less  intimidating. And maybe the little prototype we will create throughout  the [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by Christian Schlager</h4>
<div align="center">
<img width="60%" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/rollingworld/gfx/aerial_perspective_in_game.jpg">
</div>
<p>When you look around the XBox Indie Games Channel, there aren't a lot of  3D games around. Most XNA games only feature 2D graphics. I hope to  contribute with this tutorial to making 3D graphics a bit less  intimidating. And maybe the little prototype we will create throughout  the next pages will be the starting point of a great 3D indie game by  one of you <img src='http://www.sgtconker.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>We will make a prototype that features the kind of rolling world effect  that you can see in games such as Animal Crossing or DeathSpank. We will  also create the textures and 3D models that go along with the rolling  effect and recreate the combination of 2D art with a 3D world you can  see in the game DeathSpank.<br />
<span id="more-1745"></span></p>
<h4>Difficulty</h4>
<p>This tutorial is intended for Beginner/Intermediate developers.<br />
If you played around with XNA and /or worked on 2D games before this tutorial should be no problem for you.</p>
<h4>Content</h4>
<p>The first section of this tutorial covers the creation of the assets for our game.<br />
We will draw textures for the world, for the trees and a very simple one for the hero.<br />
We will also create a simple DirectX effect file which we will use to render the models we create in SoftImage Mod Tool.<br />
Once we have all the assets we will set up our game project in Visual  Studio, load and render game objects and then move the hero of our game  around.<br />
In the last section we will add the rolling world effect. We will  develop a concept of the effect with sketches and pseudo-code and then  implement the effect.<br />
Finally, there is some bonus content you might try once you are done with the tutorial.<br />
This tutorials comes with pre-made assets in case you are only  interested in the programming side of the tutorial. You can also skip  the foreplay completely and jump to the rolling world effect part using  the project in the folder WorldGame.<br />
You can also explore for yourself with the complete rolling world game in the folder RollingWorldGame.</p>
<h4>Software</h4>
<dl>
<dt>Visual C# 2008 Express</dt>
<dd>The Visual Studio 2008 Express is a free set of tools for developing applications for Windows.<br />
<a href="http://www.microsoft.com/express/Downloads/#2008-Visual-CS" target="new">Download Visual C\# 2008 Express</a> </dd>
<dt>XNA Game Studio 3.1</dt>
<dd>This software package contains the XNA framework which includes an  extensive set of class libraries specific to game development. Once you  installed the Game Studio you can use it in Visual Studio:<br />
<a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=80782277-d584-42d2-8024-893fcd9d3e82" target="new">Microsoft XNA Game Studio 3.1</a> </dd>
<dt>Paint.NET</dt>
<dd>Paint.NET is free image and photo editing software for Windows. We will use it to create textures for our game:<br />
<a href="http://www.getpaint.net/download.html" target="new">Download Paint.NET</a> </dd>
<dt>SoftImage Mod Tool</dt>
<dd>We will be using Autodesk SoftImage Mod Tool to create the 3D  models. The version we will use is for non-commercial use only which is  fine for this tutorial:<br />
<a href="http://usa.autodesk.com/adsk/servlet/pc/item?siteID=123112&amp;id=13571320" target="new">Download Autodesk Softimage Mod Tool</a></dd>
</dl>
<h4>Feedback</h4>
<p>My name is Christian Schlager and I wrote this tutorial. If you like it,  have constructive feedback or found a mistake in the tutorial please  leave a comment here, or on my page: <a href="http://googoobachoo.blogspot.com/2010/08/rolling-world-tutorial.html" target="new">http://googoobachoo.blogspot.com</a></p>
<h2>Downloads</h2>
<p>This tutorial is accompanied by the following downloads:</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rollingworld/WorldGame.zip">WorldGame.zip</a><br />
<a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rollingworld/RollingWorldGame.zip">RollingWorldGame.zip</a><br />
<a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/rollingworld/Assets.zip">Assets.zip</a></p>
<h4>Next Page: Creating the assets</h4>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-rolling-world-tutorial/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Article: Texture Modification using Render Targets, with some Stencil Buffer Action</title>
		<link>http://www.sgtconker.com/2010/08/article-texture-modification-using-render-targets-with-some-stencil-buffer-action/</link>
		<comments>http://www.sgtconker.com/2010/08/article-texture-modification-using-render-targets-with-some-stencil-buffer-action/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 20:56:49 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[2D]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Dave Carlile]]></category>
		<category><![CDATA[Stencil Buffer]]></category>
		<category><![CDATA[Texture Modification]]></category>
		<category><![CDATA[XNA 4.0]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1595</guid>
		<description><![CDATA[by Dave Carlile

Sometimes you need to modify a texture while your game is running, and there are a number of ways to do this. One of the first things newer game programmers often try to do is use Texture2D.GetData to copy the texture data from the GPU to an array on the CPU, modify the [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by Dave Carlile</h4>
<p style="text-align: center;"><img class="aligncenter" title="Planet Craters" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/dave_2/image001.jpg" alt="Planet Craters" width="320" height="256" /></p>
<p>Sometimes you need to modify a texture while your game is running, and there are a number of ways to do this. One of the first things newer game programmers often try to do is use Texture2D.GetData to copy the texture data from the GPU to an array on the CPU, modify the bytes, and then send it back to the GPU with Texture2D.SetData.</p>
<p>This is a bad idea on many, levels. Beyond issues with <a href="http://blogs.msdn.com/b/shawnhar/archive/2008/04/14/stalling-the-pipeline.aspx">pipeline stalls</a>, GetData and SetData can be slow, especially when working with a large texture. Any time you’re tempted grab data from the GPU for use on the CPU you should very carefully consider all of your options. There are often other solutions that let you keep the data entirely on the GPU and accomplish the same thing.</p>
<p>This tutorial will use an example that could be solved with GetData and SetData, and show you another alternative using render targets and the stencil buffer that will let you perform the same function entirely on the GPU.</p>
<p><span id="more-1595"></span></p>
<h1>CPU Craters</h1>
<p>Let’s pretend you want to draw 2D planet, and periodically add a crater to it.  You want a hole to appear somewhere on the planet, so it looks like part of it was removed.</p>
<p><img class="alignnone" title="Planet Craters" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/dave_2/image001.jpg" alt="Planet Craters" width="320" height="256" /></p>
<p>You could do this using the GetData/SetData method by getting the data from a texture into an array, setting the color to the background (or alpha to 0) in the shape of the crater, then writing the data back to the texture. Or you could be a little cleverer and eliminate GetData by always keeping the data in the array, but you still have to do the SetData to get it into the texture on the GPU each time it’s changed.</p>
<h1>GPU Craters</h1>
<p>The method we’ll use to do this entirely on the GPU involves several steps.  First, we need a couple of resources.  We’ll use a simple textured circle for a planet, and a “crater” shaped texture for the crater.</p>
<p><img class="alignnone" title="Planet" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/dave_2/image002.jpg" alt="" width="256" height="256" /><img class="alignnone" title="Crater" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/dave_2/image003.jpg" alt="" width="256" height="256" /></p>
<p>It’s important to note that the black areas on these have an alpha value of 0, meaning completely transparent. For the planet this just lets us draw the round shape over the background without looking like a square image. But for the crater image the alpha value is very important since it will control what part of the crater image is removed from the planet.</p>
<p>Next, we need to set up two render targets (these will be referred to later as Render Target A, and Render Target B). When we need to add a crater, one of these will be used as a target for drawing to, while the other used as a texture. The next time we add a crater they will swap roles – the texture will become the target, and the target will become the texture. This is called “ping-ponging” and will be discussed more fully later.</p>
<p>Once we have these resources ready to go, the method for adding a crater goes like this:</p>
<ol>
<li>Activate Render Target A using GraphicsDevice.SetRenderTarget.</li>
<li>Clear the graphics device, setting the color to solid black, and the stencil buffer to 0.</li>
<li>Set up the stencil buffer state so whatever we draw writes a value of 1 to the stencil buffer.</li>
<li>Set up the alpha test state so we only draw where the alpha value is zero.</li>
<li>Draw the crater texture. Because of the way we’ve set up the graphics device, only the parts of the crater texture that have alpha = 0 will be drawn, and those parts will write a 1 to the stencil buffer.  So what we have at this point is a “mask” in the stencil buffer that we can use in the next step. The white area in the following image represents the stencil mask we’ve set up – the stencil buffer contains “1” in the white area, and “0” everywhere else.<br />
<img class="alignnone" title="Crater Mask" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/dave_2/image004.jpg" alt="" width="256" height="256" /></li>
<li>Set up the stencil buffer so when we draw, anything that has a value of 1 in the stencil buffer will be masked out – meaning it won’t draw.</li>
<li>Draw the “planet texture”. Because of the way we’ve set up the graphics device, anything with a 1 in the stencil buffer won’t be drawn – since these 1’s are in the shape of a crater, that shape will be masked out of the planet texture, leaving holes that look like craters.<br />
<img class="alignnone" title="Crater Planet" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/dave_2/image005.jpg" alt="" width="256" height="256" /></li>
<li>Set the render target to the backbuffer.  We can now access Render Target A as a texture, and that texture contains the planet texture with a crater-shaped hole in it.</li>
</ol>
<p>From now on, until we need to add another crater, we can treat Render Target A as a texture and draw it using SpriteBatch, and we’ll have a nice crater. Now, what if we need to add another crater? This is where the ping-ponging comes in. Since Render Target A is now the “planet texture”, we need to be able to draw somewhere else when we’re filling in the stencil buffer with our crater shape. It just so happens that we set up another place to draw to, Render Target B.</p>
<p>So now, in Step 1, instead of activating Render Target A we need to activate Render Target B and draw the crater shapes into that.  But what happens when we get to Step 7? Well, the “planet texture” is now in Render Target A, so we draw that.  And in Step 8, Render Target B now contains our new planet texture with two craters.</p>
<p>And if we add a third crater then we’re back to where we started – drawing to Render Target A, and using Render Target B as the source texture. In other words, we “ping-pong” between the two render targets – each time we need to modify the texture, one is used for a texture, and one is used for drawing to, and then those roles are swapped.</p>
<p>You may have noticed that there’s one issue here.  The first time through, Render Target B has nothing in it, so we can’t use it as the planet texture.  This can be handled by using the actual planet texture the first time, and the render target thereafter.</p>
<h1>The Code</h1>
<p>Now let’s walk through the code involved, using XNA 4.0.  You can do this in 3.1, but you’ll have to make significant changes when creating the render targets and setting the render states.</p>
<p>The complete code is in the downloadable project linked at the end of the tutorial.  We’ll just go through the highlights here, referring to the steps mentioned above as we go.</p>
<p>The XNA 4.0 API has been changed substantially where render states are concerned, and for the better. Render states have been grouped by functionality into several classes. You create instances of these classes to represent the state you want, then set them on the graphics device, or pass them to SpriteBatch.  So first we need to create these render state objects.</p>
<h2>Set Up Render State Objects</h2>
<p>For Step 3, we need to use the DepthStencilState class to set up the device to always set the stencil buffer to 1. We enable the stencil buffer, set the stencil function to Always, the pass operation to Replace, and ReferenceStencil to 1. This means that as we’re drawing, each pixel will Always pass, and the value in the stencil buffer will be Replaced with 1.</p>
<pre class="brush: csharp; title: ;">
        // set up stencil state to always replace stencil buffer with 1
        stencilAlways = new DepthStencilState();
        stencilAlways.StencilEnable = true;
        stencilAlways.StencilFunction = CompareFunction.Always;
        stencilAlways.StencilPass = StencilOperation.Replace;
        stencilAlways.ReferenceStencil = 1;
        stencilAlways.DepthBufferEnable = false;
</pre>
<p>And for Step 4 we need to use the standard AlphaTestEffect so we can draw the asteroid texture only where the alpha value is 0.</p>
<pre class="brush: csharp; title: ;">
      // set up alpha test effect
      Matrix projection = Matrix.CreateOrthographicOffCenter(0, PlanetDataSize, PlanetDataSize, 0, 0, 1);
      Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);

      alphaTestEffect = new AlphaTestEffect(GraphicsDevice);
      alphaTestEffect.VertexColorEnabled = true;
      alphaTestEffect.DiffuseColor = Color.White.ToVector3();
      alphaTestEffect.AlphaFunction = CompareFunction.Equal;
      alphaTestEffect.ReferenceAlpha = 0;
      alphaTestEffect.World = Matrix.Identity;
      alphaTestEffect.View = Matrix.Identity;
      alphaTestEffect.Projection = halfPixelOffset * projection;
</pre>
<p>We first set up an orthographic projection matrix that matches SpriteBatch. We set AlphaFunction to Equal, and ReferenceAlpha to 0.  This means the alpha test will pass whenever the alpha value we’re drawing is equal to 0. In our crater texture, the crater area has an alpha value of 0, while the surrounding area has 1, so only the crater area will be drawn.<br />
For Step 6 we need a stencil buffer state that allows drawing only where the stencil buffer contains a 0. We enable the stencil buffer, set the stencil function to Equal, the pass operation to Keep, and the reference stencil to 0. This means that when we’re drawing, each pixel will pass if the value in the stencil buffer is Equal to 0.</p>
<pre class="brush: csharp; title: ;">
        // set up stencil state to pass if the stencil value is 0
        stencilKeepIfZero = new DepthStencilState();
        stencilKeepIfZero.StencilEnable = true;
        stencilKeepIfZero.StencilFunction = CompareFunction.Equal;
        stencilKeepIfZero.StencilPass = StencilOperation.Keep;
        stencilKeepIfZero.ReferenceStencil = 0;
        stencilKeepIfZero.DepthBufferEnable = false;
</pre>
<h2>Create Render Targets</h2>
<p>Now that we have the render state objects created, it’s time to create the render targets.  Both are the same, so just one is shown here. This creates a render target with a Color format, and a depth format that includes a stencil buffer.</p>
<pre class="brush: csharp; title: ;">
        renderTargetA = new RenderTarget2D(GraphicsDevice, PlanetDataSize, PlanetDataSize,
                                  false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8,
                                  0, RenderTargetUsage.DiscardContents);
</pre>
<h2>Draw the Crater Mask</h2>
<p>Next up is drawing the crater masks (Steps 2-5). First we activate the render target, clear it to solid black, and clear the stencil buffer to 0.</p>
<pre class="brush: csharp; title: ;">
      GraphicsDevice.SetRenderTarget(activeRenderTarget);
      GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.Stencil,
                           new Color(0, 0, 0, 1), 0, 0);
</pre>
<p>Next we begin a SpriteBatch, passing in the stencilAlways and alphaTestEffect objects that we created earlier. Calculate some random rotation, size the crater texture using a Rectangle, and call SpriteBatch.Draw to draw the crater.</p>
<pre class="brush: csharp; title: ;">
      spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque,
                        null, stencilAlways, null, alphaTestEffect);

      Vector2 origin = new Vector2(craterTexture.Width * 0.5f,
                                   craterTexture.Height * 0.5f);

      float rotation = (float)random.NextDouble() * MathHelper.TwoPi;
      Rectangle r = new Rectangle((int)position.X, (int)position.Y, 50, 50);

      spriteBatch.Draw(craterTexture, r, null, Color.White, rotation,
                       origin, SpriteEffects.None, 0);

      spriteBatch.End();
</pre>
<h2>Draw the Planet Texture</h2>
<p>Now we need to draw the latest planet texture, using the stencil buffer to mask out the craters (Steps 6-7). We begin a SpriteBatch, passing in the stencilKeepIfZero object we created earlier. Note that the first time we draw the actual planet texture, but subsequently we draw using the texture from the previous iteration.</p>
<pre class="brush: csharp; title: ;">
      spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque,
                        null, stencilKeepIfZero, null, null);

      if (firstTime)
      {
        spriteBatch.Draw(planetTexture, Vector2.Zero, Color.White);
        firstTime = false;
      }
      else
        spriteBatch.Draw(textureRenderTarget, Vector2.Zero, Color.White);

      spriteBatch.End();
</pre>
<h2>Swap Render Targets</h2>
<p>Finally we activate the backbuffer render target.</p>
<pre class="brush: csharp; title: ;">
      GraphicsDevice.SetRenderTarget(null);
</pre>
<p>And then swap the render targets as discussed previously.</p>
<pre class="brush: csharp; title: ;">
      RenderTarget2D t = activeRenderTarget;
      activeRenderTarget = textureRenderTarget;
      textureRenderTarget = t;
</pre>
<p>In the main Draw function, you draw the latest cratered planet using the textureRenderTarget. Of course, you need to deal with using the planet texture the first time through though. The downloadable code shows one simple way to do that.</p>
<pre class="brush: csharp; title: ;">
      GraphicsDevice.Clear(Color.CornflowerBlue);

      spriteBatch.Begin();
      spriteBatch.Draw(textureRenderTarget, planetPosition, Color.White);
      spriteBatch.End();
</pre>
<h1>Conclusion</h1>
<p>And there you have it, a powerful technique for altering textures during your game. Doing this entirely on the GPU is quite a bit more complex than GetData/SetData, but is well worth the extra trouble.<br />
There are some things you can do to improve this technique. If you need to add a lot of craters, rather than adding them one at a time you can batch them up for a while, then in Step 5 draw all of them at once.<br />
I hope you found this tutorial informative. Learning about render targets and stencil buffers opens up a whole new world of possibilities beyond just making craters. What other uses can you think of?</p>
<p><strong>Download sample code:</strong> <a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/dave_2/StencilCratersTutorial.zip">StencilCratersTutorial.zip</a> (<a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/dave_license.txt">license</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/08/article-texture-modification-using-render-targets-with-some-stencil-buffer-action/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Article: Derived Effect Classes in XNA 4</title>
		<link>http://www.sgtconker.com/2010/08/article-derived-effect-classes-in-xna-4/</link>
		<comments>http://www.sgtconker.com/2010/08/article-derived-effect-classes-in-xna-4/#comments</comments>
		<pubDate>Sat, 14 Aug 2010 05:04:58 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Content Pipeline]]></category>
		<category><![CDATA[Dave Carlile]]></category>
		<category><![CDATA[Derives Effects]]></category>
		<category><![CDATA[Effects]]></category>
		<category><![CDATA[XNA 4.0]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1569</guid>
		<description><![CDATA[by Dave Carlile

One of the nice API changes in XNA 4.0 is the simplified syntax used when drawing with an Effect. In previous versions you would draw things like this:

effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
        pass.Begin();
        // draw your stuff
   [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by Dave Carlile</h4>
<p style="text-align: center;"><img class="aligncenter" title="Derived Effects" src="http://www.sgtconker.com/wp-content/uploads/contest/2010/derivedEffects.png" alt="" width="484" height="305" /></p>
<p>One of the nice API changes in XNA 4.0 is the simplified syntax used when drawing with an Effect. In previous versions you would draw things like this:</p>
<pre class="brush: csharp; title: ;">
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
        pass.Begin();
        // draw your stuff
        pass.End();
}
effect.End();
</pre>
<p>Now you can draw things like this, with EffectPass.Apply handling all the magic:</p>
<pre class="brush: csharp; title: ;">
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
        pass.Apply();
        // draw your stuff
}
</pre>
<p>Related to this is the new Effect.OnApply virtual method which gets called by EffectPass.Apply. By overriding this method in a derived class you can do things like perform pre-shader calculations and set shader parameters from properties. This is how BasicEffect and the other new standard shaders work, and it would be nice to be able to duplicate that functionality in our own derived effects.<br />
Ideally we would like to be able to do something like this:</p>
<pre class="brush: csharp; title: ;">
        MyEffect effect = Content.Load&lt;MyEffect&gt;(“myeffect”);
        effect.World = Matrix.Identity;
        effect.Color = Color.Blue;
        ...
        effect.Apply();
        ...
</pre>
<p>The first line is where we begin running into issues. In order to load a derived class using the content pipeline you have to write your own content processor, reader, and writer, for every single class.  You might think that you could load an Effect instance using the content manager, then create an instance of your derived Effect class and pass in the code. Unfortunately, there is no way to get at the code in the Effect instance (okay, that is <a href="http://blogs.msdn.com/b/shawnhar/archive/2010/05/07/effect-compilation-and-content-pipeline-automation-in-xna-game-studio-4-0.aspx">not entirely true</a>, but this solution requires the full Game Studio install).<br />
If you want to store the class properties (e.g. MyEffect.World, MyEffect.Color) as content then extending the content pipeline for each class is your best option.  But what if you don't need to store the properties?  What if you just want a cleaner interface to your shaders?  Extending the pipeline each time for these cases seems like a lot of unnecessary work.</p>
<h1>A Solution</h1>
<p>This remainder of this tutorial will show you how to load any derived Effect class from the content pipeline without having to extend the pipeline for each class.  To accomplish this we're going to create a content pipeline extension library that will compile the effect into an intermediate object that will let us get at the compiled code. We will also create a game library that will define the intermediate class so we can get to it at run time.  And finally we’ll add an extension method that will do the work of loading our derived Effect class.<br />
<span id="more-1569"></span></p>
<h1>Setup</h1>
<p>Let's start by opening Microsoft Visual Studio 2010 Express for Windows Phone and setting some things up. It’s important that you name things correctly, so make sure you use the names given while you follow these steps:</p>
<ul>
<li>Create a new Windows Game (4.0) project, call it DerivedEffectsTutorial.</li>
<li>Add a new Windows Game Library (4.0) project to the solution, call it DerivedEffects.</li>
<li>Add a new Content Pipeline Extension Library (4.0) project, call it DerivedEffects.Pipeline.</li>
<li>Reference the DerivedEffects game library in both the DerivedEffects.Pipeline and DerivedEffectsTutorial projects.</li>
<li>Reference the DerivedEffects.Pipeline in the DerivedEffectsTutorialContent project which Visual Studio generated for you.</li>
</ul>
<p>Make sure you can build the solution. All three projects should compile with no errors.</p>
<h1>Extend the Pipeline</h1>
<p>Now that everything is set up, the first thing we're going to do is extend the content pipeline so we can compile a shader in such a way as to provide us access to the compiled code at run time. This requires these steps:</p>
<ul>
<li>Create an intermediate class to store compiled shader code.</li>
<li>Implement a ContentProcessor to compile the code and store it an instance of the intermediate class. Note that we don't need to define a content importer because we can use the existing effect importer.</li>
<li>Implement a ContentTypeWriter to write out the intermediate class at compile time.</li>
<li>Implement a ContentTypeReader to read the intermediate class at run time.</li>
</ul>
<h1>Intermediate Class</h1>
<p>First we need to create an intermediate class to hold the effect code after it's compiled by the content processor. Some types of content require a different class at compile time versus run time for various reasons. But in this case the same class will work for both. Since this class is used at both compile time and run time it needs to live in the DerivedEffects game library.<br />
Visual Studio created a Class1.cs file when we added the game library project. Right click on the file in Solution Explorer, select Rename, and change the name to DerivedEffect.cs.  You should be prompted to change the name of the class to match, click “Yes”.<br />
Now open the file.  You should see the empty DerivedEffect class defined in the DerivedEffects namespace. Make the class public so it looks like this:</p>
<pre class="brush: csharp; title: ;">
namespace DerivedEffects
{
        public class DerivedEffect
        {
        }
}
</pre>
<p>Now add a private member to store the compiled code.</p>
<pre class="brush: csharp; title: ;">
        private byte[] compiledCode;
</pre>
<p>Add a constructor which accepts the code as a parameter and stores it in the private member.</p>
<pre class="brush: csharp; title: ;">
public DerivedEffect(byte[] compiledCode)
{
        this.compiledCode = compiledCode;
}
</pre>
<p>And finally add a public property to provide access to the code.</p>
<pre class="brush: csharp; title: ;">
public byte[] CompiledCode { get { return compiledCode; } }
</pre>
<p>The final class should look like this:</p>
<pre class="brush: csharp; title: ;">
namespace DerivedEffects
{
        public class DerivedEffect
        {
                private byte[] compiledCode;

                public DerivedEffect(byte[] compiledCode)
                {
                        this.compiledCode = compiledCode;
                }

                public byte[] CompiledCode { get { return compiledCode; } }
        }
}
</pre>
<p>Make sure everything still compiles before moving on to the next step.</p>
<h1>Content Processor</h1>
<p>The content processor's job is to compile the shader code and return an instance of our intermediate DerivedEffect class.  Since it is used at compile time it lives in the DerivedEffects.Pipeline project. Visual Studio created a ContentProcessor1.cs file for us when we added the pipeline extension project. Right click on the file in Solution Explorer, select Rename, and change the name to DerivedEffectProcessor.cs.  You should be prompted to change the name of the class to match, click “Yes”.<br />
Now open the file and you should see the empty DerivedEffectProcessor class defined in the DerivedEffects.Pipeline namespace. The class should look like this (with generated comments removed for brevity):</p>
<pre class="brush: csharp; title: ;">
using TInput = System.String;
using TOutput = System.String;

namespace DerivedEffects.Pipeline
{
        [ContentProcessor(DisplayName = &quot;DerivedEffects.Pipeline.ContentProcessor1&quot;)]
        public class DerivedEffectProcessor : ContentProcessor&lt;TInput, TOutput&gt;
        {
                public override TOutput Process(TInput input, ContentProcessorContext context)
                {
                        throw new NotImplementedException();
                }
        }
}
</pre>
<p>The Process method takes an input type and returns out output type. The input type in our case is the EffectContent class which is output by the default effect importer (this is the “Effect - XNA Framework” content importer you see when you select an .fx file in solution explorer and look at the file properties).</p>
<p>The output type is the intermediate DerivedEffect class we defined earlier.</p>
<p>Change the TInput and TOutput aliases to the fully qualified names of our input and output types.</p>
<pre class="brush: csharp; title: ;">
using TInput = Microsoft.Xna.Framework.Content.Pipeline.Graphics.EffectContent;
using TOutput = DerivedEffects.DerivedEffect;
</pre>
<p>Alternatively you can remove the aliases and replace all instances of TInput with EffectContent, and all instances of TOutput with DerivedEffect.</p>
<p>Change the ContentProcessor attribute to give the processor a better name.  This is the name that shows up in the Content Processor property when you select an .fx file in Solution Explorer.</p>
<pre class="brush: csharp; title: ;">
[ContentProcessor(DisplayName = &quot;Effect – Derived Effects&quot;)]
</pre>
<p>Now, replace the contents of the Process method with this code to compile the effect.</p>
<pre class="brush: csharp; title: ;">
EffectProcessor compiler = new EffectProcessor();
CompiledEffectContent compiledContent = compiler.Process(input, context);
</pre>
<p>This creates an EffectProcessor instance, passes the EffectContent input to the Process method to compile the effect, and returns a CompiledEffectContent instance which will allow us access to the compiled code.<br />
Now we need to create an instance of our intermediate content class, passing it the compiled effect code – remember TOutput is the alias we defined previously for our DerivedEffect class.</p>
<pre class="brush: csharp; title: ;">
return new TOutput(compiledContent.GetEffectCode());
</pre>
<p>And that's it for the content processor. The final code should look like this (again, with the generated comments removed):</p>
<pre class="brush: csharp; title: ;">
using TInput = Microsoft.Xna.Framework.Content.Pipeline.Graphics.EffectContent;
using TOutput = DerivedEffects.DerivedEffect;

namespace DerivedEffects.Pipeline
{
        [ContentProcessor(DisplayName = &quot;Effect – Derived Effects&quot;)]
        public class DerivedEffectProcessor : ContentProcessor&lt;TInput, TOutput&gt;
        {
                public override TOutput Process(TInput input, ContentProcessorContext context)
                {
                        EffectProcessor compiler = new EffectProcessor();
                        CompiledEffectContent compiledContent = compiler.Process(input, context);
                        return new TOutput(compiledContent.GetEffectCode());
                }
        }
}
</pre>
<p>Now make sure everything still builds before continuing on. If there are problems, double check that you've set up the references correctly.</p>
<h1>Content Writer</h1>
<p>Next up is the content writer.  This class is responsible for writing an instance of the DerivedEffect class to an .xnb file during compile time.  Since the content writer is executed at compile time, where does it go?  That's right, the pipeline extension library.  Right click on the DerivedEffects.Pipeline project and select Add/New Item. Make sure XNA Game Studio 4.0 is selected in the Installed Templates list on the left, then choose Content Type Writer, name it DerivedEffectWriter.cs, and press the Add button.<br />
In the DerivedEffectWriter class, start by changing the TWrite alias to our DerivedEffect class.</p>
<pre class="brush: csharp; title: ;">
using TWrite = DerivedEffects.DerivedEffect;
</pre>
<p>Remove all of the code from the Write method and replace it with this:</p>
<pre class="brush: csharp; title: ;">
output.Write(value.CompiledCode.Length);
output.Write(value.CompiledCode);
</pre>
<p>These two lines write out the length of the compiled code array, followed by the code itself. Later on when we implement the content reader it will be able to read in the length first so it  knows how many bytes of code to read.<br />
Next, replace all the code in the GetRuntimeReader method with this:</p>
<pre class="brush: csharp; title: ;">
return typeof(DerivedEffectReader).AssemblyQualifiedName;
</pre>
<p>This line returns the name space, class name, and assembly name for the DerivedEffectReader class. It basically tells the pipeline which content reader to use when it needs to read in our DerivedEffect class.<br />
Note that we haven't defined our content reader class yet, so there will be errors if we try to compile at this point. That will be taken care of next, but first, here is what the final content writer should look like:</p>
<pre class="brush: csharp; title: ;">
using TWrite = DerivedEffects.DerivedEffect;

namespace DerivedEffects.Pipeline
{
        [ContentTypeWriter]
        public class DerivedEffectWriter : ContentTypeWriter&lt;TWrite&gt;
        {
                protected override void Write(ContentWriter output, TWrite value)
                {
                        output.Write(value.CompiledCode.Length);
                        output.Write(value.CompiledCode);
                }

                public override string GetRuntimeReader(TargetPlatform targetPlatform)
                {
                        return typeof(DerivedEffectReader).AssemblyQualifiedName;
                }
        }
}
</pre>
<h1>Content Reader</h1>
<p>We can compile an effect and write the code out to an .xnb file.  Now we need to be able to read it back from the file, which is the content reader's job.  The content reader is used at run time, which means it goes into the game library.  Right click on the DerivedEffects project and select Add/New Item. Make sure XNA Game Studio 4.0 is selected in the Installed Templates list on the left, then choose Content Type Reader, name it DerivedEffectReader.cs, and press the Add button.<br />
Change the TRead alias to our DerivedEffect class.</p>
<pre class="brush: csharp; title: ;">
using TRead = DerivedEffects.DerivedEffect;
</pre>
<p>Now replace the contents of the Read method with this code:</p>
<pre class="brush: csharp; title: ;">
int size = input.ReadInt32();
byte[] code = input.ReadBytes(size);
</pre>
<p>Recall that the content writer first wrote out the length of the code, then the code.  The reader first reads in the length of the code so it knows how many bytes to read, after which it proceeds to read that many bytes into an array.<br />
And finally, the read method needs to return a new instance of our DerivedEffect class – remember that TRead is the alias we defined for our DerivedEffect class.</p>
<pre class="brush: csharp; title: ;">
return new TRead(code);
</pre>
<p>The final content reader looks like this:</p>
<pre class="brush: csharp; title: ;">
using TRead = DerivedEffects.DerivedEffect;

namespace DerivedEffects
{
        public class DerivedEffectReader : ContentTypeReader&lt;TRead&gt;
        {
                protected override TRead Read(ContentReader input, TRead existingInstance)
                {
                        int size = input.ReadInt32();
                        byte[] code = input.ReadBytes(size);
                        return new TRead(code);
                }
        }
}
</pre>
<p>Now you should be able to compile successfully again. Make sure that is the case before moving on.</p>
<h1>Testing the Content Pipeline Changes</h1>
<p>That brings us to the end of the content pipeline extension. We've created a content processor to compile the effect, a content writer to save it out to an .xnb file at compile time, and a content reader to read it back in at run time.<br />
Allegedly we can now compile an effect file and load it into a DerivedEffect instance at run time using the content manager.  Let's make sure everything is working so far.<br />
To start with we need an .fx file. Right click on the DerivedEffectsTutorialContent project and select Add/New Item. Choose Effect File, name it MyEffect.fx, and press the Add button. You don't need to change anything in the file.<br />
Select the file in Solution Explorer. Find the Content Processor property in the file properties; click the down arrow to show the available content processors. You should see our new content processor “Effect – Derived Effects” - select it. If you don't see it, verify that you've correctly referenced the DerivedEffects.Pipeline project in the DerivedEffectsTutorialContent project (refer back to the Setup section for instructions on setting up all of the references).<br />
Open the Game1 class in the DerivedEffectsGame project. Add a using statement.</p>
<pre class="brush: csharp; title: ;">
using DerivedEffects;
</pre>
<p>Declare a new member in the Game1 class.</p>
<pre class="brush: csharp; title: ;">
DerivedEffect myEffectCode;
</pre>
<p>And a line to the LoadContent method in order to load the derived effect.</p>
<pre class="brush: csharp; title: ;">
myEffectCode = Content.Load&lt;DerivedEffect&gt;(&quot;myeffect&quot;);
</pre>
<p>Now comes the big moment – compile the project. If everything compiles then the compile time part of the content manager is working correctly. If not, you'll need to go back through the tutorial and find out what you missed.<br />
Now we need to test the run time – go ahead and run the game. If it works you'll see the beautiful cornflower blue window appear. If the content manager has a problem, such as not being able to locate the content reader for DerivedEffect, it will throw an exception.<br />
You can also set a breakpoint and examine myEffect.CompiledCode to see that it is indeed loaded with what you can assume is compiled shader code.<br />
At this point we could create an Effect object by passing the CompiledCode to the Effect constructor, like this:</p>
<pre class="brush: csharp; title: ;">
Effect effect = new Effect(GraphicsDevice, myEffect.CompiledCode);
</pre>
<p>And that is why we've done everything we have up to this point – the need to get access to the compiled code so we can pass it to the Effect constructor.  If the existing Effect class would expose a property like this we could do what we're trying to do without involving the content pipeline at all.  I'm sure the powers that be have a good reason for not exposing it, but it makes things a little awkward.<br />
Now we need to work on loading our own effect descendent. Based the previous line of code, you've probably already figured out what we need to do.</p>
<h1>Derived Effect Class</h1>
<p>Let's start by creating our derived effect class.  Right click on the DerivedEffectsTutorial game project, select Add/Class, name it MyEffect.cs, and press the Add button.<br />
You'll need to add a couple of using statements.</p>
<pre class="brush: csharp; title: ;">
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
</pre>
<p>You'll also need to have the class descend from Effect, and create one of the Effect constructors. It should look like this:</p>
<pre class="brush: csharp; title: ;">
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DerivedEffectsTutorial
{
        class MyEffect:Effect
        {
                public MyEffect(GraphicsDevice graphicsDevice, byte[] effectCode)
                        : base(graphicsDevice, effectCode)
                {
                }
        }
}
</pre>
<p>Now back in the Game1 class, add a new class member.</p>
<pre class="brush: csharp; title: ;">
MyEffect effect;
</pre>
<p>And add a line to LoadContent to create a MyEffect instance.</p>
<pre class="brush: csharp; title: ;">
effect = new MyEffect(GraphicsDevice, myEffectCode.CompiledCode);
</pre>
<p>The LoadContent method should look like this:</p>
<pre class="brush: csharp; title: ;">
protected override void LoadContent()
{
        myEffectCode = Content.Load&lt;DerivedEffect&gt;(&quot;myeffect&quot;);
        effect = new MyEffect(GraphicsDevice, myEffectCode.CompiledCode);
}
</pre>
<p>And there you have it, an instance of your very own shader class derived from Effect! It will work anywhere you would normally use an effect.  You can override OnApply and have it do things when EffectPass.Apply is called, add your own properties, and so on.<br />
But, now we need to kick it up a notch.</p>
<h1>BAM!</h1>
<p>In the beginning we decided we'd like to be able to do this.</p>
<pre class="brush: csharp; title: ;">
MyEffect effect = Content.Load&lt;MyEffect&gt;(“myeffect”);
</pre>
<p>Well, we can't do that using this solution, but how about this instead?</p>
<pre class="brush: csharp; title: ;">
MyEffect effect = Content.LoadDerivedEffect&lt;MyEffect&gt;(&quot;myeffect&quot;);
</pre>
<p>We can accomplish this by adding an extension method to the ContentManager class, so let's get started.<br />
Add a new class to the DerivedEffects game library, call it ContentManagerExtensions.  Make sure the class is static and public.</p>
<pre class="brush: csharp; title: ;">
public static class ContentManagerExtensions
{
}
</pre>
<p>Add some using statements.</p>
<pre class="brush: csharp; title: ;">
using System.Reflection;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
</pre>
<p>Add the LoadDerivedEffect extension method to the class.  Notice the use of generics, and that the allowed classes must be derived from Effect.</p>
<pre class="brush: csharp; title: ;">
public static T LoadDerivedEffect&lt;T&gt;(this ContentManager content, string assetName)
  where T:Effect
{
}
</pre>
<p>Inside the function, we need to be able to get to the graphics device. We can do that by finding the graphics device service.</p>
<pre class="brush: csharp; title: ;">
IGraphicsDeviceService graphicsDeviceService =
    (IGraphicsDeviceService)content.ServiceProvider.GetService(typeof(IGraphicsDeviceService));
</pre>
<p>This uses the content manager's ServiceProvider property to look for the graphics device service.<br />
Next we load the compiled effect code.</p>
<pre class="brush: csharp; title: ;">
DerivedEffect effect = content.Load&lt;DerivedEffect&gt;(assetName);
</pre>
<p>This is the same code we used before to load the DerivedEffect instance, but we're now using the asset name that was passed to LoadDerivedEffect.<br />
Now comes the interesting part. It would be nice if we could do this:</p>
<pre class="brush: csharp; title: ;">
return new T(graphicsDeviceService.GraphicsDevice, effect.CompiledCode);
</pre>
<p>Unfortunately, you can't do that with generics – you can only create objects with parameterless constructors. But, we can use reflection to find and call the constructor we want.</p>
<pre class="brush: csharp; title: ;">
Type classType = typeof(T);

ConstructorInfo classConstructor = classType.GetConstructor(
                BindingFlags.Instance | BindingFlags.Public, null,
                new Type[] { graphicsDeviceService.GraphicsDevice.GetType(),
                        effect.CompiledCode.GetType() },
                null);
</pre>
<p>This code first gets the type for the generic class (e.g. MyEffect). It then uses that to locate the constructor that takes GraphicsDevice and byte[] parameters.  Once we have that we can create and return and instance of the class by calling the constructor and passing the graphics device and compiled code.</p>
<pre class="brush: csharp; title: ;">
return (T)classConstructor.Invoke(new object[]
    { graphicsDeviceService.GraphicsDevice, effect.CompiledCode });
</pre>
<p>The final code should look like this:</p>
<pre class="brush: csharp; title: ;">
namespace DerivedEffects
{
        public static class ContentManagerExtensions
        {
                public static T LoadDerivedEffect&lt;T&gt;(this ContentManager content, string assetName)
                        where T : Effect
                {
                        IGraphicsDeviceService graphicsDeviceService =
                                (IGraphicsDeviceService)content.ServiceProvider.GetService(
                                        typeof(IGraphicsDeviceService));

                        DerivedEffect effect = content.Load&lt;DerivedEffect&gt;(assetName);

                        Type classType = typeof(T);
                        ConstructorInfo classConstructor = classType.GetConstructor(
                                BindingFlags.Instance | BindingFlags.Public, null,
                                new Type[] { graphicsDeviceService.GraphicsDevice.GetType(),
                                        effect.CompiledCode.GetType() }, null);

                        return (T)classConstructor.Invoke(new object[]
                                { graphicsDeviceService.GraphicsDevice,
                                        effect.CompiledCode });
                }
        }
}
</pre>
<p>Now to make sure it's working, go back to the Game1 class, remove the DerivedEffect member and replace all of the code in LoadContent with:</p>
<pre class="brush: csharp; title: ;">
effect = Content.LoadDerivedEffect&lt;MyEffect&gt;(&quot;myeffect&quot;);
</pre>
<p>The project should compile and run with no errors, and you now have an instance of your derived effect class.</p>
<h1>What Next?</h1>
<p>The downloadable code included with this tutorial extends the example with a more fully implemented MyEffect class, including OnApply and pre-shader calculations, as well as some drawing code that uses it. Going through all of that here would make a long tutorial prohibitively long.<br />
It was mentioned earlier that the DerivedEffects and DerivedEffects.Pipeline libraries are reusable. All you need to do in your new game projects is reference DerivedEffects.Pipeline in your game's content project, and DerivedEffects in your game project, and make sure the run time library is distributed with your game.  That's all there is to it.</p>
<h1>Finale</h1>
<p>This was a lot of work to do something that should be simple. If the Effect class exposed the compiled effect code this would boil down to just the content manager extension method. But since it doesn't, we can leverage the content pipeline to help us out by providing the data we need.<br />
Implementing derived effects can really improve code readability and reuse, especially with the latest Effects API changes. Hopefully this method of loading your derived classes through the content pipeline makes it that much easier to use them.  Happy sub-classing!</p>
<p><strong>Download sample code:</strong> <a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/DerivedEffectsTutorial.zip">DerivedEffectsTutorial.zip</a> (<a href="http://www.sgtconker.com/wp-content/uploads/contest/2010/dave_license.txt">license</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/08/article-derived-effect-classes-in-xna-4/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Pong in F#</title>
		<link>http://www.sgtconker.com/2010/02/pong-in-f/</link>
		<comments>http://www.sgtconker.com/2010/02/pong-in-f/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 19:54:30 +0000</pubDate>
		<dc:creator>Captain ZSquare</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[F#]]></category>
		<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Nick Gravelyn]]></category>
		<category><![CDATA[Pong]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1038</guid>
		<description><![CDATA[Former MVP, currently XNA Team Member, Nick Gravelyn talks about how he made Pong using F#. Not my cup of tea, but still might be an interesting read for some people.

]]></description>
			<content:encoded><![CDATA[<p>Former MVP, currently XNA Team Member, Nick Gravelyn talks about how he made Pong using <a href="http://en.wikipedia.org/wiki/F_Sharp_%28programming_language%29">F#</a>. Not my cup of tea, but still might be an <a href="http://nickgravelyn.com/2010/02/pong-in-fsharp-with-xna-game-studio/">interesting read</a> for some people.</p>
<p style="text-align: center;"><a href="http://nickgravelyn.com/2010/02/pong-in-fsharp-with-xna-game-studio/"><img class="aligncenter" title="Pong in F#" src="http://nickgravelyn.com/wp-content/uploads/2010/02/fsharp-pong.png" alt="" width="491" height="387" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/02/pong-in-f/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Article: Using XNA Content pipeline extensions for localization.</title>
		<link>http://www.sgtconker.com/2010/01/article-using-xna-content-pipeline-extensions-for-localization/</link>
		<comments>http://www.sgtconker.com/2010/01/article-using-xna-content-pipeline-extensions-for-localization/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 00:24:07 +0000</pubDate>
		<dc:creator>Sgt. Conker</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Content Pipeline]]></category>
		<category><![CDATA[Localization]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=979</guid>
		<description><![CDATA[by Roy Triesscheijn
Introduction
In this tutorial series I will show how to setup a simple Content Pipeline extension. At first it will be used to parse XML files containing text and their translations, in a part 2 we are going to extend our processor to also parse other xml files which contain data about localized textures [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://roy-t.nl">Roy Triesscheijn</a></h4>
<h4>Introduction</h4>
<p>In this tutorial series I will show how to setup a simple Content Pipeline extension. At first it will be used to parse XML files containing text and their translations, in a part 2 we are going to extend our processor to also parse other xml files which contain data about localized textures and sounds. We extend XNA’s content manager to make use of all this extra data.<br />
<span id="more-979"></span></p>
<p>Doing all this work in a content processor and writing a custom content manager means that we don’t have to change every line of code where we load content to factor in localization. All we need to do is add new content (like a texture with text on it in a different language) and write an xml file that explains our new content manager what files are alternatives to the original file and what language they are in. This approach works on all platforms XNA runs on, because the localization data is compiled into XNB files.</p>
<h4>Part 1: Setup, and localizing strings.</h4>
<p>As this is part 1 of this tutorial we are only going to focus on setting up the content pipeline extension and using it to display strings in different languages<em>. (Note: that hardcoded strings are never loaded via the ContentManager, so you will have to change all hardcoded strings in your code with a call to our new content manager, there isn’t a way around this unfortunately).</em></p>
<h5>The XML File</h5>
<p>Before we fire up Visual Studio we are going to have to think about the XML format for our string translation data. This is what I came up with, but of course you’re free to develop your own format suitable for your needs.</p>
<p><em>(Note: I’ve called my implementation XNABabylon, you’ll probably see that name pop-up now and then).</em></p>
<p>This is the XML format I decided on and will use for the rest of this tutorial.</p>
<pre>
<pre class="brush: plain; title: ;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;XNABabylonStringFile&gt;
  &lt;version&gt;1.0&lt;/version&gt;
  &lt;revisionDate&gt;25-01-2010&lt;/revisionDate&gt;
  &lt;author&gt;Roy Triesscheijn&lt;/author&gt;
  &lt;language&gt;English&lt;/language&gt;
  &lt;!--The package id for a file named PACKAGE.LANGUAGE.bab should be PACKAGE--&gt;
  &lt;package id=&quot;MainMenu&quot;&gt;
    &lt;key id=&quot;start&quot; val=&quot;Start Game&quot;/&gt;
    &lt;key id=&quot;quit&quot; val=&quot;Quit game by pressing escape&quot;/&gt;
    &lt;key id=&quot;motd&quot; val=&quot;Press space to change language&quot;/&gt;
  &lt;/package&gt;
&lt;/XNABabylonStringFile&gt;
</pre>
</pre>
<p>We will use the package id, which is also the first part of the filename, to load the correct file. (The second part of the filename is the language). The package id we will also be used for <a href="http://en.wikipedia.org/wiki/Namespace">namespacing</a>. Each file should contain one package.</p>
<h5>Setting up the solution</h5>
<p>Now we’ve got the formalities out of the way, let’s start coding!</p>
<p>Open up the solution in which you want to add localization (or create a new XNA Game Project). Right click the solution in the solution explorer and choose “Add new project”</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image0024.gif"><img style="display: inline; border-width: 0px;" title="clip_image002[4]" src="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image0024_thumb.gif" border="0" alt="clip_image002[4]" width="244" height="157" /></a></p>
<p>Add a new ContentPipeLineExtension to your solution. Now we need reference this extension in our game project. To do this you have to add a reference to your extension project in both your Game project <strong>AND </strong>in the games content project.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image0044.gif"><img style="display: inline; border-width: 0px;" title="clip_image004[4]" src="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image0044_thumb.gif" border="0" alt="clip_image004[4]" width="201" height="221" /></a><a href="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image0064.gif"><img style="display: inline; border-width: 0px;" title="clip_image006[4]" src="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image0064_thumb.gif" border="0" alt="clip_image006[4]" width="198" height="204" /></a></p>
<h5>The Importer</h5>
<p>Now we are going to create the classes for our ContentPipeLineExtension project. Create a new class and call it BABImporter, this class is going to Import our ‘xml’ files and convert them to instances of System.Xml.XmlDocument.<br />
As you’ll see this is pretty trivial to do, however we need to make sure XNA understands what our class is for.</p>
<p>Right under the using statements, before the namespace add the following line:</p>
<pre class="brush: csharp; title: ;">using TImport = System.Xml.XmlDocument;</pre>
<p>Here we define that our output type for this importer is going to be an XmlDocument. Now make sure your class inherits from ContentImporter by modifying your class defintion to:</p>
<pre class="brush: csharp; title: ;">public class BABImporter : ContentImporter</pre>
<p>(If needed add the necesairy using statements by right clicking on the text and selecting resolve) Now right above your class definition add the following line:</p>
<pre class="brush: csharp; title: ;">[ContentImporter(&quot;.bab&quot;, DisplayName = &quot;XNA Babylon .bab importer&quot;, DefaultProcessor = &quot;BABProcessor&quot;)]</pre>
<p>This data tells Visual Studio that this class has a special meaning in the editor. If we compile our class, all projects that have a reference to this class’ project will add this importer to the list of importers for content, also if we add new .bab files to a project the editor will automatically choose this importer. You see that we already have a DefaultProcessor named. Here you should fill in the processor that you want assigned to .bab files by default. (Fill in the class name for the processor that we are going to make shortly).</p>
<p>Now all we need to do for the importer is overriding the method Import. So create a new method in this class looking like this:</p>
<pre class="brush: csharp; title: ;">
public override TImport Import(string filename, ContentImporterContext context)
        {
            XmlDocument stringFile = new XmlDocument();
            try
            {
                stringFile.Load(filename);
            }
            catch (Exception e)
            {
                context.Logger.LogImportantMessage(&quot;The file &quot;
                    + filename + &quot; is not valid: &quot; + e.Message);
                throw e;
            }
            return stringFile;
        }
</pre>
<p>As you can see here, all we do is creating a new XmlDocument from the file inputted. Looks simple doesn’t it?</p>
<h5>The BABFile class</h5>
<p>Before we can process this data we need to define a class that can hold all the relevant information after processing. Create a simple class called BABFile like this one that can store all the data from your xml file, make sure to mark it [Serializable].</p>
<pre class="brush: csharp; title: ;">
[Serializable]
    public class BABFile
    {
        public string language;
        public double version;
        public string author;
        public string package;
        public DateTime revision;
        public Dictionary&lt;string string ,&gt; keys;

        public BABFile()
        {
            keys = new Dictionary&lt;string string ,&gt;();
        }
    }
</pre>
<h5>The processor</h5>
<p>Add another class to your extension project and call it BABProcessor, this processor is going to receive the output of the importer as input, and processes it into an instance of the BABFile class. The processor is just a simple XML reader, however we do have to mark the class with a few special attributes so that Visual Studio knows what it’s for.<br />
First add the following lines under the using statements above the namespace declaration:</p>
<pre class="brush: csharp; title: ;">
using TInput = System.Xml.XmlDocument;
using TOutput = XNABabylon.Importers.BABFile;
</pre>
<p>These lines define our input and output types. Now make sure that your class inherits from ContentProcessor (resolve the using statements if needed).<br />
And add this line above your class declaration:</p>
<pre class="brush: csharp; title: ;">[ContentProcessor(DisplayName = &quot;XNA Babylon .bab Processor&quot;)] </pre>
<p>This tells visual studio how to display this content processor in the dropdown menus of content in projects that reference this project. All we need to do now is overide the method Process and add some basic XML reading, I’ll just put the code down right here because I don’t think it’s hard to understand, but feel free to ask questions.</p>
<pre class="brush: csharp; title: ;">
public override TOutput Process(TInput input, ContentProcessorContext context)
        {
            TOutput output = new BABFile();

            //We traverse the XML file as usual and store certain elements into the
            //output object;
            if(input.GetElementsByTagName(&quot;XNABabylonStringFile&quot;).Count &gt; 0)
            {
                foreach (XmlNode node in input.GetElementsByTagName(&quot;XNABabylonStringFile&quot;)[0].ChildNodes)
                {
                    switch (node.Name)
                    {
                        case &quot;version&quot;:
                            Double.TryParse(node.InnerText, out output.version);
                            break;
                        case &quot;revisionDate&quot;:
                            DateTime.TryParse(node.InnerText, out output.revision);
                            break;
                        case &quot;author&quot;:
                            output.author = node.InnerText;
                            break;
                        case &quot;language&quot;:
                            output.language = node.InnerText;
                            break;

                        case &quot;package&quot;:
                            //Loop trough all the keys and store the key id and translated value into a dictionary
                            Dictionary&lt;string string ,&gt; package = new Dictionary&lt;string string ,&gt;();
                            foreach (XmlNode key in node.ChildNodes)
                            {
                                output.keys.Add(key.Attributes[&quot;id&quot;].InnerText, key.Attributes[&quot;val&quot;].InnerText);
                            }
                            break;
                    }
                }
            }

            return output;
        }
</pre>
<p>Now compile and resolve any errors you might have (there should be none). Testing the first files Go to your GameProject and add a new xml file to the Content project in there. (Right click it and choose add new). Rename the xml file to “MainMenu.English.bab” and select it in visual studio. Now in this file’s properties make sure to set build action to “Compile” and set the correct importer and processor as show below.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image00210.gif"><img style="display: inline; border-width: 0px;" title="clip_image002[10]" src="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image00210_thumb.gif" border="0" alt="clip_image002[10]" width="244" height="187" /></a></p>
<p>(If the importer and processor don’t show up, make sure that the reference to your extension project is both in the Content project’s references and in the encapsulating game project’s reference the latter we don’t need yet, but why not add it already).</p>
<p>Open up MainMenu.English.bab and just paste in the content from the sample xml file, located at the beginning of this tutorial. Then create another file called MainMenu.Dutch.bab set the same properties and paste in the following xml data:</p>
<pre>
<pre class="brush: plain; title: ;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;XNABabylonStringFile&gt;
  &lt;version&gt;1.0&lt;/version&gt;
  &lt;revisionDate&gt;25-01-2010&lt;/revisionDate&gt;
  &lt;author&gt;Roy Triesscheijn&lt;/author&gt;
  &lt;language&gt;Dutch&lt;/language&gt;
  &lt;!--The package id for a file named PACKAGE.LANGUAGE.bab should be PACKAGE--&gt;
  &lt;package id=&quot;MainMenu&quot;&gt;
    &lt;key id=&quot;start&quot; val=&quot;Start Spel&quot;/&gt;
    &lt;key id=&quot;quit&quot; val=&quot;Stop het spel door te drukken op escape&quot;/&gt;
    &lt;key id=&quot;motd&quot; val=&quot;Druk op spatie om van taal te veranderen&quot;/&gt;
  &lt;/package&gt;
&lt;/XNABabylonStringFile&gt;
</pre>
</pre>
<p>So we now have English and Dutch language files. Test if everything still compiles (it should).</p>
<p>The Babylon content manager<br />
We can now import our files and we can load them using the original content manager with something like:</p>
<pre class="brush: csharp; title: ;">Content.Load(“MainMenu.English”); </pre>
<p>And manually use the BABFile’s dictionary to find our translation. However since in part two we are going to write a new ContentManager, why not start a bit earlier. Go to your Extension project again and create a new class called BabylonContent and make it look like below. I think the comments sum up nicely what the methods do but let’s walk trough them quickly. The most important method, GetString, tries to find a string by looking in a package and it’s keys. First it tries to load the file associated with the current language. If that fails it loads the file for the default language and tries to find the string there. If this fails aswell we simply return an empty string. (For debugging purposes you might want to throw a hard error here, so you don’t miss missing strings).</p>
<p>You see that in the overridden Load method we now have a special section for strings. You can now do Load(“MainMenu.Start”); and get the translation for “Start Game” in the current language. The other methods are just helpers for creating ‘proper’ strings and some bookkeeping. Nothing that should really blow your mind.</p>
<pre class="brush: csharp; title: ;">
public class BabylonContent : ContentManager
    {
        public BabylonContent(IServiceProvider serviceProvider, string rootDirectory)
            : base(serviceProvider, rootDirectory)
        {
            packages = new Dictionary&lt;string , string Dictionary&gt;&lt;string ,&gt;&gt;();
            Language = DEFAULTLANGUAGE;
        }

        /// &lt;summary&gt;
        /// Load strings using &amp;quot;PackageName.Key&amp;quot;, load other files normally.
        /// &lt;/summary&gt;
        public override T Load&lt;t&gt;(string assetName)
        {

            if (typeof(T) == typeof(String))
            {
                string[] packageKey = assetName.Split('.');
                if (packageKey.Length &gt; 1)
                {
                    return (T)(object)GetString(packageKey[0], packageKey[1]);
                }
                else
                {
                    throw new Exception(assetName + &amp;quot; is not of the format 'PackageName.Key'&amp;quot;);
                }
            }
            else
            {
                return base.Load&lt;t&gt;(assetName);
            }
        }

        /// &lt;summary&gt;
        /// Given a package and a key finds the corresponding string in the
        /// language currently set in .Language
        /// &lt;/summary&gt;
        public string GetString(string package, string key)
        {
            return GetString(package, key, language);
        }

        /// &lt;summary&gt;
        /// Given a package and a key finds the corresponding string in the
        /// language requested
        /// &lt;/summary&gt;
        public string GetString(string package, string key, string packageLanguage)
        {
            package = package.ToLower();
            key = key.ToLower();
            packageLanguage = ProperString(packageLanguage);

            if (packages.Keys.Contains(package))
            {
                return (packages[package])[key];
            }

            try
            {
                BABFile bab = base.Load&lt;babfile&gt;(package + &amp;quot;.&amp;quot; + packageLanguage);
                packages.Add(package, bab.keys);
            }
            catch (ContentLoadException e)
            {
                //Now try to load the content using the default language
                //but only if the current language isn't the default language
                //else we would get stuck in infinite exception recursion.
                if (!packageLanguage.Equals(DEFAULTLANGUAGE))
                {
                    return GetString(package, key, DEFAULTLANGUAGE);
                }
            }

            if (packages.Keys.Contains(package))
            {
                return (packages[package])[key];
            }

            //The string searched for couldnt be found in the
            //translated file or the default file.
            return &amp;quot;&amp;quot;;

        }

        /// &lt;summary&gt;
        /// Converts LaNGuAGe to Language
        /// &lt;/summary&gt;
        private string ProperString(string value)
        {
            if (value.Length &gt; 0)
            {
                value = value.ToLower();
                value = value.ToUpper()[0] + value.Substring(1); ;
            }
            return value;
        }

        private Dictionary&lt;string , string Dictionary&gt;&lt;string ,&gt;&gt; packages;

        private string language;
        public string Language
        {
            get
            {
                return language;
            }
            set
            {
                //Set the new language and clear the translation dictionary
                if (language == null || !language.Equals(ProperString(value)))
                {
                    language = ProperString(value);
                    packages.Clear();
                }
            }
        }

        //Change this variable to the default language your content files are in
        //This value will be used as a fallback for untranslated content
        private static string DEFAULTLANGUAGE = &amp;quot;English&amp;quot;;
    }
</pre>
<p>(In the next tutorial we are going to override the the Load&lt;&gt; method for all types to add ‘automatic’ support for localized textures and sounds).</p>
<h5>A usage example</h5>
<p>Now we’ve got all this code and nothing to show for. I’m now going to show you a couple of lines that should show you how to use this new content manager to load localized strings from files. (if you don’t want to do this yourself feel free to just download the sourcecode and run the sample code) Go to your game project and open up your game’s class (Usually Game1.cs).<br />
Define the following two members:</p>
<pre class="brush: csharp; title: ;">
SpriteFont font;
KeyboardState oldState;
</pre>
<p>Now add the following line to the end of the constructor.</p>
<pre class="brush: csharp; title: ;">Content = new BabylonContent(Content.ServiceProvider, Content.RootDirectory); </pre>
<p>This line overwrites the default ContentManager with our newly created instance which is capable of loading strings and doing some localization. (And which will do much more in part 2).<br />
Add the following line to LoadContent:</p>
<pre class="brush: csharp; title: ;">font = Content.Load(&quot;Arial&quot;);</pre>
<p>And change the update method to look like this:</p>
<pre class="brush: csharp; title: ;">
           KeyboardState newState = Keyboard.GetState();

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
                newState.IsKeyDown(Keys.Escape))
                this.Exit();

            if(newState.IsKeyDown(Keys.Space) &amp;amp;&amp;amp; !oldState.IsKeyDown(Keys.Space))
            {
                //We can cast Content to type BabylonCOntent for extra
                //functionality
                BabylonContent BContent = (BabylonContent)Content;
                if (BContent.Language == &amp;quot;English&amp;quot;)
                {
                    BContent.Language = &amp;quot;Dutch&amp;quot;;
                }
                else
                {
                    BContent.Language = &amp;quot;English&amp;quot;;
                }
            }
            oldState = newState;

            base.Update(gameTime);
</pre>
<p>And finally the draw method to look like this:</p>
<pre class="brush: csharp; title: ;">
GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin();

            spriteBatch.DrawString(font, Content.Load&lt;string&gt;(&amp;quot;MainMenu.start&amp;quot;), Vector2.Zero, Color.White);
            spriteBatch.DrawString(font, Content.Load&lt;string&gt;(&amp;quot;MainMenu.motd&amp;quot;), new Vector2(0, 150), Color.White);
            spriteBatch.DrawString(font, Content.Load&lt;string&gt;(&amp;quot;MainMenu.quit&amp;quot;), new Vector2(0, 250), Color.White);
            spriteBatch.DrawString(font, ((BabylonContent)Content).Language, new Vector2(0, 350), Color.Gray);

            spriteBatch.End();

            base.Draw(gameTime);
</pre>
<p>Now as you can see we can just use Content.Load to load our localized strings. Let’s fire up our demo, press space to change between English and Dutch.</p>
<p><a href="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image00212.gif"><img style="display: inline; border: 0px;" title="clip_image002[12]" src="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image00212_thumb.gif" border="0" alt="clip_image002[12]" width="193" height="244" /></a><a href="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image0048.gif"><img style="display: inline; border: 0px;" title="clip_image004[8]" src="http://www.sgtconker.com/wp-content/uploads/2010/01/clip_image0048_thumb.gif" border="0" alt="clip_image004[8]" width="243" height="244" /></a></p>
<h4>Conclusion</h4>
<p>With a relatively little amount of code we made feature full string localization that can be plugged into games easily. If you have a lot of hardcoded strings in your game it might take a while to put them all into xml files and change them to Content.Load&lt;&gt; instructions. In the next part we are going to make our content manager localize textures and sound files. Because there we already use Content.Load&lt;&gt; no code has to be changed after plugging in the new content manager. All we need to do is make some xml files.</p>
<p>This approach to localization is flexible and enforces a couple of good practices (like not using hardcoded strings). I think it’s easy to built in to an almost completed game. And games that are available in many languages might be more enjoyable for people who are not native speakers in the language your game uses. Using xml files in a package like structure makes it easy for multiple translators to work on different localizations of the strings at the same time, without having to look at source code or using complex tools.</p>
<p>Only loading the languages that are requested make this code pretty efficient, however the code might need a few iterations of ‘clean up’ which is always the case with “first release” code.</p>
<p><a href="http://www.sgtconker.com/Downloads/articles/XNABabylon.zip">Download Sample Project</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/01/article-using-xna-content-pipeline-extensions-for-localization/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Enhanced Crowd Rendering in Dead Shift</title>
		<link>http://www.sgtconker.com/2010/01/enhanced-crowd-rendering-in-dead-shift/</link>
		<comments>http://www.sgtconker.com/2010/01/enhanced-crowd-rendering-in-dead-shift/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 18:17:04 +0000</pubDate>
		<dc:creator>Captain ZSquare</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[3D]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[Dead Shift]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Punk Labs]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=965</guid>
		<description><![CDATA[The guys behind Dead Shift just posted a new video, accompanied by a discussion about how they enhanced a technique for crowd rendering taken from GPU Gems 3.
You can watch the demonstration video below, and then go and read all the details.

]]></description>
			<content:encoded><![CDATA[<p>The guys behind<a href="http://deadshift.com/"> Dead Shift</a> just posted a new video, accompanied by a discussion about how they enhanced a technique for crowd rendering taken from<a href="http://http.developer.nvidia.com/GPUGems3/gpugems3_ch02.html"> GPU Gems 3</a>.<br />
You can watch the demonstration video below, and then <a href="http://deadshift.com/blog/enhanced-crowd-rendering">go and read all the details</a>.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="344" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://www.youtube.com/v/i88m8NqiAPw&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/i88m8NqiAPw&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/01/enhanced-crowd-rendering-in-dead-shift/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

