<?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; Articles</title>
	<atom:link href="http://www.sgtconker.com/category/articles/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>High End Performance Optimizations on the Xbox 360 and Windows Phone 7</title>
		<link>http://www.sgtconker.com/2011/05/high-end-performance-optimizations-on-the-xbox-360-and-windows-phone-7/</link>
		<comments>http://www.sgtconker.com/2011/05/high-end-performance-optimizations-on-the-xbox-360-and-windows-phone-7/#comments</comments>
		<pubDate>Sun, 15 May 2011 06:21:19 +0000</pubDate>
		<dc:creator>Captain ZSquare</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[UberGeekGames]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1996</guid>
		<description><![CDATA[Ian Nicolades
Technical Director, UberGeekGames
For the Xbox or Windows Phone 7 programmer, performance is something that should always be kept in mind. For any moderately complex game, it can be very easy for framerate issues to crop up, and seeing as those pesky gamers insist on having a smooth playing experience, it can quickly become problematic.
Having [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">Ian Nicolades</h4>
<h4 style="text-align: center;">Technical Director, UberGeekGames</h4>
<p>For the Xbox or Windows Phone 7 programmer, performance is something that should always be kept in mind. For any moderately complex game, it can be very easy for framerate issues to crop up, and seeing as those pesky gamers insist on having a smooth playing experience, it can quickly become problematic.</p>
<p>Having had quite a bit of experience in this area with our last few games, this article will be a “missing manual” of sorts; the kind of cheat sheet that would have saved me more than one headache! <img src='http://www.sgtconker.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-1996"></span></p>
<h2>The target audience</h2>
<p>I’m going to make a couple of reasonable assumptions to guide us. First, you either have a game that currently has performance issues, or you’re planning a game that will most likely run into performance issues later on in development. Second, you’ve already read through Shawn’s blog posts on performance. If you haven’t, go read them now: <a href="http://msdn.com/blogs/shawnhar">http://msdn.com/blogs/shawnhar</a> I’ll wait.</p>
<p>Back? Excellent. You should already be familiar with the basic principles of profiling, how to use a profiler, rig up an FPS counter, and how to determine if you’re CPU or GPU bound. Without further ado, we will now dive into the deep end of the performance pool, so to speak. Each of the following sections will cover a technique that can help improve your game’s performance.</p>
<h2>Quadtrees, Grid Registration, and spatial partitioning</h2>
<p>Quadtrees are an oft-recommended improvement, and with good reason – they can vastly improve the performance of many different systems, the most popular being collision detection and view space culling.</p>
<p>For example, let’s say you’re building a shooter and will have a large number of bullets colliding with an even larger number of enemies. A naive approach would be to run your collision detection algorithm on every bullet against every enemy. This will take exponentially longer as the number of enemies and bullets increases.</p>
<p>By implementing a quadtree, you break the game world up into smaller chunks. Enemies, bullets, and anything else that needs to be collided with will be added to whichever chunk contains them. This way, you only need to check collisions against the bullets and enemies in the same chunk.</p>
<p>Quadtrees can be built in both 2D and 3D worlds. In 3D, they can also be used for efficient view space culling. They are typically known as “octrees” in 3D space.</p>
<h2>Garbage collection</h2>
<p>The CLR on the Xbox and WP7 have much slower garbage collectors than on the PC (soon this won’t be the case for WP7: <a href="http://blogs.msdn.com/b/abhinaba/archive/2011/04/13/generational-gc-in-windows-phone-mango.aspx">http://blogs.msdn.com/b/abhinaba/archive/2011/04/13/generational-gc-in-windows-phone-mango.aspx</a> – huzzah!). If your game has frequent stuttering or pauses, then you most likely have a garbage collection issue. This has been covered in Shawn’s blog, but here are a few additional tips I’ve picked up:</p>
<p>-          Beware of boxing. This can come from odd places, such as adding maintaining a list of interfaces; the following code will generate garbage:</p>
<pre class="brush: plain; title: ;">

interface ISomethingOrOther

{
    void Something();
}

struct Something : ISomethingOrOther
{
    public void Something()
   {
   }
}

List&lt;ISomethingOrOther&gt; ListOfInterfaces = new List&lt;ISomethingOrOther&gt;();

ListOfInterfaces.Add(new Something()); // boxing!
</pre>
<p>-          Boxing can also occur when you use an enum as a key in a Dictionary&lt;Enum, something&gt;. I usually use a Dictionary&lt;int, something&gt; and cast to int when indexing into it like so:</p>
<pre class="brush: plain; title: ;">
enum YourEnum

{

    A, B, C

}

//adding elements will cause boxing.

Dictionary&lt;YourEnum, string&gt; dictionaryWithBoxing = new Dictionary&lt;YourEnum, string&gt;()

{

    { YourEnum.A, &quot;a&quot; },

    { YourEnum.B, &quot;b&quot; },

    { YourEnum.C, &quot;c&quot; },

}

//no boxing!

Dictionary&lt;int, string&gt; yourDictionaryWithoutBoxing = new Dictionary&lt;int, string&gt;()

{

    { (int)YourEnum.A, &quot;a&quot; },

    { (int)YourEnum.B, &quot;b&quot; },

    { (int)YourEnum.C, &quot;c&quot; },

}
</pre>
<p>Nick has more info in this blog post: <a href="http://blog.nickgravelyn.com/2009/04/net-misconceptions-part-1/">http://blog.nickgravelyn.com/2009/04/net-misconceptions-part-1/</a></p>
<p>-          Make liberal use of pooling to avoid creating new objects at runtime. A simple template that I use:</p>
<pre class="brush: plain; title: ;">

class SomeObject
{
    //stuff
    public void Spawn(Vector2 position)
    {
    }
}

class SomeObjectPool

{
    public static bool[] isAlive;
    public static SomeObject[] pool;
    public static SomeObjectPool()
    {
        pool = new SomeObject[100];
        isAlive = new bool[100];
        for(int i=0;i&lt;pool.Length;i++)
        {
            isAlive[i] = false;
            pool[i] = new SomeObject();
        }
    }

public static void Spawn(Vector2 position)
{
    for(int i=0;i&lt;pool.Length;i++)
    {
        If(!isAlive[i])
        {
            isAlive[i] = true;
            pool[i].Spawn(position);
            break;
        }
    }
}
}
</pre>
<p>Nick also has a template for this: <a href="http://forums.create.msdn.com/forums/t/3375.aspx">http://forums.create.msdn.com/forums/t/3375.aspx</a></p>
<p>-          Pooling classes is almost always a better solution than switching to structs, unless you know exactly why you need them. Classes behave very differently from structs, sometimes in unintuitive ways if you are not familiar with the difference between value and reference types. This page contains a good primer on the differences: <a href="http://www.albahari.com/valuevsreftypes.aspx">http://www.albahari.com/valuevsreftypes.aspx</a></p>
<h2>Draw that 2D content most efficiently with Spritesheets</h2>
<p>If you draw sprites individually, loading them one at a time and drawing them, you will prevent the GPU from batching its draw calls in the most efficient manner. By using spritesheets, the GPU will not need to switch textures in between draw calls and can batch your drawing more efficiently. This post by Shawn succinctly explains the general idea: <a href="http://forums.create.msdn.com/forums/p/24254/131437.aspx#131437">http://forums.create.msdn.com/forums/p/24254/131437.aspx#131437</a></p>
<p>The spritesheet sample is here: <a href="http://create.msdn.com/en-US/education/catalog/sample/sprite_sheet">http://create.msdn.com/en-US/education/catalog/sample/sprite_sheet</a></p>
<p>And I’ve personally been using Nick’s SpriteSheetPacker tool to automate the packaging process, with great success: <a href="http://spritesheetpacker.codeplex.com/">http://spritesheetpacker.codeplex.com/</a></p>
<h2>Batch your SpriteBatches</h2>
<p>Efficient rendering is all about batching. Remember the elf in a box model: <a href="http://blogs.msdn.com/b/shawnhar/archive/2008/03/31/an-elf-in-a-box.aspx">http://blogs.msdn.com/b/shawnhar/archive/2008/03/31/an-elf-in-a-box.aspx</a></p>
<p>If you want to maximize GPU performance, use as few SpriteBatch batches as possible. There are, of course, many cases where you just have to end and begin a new SpriteBatch in order to switch renderstates or blend states, but for all other cases – use a single spritebatch!</p>
<h2>Multithreading</h2>
<p>On the Xbox 360, you have three separate processor cores and six hardware threads, four of which are available for you to use (one on core one, one on core two, and the two on core three; see this MSDN article <a href="http://msdn.microsoft.com/en-us/library/system.threading.thread.setprocessoraffinity.aspx">http://msdn.microsoft.com/en-us/library/system.threading.thread.setprocessoraffinity.aspx</a>).</p>
<p>If you are CPU bound, you might gain some performance by threading. Common tasks that are likely candidates for threading:</p>
<p>-          Particles; if your particles are updated on the CPU and take a significant amount of processing time, they will likely be one of the easiest things to multithread.</p>
<p>-          Collision detection; while this can be tricky to synchronize depending on what you’re it can work well.</p>
<p>-          The sky is the limit when it comes to what you can offload. With enough work you could theoretically offload most any system to another thread. The key is making sure that the performance gains will be high enough to warrant the overhead of managing the thread, and how easy it will be to synchronize data between threads.</p>
<p>On WP7, you are limited to a single core, 1GHz processor. Multithreading is unlikely to see any wins here, as it will just add overhead.</p>
<h2>Manually inlining high frequency code</h2>
<p>You may get to the point where you still have performance trouble but there are no more big wins left, or all the low hanging fruit has been picked, so to speak. At this point, manually inlining methods that are called at a high frequency could be the next best step. Manually inlining is nothing more than avoiding excess method calls when possible. Take the following piece of code:</p>
<pre class="brush: plain; title: ;">

foreach(Particle particle in ParticleList)
{
    particle.Update();
}

class Particle
{
    public void Update()
    {
        Position += Velocity
    }
}
</pre>
<p>There is a small amount of overhead when calling a method. This alternate version will be faster:</p>
<pre class="brush: plain; title: ;">

void Update()
{
    foreach(Particle particle in ParticleList)
    {
        particle.Position += particle.Velocity; //slightly faster
    }
}
</pre>
<p>The gains here are relatively small, but can make a difference in with lots of values such as particle engines.</p>
<h2>Cache values wherever possible</h2>
<p>Optimization, at its core, is just figuring out how to get the same or similar results while doing less work. Caching values is a perfect example of this. When drawing a texture, for example, how many times do you do this?</p>
<pre class="brush: plain; title: ;">

void Draw()
{
    Rectangle drawingRect = new Rectangle(foo, bar, foobar, barfoo);
    spriteBatch.Draw(Texture, drawingRectangle, Color);
}
</pre>
<p>What’s the point of recreating the rectangle each frame if the value doesn’t change? Define that outside of the loop like this:</p>
<pre class="brush: plain; title: ;">
Rectangle drawingRect = new Rectangle(foo, bar, foobar, barfoo);
void Draw()
{
    spriteBatch.Draw(Texture, drawingRectangle, Color);
}
</pre>
<h2>Properties</h2>
<p>Properties are roughly equivalent to a JIT method call. And we’ve already established that method calls take a nontrivial amount of time to execute. Therefore, properties are best to be avoided unless necessary.</p>
<p>“But, kind sir, all the C# style guides tell me to use properties! Why would they recommend such a thing if it’s so bad?”</p>
<p>Simply put, most guides I’ve seen which recommend this assume that you are either going for maximum readability and maintainability, and/or performance isn’t of much concern (eg, a winforms tool). And on the PC, you’re almost certainly not going to run into issues stemming from properties, as the latest processor can chew through them with ease. On hardware such as the WP7 or the Xbox 360, every cycle can count.</p>
<p>In other words, if you want to look at pretty code all day, you should stay far away from game development. <img src='http://www.sgtconker.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>Array indexing</h2>
<p>Another subtle improvement in tight loops is how you index into an array’s elements. An array index costs about the same as a JIT method call, plus some overhead for bounds checking. Take this code for example:</p>
<pre class="brush: plain; title: ;">

SomeObject[] objectArray;

Void DoSomeStuff()
{
    for(int i=0;i&lt;objectArray.Length;i++)
    {
        objectArray[i].Position += something;
        objectArray[i].Velocity *= whatever;
        objectArray[i].Counter++;
    }
}
</pre>
<p>You can cache the variable to avoid this overhead:</p>
<pre class="brush: plain; title: ;">

SomeObject[] objectArray;

Void DoSomeStuff()
{
    for(int i=0;i&lt;objectArray.Length;i++)
    {
        SomeObject obj = objectArray[i];
        obj.Position += something;
        obj.Velocity *= whatever;
        obj.Counter++;
    }
}
</pre>
<h2>Dictionaries vs Arrays</h2>
<p>Dictionaries are great. They are an invaluable coding tool that makes efficiently organizing data easy. However, it is quite possible for them to become a performance bottleneck, as they are about twice as slow as an array index, and can be even slower if you’re unnecessarily indexing into them more than once. Here’s some example code to explain this:</p>
<pre class="brush: plain; title: ;">

Dictionary&lt;int, Texture2D&gt; textureDictionary;
…

//this is the slowest way to use a Dictionary, as we are effectively doing two lookups for the same object. Slowness!

if(textureDictionary.ContainsKey(textureKey))
{
    Texture2D texture = textureDictionary[textureKey];
    //do something with texture
}

//this is faster as we are only doing one lookup.
Texture2D texture = null;
if(textureDictionary.TryGetValue(textureKey, out texture)
{
    //do something with texture here
}
</pre>
<h2>Vector operations</h2>
<p>When possible, use the Vector2.Whatever() methods that pass their arguments by reference and use out to supply their output. This will be faster than using the normal C# addition/subtract/multiplication/division operators. Take this example code:</p>
<pre class="brush: plain; title: ;">

//Easy to read, but slow!
someVector += anotherVector * someFloat;

//More verbose, yet faster
Vector2 tmp = new Vector2();
Vector2.Multiply(ref anotherVector, someFloat, out tmp);
Vector2.Add(ref someVector, ref tmp, out someVector);
</pre>
<p>Soon, this will be even faster on WP7: <a href="http://blogs.msdn.com/b/abhinaba/archive/2011/04/10/simd-support-in-netcf.aspx">http://blogs.msdn.com/b/abhinaba/archive/2011/04/10/simd-support-in-netcf.aspx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2011/05/high-end-performance-optimizations-on-the-xbox-360-and-windows-phone-7/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Articles: MVC in games</title>
		<link>http://www.sgtconker.com/2010/12/articles-mvc-in-games/</link>
		<comments>http://www.sgtconker.com/2010/12/articles-mvc-in-games/#comments</comments>
		<pubDate>Fri, 03 Dec 2010 10:51:57 +0000</pubDate>
		<dc:creator>Captain boki</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[VoteForGeorge]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[WP7Dev]]></category>
		<category><![CDATA[Xbox 360]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1914</guid>
		<description><![CDATA[by Roy Triesscheijn
MVC Primer
MVC stands for "Model View Controller" and has been an architectural pattern in software engineering for quite some time now. MVC allows decoupling between what 'the program is supposed to do' and how this is made visible and controlled.
In MVC the three main responsibilities of the application are handled by three separate [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://www.roy-t.nl">Roy Triesscheijn</a></h4>
<h2>MVC Primer</h2>
<p>MVC stands for "Model View Controller" and has been an architectural pattern in software engineering for quite some time now. MVC allows decoupling between what 'the program is supposed to do' and how this is made visible and controlled.</p>
<p>In MVC the three main responsibilities of the application are handled by three separate parts:</p>
<ul>
<li>The <em>model</em> houses the actual business logic. The model is totally decoupled from the controller and view.</li>
<li>The <em>view</em> observes the information from the model, and if needed request an update of the information. Data from the model is lightly massaged, formatted and then presented.</li>
<li>The <em>controller</em> controls the application by mapping different kinds of input to public methods available on the model. The model itself always has the final responsibility of doing something with the request made by the controller. In many form-based applications the view and controller are hard to distinguish from each other.</li>
</ul>
<p>Using MVC will allow you to reuse your complex model in different scenarios. Want to prepare your program for a different kind of input? Just write a new controller. Want to visualize your data in another way, just write a new viewer. In a good application controllers and viewers can even be changed while the application is running.</p>
<p><span id="more-1914"></span></p>
<h2>Relevance in games</h2>
<p>All the normal pros of MVC apply to game development. When creating games using the XNA Framework the ability to easily change the view and controller of your game becomes incredibly useful. I will demonstrate this by giving an example for the Model, View and Controller of an imaginary game that is being developed for the Xbox360, PC and WP7.</p>
<h2>Model</h2>
<p>When you develop a game the game mechanics will be stored in the model of the game. This same model can be used on the Xbox360, WP7 and the PC. When you write a game you will always have to write some sort of model. The only thing to take extra care of is to keep it decoupled from the view and controller. Never should the model handle some sort of input or put some restraint on how something is displayed on screen. This might take a bit getting used to, but the benefits will come clear when visiting the view and controller.</p>
<h2>View</h2>
<p>Because we want our game to work on platforms with different capabilities, we develop different views for each of them. The WP7 view can't have shaders for example, and should have a layout optimized for a small screen with a 480x800 resolution. So we choose to limit the amount of statistics the user sees and just show the gameplay and a score.</p>
<p>However on the 360 and PC we have plenty of screen estate, so we choose a different layout, show off the statistics, use smaller fonts, and we use shaders to make everything look extra crisp. The model is already in place and runs on all platforms so we don't have to do any work on it. The only 'per-platform' work we have to do (so far) is the visualization. This saves us a lot of time.</p>
<h2>Controller</h2>
<p>Well let's continue and take a look at the controller. Again there are big differences; the Xbox uses a gamepad, where WP7 uses a multi-touch screen, the PC uses a mouse and keyboard. You can see again that it is useful to have the model completely separated from this. And to have specific controllers take care of these different scenarios. We will now have to write a class for each type of input that converts raw input (a button pressed, or a mouse gesture) to an abstract input, for example "Input.Left". Then a second controller should convert this abstract input into a request for an action based on the model's state.</p>
<p>Let's take the controls of a camera as an example. On a PC I would press the 'up'-key on my keyboard this would be converted to the abstract input "Input.Up". This would be delegated to the controller that is specific to the current state, which then translates "Input.Up" to a request to the model of the camera to look up. (Note that the model will always determine itself if it looks up according to its business rules, the up direction could be blocked or another business rule could prevent the action).</p>
<p>On an Xbox360 the first step is different. I would nudge my thumb stick up. The appropriate input controller would again convert this to appropriate abstract input "input.Up". The rest is the same as with the keyboard example.</p>
<h2>Solution in code</h2>
<p>Now we've talked about benefits of MVC in games and common problems which happen when not using MVC, it would be an appropriate time to show a solution to this problem.</p>
<p>For this example I've written a very small Pong game using the principles described above. The most important classes, as well a tiny bit of extra commentary are listed below. You can <a href="http://www.sgtconker.com/wp-content/uploads/2010/12/MVCInGamesCode.zip">download the full sample here</a>.</p>
<p>Let's start with the model. Let's create an abstract model and then a model for the paddles/players.</p>
<pre class="brush: csharp; title: ;">
public abstract class Model
{
	public Model(World world)
	{
		this.world = world;
	}

	public abstract void Update(float elapsedSeconds);

	#region StateVariables
	public virtual Vector2 Position{ get; set; }
	protected World world;
	#endregion
}

public class PlayerModel : Model
{
	/// &lt;summary&gt;
	/// Creates a new player in the world, specify everything in world coordinates
	/// not screen coordinates.
	/// &lt;/summary&gt;
	/// &lt;param name=&quot;startPosition&quot;&gt;top left position&lt;/param&gt;
	public PlayerModel(World world, int width, int height, Vector2 startPosition)
		: base(world)
	{
		this.width = width;
		this.height = height;
		this.Position = startPosition;
	}

	public override void Update(float elapsedSeconds){}

	#region MethodsForController

	public void Influence(PlayerAction action, float elapsedSeconds)
	{
		switch (action)
		{
			case PlayerAction.MoveUp:
				Influence_MoveUp(elapsedSeconds);
				break;
			case PlayerAction.MoveDown:
				Influence_MoveDown(elapsedSeconds);
				break;
		}
	}

	private void Influence_MoveUp(float elapsedSeconds)
	{
		Position = new Vector2(Position.X, Position.Y - (speed * elapsedSeconds));
		if (Position.Y &lt; 0 )
		{
			Position = new Vector2(Position.X, 0);
		}
	}

	private void Influence_MoveDown(float elapsedSeconds)
	{
		Position = new Vector2(Position.X, Position.Y + (speed * elapsedSeconds));
		if (height + Position.Y &gt; world.boundaries.Height)
		{
			Position = new Vector2(Position.X, world.boundaries.Height - height);
		}
	}
	#endregion        

	#region StateVariables
	public int width;
	public int height;
	public float speed = 90;
	#endregion
}

public enum PlayerAction { Nothing, MoveUp, MoveDown };
</pre>
<p>By creating a method "Influence" I've made it very explicit here that you always request something from the model, it's never sure if the player will actually move up or down. This depends on the business rules.</p>
<p>Now there is of course also a ball, but I lets you find it in the accompanied source code. Let's take a look at the viewer for our PlayerModel.</p>
<pre class="brush: csharp; title: ;">
public class PlayerViewer : Viewer
{
	public PlayerViewer(PlayerModel player, Texture2D texture)
	{
		this.player = player;
		this.texture = texture;
	}

	public override void Draw(SpriteBatch spriteBatch)
	{
		Rectangle playerRect = new Rectangle((int)player.Position.X, (int)player.Position.Y, player.width, player.height);
		spriteBatch.Draw(texture, playerRect, Color.White);
	}

	private Texture2D texture;
	private PlayerModel player;
}
</pre>
<p>There is nothing difficult here as you can see. We just draw a simple texture at the position of the player. Note that in real-world applications the model and view could be using two different coordinate sets, so you will often have to convert between 'model-space' and 'screen-space' in a viewer.</p>
<p>Now for our controllers there is a large class (called InputManager) that converts raw input (as described in the controller section) to an abstract input represented by the following enumeration:</p>
<pre class="brush: csharp; title: ;">
public enum Inputs
{
	A, B, X, Y, Left, Right, Up, Down, Start, Back
}
</pre>
<p>This class and the abstract inputs are then used in the controller of our player model.</p>
<pre class="brush: csharp; title: ;">
public class PlayerController : ModelController
{
	public PlayerController(PlayerModel player, InputType type, PlayerIndex index)
	{
		this.player = player;
		manager = new InputManager(type, index);
		keyMap = new Dictionary&lt;PlayerAction, Inputs&gt;();

		//normally fill the keyMap with user settings.
		keyMap.Add(PlayerAction.MoveUp, Inputs.Up);
		keyMap.Add(PlayerAction.MoveDown, Inputs.Down);
	}

	public override void Control(float elapsedSeconds)
	{
		manager.Update();
		if(manager.IsInputDown(keyMap[PlayerAction.MoveUp]))
		{
			player.Influence(PlayerAction.MoveUp, elapsedSeconds);
		}
		else if (manager.IsInputDown(keyMap[PlayerAction.MoveDown]))
		{
			player.Influence(PlayerAction.MoveDown, elapsedSeconds);
		}
	}

	private InputManager manager;
	private PlayerModel player;
	private Dictionary&lt;PlayerAction, Inputs&gt; keyMap;
}
</pre>
<p>As you can see we map the different actions that are possible to different abstract inputs, which themselves are matched to different raw inputs. These layers of abstraction are very useful, maybe also in ways that you haven't imagined yet. For example how about a controller that doesn't read keyboard, mouse, gamepad or gesture input at all?</p>
<p>Take a look at the AIPlayerController, which will probably beat you!</p>
<pre class="brush: csharp; title: ;">
public class AIPlayerController : ModelController
{
	public AIPlayerController(PlayerModel player, World world)
	{
		this.player = player;
		this.world = world;
	}

	public override void Control(float elapsedSeconds)
	{
		float playerCenterY = player.Position.Y + (player.height / 2);
		float ballCenterY = world.ball.Position.Y + (world.ball.height / 2);
		float diff = Math.Abs(playerCenterY - ballCenterY);
		if (diff &gt; 20)
		{
			if (playerCenterY &gt; ballCenterY)
			{
				player.Influence(PlayerAction.MoveUp, elapsedSeconds);
			}
			else if (playerCenterY &lt; ballCenterY)
			{
				player.Influence(PlayerAction.MoveDown, elapsedSeconds);
			}
		}
	}

	private PlayerModel player;
	private World world;
}
</pre>
<p>So, download the code, play a little write a couple of different views and controllers and maybe expand the model so that you really understand the power of MVC in games!</p>
<h2>Conclusion</h2>
<p>I hope by now the usefulness of MVC in games has become quite clear. I think the benefit of MVC, especially when targeting such diverse devices as PC/Xbox360 and WP7 is huge, this could really save you a lot of time.</p>
<p>The given source code, tiny as it is, should give you some idea on how to implement your own way of doing MVC in your games. Please note that when using MVC there are plenty of ways for you to exploit the usefulness of inheritance, encapsulation, interfaces, abstract class and the likes. I have not done this much because I wanted to keep the sample code as small as possible but for slightly larger project you will definitely benefit from exploiting this.</p>
<h2>Further reading</h2>
<p>I hope you've enjoyed this tutorial. But there is more:</p>
<p>For an in depth article of MVC see:<br />
<a href="http://en.wikipedia.org/wiki/Model–View–Controller">http://en.wikipedia.org/wiki/Model–View–Controller</a></p>
<p>For notes on the input manager that converts gamepad and keyboard input to abstract input, see: <a href="http://roy-t.nl/index.php/2010/11/05/codesnippet-handy-input-manager/">http://roy-t.nl/index.php/2010/11/05/codesnippet-handy-input-manager/</a></p>
<p>For more interesting tutorials see:<br />
<a href="http://roy-t.nl">http://roy-t.nl</a> (my personal blog)<br />
<a href="http://www.sgtconker.com">http://www.sgtconker.com</a> (great website with all sorts of game development related tutorials, including some of my own).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/12/articles-mvc-in-games/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Results for the Absolutely Fine XNA Tutorial Contest</title>
		<link>http://www.sgtconker.com/2010/10/results-for-the-absolutely-fine-xna-tutorial-contest/</link>
		<comments>http://www.sgtconker.com/2010/10/results-for-the-absolutely-fine-xna-tutorial-contest/#comments</comments>
		<pubDate>Thu, 07 Oct 2010 14:48:29 +0000</pubDate>
		<dc:creator>Captain ZSquare</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Contest]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Congrats]]></category>
		<category><![CDATA[Winners]]></category>
		<category><![CDATA[XNA]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1831</guid>
		<description><![CDATA[We have judged, we have analyzed the votes received from you; and now we have our winners!
The first place goes to
Rolling World Tutorial
by Christian Schlager
His prize consists of:

One SunBurn Community License
One License for Toon Boom Studio
One 12-Months XNA Creator's Club Premium Subscription

The second place goes to
XNA Farseer Platform Physics Tutorial
by Roy Triesscheijn
For his hardwork, he [...]]]></description>
			<content:encoded><![CDATA[<p>We have judged, we have analyzed the votes received from you; and now we have our winners!</p>
<p>The first place goes to</p>
<h3><a href="../2010/09/article-rolling-world-tutorial/">Rolling World Tutorial</a></h3>
<h4>by Christian Schlager</h4>
<p>His prize consists of:</p>
<ul>
<li>One <a href="http://www.synapsegaming.com/products/sunburn/engine/editions.aspx#Community">SunBurn Community License</a></li>
<li>One License for <a href="http://www.toonboom.com/products/toonBoomStudio/">Toon Boom Studio</a></li>
<li>One 12-Months XNA Creator's Club <a href="http://creators.xna.com/en-US/membership">Premium Subscription</a></li>
</ul>
<p>The second place goes to</p>
<h3><a href="../2010/09/article-xna-farseer-platform-physics-tutorial/">XNA Farseer Platform Physics Tutorial</a></h3>
<h4>by Roy Triesscheijn</h4>
<p>For his hardwork, he receives:</p>
<ul>
<li>One License for <a href="http://www.toonboom.com/products/toonBoomStudio/">Toon Boom Studio</a></li>
<li>One 4-Months XNA Creator's Club <a href="http://creators.xna.com/en-US/membership">Premium Subscription</a></li>
</ul>
<p>And finally, the third place goes to :</p>
<h3><a href="../2010/08/programming-your-first-xna-4-game-pong/">Programming your first XNA 4.0 game for PC, Xbox 360 &amp; Windows Phone 7: Pong</a></h3>
<h4>by Thomas "Mister Helmut" Altenburger</h4>
<p>He also receives:</p>
<ul>
<li>One License for <a href="http://www.toonboom.com/products/toonBoomStudio/">Toon Boom Studio</a></li>
<li>One 4-Months XNA Creator's Club <a href="http://creators.xna.com/en-US/membership">Premium Subscription</a></li>
</ul>
<p>Congratulation to all of our winners. They deserve it!</p>
<p>We'd like to thank our sponsors for their support:</p>
<ul>
<li><a href="http://www.toonboom.com/main/">Toon Boom Animation Inc.</a> for the Toon Boom Licenses</li>
<li><a href="http://www.synapsegaming.com/">Synapse Gaming</a> for the SunBurn Community License</li>
<li>Cpt. ZSquare, for the Creator's Club subscription codes</li>
<li>Everyone in the Sgt. Conker barracks for the hard work they put in <img src='http://www.sgtconker.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
<p>And another set of thanks and applause go to all of our participants, who worked hard to bring us all the articles.</p>
<p>Here they are again, in all their glory:</p>
<ul>
<li><a href="../2010/09/article-arbitrarily-shaped-secondary-2d-viewports/">Arbitrary Shaped Secondary 2D Viewports</a>, by Harry Trautmann</li>
<li><a href="../2010/09/article-character-movement/">Character Movement</a>, by David Kendall</li>
<li><a href="../2010/08/article-derived-effect-classes-in-xna-4/">Derived Effect Classes in XNA 4.0</a>, by Dave Carlile</li>
<li><a href="../2010/08/article-input-playback/">Input Playback</a>, by Jesse Chounard</li>
<li><a href="../2010/09/article-multiple-columns-with-game-state-management/">Multiple columns with Game State Management</a>, by Jeff Brown</li>
<li><a href="../2010/09/article-node-based-scripting/">Node-Based Scripting</a>, by Blecki</li>
<li><a href="../2010/08/programming-your-first-xna-4-game-pong/">Programming your first XNA 4.0 game for PC, Xbox 360 &amp; Windows Phone 7: Pong</a>, by Thomas "Mister Helmut" Altenburger</li>
<li><a href="../2010/09/article-rolling-world-tutorial/">Rolling World Tutorial</a>, by Christian Schlager</li>
<li><a href="../2010/09/article-scripting-on-the-xbox-360-windows-phone-and-beyond/">Scripting on the Xbox 360, Windows Phone and Beyond!</a>, by UberGeekGames</li>
<li><a href="../2010/09/article-shaders-introduction/">Shaders - Introduction</a>, by Daniel Greenheck</li>
<li><a href="../2010/09/article-shaders-ambient-lighting/">Shaders - Ambient Lighting</a>, by Daniel Greenheck</li>
<li><a href="../2010/09/article-shaders-diffuse-lighting-2/">Shaders - Diffuse Lighting</a>, by Daniel Greenheck</li>
<li><a href="../2010/09/article-shaders-specular-lighting/">Shaders - Specular Lighting</a>, by Daniel Greenheck</li>
<li><a href="../2010/09/article-shaders-texturing/">Shaders - Texturing</a>, by Daniel Greenheck</li>
<li><a href="../2010/09/article-shaders-rim-lighting/">Shaders - Rim Lighting</a>, by Daniel Greenheck</li>
<li><a href="../2010/09/article-simple-3d-camera-in-xna/">Simple 3D Camera in XNA</a>, by Pete Street</li>
<li><a href="../2010/08/article-texture-modification-using-render-targets-with-some-stencil-buffer-action/">Texture Modification using Render Targets, with some Stencil Buffer Action</a>, by Dave Carlile</li>
<li><a href="../2010/09/article-vacant-skies-action-rpg-tutorial-series/">Vacant Skies - Action RPG Tutorial Series</a>, by Aaron T Foley</li>
<li><a href="../2010/09/article-wcf-on-the-windows-phone-7%E2%80%93the-how-to-guide/">WCF on the Windows Phone 7 - The How-To Guide</a>, by Simon Jackson</li>
<li><a href="../2010/09/article-xna-farseer-platform-physics-tutorial/">XNA Farseer Platform Physics Tutorial</a>, by Roy Triesscheijn</li>
</ul>
<h2>About our sponsors</h2>
<p><strong>Toon Boom Studio</strong> is a great product for 2D animations, allowing you to use a wide range of techniques for your work, including: stop-motion animation, traditional digital animation, traditional paper animation, cut-out animation and rotoscoping. In their own words: "<a href="http://www.toonboom.com/main/">Toon Boom Animation</a> offers easy to use software applications for storyboarding and animation, that perfectly fit game developers' needs. Propel your games to the next level using pre-visualization and leading-edge animation features." I found the product very easy to use, and it will be a great addition to the arsenal of your development tools.</p>
<p><strong>SunBurn</strong> is a Lighting and Rendering engine built on top of our beloved XNA Framework. As the guys at Synapse Gaming say, "combining the latest lighting and rendering technology with a flexible and easy to use framework, SunBurn performs the heavy-lifting, letting you focus on your games." For a full list of features included in the SunBurn Engine, visit <a href="http://www.synapsegaming.com/products/sunburn/engine/features.aspx">their site</a>. The license we're giving out as a prize is provided by the kind people and <a href="http://www.synapsegaming.com/">Synapse Gaming</a>.</p>
<p><strong><br />
</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/10/results-for-the-absolutely-fine-xna-tutorial-contest/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Rim Lighting</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-rim-lighting/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-rim-lighting/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 20:21:36 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Daniel Greenheck]]></category>
		<category><![CDATA[digitseven]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1794</guid>
		<description><![CDATA[by Daniel Greenheck
What should I be familiar with before I go through this tutorial?
- The content discussed in the ambient, diffuse and specular tutorials.
- Dot products, vectors
What is Rim Lighting?
Rim lighting is a shader technique you often see in role-playing games when there's a treasure chest or door which needs to be opened. Around the [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<p>What should I be familiar with before I go through this tutorial?<br />
- The content discussed in the <a href="http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/">ambient</a>, <a href="http://www.sgtconker.com/2010/09/article-shaders-diffuse-lighting-2/">diffuse</a> and <a href="http://www.sgtconker.com/2010/09/article-shaders-specular-lighting/">specular</a> tutorials.<br />
- Dot products, vectors</p>
<h2>What is Rim Lighting?</h2>
<p>Rim lighting is a shader technique you often see in role-playing games when there's a treasure chest or door which needs to be opened. Around the border of the object there is a soft glow which differentiates it from the rest of the objects in the scene. The concept behind the rim lighting shader is extremely simple: the more a surface faces away from the camera, the more rim lighting it should get. Looking at the sphere below illustrates the point:<br />
<img class="alignnone" title="Sphere" src="http://digitseven.com/images/sphere.jpg" alt="" width="373" height="245" /></p>
<p><span id="more-1794"></span></p>
<p>Here, the rim light is set to be blue while the diffuse light is just a white light at 75% intensity. On the edges of the sphere, the normals of the triangles (remember a normal is the vector pointing perpendicular out of the surface) are more perpendicular to the line of sight, which is going straight into the page. The more perpendicular the normal is to the line of sight, the more rim light the surface receives.<br />
Now what mathematical tool allows us to compare how perpendicular/parallel two vectors are? That's right! The dot product. If you take the dot product of two normalized vectors which are parallel and pointing in the same direction, you get 1. If the vectors are perpendicular, you get zero. Using this knowledge we will know manipulate some shader code to create a rim lighting shader!</p>
<h2>The Rim Lighting Shader</h2>
<p>As usual, I once again present you with the entire specular shader. If you skipped my intro to this article, which I can't blame you for, I'll remind you that I left out the commenting on anything non-specular to save space and make the presentation a little nicer. If you don't know what the other parts of the program do, go back and read the Ambient and Diffuse shaders.</p>
<pre class="brush: plain; title: ;">
float4x4 World;
float4x4 View;
float4x4 Projection;

float4 AmbientColor;
float4 DiffuseColor;
float4 SpecularColor;
float4 RimColor;

float AmbientIntensity;
float DiffuseIntensity;
float SpecularIntensity;
float RimIntensity;         // Intensity of the rim light

float3 DiffuseLightDirection;
float3 CameraPosition;
float3 CameraDirection;
float Shinniness;

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD0;
    float3 CameraView : TEXCOORD1;
};

VertexShaderOutput VertexShader( VertexShaderInput input )
{
    VertexShaderOutput output;

    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

    output.Normal = mul( input.Normal, World );

    // Get the vector from the camera to the vertex for the specular component by
    // subtracting the world position from the camera
    output.CameraView = normalize( CameraPosition - worldPosition );

    return output;
}

float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Normalize our variables
    float3 lightdir = normalize( DiffuseLightDirection );
    float3 norm = normalize( input.Normal );

    // Calculate the rim lighting component by subtract the dot product of the normal and camera direction
    // from 1, then taking that to the 2nd power. This will give pixels at more perpendicular angles to the camera
    // a glow effect. Multiply that by rim color and intensity to adjust the color and brightness.
    // - If you take the dot product to a higher power, the glow will be thinner and closer to the edges.
    // - If you take the dot product to a lower power, the glow will be more spread out away from the edges.
    float4 rim = pow( 1 - dot( norm, CameraDirection ), 1.5 ) * RimColor * RimIntensity;

    // Calculate the specular component
    float3 halfAngle = normalize( lightdir + input.CameraView );
    float4 specular = pow( saturate( dot( norm, halfAngle ) ), Shinniness ) * SpecularColor * SpecularIntensity;

    // Calculate the diffuse component
    float4 diffuse = dot( lightdir, input.Normal ) * DiffuseColor * DiffuseIntensity;
    // Calculate the ambient component
    float4 ambient = AmbientColor * AmbientIntensity;

    return rim + ambient + specular + diffuse;
}

technique RimLighting
{
    pass Pass0
    {
        VertexShader = compile vs_1_1 VertexShader();
        PixelShader = compile ps_2_0 PixelShader();
    }
}
</pre>
<p>The only difference between this and the specular lighting shader is a new variable called CameraDirection, some new variables to control the rim lighting effect and an extra line in the pixel shader. Let's start with the variable.</p>
<h2>New Rim Light Variables</h2>
<pre class="brush: plain; title: ;">
float4 RimColor;
float  RimIntensity;
float3 CameraDirection;
</pre>
<p>The first two variables are self-explanatory: they control the intensity and color of the rim light. CameraDirection is a very simple variable: all it is is a vector which points away from the camera in the direction you are looking. Below is a wonderful 2D drawing of what the camera direction vector is describing; 3D just adds another dimension but in essence is the same. The eye is at the center, the star is the object, and the red arrow is a normalized vector.<br />
<img class="alignnone" title="CameraDirection" src="http://digitseven.com/images/rimcameradirection.jpg" alt="" width="238" height="206" /><img class="alignnone" title="CameraDirection" src="http://digitseven.com/images/rimcameradirection.jpg" alt="" width="238" height="206" /></p>
<p>CameraDirection points TOWARDS the object</p>
<p>And that's really all you need to know in terms of new variables!</p>
<h2>Pixel Shader</h2>
<pre class="brush: plain; title: ;">
float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Normalize our variables
    float3 lightdir = normalize( DiffuseLightDirection );
    float3 norm = normalize( input.Normal );

    // Calculate the rim lighting component by subtract the dot product of the normal and camera direction
    // from 1, then taking that to the 2nd power. This will give pixels at more perpendicular angles to the camera
    // a glow effect. Multiply that by rim color and intensity to adjust the color and brightness.
    // - If you take the dot product to a higher power, the glow will be thinner and closer to the edges.
    // - If you take the dot product to a lower power, the glow will be more spread out away from the edges.
    float4 rim = pow( 1 - dot( norm, CameraDirection ), 1.5 ) * RimColor * RimIntensity;

    // Calculate the specular component
    float3 halfAngle = normalize( lightdir + input.CameraView );
    float4 specular = pow( saturate( dot( norm, halfAngle ) ), Shinniness ) * SpecularColor * SpecularIntensity;

    // Calculate the diffuse component
    float4 diffuse = dot( lightdir, input.Normal ) * DiffuseColor * DiffuseIntensity;
    // Calculate the ambient component
    float4 ambient = AmbientColor * AmbientIntensity;

    return rim + ambient + specular + diffuse;
}
</pre>
<p>The pixel shader is the same except for the line which is accompanied by the massive comment. Let's analyze the statement starting with what's inside the pow() function. Remember back to what I mentioned above about the dot product. When the normal of a surface is perpendicular to the line of sight, it gets the most rim light. The dot product of a perpendicular normal with the line of sight would result in 0, so that is backwards from what we want. When the dot product is 0, we really want the rim light at full intensity. So by subtracting the dot product of the normal and the CameraDirection from one, we get just this. So we get some number between 0 and 1, 1 giving us full intensity rim light and 0 giving us no rim light at all.<br />
Surrounding the dot product inverse is the pow() function. The power function allows us to adjust the falloff of our rim light. Since the amount of light is always between 0 and 1, taking it to a power greater than 1 results in a number less than the original number. For example, .5^2 = .25. This is how light eminating from a light source normally falls off, to the square of the distance. You can play around with the power (I have it set at a medium 1.5) to get the effect you want. The higher the power, the less rim lighting you will get on surfaces whose normals are more parallel to the camera direction than perpendicular. Here is an example of variation of power. The diffuse light is white and the rim light is blue.</p>
<p><img class="alignnone" title="Power" src="http://digitseven.com/images/power.jpg" alt="" width="603" height="280" /></p>
<p>As you can see, the smaller the power, the more spread out the rim light is. The larger the power, the more the light is confined to the edges. Finally, I just take that rim light component and multiply it with the RimColor and RimIntensity variables! And there you have it, glowing edges.</p>
<h2>Conclusion</h2>
<p>Rim lighting is a cool and easy technique to add a fun touch to your game or 3D model. The simple calculation shouldn't put much of a dent in your graphics performance either, although the pow() function is a little processing intensity. You could get around this by removing it entirely, but then you no longer have control over the spread of the light. It's up to you to decide based on your application and hardware limitations. Once again, any questions or comments, feel free to email me at dan@digitseven.com. And be sure to <a href="http://digitseven.com/default.aspx">sign up for the newsletter</a>, which I'll use to keep you posted on new updates to the site. Enjoy!</p>
<p><a href="http://digitseven.com/Documents/RimLight.zip">DOWNLOAD Rim Lighting PROJECT HERE</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-rim-lighting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Texturing</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-texturing/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-texturing/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 19:34:06 +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[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Daniel Greenheck]]></category>
		<category><![CDATA[digitseven]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1792</guid>
		<description><![CDATA[by Daniel Greenheck
This tutorial will cover attaching an image (I'll be using the word texture from now on) to a model to give it a much more detailed look.  Texturing is an essential of creating a realistic scene because it  allows us to give objects very fine detail. Without textures, everything  in [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<div class="wp-caption alignnone" style="width: 561px"><img title="A simple box with a stone black texture" src="http://digitseven.com/images/texturedbox.png" alt="" width="551" height="520" /><p class="wp-caption-text">A simple box with a stone black texture</p></div>
<p>This tutorial will cover attaching an image (I'll be using the word <em>texture </em>from now on) to a model to give it a much more detailed look.  Texturing is an essential of creating a realistic scene because it  allows us to give objects very fine detail. Without textures, everything  in the scene would basically be one color, look very flat and just be  generally boring. The right textures can even give an object the  illusion of depth, further increasing the realism. The stone box above  looks like it has deep cracks in it between the blocks, but that's just  an illusion. The entire box is defined using eight vertices. To  geometrically represent those cracks, it would take thousands of  vertices, something that definitely isn't feasible.</p>
<p><span id="more-1792"></span><br />
So how do we  take a texture and apply it to an object? The whole process is quite  simple. If you remember back to the diffuse shader tutorial, we started  using the VertexPositionNormalTexture structure for our vertices. At the  time I told you to ignore the texture part but now we'll be making full  use of this! Following the normal data in the constructor of VertexPositionNormalTexture, it asks for a set of <strong>texture coordinates</strong>:  a Vector2 used to tell  how our shaders how the texture is attached to the model. What are  texture coordinates you ask?</p>
<blockquote>
<h3>An Explanation of Texture Coordinates</h3>
<p>Texture coordinates are very  simple concept. Take a look at this diagram below; it's a breakdown of  the stone box pictured above.</p>
<div><img src="http://digitseven.com/images/coordinatesdiagram.jpg" alt="" /></div>
<p>As I mentioned before, texture coordinates are a Vector2. The horizontal axis of  the image is assigned to the <em>U</em> component and the vertical <em>t</em>o  the<em> V </em>component. Each component represents the proportion of  distance from the origin along that axis. In simpler terms, the value of  U and V each normally range from 0.0 - 1.0, the origin being the  upper-left corner of the image.<br />
When we specify the texture  coordinates for a vertex, we're telling it what part of the texture  attaches there. Looking at the example I provided above, we'll take the  lower-left triangle on the front face. To attach the texture so it  covers the entire face, my texture coordinates would be as follows:</p>
<blockquote><p><em>Upper-Left Front Vertex</em>: The  origin of the image should attach directly to that point, so <strong>(0 , 0)</strong>.<br />
<em>Bottom-Left Front Vertex</em>: The  lower-left corner of the image should attach here, so<strong> (0 , 1)</strong>.<br />
<em>Bottom-Right  Front Vertex</em>: Following the same principle as the first two, <strong>(1 ,  1)</strong>.</p></blockquote>
<p>Just to keep this simple,  I'm using one's and zero's. If you wanted to use just the upper-left  quadrant of the image, (using the same triangle again) I would use these  texture coordinates:</p>
<blockquote><p><em>Upper-Left  Front Vertex</em>: The origin of the image should  attach directly to that point, so <strong>(0 , 0)</strong>.<br />
<em>Bottom-Left Front Vertex</em>: We're only going halfway down the V axis  this time<strong> (0 , .5)</strong>.<br />
<em>Bottom-Right Front Vertex</em>:  The middle of the image should attach here, so <strong>(.5 , .5)</strong>.</p></blockquote>
<p>Since we're only using half the image now, it would give a  stretching effect. Once you get your shader working properly,  experiment with adjust your texture coordinates to see what effects  different values give.</p></blockquote>
<p>The shader will then go through each triangle on the scene, the pixel shader interpolating the texture coordinates between all the vertices of each triangle. That's how you can specify only three attachment points on a triangle, but get the image spread across the entire surface. Once you get the texture coordinates for the pixel, it will sample the texture at those coordinates, returning the pixel color (which you can adjust by the amount of light that hits it, etc.) That's it! Let's take a look at the shader code.</p>
<h2>The All-Purpose Shader</h2>
<p>I've  added the texture code to the shader we've been building up over the  last few tutorials. If you scan the code, you'll  probably notice how <em>little </em>code I added. In fact I only added  about 4 lines of code to implement texturing, none of them being math-oriented either (thank  the heavens). Now we have a basic shader that can  handle ambient, diffuse and specular lighting while also allowing you to  add textures to your models.</p>
<pre class="brush: csharp; title: ;">
float4x4 World;
float4x4 View;
float4x4 Projection;

float4 AmbientColor;
float AmbientIntensity;

float4 DiffuseColor;
float DiffuseIntensity;
float3 DiffuseLightDirection;

float4 SpecularColor;
float SpecularIntensity;
float Shinniness;
float3 CameraPosition;

// Texturing variables
Texture ModelTexture;        // Our texture which will be mapped onto our object

// Pass coordinates to our texture sampler to get a color for a certain pixel
sampler TextureSampler = sampler_state {
    texture = &lt;ModelTexture&gt; ;
    magfilter = LINEAR;
    minfilter = LINEAR;
    mipfilter= LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;};

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
    float2 TexCoords : TEXCOORD0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD0;
    float3 CameraView : TEXCOORD1;
    float2 TexCoords :TEXCOORD2;
};

VertexShaderOutput VertexShader( VertexShaderInput input )
{
    VertexShaderOutput output;

    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

    output.Normal = mul( input.Normal, World );
    output.CameraView = normalize( CameraPosition - worldPosition );

    // Just pass the texture coordinates to the vertex shader output.
    // When they transfer to the pixel shader, they will be interpolated
    // per pixel.
    output.TexCoords = input.TexCoords;

    return output;
}

float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Sample our texture at the specified texture coordinates to get the texture color
    float4 texColor = tex2D( TextureSampler, input.TexCoords );

    float3 lightdir = normalize( DiffuseLightDirection );
    float3 norm = normalize( input.Normal );
    float3 halfAngle = normalize( lightdir + input.CameraView );
    float specular = pow( saturate( dot( norm, halfAngle ) ), Shinniness ) * SpecularColor * SpecularIntensity;

    float4 diffuse = dot( lightdir, input.Normal ) * DiffuseIntensity * DiffuseColor;
    float4 ambient = AmbientIntensity * AmbientColor;

    return texColor * ( diffuse + ambient + specular );
}

technique Texturing
{
    pass Pass0
    {
        VertexShader = compile vs_1_1 VertexShader();
        PixelShader = compile ps_2_0 PixelShader();
    }
}
</pre>
<h2>Changes to The Vertex In/Out Structures</h2>
<p>Nothing major happened here. All we did was add a <em>float2 </em>to each structure to store our texture coordinates. I've just assigned the next TEXCOORDS semantic that was available. The input structure will contain texture coordinates for the vertices and the output structure will contain the interpolated texture coordinates for the pixel shaders, which is what we want.</p>
<h2>Two New Variables</h2>
<pre class="brush: csharp; title: ;">
// Texturing variables
Texture ModelTexture;        // Our texture which will be mapped onto our object

// Pass coordinates to our texture sampler to get a color for a certain pixel
sampler TextureSampler = sampler_state {
    texture = &lt;ModelTexture&gt; ;
    magfilter = LINEAR;
    minfilter = LINEAR;
    mipfilter= LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;};
</pre>
<p>1. <strong>ModelTexture </strong>- This is where the texture is stored.  We call SetValue() on the XNA side with a reference to Texture or Texture2D to set the texture we want our  shader to sample.</p>
<p>2. <strong>TextureSampler </strong>-  This handy little device allows us to pass in a pair of texture  coordinates and get the color of the texture at that point. It may look  complicated to declare but it really isn't. There's a whole boatload of  arguments )separated by semicolons) you can specify for a <em>sampler </em>but  I've just chosen six here. The first is a reference to the texture we  want to sample, so we put <strong>ModelTexture </strong>between &lt;&gt;. The next  three are filters applied to the texture. If you want to learn what  they do, you'll have to do a little research on your own (Google!). The  next two, <strong>AddressU </strong>and <strong>AddressV</strong>, have several states:</p>
<ul>
<li><em>WRAP </em>- If the values exceed 1, the texture is repeated  along that axis. So if AddressU was set to WRAP and the U coordinate was  5, it would repeat 5 times along the U axis.</li>
<li><em>CLAMP </em>- The  values are clamped between 0 and 1. If they precede 0, they are set to  0. If they exceed 1, they are set to 1.</li>
<li><em>MIRROR </em>- Similar to WRAP, but each consecutive tile is a mirrored from  the last along the axis perpendicular to the mirrored axis.</li>
</ul>
<h2>Vertex Shader</h2>
<p>The only line I added here was passing the vertex shader coordinates to the output structure so they could be interpolated in the pixel shader.</p>
<h2>Pixel Shader</h2>
<p>Once in the pixel shader, we can finally sample our texture for what we need. By calling tex2D() on our texture sampler and the interpolated texture coordinates from our input data, we get back a float4 which represents the color of the texture at that pixel. Perfect! Now what to do with it?<br />
In the previous shaders, everytime I added a new lighting component, I would add it to the total sum. With texture color this is different. The texture color is independent of the light; it is an intrinsic property of the object we are working with. If our box is textured with a stone wall, it's going to be colored like a stone wall if the lights are on or off. By multiplying our texture color by the sum of the lighting components, we can get our desired effect of having a darker color when it's dark and a lighter color when it's bright.</p>
<h2>The XNA Side of Things</h2>
<p>There isn't a whole lot to do on the  XNA side to use our new shader. Make sure to reference to your new  shader and change the technique name to "Texturing" or whatever you chose. Since our shader now  needs a texture, you're also going to need to declare a Texture2D variable. In <em>the  LoadContent() </em>method, load whatever texture you please into the  texture variable from the content pipeline. Then in the main <em>Draw()</em> method of your game, set the value of <strong>ModelTexture </strong>to the Texture2D variable you declared  so the shader knows what texture to draw. You should now have a  textured model on the screen!</p>
<h2>Conclusion</h2>
<p>Congratulations! If you've followed the tutorials to this point, you've  created a shader that basically replicates the functionality of the BasicEffect class in XNA.  "What?! They already wrote this stuff?" Easy there. You may have  replicated some existing functionality, but you now have a superb  understanding of how shaders work ( Hopefully. Or you are just amazingly  confused at what I've been talking about this entire time which is a  very real possibility) and a fully tweakable shader.<br />
By adding  texturing to our all-purpose shader, you can now give an amazing amount  of detail to characters, buildings, cars, trees, weapons or whatever  else might be inhabiting your game world. Texturing gives objects the  illusion of depth and detail without defining extra geometry. If you  continue your shader education, you will find some amazing techniques  used to give the illusion of depth and detail such as bump mapping and  parallax mapping. And guess what? Both of those techniques use special  textures that are sampled in nearly the same way we did with this  shader.<br />
I will be covering more advanced shaders from now on, so  make sure you have the details in the tutorials up to this point down  pat. Feel free to experiment with the code we've written to get a firmer  grasp on what each part of it does. Try to write a shader to give your  model a unique effect not covered here. Good luck and happy programming!</p>
<p><strong>Download source: <a href="http://digitseven.com/Documents/Texturing.zip">Texturing.zip</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-texturing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Specular Lighting</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-specular-lighting/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-specular-lighting/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 19:15:52 +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[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Daniel Greenheck]]></category>
		<category><![CDATA[digitseven]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1789</guid>
		<description><![CDATA[by Daniel Greenheck
What should I be familiar with before I go through this tutorial?
- The content discussed in the introduction, ambient and diffuse tutorials.
One Thing Before I Begin...
To keep things succinct, I will no longer explain or comment things explained in previous tutorials. Throughout these series of tutorials, I'm going to expect you've gone through [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<p><strong><em>What should I be familiar with before I go through this tutorial?</em></strong><br />
- The content discussed in the <a href="http://www.sgtconker.com/2010/09/article-shaders-introduction/">introduction</a>, <a href="http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/">ambient</a> and <a href="http://www.sgtconker.com/2010/09/article-shaders-diffuse-lighting-2/">diffuse </a>tutorials.</p>
<h2>One Thing Before I Begin...</h2>
<p>To keep things succinct, I will no longer explain or comment things explained in previous tutorials. Throughout these series of tutorials, I'm going to expect you've gone through the previous tutorials. No sense in beating a dead horse. So if you look at the variables section and only see the Specular variables, rest assured the others are still in the actual program. I just think it will be easier for you as a reader if I only present you with new information. That aside, let's begin!</p>
<h2>What is Specular Lighting?</h2>
<p>Specular lighting in one word: shiny. The world specular in itself  means a mirror-like surface, so you can imagine that anything that has  specular lighting is very reflective, causing it to have shiny  highlights. If you place a polished chrome ball under a direct light  source, you'll probably see a big shiny spot blinding you; this is the  specular highlight. Specular reflections  are caused by the reflection of the actual light source itself. If  the surface isn't flat however, it will warp the light and you'll  usually see it as a small dot of bright light or curved lines of light.  When you're out on a sunny day, look around at smooth, metallic objects  and notice their specular highlights. Try and determine how the light is  coming in and being reflected off the surface to your eye. The more you  understand about real-world lighting, the better you'll understand what  we're trying to replicate in our shaders.</p>
<div><img src="http://digitseven.com/images/595002557_8aa8f72677.jpg" alt="" /><br />
<span style="font-size: xx-small;">The perfect example of specular  lighting. Notice the highlight is really the reflection of the sun.</span></div>
<h2><span id="more-1789"></span></h2>
<h2>The Specular Shader</h2>
<p>As usual, I once again present you with the entire specular shader. If you skipped my intro to this article, which I can't blame you for, I'll remind you that I left out the commenting on anything non-specular to save space and make the presentation a little nicer. If you don't know what the other parts of the program do, go back and read the Ambient and Diffuse shaders.</p>
<pre class="brush: csharp; title: ;">
float4x4 World;
float4x4 View;
float4x4 Projection;

float4 AmbientColor;
float AmbientIntensity;

float4 DiffuseColor;
float DiffuseIntensity;
float3 DiffuseLightDirection;

// Specular Variables
float4 SpecularColor;
float SpecularIntensity;
float Shinniness;                // Sharpness the specular highlights. Higher number = sharper highlight
float3 CameraPosition;

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD0;
    float3 CameraView : TEXCOORD1;
};

VertexShaderOutput VertexShader( VertexShaderInput input )
{
    VertexShaderOutput output;

    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

    output.Normal = mul( input.Normal, World );

    // Get the vector from the camera to the vertex for the specular component by
    // subtracting the world position from the camera
    output.CameraView = normalize( CameraPosition - worldPosition );

    return output;
}

float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Normalize our variables
    float3 lightdir = normalize( DiffuseLightDirection );
    float3 norm = normalize( input.Normal );

    // Calculate the half angle: the half the angle between our light direction and camera view
    float3 halfAngle = normalize( lightdir + input.CameraView );

    // Take the dot product between the normal of the pixel and the half angle. The closer the two
    // vectors are to pointing in the same direction, the higher the dot product. Take that to the [Shinniness]
    // power to make the highlight strong in the middle and fade out as you get towards the edges.
    float specular = pow( saturate( dot( norm, halfAngle ) ), Shinniness ) * SpecularColor * SpecularIntensity;

    float4 diffuse = dot( lightdir, input.Normal ) * DiffuseIntensity * DiffuseColor;
    float4 ambient = AmbientIntensity * AmbientColor;

    return saturate( diffuse + ambient + specular );
}

technique Specular
{
    pass Pass0
    {
        VertexShader = compile vs_1_1 VertexShader();
        PixelShader = compile ps_2_0 PixelShader();
    }
}
</pre>
<p>There's four things of interest we've added to the program:</p>
<ol>
<li>Four new variables: <strong>SpecularColor</strong>,  <strong>SpecularIntensity</strong>, <strong>Shinniness </strong>and <strong>CameraPosition</strong>.</li>
<li>In the output  structure, we added a new <em>float3 </em>for CameraView.</li>
<li>In the vertex  shader, we calculate our <strong>CameraView </strong>by subtracting the <strong>WorldPosition </strong>of the vertex from our <strong>CameraPosition.</strong></li>
<li>The pixel shaders  does some calculations to calculate the specular component. They look  pretty confusing right now, but don't worry, we'll break them down.</li>
</ol>
<h2>New Specular Variables</h2>
<pre class="brush: csharp; title: ;">
float4 SpecularColor;
float SpecularIntensity;
float Shinniness;                // Sharpness the specular highlights. Higher number = sharper highlight
float3 CameraPosition;
</pre>
<p>The first two variables are the same as the Ambient and Diffuse variables of similar name: they adjust the color and intensity of the specular light, respectively. The next variable is brand new however: <strong>Shinniness</strong>. This is a floating point number that adjusts the size and sharpness of the specular light. If you have a higher value, you're going to get a very intense, small highlight. If you set it to a lower value, the specular highlight will be broader, but overall not as sharp. Play with different values to get the effect you want. The range of values you'll want to stay within is 10 and 2000, though you can really pick whatever you want.</p>
<p>The next variable is the current position of the camera in the scene, a.k.a. the "eye" you are looking through. Since the specular highlights you see depend on your angle with the object and the light source, we'll need to update this variable every frame. For example: If you walk around a freshly-waxed car, you'll notice the specular highlights on the body and windows don't stay in the same spot. Depending on your position, the sun will be reflected to your eye off different parts of the car and at different angles.</p>
<h2>Adding the CameraView to the Output Structure</h2>
<pre class="brush: csharp; title: ;">
struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD0;
    float3 CameraView : TEXCOORD1;
};
</pre>
<p>We've added one new parameter to our <em>VertexShaderOutput</em>: CameraView. All we are passing here is a unit vector which represents the direction from the camera to the current vertex.</p>
<h2>Vertex Shader</h2>
<pre class="brush: csharp; title: ;">
VertexShaderOutput VertexShader( VertexShaderInput input )
{
    VertexShaderOutput output;

    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

    output.Normal = mul( input.Normal, World );

    // Get the vector from the camera to the vertex for the specular component by
    // subtracting the world position from the camera
    output.CameraView = normalize( CameraPosition - worldPosition );

    return output;
}
</pre>
<p>Compared to the diffuse shader, everything is the almost exactly the same. The only new thing we added is calculating the <strong>CameraView</strong>, which I just mentioned above. We just take the <strong>CameraPosition </strong>and subtract the position of the vertex in <em>world space</em>. Vector algebra determines that this gives the vector from the camera to the vertex. Then we normalize that to get a unit vector. Simple! We'll be using <strong>CameraView </strong>next...</p>
<h2>Pixel Shader</h2>
<pre class="brush: csharp; title: ;">
float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Normalize our variables
    float3 lightDir = normalize( DiffuseLightDirection );
    float3 norm = normalize( input.Normal );

    // Calculate the half angle: the half the angle between our light direction and camera view
    float3 halfAngle = normalize( lightDir + input.CameraView );
    // Take the dot product between the normal of the pixel and the half angle. The closer the two
    // vectors are to pointing in the same direction, the higher the dot product. Take that to the [Shinniness]
    // power to make the highlight strong in the middle and fade out as you get towards the edges.
    float specular = pow( saturate( dot( norm, halfAngle ) ), Shinniness ) * SpecularColor * SpecularIntensity;

    float4 diffuse = dot( lightdir, input.Normal ) * DiffuseIntensity * DiffuseColor;
    float4 ambient = AmbientIntensity * AmbientColor;

    return saturate( diffuse + ambient + specular );
}
</pre>
<div><img src="http://digitseven.com/images/specularlighting.png" alt="" /> <img src="http://digitseven.com/images/example.jpg" alt="" /></div>
<p>The  picture on the left is my cartoon depiction of what is going on. We have  an eyeball representing the camera position, the sun representing where the light is coming in from, and a little red box to act as our scene object. I've labeled each vector, all which you can  find in the pixel shader code. Take this time to locate all of them now  so you can follow along as we pick apart the code. The picture on the  right is what the eyeball in the cartoon would actually see.<br />
First, we stored the normalized <strong>DiffuseLightDirection</strong> in <strong>lightDir</strong>.  Anything but a unit vector will give us weird results. We follow that  by normalizing the <em>normal </em>of the current pixel (Remember we're  normalize in the pixel shader because we want the interpolated normal of  the pixel. If normalized in the vertex shader, it would still  interpolate is it went to the pixel shader and therefore wouldn't be a  normalized vector anymore.) and storing that in <strong>norm</strong>. Next, we  calculate the <strong>halfAngle </strong>by adding together <strong>lightDir </strong>and <strong>CameraView </strong>(vector from the camera to the box). If you look at the picture,  you can see <strong>halfAngle </strong>directly bisects the angle from <strong>lightDir</strong> to<strong> </strong><strong>CameraView</strong>. Okay. Now all our variables are defined.  Now we can finally calculate our specular component.<br />
If you  remember, in the diffuse component we took the dot product of the normal  and the light direction to find out how much light actually hit the  surface. The specular light uses the same concept, except it now also  depends on the position of the camera (or "eye"). Instead of taking the  dot product between the normal and the light direction, we're going to  take the dot product of normal and the half angle. Why? Physics break!</p>
<blockquote>
<h3>A Brief Digression on Optics</h3>
<p>If you really want to understand how shaders  work, a very thorough understanding of optical properties is an  absolute must. Knowing the real-world phenomena we are trying to  simulate and how they physically work gives you a much better idea of  what we're trying to accomplish. I'll give you a little optics  background so you can understand what's going on in this tutorial.  However, I would highly suggest looking at more sources to further your  understanding.<br />
<em><strong>When light strikes a surface at a certain  vector, called the angle of incidence, it bounces off the surface,  reflecting across the normal of the point on the surface it hits.</strong></em> If the normals of a surface are all pointing in the <em>same </em>direction  (think mirror), the reflected light will all be reflected at the same  angle, so the light rays will still be parallel to eachother. This keeps  the image intact when it gets reflected back to your eye. If the  normals of the surface are all pointing in <em>different </em>directions  (think rough boulder), the reflected light is scattered in all different  directions, some light rays even bouncing back towards the light  source. The rays are <span style="text-decoration: underline;">no longer parallel to eachother</span>, so  different parts of the image are shooting off in all different  directions. This is why you don't see a reflected image in a boulder  like you do in a mirror. The shinnier the surface, the less scattering  and the closer you get to a mirror. I've provided a picture below that  demonstrates what I've just explained.</p>
<div><img src="http://digitseven.com/images/optics.png" alt="" /></div>
<p>The <strong>Shinniness </strong>variable helps  us define how smooth or rough a surface is. The rougher the surface, the  smaller the value. You'll see why in a minute. In the cartoon diagram  with the red box, the light travels from the sun, reflects across the  normal of the pixel and makes it to our eye. However, our eye isn't  exactly at the receiving end of the reflected ray; it's slightly above.  Yet in the 3D rendering we can see it still gets light. Why is this?  Because in that picture, the box isn't perfectly smooth, so we can  assume that there will be some scattering to the eye. It's really all  just guess and check if you think about it. Comforting isn't it?</p></blockquote>
<p>Now that we know some laws of optics, we can start where we left off. We  take the dot product of <strong>norm </strong>and <strong>halfAngle </strong>to see how  much direct light the eye will get. The larger the angle between the  two, the further away our eye is from the "predicted" path of the  reflected rays; therefore we will get less specular/reflective light. We  take the result of that and take it to the <strong>Shinniness </strong>power. If  you think about an exponential graph, the higher the exponent, the  quicker a number below 1 goes to zero. This is a way to simulate how  rough surfaces can scatter light more than smooth surfaces. A smaller  power, a rougher surface, more scattering. A higher power, a smoother  surface, less scattering. We multiply that result by <strong>SpecularColor </strong>and  <strong>SpecularIntensity </strong>like our other light types and voila! We now  have specular light. We just add the specular component to our final sum  at the end of the pixel shader and our model should now be specularly  lit.</p>
<p>If you want to know how to set the variables from XNA,  be sure to check out the <strong>Diffuse </strong>or <strong>Ambient </strong>light  tutorial.</p>
<h2>Conclusion</h2>
<p>Specular lighting is a step towards the more complicated aspects of  programming shaders. By adding it into your 3D application, you can see  it definitely adds a lot of realism. Once you start getting into  advanced lighting techniques, you really need to know your stuff:  vectors, optics, matrix multiplication, etc. etc. I'll put up some  resources on optics on the <a href="http://digitseven.com/links.aspx">Links</a> page if you want to learn a bit more. There's already some links for  matrices. As these tutorials get more complex, I'll probably be making a  lot more mistakes so be sure to send me an email at <strong>dan@digitseven.com</strong>.  And of course, if you have any questions about anything I've covered,  please email me and I'll do my best to help you out. Also, make sure you <a href="http://digitseven.com/default.aspx">sign up for the newsletter</a> on the home page to stay updated with my latest posts Enjoy!</p>
<p><strong>Download the source: <a href="http://digitseven.com/Documents/SpecularLight.zip">SpecularLighting.zip</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-specular-lighting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Diffuse Lighting</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-diffuse-lighting-2/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-diffuse-lighting-2/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 19:04:11 +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[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Daniel Greenheck]]></category>
		<category><![CDATA[digitseven]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1785</guid>
		<description><![CDATA[by Daniel Greenheck
What should I be familiar with before I go through this tutorial?
- The content discussed in the introduction and ambient shader tutorials.
- A simple knowledge of vectors, matrices and dot products (click on the links for Wiki articles) will REALLY help you understand  some of the light calculations going on. although I'll [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<p>What should I be familiar with before I go through this tutorial?<br />
- The content discussed in the <a href="http://www.sgtconker.com/2010/09/article-shaders-introduction/">introduction</a> and <a href="http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/">ambient</a> shader tutorials.<br />
- A simple knowledge of vectors, <a href="http://en.wikipedia.org/wiki/Matrix_%28mathematics%29">matrices</a> and <a href="http://en.wikipedia.org/wiki/Dot_product" target="_blank">dot products</a> (click on the links for Wiki articles) will REALLY help you understand  some of the light calculations going on. although I'll do my best to  explain those topics in this tutorial.</p>
<h2>What is Diffuse Lighting?</h2>
<p>Diffuse lighting can best be described as directional light. There are three types of diffuse lighting: directional, point light and spotlight. I have a picture of each below in respective order. Directional light comes down at the same angle no matter where you are standing; the light has no position, just direction. Point light is like a light bulb, it all emanates  from a single point equally in all directions. A spot light is like an oriented floodlight or a flashlight. Diffuse light also creates shadows, but that's a much more advanced topic we won't dive in to until later.</p>
<p><img class="alignnone" title="http://digitseven.com/images/directional.jpg" src="http://digitseven.com/images/directional.jpg" alt="" width="479" height="362" /></p>
<p><span id="more-1785"></span></p>
<p><img class="alignnone" title="Point" src="http://digitseven.com/images/point.jpg" alt="" width="500" height="333" /></p>
<p><img class="alignnone" title="spot" src="http://digitseven.com/images/point_spotlight_dynamic.jpg" alt="" width="640" height="480" /></p>
<h2>The Diffuse Shader</h2>
<p>Once again, here's the entire diffuse shader for you to look at. You can probably notice it has all the same elements of the ambient shader, along with a few extra parts.</p>
<pre class="brush: csharp; title: ;">
// Matrices
float4x4 World;
float4x4 View;
float4x4 Projection;

// Ambient Variables
float4 AmbientColor;
float AmbientIntensity;

// Diffuse Variables
float4 DiffuseColor;
float DiffuseIntensity;
float3 DiffuseLightDirection;

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD1;
};

VertexShaderOutput VertexShader( VertexShaderInput input )
{
    VertexShaderOutput output;

    // Transform our position by the matricies
    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

    // Transform the normal from model space to world space
    output.Normal = normalize( mul( input.Normal, World ) );

    return output;
}

float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Determine the diffuse component by finding the angle between the light and the normal.
    // The smaller the angle between the normal and the light direction, the closer the dot
    // product will be to 1, and the brighter the pixel will be.
    float4 diffuse = dot( DiffuseLightDirection, input.Normal ) * DiffuseIntensity * DiffuseColor;

    // Calculate our ambient component
    float4 ambient = AmbientIntensity * AmbientColor;

    // Return the total light component as a combination of the diffuse and ambient.
    // Saturate it to keep the color between 0 and 1.
    return saturate( diffuse + ambient );
}

technique Diffuse
{
    pass Pass0
    {
        VertexShader = compile vs_1_1 VertexShader();
        // We upgraded to pixel shader 2.0 so we can used more advanced commands
        PixelShader = compile ps_2_0 PixelShader();
    }
}
</pre>
<p>So what's the same?</p>
<ol>
<li><span style="text-decoration: underline;">Variables</span>: All three      matrices (<strong>World</strong>, <strong>View</strong>, <strong>Projection</strong>), <strong>AmbientColor </strong>and      <strong>AmbientIntensity </strong>are back.</li>
<li><span style="text-decoration: underline;">Structures</span>: Position      makes an appearance once again.</li>
<li><span style="text-decoration: underline;">Vertex Shader</span>: The      vertices are still transformed using the <strong>World</strong>, <strong>View </strong>and  <strong>Projection </strong>matrices.</li>
<li><span style="text-decoration: underline;">Pixel  Shader</span>: The      ambient lighting component is still calculated.</li>
</ol>
<p>Now, let's take a  look at what's new.</p>
<ol>
<li>We have three new variables for our diffuse light: <strong>DiffuseColor</strong>,  <strong>DiffuseIntensity</strong>, <strong>DiffuseLightDirection</strong>. Direction is the  only new concept here.</li>
<li>A <em>float3 </em>called  Normal has been added to both the input and output structures for the  vertex shader.</li>
<li>In our vertex shader, we do  a transformation on the normal from <em>VertexShaderInput </em>and pass  that on to the pixel shader.</li>
<li>In our pixel  shader, we calculate the diffuse component of the light.</li>
<li>We changed the pixel shader version from 1_1 to 2_0 to allow  us to do more advanced features in the pixel shader (i.e. normalize a  vector).</li>
</ol>
<p>Let's take a look at each of those  additions in detail. First we need to take a little side step to talk  about normals...</p>
<h2>Juat a Normal Kind of Light</h2>
<p>When we did ambient light, it didn't  matter where the light was coming from or how the light hit a certain  face. We just assumed each face was hit by the same amount of light,  giving the effect of everything being the same color. With diffuse  lighting, however, we now have a light coming in at a specific  direction, so each face isn't going to get hit by the same amount of  light. Imagine placing a small object by your desk lamp (and if you  don't have one of those, imagine that too). You'd notice right away that  the side facing the light gets more light than the side facing away,  resulting in a brighter color. This is because the <strong>normal</strong> of the  face aimed towards the light is pointed more directly at the light  source. A normal is a pretty simple concept. Here's a 3D model with the  normals shown as red rays coming out of the faces.<br />
<img src="http://digitseven.com/images/boxnormals.jpg" alt="" /><br />
Each  of those rays is <em>orthogonal </em>to the face it comes out of (fancy  term for perpendicular.) Our model uses normals like these and compares  it with the light direction to see how much light the face should get.  If a normal is pointing either perpendicular or completely away from the  light source, there's not a chance even a ray of light will directly  hit the face. We'll get back to normals later. All you  need to know is <span style="text-decoration: underline;">normals are used for calculating how much light a  face should get.</span> Let's get back into our shader code now.</p>
<h2>Variable Declaration</h2>
<pre class="brush: csharp; title: ;">
// Matrices
float4x4 World;
float4x4 View;
float4x4 Projection;

// Ambient Variables
float4 AmbientColor;
float AmbientIntensity;

// Diffuse Variables
float4 DiffuseColor;
float DiffuseIntensity;
float3 DiffuseLightDirection;
</pre>
<p>The matrices and ambient variables  we covered in the last tutorial haven't changed at all, so I won't go  over those. However, we've added three new variables for our  diffuse lighting. The first two- <strong>DiffuseColor </strong>and <strong>DiffuseIntensity</strong>-  are analogs to <strong>AmbientColor </strong>and <strong>AmbientIntensity</strong>. They  control the color and brightness our diffuse light, respectively. Our  next variable, however, is brand spankin' new: <strong>DiffuseLightDirection</strong>.  From the name you can probably construe it defines the direction our  light will shine down at. And that's exactly what it is. There's one  peculiarity you should know about defining light direction though:<em><strong> </strong>the light shines down in the opposite direction you define it.</em> So if you want your light to shine straight down on your object,  naturally you would think to assign float3(0, -1, 0) to your <strong>DiffuseLightDirection</strong>.  But nope, that will cause the light to shine straight up.</p>
<h2>The Vertex Shader Input and Output Structures</h2>
<pre class="brush: csharp; title: ;">
struct VertexShaderInput    // Input for the vertex shader
{
    float4 Position : POSITION0;
    float3 Normal : NORMAL0;
};

struct VertexShaderOutput    // Output for the vertex shader
{
    float4 Position : POSITION0;
    float3 Normal : TEXCOORD0;
};
</pre>
<p>Since we now know that we need normals from  our model for our shader, I went ahead and added a <em>float3 </em>(equivalent  of a Vector3 in XNA) to our <em>VertexShaderInput </em>structure to  represent the normal for the vertex. One problem you probably noticed is  that the normals I described above were for <strong>surfaces</strong> not <strong>vertices.</strong> Well this isn't a problem at all! To find the vertex normal, you simply  average the normals of all the faces that that use that vertex. I  described the actual code below when I get into the XNA part, so don't  worry. The normal parameter was also added to the <em>VertexShaderOutput</em>,  but we're going to be doing some work on it in the vertex shader so it  isn't the same as the normal we pass in through <em>VertexShaderInput</em>.  We'll look at the vertex shader next to see how we're actually  modifying the normal.</p>
<h2>Vertex Shader</h2>
<pre class="brush: csharp; title: ;">
VertexShaderOutput VertexShader( VertexShaderInput input )
{
    // Initialize our vertex shader output
    VertexShaderOutput output;

    // Transform our position by the matricies
    float4 worldPosition = mul( input.Position, World );
    float4 viewPosition = mul( worldPosition, View );
    output.Position = mul( viewPosition, Projection );

    // Transform the normal from model space to world space
    output.Normal = normalize( mul( input.Normal, World ) );

    return output;
}
</pre>
<p>You'll notice there's a lot of familiar code here already. The transformations  on the vertex position are exactly the same as they were in the ambient  shader. The only new line we added takes the input normal, transforms  it by the <strong>World </strong>matrix and normalizes the result. Let's break  that down... Inside the parentheses, we take the vertex normal we passed  in and multiply it with the <strong>World </strong>matrix. We do this for the  same reason we multiply our position with the <strong>World </strong>matrix: our  normal is defined in <em>model space</em> (relative to the model origin)  and we need to get it into <em>world space</em>, since that's where our  light direction is defined. Our model could be rotated and translated  and all sorts of stuff- which is all taken care of in the <strong>World </strong>matrix-  so we need to apply those transformations to the normal too. After we  get our normal in <em>world space</em>, we normalize it. Don't confuse  "normal" with "normalize" either. A "normal" defines which way a face or  vertex is pointing. "Normalizing" a vector makes it <em>unit length</em>,  or have a length of 1. Unit vectors are used to specify direction  without magnitude. Two normal vectors pointing in the same direction  with different magnitudes would somehow mean that one face is pointing  in a direction with more force than the other, which really makes no  sense at all. After calculating the output normal, we now have  everything we need to calculate diffuse light in our pixel shader.</p>
<h2>Pixel Shader</h2>
<pre class="brush: csharp; title: ;">
float4 PixelShader( VertexShaderOutput input ) : COLOR0
{
    // Normalize our light direction
    float3 normLightDirection = normalize( DiffuseLightDirection );

    // Determine the diffuse component by finding the angle between the light and the normal.
    // The smaller the angle between the normal and the light direction, the closer the dot
    // product will be to 1, and the brighter the pixel will be.
    float4 diffuse = dot( normLightDirection, input.Normal ) * DiffuseIntensity * DiffuseColor;

    // Calculate our ambient component like we did with the ambient shader.
    float4 ambient = AmbientIntensity * AmbientColor;

    // Return the total light component as a combination of the diffuse and ambient.
    // Saturate it to keep the color within 1.
    return saturate( diffuse + ambient );
}
</pre>
<p>We've finally made it to the last step of the shader! Once again, we've copied over a lot of stuff  from the ambient lighting pixel shader. In fact, we've copied all of it.  We've also added two things: normalizing our light direction at the  pixel-shader-level forThe only thing we've added is the calculation of  our diffuse component. Since we want per-pixel diffuse lighting, we've  put the calculation for the diffuse component in the pixel shader. To  calculate how much light the pixel gets from our diffuse light, we take  the dot product of the diffuse light direction with the transformed  vertex normal and multiply it with <strong>DiffuseIntensity </strong>and <strong>DiffuseColor</strong>.  Wow, that's a mouthful! First, you might be wondering what a dot  product is. Read this little section first. If you already know what a  dot product is, feel free to skip it.</p>
<blockquote>
<h3>A brief digression on the Dot Product</h3>
<p>The <strong>dot  product</strong> is something we haven't come across yet. What it does is  compare the angle between two vectors and returns a <em>float.</em> If the  vectors are both <em>unit length</em>, you'll get a result between -1 and  1. If they aren't, you'll get a wildly varying value that you really  can't do anything with. A dot product of 20 could mean a billion things.  Now you know why we normalized our light direction and vertex normal.</p>
<p>If Vector1 and Vector2...</p>
<blockquote><p>- are pointing in the exact  same direction then <strong>dot( V1, V2 ) = 1</strong><br />
- are perpendicular to  each other then<strong> dot( V1, V2 ) = 0</strong><br />
- are pointing in exact  opposite directions then <strong>dot( V1, V2 ) = -1</strong></p></blockquote>
</blockquote>
<blockquote><p>Those are just the exact cases. Everything in between will vary  depending on where it's pointing. The closer they are to pointing in the  same direction, the closer to 1. The opposite holds with pointing in  the opposite direction. If you're confused, check out the Links section  on the navigation bar for more information on dot products.</p></blockquote>
<p>Now that we have dot products out of the way, we can finally apply it to our diffuse  calculation. When our normal is pointing in the opposite direction of  the <strong>DiffuseLightDirection </strong>(remember that our light direction is  defined opposite of what you think it should be), our dot product will  be 1. Multiply that with <strong>DiffuseColor </strong>and <strong>DiffuseIntensity </strong>and  we'll end up with our maximum possible value for the diffuse component.  If the normal and light direction are perpendicular, the dot product  will be zero and we'll get no light. This makes sense since a side  perpendicular to a light source isn't going to get hit by light rays.<br />
Phew! Now that we finally have our diffuse and ambient components, all  we do is add them together. Before we return the sum however, we want to  put apply the saturate() function. This caps any component of our pixel  color between 0 and 1. If the dot product was negative, we'd have  negative color values which would throw an error.</p>
<h2>Adding Normals to Our Models</h2>
<p>The biggest change we need on the XNA side is adding our normal  data to ou vertices. For the ambient shader I used the VertexPositionColor  structure for storing my vertices. Unfortunately, this doesn't have  anywhere to store normal information. So I've upgraded the vertices on  my box to VertexPositionNormalTexture,  leaving the texture coordinates blank for now. Remember that shaders  don't care if there's extra information there; they just take what they  need and move on. I'll be covering a texture shader within the next few  tutorials so let's go ahead and use that structure. Now, for calculating  the normals. This can vary greatly depending on what you have: a list  of verticies, a list of indexed vertices, a model. I won't cover the  first case and normally any model you find will already have the normals  in it, so I'm going to give a brief overview of indexed vertices  defined in the <strong>TriangleList </strong>format. I apologize if you defined  your verticies in a different fashion, but don't get too upset. A quick  check over at the <a href="http://forums.xna.com/forums/">XNA Forums</a> or a Google search should help you out with that. Here's a step-by-step  guide on how to calculate normals for indexed vertices which use the <strong>TriangleList </strong>method.</p>
<ol>
<li>Create you vertices and indices as you  normally would.</li>
<li>Loop through your indices <strong>three </strong>at a  time. Since your indicies are defined using a <strong>TriangleList</strong>, you  know each three consecutive indices represent a triangle in your model.</li>
<li>Get  the three vertices from I1, I2 and I3 and name them V1, V2 and V3.</li>
<li>Create  two Vector3's: <strong>VectorA </strong>= <em>V2.Position - V1.Position</em> and <strong>VectorB </strong>= <em>V3.Position - V1.Position.</em></li>
<li>Take the cross product  of <strong>VectorB </strong>with <strong>VectorA </strong>(order matters) and normalize that  result. This will give you your face normal.</li>
<li>Now go back and  add that face normal to V1.Normal, V2.Normal and V3.Normal.</li>
<li>Repeat  for every three indices and voila, each vertex now has it's vertex  normal.</li>
</ol>
<p>By adding the face normal to each vertex that  made up the face, we've effectively averaged together all the face  normals for each vertex, which is the definition of a vertex normal.Once you get that implemented, our models should now  have all the necessary information to draw them with diffuse light.</p>
<h2>Setting Our Shader Variables</h2>
<pre class="brush: csharp; title: ;">

    // Set the parameters of the shader

    diffuseEffect.Parameters[ &quot;World&quot; ].SetValue( Matrix.CreateRotationY( (float)gameTime.TotalGameTime.TotalSeconds )  );

    diffuseEffect.Parameters[ &quot;View&quot; ].SetValue( viewMatrix );

    diffuseEffect.Parameters[ &quot;Projection&quot; ].SetValue( projectionMatrix );

    diffuseEffect.Parameters[ &quot;AmbientColor&quot; ].SetValue( new Vector4( 1, 1, 1, 1 ) );

    diffuseEffect.Parameters[ &quot;AmbientIntensity&quot; ].SetValue( .3f );

    diffuseEffect.Parameters[ &quot;DiffuseColor&quot; ].SetValue( new Vector4( 0, 1, 0, 1 ) );

    diffuseEffect.Parameters[ &quot;DiffuseIntensity&quot; ].SetValue( .8f );
    diffuseEffect.Parameters[ &quot;DiffuseLightDirection&quot; ].SetValue( new Vector3( .7f, 1f, -.8f ) );
</pre>
<p>Nothing has really changed here. We've just tacked on three more SetValue()'s for our three diffuse  variables. Set your <strong>DiffuseColor, </strong><strong>DiffuseIntensity </strong>and <strong>DiffuseLightDirection</strong> (we normalize it here to avoid the calculation in the shader. And  remember, it's opposite of the direction the light shines at!) and  you're almost good to go!</p>
<h2>Drawing Vertices With Our Diffuse Effect</h2>
<p>Once again, not much has changed here. Make sure you change your  VertexDeclaration and DrawUserPrimitives call to VertexPositionNormalTexture so the graphics  card knows we've added normal data. If you skip that, you'll probably  end up with nothing but black blob. Everything should be ready to go  now... so go ahead, hit F5 and watch that cube spin in it's shaded,  rainbowed glory! You should get something similar to this video:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="385" 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/s1nqiD0nDCY?fs=1&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="480" height="385" src="http://www.youtube.com/v/s1nqiD0nDCY?fs=1&amp;hl=en_US" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h2>Conclusion</h2>
<p>So there we go, another shader down.  By now I hope you're starting to get a feel for how these shaders work  and what goes into them. You should start seeing a pattern as you go  along: vertex shaders transforming data, pixel shaders using the  transformed data to calculate colors. Every vertex shader and pixel  shader you come across is going to work like that for the most part.  I'll be covering specular light in the next tutorial, which will give  you a nice shiny effect on your objects. I might have to ditch the cube  for a sphere... I don't think he'll take kindly to that news... Anyway,  best of luck to you in your programming! If you happen to catch any  errors or need any clarifications, be sure to send me an email at <strong>dan@digitseven.com</strong>,  I'd be more than happy to help. Make sure to <a href="http://digitseven.com/default.aspx">sign up for the newsletter</a> to stay updated with my latest tutorials and code uploads!</p>
<p><strong>Download the source: <a href="http://digitseven.com/Documents/DiffuseLight.zip">DiffuseLighting.zip</a></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-diffuse-lighting-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Ambient Lighting</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 21:21:26 +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[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Daniel Greenheck]]></category>
		<category><![CDATA[digitseven]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1780</guid>
		<description><![CDATA[by Daniel Greenheck
Since these are shader tutorials and not XNA tutorials, I'm guessing you already have a basic understanding of these topic
- How to draw a simple model or some vertices in XNA.
- How to add files to the Content Pipeline.
- The content in my Shader Introduction.
A few words to start...
Before someone makes the wise-crack [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<p>Since these are shader tutorials and not XNA tutorials, I'm guessing you already have a basic understanding of these topic<br />
- How to draw a simple model or some vertices in XNA.<br />
- How to add files to the Content Pipeline.<br />
- The content in my <a href="http://www.sgtconker.com/2010/09/article-shaders-introduction/">Shader Introduction</a>.</p>
<h2>A few words to start...</h2>
<p>Before someone makes the wise-crack  that ambient lighting is already taken care of in the BasicEffect class  in XNA, I'm going to tell you: ambient lighting is already taken care  of in the <em>BasicEffect </em>class in XNA. The reason I'm giving this  tutorial is because these basic shaders lay the foundation for more  advanced and complex shaders. If you can understand how simple shaders  work, it will help you out <em>profoundly </em>when dealing with complex  topics like bump mapping and projective texturing later on. I highly  recommend avoiding the BasicEffect class if you are completely new to  shaders. Instead focusing on building your foundation of shader  knowledge; it's completely necessary if you ever plan on making anything  beyond a game that looks like Mario 64.<br />
If you don't plan on  using advanced shaders or you already know the basics of HLSL, <strong><a href="http://msdn.microsoft.com/en-us/library/bb203926.aspx">here’s a  tutorial</a></strong> on how to use the BasicEffect class (which is also on  my links page).</p>
<p>Now, for those of you who are still with me! Ambient lighting is  about as simple as it gets, so this will be a good place to start if you  are completely unfamiliar with HLSL. A scene with only ambient lighting  by itself looks like a polar bear in a snow storm, so if you want a  little more detailed effect, I would skip to the diffuse lighting  tutorial. However, in later tutorials, I'll be focusing mainly on the  actual code inside the vertex and pixel shaders; I'm going to assume  you've already read this tutorial and have a basic understanding of  shaders. So consider yourself warned!</p>
<p><span id="more-1780"></span></p>
<h2>What is Ambient Lighting?</h2>
<p>Well I see I’ve blabbed on without even mentioning what we  are programming! Ambient lighting can best be described by going  outside on a cloudy day. If you look around, there is really no direct  light source: you don’t have the sun shining overhead, creating shadows  with every object it hits. In fact, if you look around, there probably  aren’t many shadows to be found (unless there is some artificial light,  then that’s just cheating). Ambient light is the result of the suns rays  bouncing of so many different surfaces that they light parts of the  world that aren’t even directly lit. Go outside on a sunny day sometime and see for yourself. Notice how areas that aren’t being lit by direct light aren’t completely dark. I also like to think of  ambient lighting as <em>global lighting</em>: it manages to light up every  part of the world, the same amount, no matter where it is. An object  lit by only ambient light will look something like this:</p>
<div><img src="http://digitseven.com/images/box1.png" alt="" /></div>
<p>Blah! It's boring and there's no  definition to any corners or edges. Although almost useless by itself,  ambient lighting is a necessary part of any scene to give it some static  light. Now, on to the fun stuff!</p>
<h2>The Ambient Lighting Shader</h2>
<p>I'm just going to show you the entire Ambient Lighting shader right away so you can glance over it. As we go along, I'll explain each part of it, piece-by-piece. So let's get started!</p>
<pre class="brush: plain; title: ;">
    float4x4 World;             // World matrix
    float4x4 View;              // View matrix
    float4x4 Projection;        // Projection matrix

    float4 AmbientColor = float4( 1, 1, 1, 1 );     // Ambient lighting color
    float AmbientIntensity = 0.8;                   // How bright the ambient light is ( 0.0 - 1.0, 0 = No light, 1 = Full Light )

    struct VertexShaderInput    // Input data for vertex shader
    {
        float4 Position : POSITION0;    // Pass in just the position of the vertex to the vertex shader
    };

    struct VertexShaderOutput   // Output data for vertex shader/input data for pixel shader
    {
        float4 Position : POSITION0;    // We'll be passing our transformed position to the pixel shader
    };

    // Vertex Shader

    VertexShaderOutput VertexShaderFunction( VertexShaderInput input )
    {
        VertexShaderOutput output;

        float4 worldPosition = mul( input.Position, World );
        float4 viewPosition = mul( worldPosition, View );
        output.Position = mul( viewPosition, Projection );

        return output;
    }

    // Pixel Shader

    float4 PixelShaderFunction( VertexShaderOutput input ) : COLOR0
    {
        return ( AmbientColor * AmbientIntensity );
    }

    technique Ambient
    {
        pass Pass0
        {
            VertexShader = compile vs_1_1 VertexShaderFunction();
            PixelShader = compile ps_1_1 PixelShaderFunction();
        }
    }
</pre>
<p>As you can tell right  away, there isn’t a whole lot going on here. Here's what we can see in  this shader:</p>
<ol>
<li>The global variabes are  defined at the top.</li>
<li>The input and output  structures for our vertex shader are defined.</li>
<li>The vertex  shader function is right below that.</li>
<li>Followed by the  pixel shader.</li>
<li>And our Ambient technique with a single pass  finishes up the shader.</li>
</ol>
<h2>Variable Declaration</h2>
<pre class="brush: plain; title: ;">
    float4x4 World;                                // World matrix
    float4x4 View;                                 // View matrix
    float4x4 Projection;                           // Projection matrix

    float4 AmbientColor = float4( 1, 1, 1, 1 );    // Ambient lighting color
    float AmbientIntensity = 0.8;                  // How bright the ambient light is ( 0.0 - 1.0, 0 = No light, 1 = Full Light )
</pre>
<p>There are five different global variables needed to make an ambient light shader: Our <strong>World</strong>, <strong>View </strong>and <strong>Projection </strong>matrices along with our <strong>AmbientColor </strong>and  <strong>AmbientIntensity</strong>. The first three will make their appearance in practically every shader you will create. Those three <em>float4x4</em> variables- <strong>World, View </strong>and <strong>Projection- </strong>are placeholders for your matrices. I’m not going to completely dive into  the topic of matrices here since there is a lot of advanced math behind them which  is beyond the scope and focus of this tutorial. If you want to know the  actual mathematics behind them, I would suggest just the always informative <strong><a href="http://en.wikipedia.org/wiki/Matrix_%28mathematics%29">Wikipedia</a></strong> or this link<strong>: </strong><a href="http://www.ziggyware.com/readarticle.php?article_id=100"><strong>Introduction  to Matrices</strong></a>. All you need to know for now is that the matrices  help XNA transform your model from its 3D coordinates you define it in to 2D screen space for your viewing pleasure.</p>
<p>The next two  variables are unique to the ambient shader. <strong>AmbientColor</strong> is pretty self-explanatory:  this stores the color of your ambient light. We use <em>float4</em>, each  component of the float representing a component of our ambient color:  red, green, blue and alpha (a fancy term for transparency). If you look above, I set the ambient color like this:</p>
<pre class="brush: plain; title: ;">
    float4 AmbientColor = float4( 1, 1, 1, 1 );     // Ambient lighting color
</pre>
<p>Unlike in XNA or  C#, you don’t need to specify the new keyword  when you initialize an array. You just have <em>float </em>followed by a comma-delimited list of values in parenthesis. Make  sure the number of items matches the dimensions of the <em>float</em>, or you’ll  get a compile error. You can have <em>float, float2, float3</em>, but no more values  than that. Anything beyond a <em>float4 </em>doesn't have a lot of use in a  shader.</p>
<p><strong>AmbientIntensity: </strong>This  is just a floating point from 0 to 1 which is a proportion of how much  of the <strong>AmbientColor </strong>you want to apply to the object.</p>
<h2>The Vertex Shader Input and Output Structures</h2>
<pre class="brush: plain; title: ;">
struct VertexShaderInput
{
    float4 Position : POSITION0;    // Pass in just the position of the vertex to the vertex shader
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;    // We'll be passing our transformed position to the pixel shader
};
</pre>
<p>Our <em>VertexShaderInput </em>and <em>VertexShaderOutput</em> are extremely simple, so this is a good time to introduce a lot of  idiosyncrasies about shader structures. Let's look at format of the <em>VertexShaderInput</em> structure first. You see it starts with the <em>struct</em> identifier,  followed by the name of the structure. Then we have the infamous curly  brackets followed by a list of parameters the structure holds. This one  only requires a <em>float4 </em>for position. Simple enough.<br />
Now  what's this crazy business hanging off the end of our parameter?<strong> :  POSITION0</strong>? What the heck is this?! This, my friend, is called a  semantic. They tell the graphics card what type of data we're passing in  our shaders. <strong><a href="http://msdn.microsoft.com/en-us/library/bb509647%28VS.85%29.aspx">Here's  a reference list of all the semantics available in HLSL</a></strong> (As you  can see from the link, there's a list for vertex shaders and pixel  shaders; they are two different sets. Keep that in mind.) For position,  you would use the <strong>POSITION[n] </strong>semantic, for color, you would use  the <strong>COLOR[n]</strong> semantic, and so on. You can also see there is a  little number after the semantic. This allows you to pass in more than  one type of the same variable. For instance, if I wanted to pass a set  of texture coordinates and a set of coordinates for my bump map, I would  use the semantics <strong>TEXCOORD0, TEXCOORD1.</strong> They may seem a little  confusing now, but don't worry; in future tutorials you'll see them used  a little more extensively.</p>
<h3>A Note About Semantics</h3>
<blockquote><p>It doesn't matter if you pass in vertices with the type VertexPositionColor, VertexPositionNormalTextured, or even a custom vertex format. The graphics card will always know where the position is stored in your vertex data. When you set the VertexDeclaration of the GraphicsDevice, the VertexElements member (of your vertex structure) has all the data saying which parts of the vertex structure are mapped to which semantics. Every piece of data has a little tag on it defining what it is to keep things nice and organized.</p></blockquote>
<p>The vertex shader output is exactly the  same as <em>VertexShaderInput</em>, so we'll leave it at that. We'll be  modifying our position we pass in from <em>VertexShaderInput</em> and  passing that on to <em>VertexShaderOutput,</em> so it isn't completely  useless. As I mentioned in my shader introduction, remember that you  don't need these structures for your shader to work. You could change  your vertex and pixel shader to this:</p>
<pre class="brush: csharp; title: ;">
float4 VertexShaderFunction( float4 position : POSITION0 ) : POSITION0
{
    float4 worldPosition = mul( position, World );
    float4 viewPosition = mul( worldPosition, View );
    return mul( viewPosition, Projection );
}

float4 PixelShaderFunction( float4 position : POSITION0 ) : COLOR0
{
    return ( AmbientColor * AmbientIntensity );
}
</pre>
<p>and it would work exactly the same as if you used the structures. In this case I would almost prefer the above format over the structures since it is more succinct, but I like to use structures all the time for consistency's sake. It's up to you how you want to handle it. Okay, on to the brains of our shader.</p>
<h2>Vertex Shader</h2>
<pre class="brush: csharp; title: ;">
    // Vertex Shader
    VertexShaderOutput VertexShaderFunction( VertexShaderInput input )
    {
        VertexShaderOutput output;

        float4 worldPosition = mul( input.Position, World );
        float4 viewPosition = mul( worldPosition, View );
        output.Position = mul( viewPosition, Projection );

        return output;
    }
</pre>
<p>Here we have our simple vertex  shader program. Let's look at it step-by-step. First, we declare an  instance of <em>VertexShaderOutput </em>so the vertex shader can return  some data. Remember this structure holds only position, so that's what  the entirety of this vertex shader is going to work with. Next, there  are three lines that are all related to each other: The first, takes the  position based in to our vertex shader which is defined in 3D space and  transforms it into <em>world space</em>. Now we have our world position.  Next, we transform our world position by the view matrix to get in <em>camera  space</em>. Finally, we transform our <em>camera space</em> position into  screen space with the projection matrix.<br />
Let's take a step back  and look at what's really going on with the first line. What is a world  matrix used for? A world matrix takes the vertices and converts them  from <em>object space</em> into <em>world space</em>. What does this mean?  Let's say you have a model of a box, where each side is 2 units long. So  each corner will be defined as 1 unit away from the axes of the object.  The front upper-right corner will be (1,1,1), the back upper-left  corner will be (-1,1,-1) and so on. These coordinates are defined in <em>object  space</em>, relative to the box. Let's say our cube is actually  positioned at (5,5,5) in our world. So really, the front upper-right  corner will be at (6,6,6) in <em>world space</em>, the back lower-left  corner will be (4,6,4). Here's a 2D representation of the concept:</p>
<div><img src="http://digitseven.com/images/worldvsobjectspace.jpg" alt="" /></div>
<p>Since all we needed to do  was transform our 3D position into<em> screen space</em>, we're all ready  for the pixel shader!</p>
<h2>Pixel Shader</h2>
<pre class="brush: csharp; title: ;">
    // Pixel Shader
    float4 PixelShaderFunction( VertexShaderOutput input ) : COLOR0
    {
        return ( AmbientColor * AmbientIntensity );
    }
</pre>
<p>Take a good look at this pixel  shader and admire its beauty. Why? Because this is about as easy as it  can get. Pixel shaders can get pretty beefy when advanced vector math  and texturing sampling comes into play, so enjoy this now. All this pixel shader does is take the <strong>AmbientColor </strong>and multiply it with the <strong>AmbientIntensity</strong>. So if you make your  intensity 0.8 like I did, it will return 80% of each color component,  resulting in a darker color. Experiment with different values and see  how the brightness of the color changes.<br />
You can also see that  we attached a semantic at the top of the pixel shader for <strong>COLOR0.</strong> Remember, there's different semantics for vertex shaders than pixel  shaders! <strong>COLOR0 </strong>maps to the first output color for the pixel  shader, so we'll use that one. If we were refer to <strong>COLOR0 </strong>in the  context of a vertex shader, it would be first storage location for a  color we wanted to apply to our vertices in some way.<br />
You're  probably wondering one last thing: "We never used our transformed  position!? Why even pass in the transformed position then?" Yes indeed,  we definitely did not. In the pixel shader at least. We still had to do  the transformations in the vertex shader, otherwise our graphics card  would have no idea where our vertices would go on the screen. All the  pixel shader does is interpolate the colors between the vertices. Since  we're just using an ambient color, we have the same color for every  pixel. So to answer the final question: no reason at all. In every other  shader, you're going to need the position of the vertex to calculate  values like how much light the pixel is getting. But in this case, we  can get away with leaving the arguments of the pixel shader completely  blank. Once again, I just pass it in for consistency.</p>
<p><em><strong>Okay! We finally finished our shader. Now we just need to get XNA to draw using it...</strong></em></p>
<h2>Preparing XNA for Crazy Shadin'</h2>
<p>Before we get too excited about using shaders, we need to set up XNA so we can render with shaders. First, put the variable declaration for our ambient effect at the top of your game file:</p>
<pre class="brush: csharp; title: ;">
Effect ambientEffect;
</pre>
<p>Now our application has a reference to the effect. Then, in the LoadContent method in your game file, add this:</p>
<pre class="brush: csharp; title: ;">
// Load our ambient effect
ambientEffect = Content.Load&lt;Effect&gt;( &quot;Ambient&quot; );
</pre>
<p>This loads the effect file which I've called "Ambient" from the Content Pipeline into our ambientEffect reference. Make sure your Ambient shader is added to the Content Pipeline or XNA won't be able to find it. There! That's all we needed to set up our application for shaders.</p>
<h2>Setting Global Shader Variables from XNA</h2>
<p>Now that you have your shader all implemented, it needs to be passed information from XNA. Once you set a value of a variable in a shader, it stays at that value until it's set again. If the state of the data never changes- let's say the color will always be red- you only have to set that global variable once when you initialize the shader. That will save you the cost of redundantly setting variables. I like to set all of the global variables per frame. Not setting them all the time can be problematic if you add another model in that uses the same shader but different values. It can get pretty hairy to debug that situation if your code is pretty complex. However, if you're looking to squeeze the last few drops of performance out of your application and you know when a global variable will always remain the same, you can try optimizing that block of code. Here's the XNA code for setting your desired technique and setting the values of the parameters:</p>
<pre class="brush: csharp; title: ;">
    // Set what technique we want to render with
    ambientEffect.CurrentTechnique = ambientEffect.Techniques[ &quot;Ambient&quot; ];

    // Set the parameters of the shader
    ambientEffect.Parameters[ &quot;World&quot; ].SetValue( Matrix.CreateRotationY( (float)gameTime.TotalGameTime.TotalSeconds ) );
    ambientEffect.Parameters[ &quot;View&quot; ].SetValue( viewMatrix );
    ambientEffect.Parameters[ &quot;Projection&quot; ].SetValue( projectionMatrix );
    ambientEffect.Parameters[ &quot;AmbientColor&quot; ].SetValue( new Vector4( 1, 1, 1, 1 ) );
    ambientEffect.Parameters[ &quot;AmbientIntensity&quot; ].SetValue( .8f );
</pre>
<p>This code goes right after you clear the GraphicsDevice in your draw method. In the first line, we are setting the current technique to "Ambient". Nothing special there. You can see in the next five lines of code, we're accessing each global variable from the list of parameters and setting its value. For the <strong>World </strong>matrix, I just set up a simple spin around the Y axis to give a little excitement to it. I have the <strong>AmbientColor </strong>set to white. I want that at 80% brightness, so I set the <strong>AmbientIntensity </strong>to 0.8. Easy as cake!</p>
<h2>Drawing Vertices With Our Ambient Effect</h2>
<pre class="brush: csharp; title: ;">
// Begin the effect
ambientEffect.Begin();
foreach ( EffectPass pass in ambientEffect.CurrentTechnique.Passes )
{
    pass.Begin();

    // Set the vertex declaration so our graphics device knows what to render
    GraphicsDevice.VertexDeclaration = new VertexDeclaration( GraphicsDevice, VertexPositionColor.VertexElements );
    // Draw the box
    GraphicsDevice.DrawUserPrimitives&lt;VertexPositionColor&gt;( PrimitiveType.TriangleList, box.Vertices, 0, box.Vertices.Length / 3 );

    pass.End();
}
ambientEffect.End();
</pre>
<p>Okay, hang in there. We're almost to the end. This is the final bit of code we need to add to our application to draw with shaders. Put this block of code directly after the global-variable-setting code from above. Just an FYI, I'm going to skip the draw stuff in the middle since I've assumed all along you know how to draw things in XNA. Our first line when drawing with shaders is always calling Begin() on the effect. This tells it that you're about to use it for rendering. Next, you create a For loop to iterate through each pass in the shader. Remember in the introduction how I mentioned shaders could have several passes? In this case though we only have one, but put the For loop there anyway just for the sake of it in case I want to add more passes to my shader later. Inside of that For loop, we call Begin() on the pass, draw our stuff, then call End() on the pass to tell it we finished drawing. It loops through the rest of the passes until it's completely done. Finally, you call End() on the effect to tell it we're rendering with it. There! Run your application and you should end up with something like the video below. I created a box in my example, so you should get a solid white (rotating) silhouette of whatever model you use.</p>
<p><strong>The (Almost) Beautiful Result</strong></p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="385" 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/xth0ukrfQKc?fs=1&amp;hl=en_US" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="480" height="385" src="http://www.youtube.com/v/xth0ukrfQKc?fs=1&amp;hl=en_US" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h2>Conclusion</h2>
<p>Well I hope my <em>little </em>(psh, far from it!)  article on ambient shaders helped you get a better grasp on shaders.  We've definitely covered a lot of material, way more than to be expected  for the most basic shader, but that's mainly because I spent the  majority of the time introducing how shaders work and how they are set  up. I know I've said this a million times already, but I'm going to say  it a million times more: The basics covered in this article are  necessary to understand more advanced shaders in the future. Also, in  the next tutorials I'm now going to assume you have this stuff down pat,  so I will focus much more on the actual code inside the vertex and  pixel shader, what it's doing and why it's there, not the shader  "etiquette" and structure. Once again, if you have <em>any </em>questions  at all, feel free to drop me a line at <strong>dan@digitseven.com</strong>. Also,  I've probably made a few mistakes as I went along too, so if you come  across something that doesn't match up I'd like to know so I can fix it. And be sure to head over to the home page and <a href="http://digitseven.com/default.aspx">sign up for the newsletter</a> to stay updated when new tutorials and code are released.</p>
<p>Download the XNA Project: <a href="http://digitseven.com/Documents/AmbientLight.zip">Ambient Lighting</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-ambient-lighting/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Article: Shaders &#8211; Introduction</title>
		<link>http://www.sgtconker.com/2010/09/article-shaders-introduction/</link>
		<comments>http://www.sgtconker.com/2010/09/article-shaders-introduction/#comments</comments>
		<pubDate>Sun, 19 Sep 2010 21:26:16 +0000</pubDate>
		<dc:creator>Absolutely Fine Tutorial Contest</dc:creator>
				<category><![CDATA[2010 Contest Entries]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[Shaders]]></category>
		<category><![CDATA[XNA]]></category>
		<category><![CDATA[Absolutely Fine Tutorial Contest]]></category>
		<category><![CDATA[HLSL]]></category>

		<guid isPermaLink="false">http://www.sgtconker.com/?p=1771</guid>
		<description><![CDATA[by Daniel Greenheck
Introducing the Introduction
I'm not an expert on High Level Shader Language (HLSL) by any means, and that's probably a good thing for those of you who don't know much about it either. When I first started programming shaders, I had a hard time finding anything that could really explain it at a level [...]]]></description>
			<content:encoded><![CDATA[<h4 style="text-align: center;">by <a href="http://digitseven.com">Daniel Greenheck</a></h4>
<h2>Introducing the Introduction</h2>
<p>I'm not an expert on High Level Shader Language (HLSL) by any means, and that's probably a good thing for those of you who don't know much about it either. When I first started programming shaders, I had a hard time finding anything that could really explain it at a level that I could understand. This introduction isn't going to go into the graphics pipeline at all, you'll have to search elsewhere for that level of detail. Instead, I'm going to go into the very basics of a shading program and give you an idea of how everything fits together in the bigger picture.</p>
<h2>What is a shader?</h2>
<p>Shaders are simply a means of manipulating data in some way to get a desired result. They operate on two types of data: vertices and pixels. There are two types of shaders dedicated to each: vertex and pixel shaders. Vertex shaders modify vertex positions and other data at the vertex level. Pixel shaders take data between the vertices by interpolating the values between each pixel. The final result is the color of that pixel. Shaders are powerful because you can tell them exactly how you want to manipulate each vertex and each pixel. With all that power comes a lot of complexity, so I'm going to try to break it down a bit so the task doesn't look so daunting. I was afraid of shaders for a while, but eventually I embraced them because they really are quite elegant and beautiful once you get your head around them.</p>
<p><span id="more-1771"></span></p>
<h2>.FX Files</h2>
<p>Pronounced "effects" files, you store you shaders inside of these files which get loaded inside of your program. In your XNA code, you'll specify which shaders from the file you want to use by specifying a technique, which will be explained later. Usually you'll have several effect fiels in your project since you'll be using many different types of shaders for different scenarios.</p>
<h2>Shader Format</h2>
<p>Here's an example structure of a shader file:</p>
<pre class="brush: plain; title: ;">
float var1;      // Variable Declaration
   float var2;
   ...

   struct VSInput   // Structure defining what data your vertex shader needs passed into it
   {
   };
   struct VSOutput  // Structure defining what data you vertex shader outputs to the pixel shader.
   {
   };

   // The vertex shader
   VSOutput VertexShader( VSInput inputData )
   {
   }
   // The pixel shader
   float4 PixelShader( VSOutput inputData )
   {
   }

   // The technique gives you a way of selecting which shaders you want to use and in
   // what combination in case you have more in one file. This technique will expand
   // to include several different passes referencing different vertex and pixel shaders
   // when you get into more advanced shaders.
   technique Diffuse
   {
      pass Pass0
      {
         VertexShader = compile vs_1_1 VertexShader();
         PixelShader = compile ps_1_1 PixelShader();
      }
   }
</pre>
<p>Now most of that may seem like complete jibberish to you, but don't worry, I'll start explaining it piece by piece.</p>
<h2>Variable Declaration</h2>
<p>Just like in a regular XNA or C# program, this is where you are going to declare any global variables used by the shader- things like light direction, world, view and projection matrices, light colors, and any other variables your shader might need. These global variables are especially important because these also act as parameters that can be accessed from XNA or C#, acting as a bridge for you to pass data over from XNA into the shader. You call the effect.Parameters.SetValue() to set the value of a global variable. <a href="http://msdn.microsoft.com/en-us/library/bb509587%28VS.85%29.aspx">Here's a list of all the different intrinsic variable types you can use for your global variables.</a></p>
<h2>Vertex Shader Input and Output Structs</h2>
<p>These were probably the most confusing parts of the shader (for me anyway!), even though they are really extremely simple and intuitive. These structures define what data needs to be passed IN to the vertex shader (VSInput) and what data needs to be passed OUT of the vertex shader (VSOutput) and in to the pixel shader. You'll end up seeing variables such as <em>Position, Color, Texture Coordinat</em>es, listed inside of these structures etc. Look at examples of shaders to see what kind of information is passed between the program and the vertex and pixel shader. The problem I had in understanding these structures is that NOWHERE in my program did I ever actually manually pass in something like that. The magic mystery part is that it's all done under the hood. When you call your Draw() method, it automatically passes in your vertex data and stuffs it into the VSInput (that name is arbitrary by the way) structure. Just think of it as a way of consolidating all of your arguments for your vertex shader. A vertex shader is just a method, and the structure which defines the vertex shader input arguments in one neat little package. If you look at the argument for the vertex shader, you can see it takes in the VSInput structure. Heck, you could even forget about using structures if you wanted to and list each argument separately. That is a little messier though and not really recommended. Okay, moving on.</p>
<h2>Vertex Shader</h2>
<p>The vertex shader is just a method that handles all the manipulation of your vertices. This method is run inside of your graphics card, however, making it blazingly fast. Here you will handle transformations of your vertices into world space (if you don't know what that is, don't worry! It will be covered in the ambient lighting tutorial), calculate the amount of light that hits the vertex, manipulate the texture coordinates. You then take whatever information you calculated, store it in your VSOutput struct, and return it (Notice the return type for the VertexShader is VSOutput. Just like a method in C# or XNA!). That data will be used further down the pipeline in your pixel shader. Don't worry about telling it where to go though, your graphics card handles all of that.<br />
The powerful thing about vertex shaders is that you can really do whatever you want to a vertex. You could add in code that would make the vertex color lighter if it's Y value was higher. You could also even simulate an ocean wave by keeping track of a time variable and using sine functions (that will be a tutorial in the future by the way!). The shader language is very powerful, so use your imagination! After you get some practice under your belt, you'll be able to program whatever you can dream up (until the math makes your brain implode)!</p>
<h2>Pixel Shader</h2>
<p>The pixel shader is a method that handles manipulations of the color of an individual teeny tiny pixel. Based on the information stored in the global variables and the information your vertex shader output, you can do some pretty advanced calculations on each pixel. Just like vertex shaders, under the hood of your beasty graphics card, it runs the pixel shader for each pixel. You're probably confused because you're wondering where it gets the position and other information from. We never specify the position of a pixel in our program or any properties of it! True, but we do for our vertices; models are defined by their set of vertices. So how do you find out the information for a pixel between several vertices? A little thing called interpolation. The pixel shader is pretty smart and knows exactly where the pixel is, how to calculate which way it's facing and all sorts of fun stuff. Once your pixel shader finishes its calculations, it returns a single float4, which stores the alpha, red, green and blue components of the pixel (ARGB). Just think, all this work just to calculate a stinkin' color!</p>
<h2>Techniques and Passes</h2>
<p>A technique is just a simple way of XNA asking "use only these shaders. please" when it draws something. In a technique, you get to define exactly which shaders to use, when to use them, how to layer them on top of eachother, etc. Yes, you heard me right, you can use multiple shaders in one draw call. This is done through the use of passes. A technique is made of several passes. Each pass consists of a vertex shader and a pixel shader. But setting up several passes in a certain order, you can combine a bunch of shaders to create really complex effects. We won't be doing anything along those lines for a while, so you can wipe the sweat of you brow!.</p>
<h2>Vertex Shaders vs. Pixel Shaders</h2>
<p>For several years, there's been an underground battle between vertex and pixel shaders, but the pixel shaders are quickly gaining the higher ground. What the hell am I talking about? It's best explained by a picture, which I have right below here.</p>
<p><img src="http://digitseven.com/images/pixelvsvertex.bmp" alt="" width="578" height="258" /></p>
<p>Now before you get worried about knowing what exactly that picture is, I'm going to tell you not to worry. On the left, we are lighting up a sphere using "per-pixel" lighting. On the right, we have an example of "per-vertex" lighting. Both are pretty intuitive concepts: in the former, the lighting calculations are done on the pixel shader, the later on the vertex shader. As you can see, the pixel shader example looks much better than the vertex shader. This is because for each pixel, we're using it's interpolated position and normal data. Although usually more performance-intensive, most graphics cards these days have plenty of power to handle it. On a vertex shader, it can only determine the color of each vertex. It doesn't know what the colors look like between the vertices, so it just guess. And as anyone can tell you, the right answer is always better than the guessed answer. So if you want smooth lighting, put your calculations on the pixel shader. If your graphics card is just hanging on by a thread, put the lighting calculations in the vertex shader. That might be easier said than done, but don't get too worried; you'll get a hang of this stuff as you make your way through my tutorials.</p>
<h2>The Flow of the Shaders...</h2>
<p>I've provided a "nice" *cough* little picture for you below that gives you an idea of how the whole shader thing works out.</p>
<p><img src="http://digitseven.com/images/shaderintro.bmp" alt="" width="495" height="239" /><br />
Image 1 - A crude step-by-step picture of what happens when you want to draw something.</p>
<p>1) You set all the global variables in your shader to whatever values you want. You'll have to pass in your World, View and Projection matrices to pretty much every single shader. You'll also be passing in colors, color intensities, light directions, light intensities, etc. etc.<br />
2) Here's where we dive under the hood of the graphics card and they hide everything from you. When you call DrawPrimitives() or Model.Draw(), it checks to see which technique you selected earlier. Once you're in that technique, it starts going through all of the passes. You can see in my XNA code on the left, I'm iterating through each pass in the current technique (I know this is a lot right now, but don't worry. The ambient lighting shader will give some concrete examples of all of this.) So now that you have a technique and you're on a certain pass...<br />
3) It calls the vertex shader method. In your pass, you specify which vertex shader you want it to use. Now when you call the vertex shader, you're probably asking "Where the heck is it getting the data that needs to be passed to the vertex shader?" That answer I don't exactly know to be honest. Since it's a little over my head, I just picture that when I make my Draw() call, the graphics card now has a theoretical filing cabinet with all of my vertex data. It starts from the top drawer, goes through the files one by one, passing each onto the vertex shader. Then it goes to the next drawer, goes through each file, etc. Once my filing cabinet has successfully been "Vertex-Shaderized" (fancy isn't it?)...<br />
4) It calls the pixel shader method, once again specified in your pass. After each pixel has run through the shader, you now have a single frame from your 3D application.</p>
<h2>Conclusion</h2>
<p>Well I hope my little introduction to shaders gave you a somewhat basic understanding of how things work and didn't just make you so frustrated that you've smashed your computer and completely given up the technological lifestyle. I didn't cover everything here, but I did that on purpose. There's a lot of technical aspects to shaders that I think are just best left as part of the learning curve, figuring them out as you go along. I hope to provide some those technical details as you travel along that curve. Anyway, if you have any questions at all, feel free to send me an email at dan@digitseven.com. And be sure to head over to the home page and <a href="http://digitseven.com/default.aspx">sign up for the newsletter</a> to stay updated when new tutorials and code are released. Good luck and happy programming!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.sgtconker.com/2010/09/article-shaders-introduction/feed/</wfw:commentRss>
		<slash:comments>3</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>
	</channel>
</rss>

