XNA Essentials

Game Programming for Xbox 360, PC + Windows Phone

NAVIGATION - SEARCH

XNA Game Studio 3.0 Unleashed book source code updated to work with MonoGame and Windows 10

 

image

 

XNA Game Studio 3.0 Unleashed Code updated to Run under Windows 10 (and HoloLens)

I’ve gone through the first pass of updating the code in the book. This took quite a bit of time. Some of the chapters are still a little wonky as I’ve ran out of time. But I wanted to get what I have done out into the public in case it was beneficial to anyone. I never really thought I’d update the code for the XNA Game Studio 3.0 Unleashed book. There were a lot of breaking changes between XNA 3.1 and XNA 4.0 and I just didn’t have the time to do it.

However, with my HoloLens being ordered, and hearing Tom Spilman on .NET Rocks last week (http://www.dotnetrocks.com/?show=1283), I decided to see what it would take to upgrade. It was surprisingly simple to get quite a few chapters converted and upgraded. Other chapters were just not attempted (like Networking stuff that isn’t directly in MonoGame [they expect you to use other libraries]). Others had to be commented out to work (like the GameServices stuff to bring up the Xbox Guide, etc.)

Still, the overall conversion project was a success. There a couple of rough edges, but now anyone can fork it and do what they'd like with it. Feel free to send a pull request, if you smooth out a rough edge. Try to keep with the original intent with the code as much as possible.

Go ahead and grab the code from GitHub:

https://github.com/kewlniss/XNAUnleashed

The Table of Contents for the book this code goes with can be found at http://xnaessentials.com/unleashed

Will there be an XNA Game Studio 4.0 Unleashed book?

I just got back from the SIEGE conference.  Actually, the conference is still going strong, and the first official day of the conference is today, Friday, October 5, 2012.  However, SIEGE put on a Windows 8 Hackathon sponsored by Microsoft.

I was asked to speak at this Hackathon and work with Glen Gordon to provide training for Windows 8 and work with folks who wanted to participate in creating a game in a 28 hour period.  It was a good time.

While I was at the event, I received an email thanking me for the content on the site and asked if I was going to update the book or if they should just use the 3.0 book to learn some of the topics discussed like HLSL.  This post is an answer to that email.

 

At this point there are no plans to update the XNA book.  The majority of the content is still appropriate but there were major breaking changes in the API between XNA 3.0 to XNA 4.0.

http://blogs.msdn.com/b/shawnhar/archive/2010/03/16/breaking-changes-in-xna-game-studio-4-0.aspx

The code in the book used Visual Studio 2008, but XNA 4 requires Visual Studio 2010.  Visual Studio 2012 is currently available but it doesn’t support XNA 4.0.

There was a workshop that was started a while back and it went through the first few chapters of the book.  This can be found at:

http://www.gamedev.net/topic/592661-xna-40-winter-workshop-introduction/

Since then, the source for the book itself has been released as open source.

There is a very helpful cheat sheet available to help upgrading from 3.0 to 4.0:

http://nelxon.com/resources/xna-3-1-to-xna-4-0-cheatsheet.php

So, if you are still just learning XNA and want to use the book, I'd actually suggest starting out with Visual Studio 2008 and working through the book just as it is.  Then once you are done, you can go through the process of upgrading the bits you are most interested in by using Visual Studio 2010 and XNA 4.  That route will provide the least amount of headache, but does take the extra step at the end.

However, if you have some things under your belt and don't mind redoing the code as you go along by using the cheat sheet, then you can just get Visual Studio 2010 and the source code and work through the cheat sheet.

My original plan was to update the book when XNA 5 would be released, but it doesn't appear that a new version will be released.  There are no plans to create a XNA Game Studio 4.0 Unleashed book.

 

I’ve been spending my time creating a book to teach app and game development for Windows 8.  For folks that want to use XNA in Windows 8, make sure to check out MonoGame.

 

Happy Coding!

-Chad

XNA Game Studio 3.0 Unleashed Source Code Released as Open Source

I’m pleased to announce that the XNA Game Studio 3.0 Unleashed book’s source code has been released under the Ms-PL license on CodePlex.

So you can use Git and create a clone locally to start working with it or you can fork it and update it for XNA 4.0.

Have fun with it!

-Chad

Creating a Selection Wheel in XNA

This tutorial will describe the process where you create a selection wheel to be used with a Gamepad controller.  This will allow you to create conversation wheels, power wheels, weapon wheels, command wheels, etc in your games.

Note this demo requires a Gamepad, so you will either need to have one hooked up to Windows or run this on the Xbox 360 (which requires an AppHub membership).

Games such as Mass Effect, Assassins Creed and Dragon Age all use selection wheels. I thought it was extremely clever the first time I saw it used in a game and I definitely enjoy games that utilize it.

Here is an example of a selection wheel inside of BioWare’s Dragon Age: Origins:

image

The wheel is populated with all of the valid choices but items that can’t be selected are dimmed.  From this wheel the player can select items which can either select that item or bring up new selections in the wheel.  For example, if the user selected the health item at the bottom (assuming it was enabled because the character was in combat) then it would immediately apply the health potion to the character and the wheel would disappear.  However, if the user selected the Potions selection on the left the items in the wheel would be replaced by the available potions the user had.  For Dragon Age, the gamer brings up this wheel by holding down the Left Trigger.

Here is an example of a command wheel in BioWare’s  Mass Effect:

image

 

This is a wheel that has a lot more options but the premise is the same.  Move the Gamepad controller around the edges to select the item.  In this case there is no “drill down” option and any selection is a final selection and the wheel closes. The gamer brings up this wheel by hitting the Right Bumper (RB) button.

If the user presses the Left Bumper (LB) button then Mass Effect’s weapon wheel is brought up:

image

Another example is one from Ubisoft’s Assassin’s Creed.  The example I’m showing here is from Assassin’s Creed 2:

image

When an item isn’t available, they just hide that item from the wheel altogether (instead of showing a disabled icon).  This also simply selects what is desired and closes the wheel.

The final examples I will show are the conversation wheels from BioWare’s Dragon Age 2 and Mass Effect:

imageimage

In these images only three items on the right are available.  When more conversation items are available they will show up on the left.  The point here is that you can utilize the same input mechanics in a wide variety of games.  I’ll attempt to explain how you can do so.

Let’s get to it already!

The example code I’ll be showing today doesn’t take into consideration any selection / disabled / non-visible items but it would be pretty easy to add that in.  Instead it focuses on the code to map the Left Thumb Stick’s X and Y coordinates to the selection wheel.  It will show how to convert the X and Y values from the thumbstick to an angle and then utilize that angle to point to the different items in our wheel.  The current item that is pointed to will be displayed beside the wheel. 

To start out I create the actual wheel in Paint.NET. 

image

And this is why I am a software engineer and not a graphic designer.

The download at the bottom includes the actual wheel.pdn (Paint .NET file) with the different layers.  The actual content project will use two different files created from this original artwork.  The first is the selection wheel itself (selection.png).  The second is the arrow (selector.png).

imageimage

Note for the blog, these have white backgrounds but in the download they are transparent. So make sure you grab the files from there and not by saving these images.

After creating the artwork I then started on the code (which was much easier I must say).  A real artist would have had no problem lining up the inner circle to the outer circle but I struggled and still am not confident it is perfectly centered. Ah to really know the tools you use is beneficial and I don’t know any image editing software very well.

So create a new Windows or Xbox 360 Game project in Visual Studio.  I called mine SelectionWheel.  Inside of the Content Project (i.e. SelectionWheelContent) add the artwork selection.png and selector.png.  Also add in a new SpriteFont called font.  (Right click on SelectionWheelContent and select Add New Item then select Sprite Font from the list. and change the name from spritefont1 to font)

Open up the font xml file (font.spritefont) and change the size to 32.  That is all of the content we need for this tutorial.

Now open up the Game1.cs file and add the following member fields to the class:

Texture2D selection;
Texture2D selector;
SpriteFont font;

Now we are going to add the integer values we will be selecting on the wheel. Add the following constants to the class:

const int ROUNDED = 0; //start with the selection on the right first 
const int ELIPSE = 1; //work your way counter-clockwise 
const int SQUARE = 2;
const int STAR = 3;
const int INFINITY = 4;
const int ABSTRACT = 5;
const int PLUS = 6;
const int CLOUD = 7;

We could modify this to have more items on the wheel.  Currently this is only 8 items for the main 8 directions of the thumbstick but we could add several more items and modify the math we will see a little later to accommodate the additional items. Notice how we start numbering them with the item on the right first.  The math involved starts with angle value of 0 on right. As you move counter-clockwise (moving up and to the left the radians / angle increases).  We will talk more about this a little later.

Next we need to create a member field to store the list of selections.  In this case we are just storing strings of the selection, but this could be any kind of object you desire. We will also add in a variable to store our radians and index of our selection.

Dictionary<int, string> selections = new Dictionary<int, string>();
float radians = 0;
int index;

Let’s initialize those selections by adding a new method InitializeSelections that we will call from the Initialize method in the game class:

void InitializeSelections()
{
    selections = new Dictionary<int, string>();
    selections.Add(ROUNDED, "ROUNDED");
    selections.Add(ELIPSE, "ELIPSE");
    selections.Add(SQUARE, "SQUARE");
    selections.Add(STAR, "STAR");
    selections.Add(INFINITY, "INFINITY");
    selections.Add(ABSTRACT, "ABSTRACT");
    selections.Add(PLUS, "PLUS");
    selections.Add(CLOUD, "CLOUD");

    index = 0; // default to selecting the value on the right (ROUNDED)
}

Inside of our Game1 constructor we can set the preferred backbuffer width and height if we want.  My setup supports 1920x1080 so that is what I’m setting.  The XNA Framework will select the highest resolution supported by the output device if the resolution asked for isn’t supported.

//Will be scaled down if not supported
graphics.PreferredBackBufferWidth = 1920;
graphics.PreferredBackBufferHeight = 1080;

graphics.ApplyChanges();

Next we can actually load the content we created by adding the following code in the LoadContent method:

selection = Content.Load<Texture2D>("selection");
selector = Content.Load<Texture2D>("selector");

font = Content.Load<SpriteFont>("font");

We will save the Update method for the last since that is where the bulk of our work will be done.  For now, let’s add the following code to our Draw method which will draw the actual selection wheel,

spriteBatch.Begin();
spriteBatch.DrawString(font, selections[index], new Vector2(530, 0), Color.Red);
spriteBatch.Draw(selection, new Rectangle(0, 0, 512, 512), Color.White);
spriteBatch.Draw(selector, new Rectangle(256, 256, 512, 512), null, Color.White,
                        -radians, new Vector2(256,256), SpriteEffects.None, 0);
spriteBatch.End();

The selection is being drawn based on the current index selected (initialized to 0).  The selection wheel is drawn and the selector is drawn right on top of it. The selector is being rotated by the negative radians amount.  The radians value will be populated in the Update method next.  It is being drawn offset so it will be in the center of the selection wheel and the origin of the selector was set to half of the texture size (256,256) so it would rotate around the middle. The selector image could be trimmed and these values modified to save some room but for this example I wanted to keep it clear as to how it is working.

Now we get to the real part of the tutorial.  Here comes the big complicated math to make this work.  It really isn’t complicated or I wouldn’t be able to do it – so don’t worry!

Inside of the Update method let’s grab the state of our Gamepad:

GamePadState gp = GamePad.GetState(PlayerIndex.One);

// Allows the game to exit
if (gp.Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
    this.Exit();

The above code should replace the existing GamePad.GetState condition in the Update method.

Next we need to calculate the index we are currently pointing to so the arrow.  In order to determine the index we first need to convert our Thumbstick’s X and Y values (which go from -1.0 to 1.0) to an angle value in radians.  Let’s start off calculating the radian value and then work our way up to determining the index.

//Get radians from thumbstick
if (gp.ThumbSticks.Left.Y != 0 || gp.ThumbSticks.Left.X != 0)
    radians = (float)(Math.Atan2(gp.ThumbSticks.Left.Y, gp.ThumbSticks.Left.X));

First, we only want to change our radians value if the thumstick is off center.  If it is centered, but the X and Y values will return 0.  Assuming the stick is actually being pushed in a particular direction we want to determine the angle.  The MathHelper.Atan2 method is extremely helpful.  This is why I love the XNA Framework. There is no need to write code for the trigonometry behind this calculation we can simply use it.  A good explanation of the Atan2 function can be found in the AppHub’s educational catalog.  The Aiming example has a TurnToFace method which actually includes a diagram in source code :)  The help for the Atan2 method is also helpful: http://msdn.microsoft.com/en-us/library/system.math.atan2.aspx

At this point we have our angle value (in radians).  You can totally just work with radians but most people (myself included) find it easier to work in degrees.  As a bonus, I’ll show how to work with radians at the end.  For now, to get the angle in degrees we need to add the following code to our Update method:

//convert to angle from radians to degrees
float degrees = radians * 180.0f / (float)Math.PI;

//changes -90 to 270
if (degrees < 0) //Atan2 returns negative for quadrant 3 and 4 
    degrees += 360; //so make it positive by adding 360 to it (get values 270-360); 

To convert from radians to degrees we only need to multiply the radians value by 180 and then divide that by Pi (~3.14).  Atan2 returns negative values for quadrant 3 and 4. So basically 181-359 degrees comes out as -180 to -1. (Atan2 returns values from -Pi to Pi to give you a full circle basically  -180 to 0 to 180 instead of 0 to 360).

We check to see if our degrees value is less than 0 and if so we add 360 to it.  This converts -179.99 to 180.01 and  -90 to 270 and -0.01 to 359.99. So we get a full 0 to 359.999 degrees in our circle.

Now that we have a value in degrees we need to convert that to an index so we can determine which value in our list of selections is actually selected.  The selection item is simply a string but it could be desired to store another type of object complete with its own properties and methods. This object could contain a flag as to if it was enabled and/or visible. It could contain an image that would be displayed on the wheel instead of a static wheel like we currently have. For now, we are keeping the tutorial simple and are just storing a string value.

Assuming our indices match up to our selections we can add the following code to our Update method:

index = (int)((degrees + 22.5f) / 45);

So there are two things happening here.  The first is we are dividing by 45 degrees.  This is because we have 8 items in our wheel.  8 goes into 360 45 times.  So each item takes up 45 degrees of the wheel.  This is all we would need if the selection of the first item (on the right) started at position 0.  However, position 0 is right in the middle of the first selection (ROUNDED in our case).  So in order to offset our angle we are adding an offset of 22.5 degrees before dividing by our 45 degrees.  22.5 is half of 45.  Since 0 splits the ROUNDED item in half, we want half. 

We could make this a little more dynamic if we wanted to.  Let’s say we had 12 items in our list instead of 8.  Assuming we added the constants and the new strings to our list and updated our image as well we could have the following code:

float itemDegree = 360.0f/selections.Count;
float offset = itemDegree / 2.0f;
index = (int)((degrees + offset) / itemDegree);

So we determine how many degrees an item takes up (itemDegree) by dividing 360 by the number of selections we have (8, 12, etc). We then determine the offset (assuming we always start with index 0 is on the right) by dividing the number of degrees and item takes up (itemDegree) in half.  We then plug in the itemDegree and offset into the same formula above where we hard coded the values.  So this would be beneficial if you are reusing the selection wheel in your code for let’s say a weapon wheel and a conversation wheel.  You could pass in your weapons values or your conversations values and the code will figure out which index should be selected.

There is one more thing we need to do to determine our index.  Since we added that offset value to our index we can get an invalid index value of 8 once we hit 337.5 (360-22.5) degrees or higher.  So we need to roll over our index back to 0 since we are on the bottom part of our first selection item (ROUNDED).  Add this to the Update method:

if (index == selections.Count)
    index = 0; //since we are adding in 22.5, we will go over, so reset it

Should you not like using a condition you can do a bit AND to accomplish the same task.  It is a little less readable but it isn’t too bad:

index = (int)((degrees + 22.5f) / 45) & (selections.Count -1 );

This does a bit AND of 7 (we have 8 selections) so this will return 0 to 7 which is what we are after.

image

When you run the game you should be able to select any point on the wheel with the gamepad and have the text update as you move the thumbstick.

Degrees are for wimps, I only use Radians!

If for some reason you enjoy working with radians and converting to degrees seems wrong to you then you could use the following:

index2 = (int)((radians + MathHelper.TwoPi + (0.3926990816987241f)) / MathHelper.PiOver4) 
                                                                & (selections.Count - 1);

I just used the same formula we used for degrees but instead of adding 360 I added TwoPi.  This is ok since at the end I bit AND the value by my selection count - 1.  So it handles overflows just fine. MathHelper.PiOver4 (Pi/4) is 45 degrees.  The obnoxious number of ~0.392 is the offset of PiOver4 / 2.

By the way, if converting radians to degrees is wrong, then I don’t want to be right. This is one of those micro optimizations that most likely isn’t worth it and you shouldn’t sacrifice readability unless you have an extreme situation.

Wrap Up

So grab the code and toy around with it.  Some things to try:

  1. Embed this code inside a condition that checks if the Left Trigger or Left Bumper being pressed.
  2. Add in the actual selection code of what happens when the user presses A.
  3. Use actual objects and add an Enabled flag to determine if you want the user to be able to select that value. Either keep the arrow from moving to those locations and hide the selections or just dim them and don’t let the user select them.
  4. Have fun with it!

Download the Source Code and Assets

Happy Coding!

-Chad

Windows Phone 7 Developer Sweepstakes end June 30th, 2011

If you are almost done with your Windows Phone 7 App or Game, you may want to put a little extra effort into finishing it up and get it certified so you can beat the deadline.

Microsoft’s fiscal year ends June 30th and so do this promotion:

Use Code: 5DXDN

URL: http://bit.ly/WP7DevOffer

If you have 1 app in the marketplace you can win a Samsung Focus. (Details & Rules on the site)

If you have 2 apps in the marketplace you get a refund on your Marketplace account fee.

Register on this site for that: http://phone.microsoftplatformready.com/Offers.aspx

If you have 5 or more apps you can get Free Advertising for one of your apps!

Enter in the WP7 Sweepstakes (Code: 5DXDN; URL: http://bit.ly/WP7DevOffer

If you publish(ed) 5 new apps between April 1 and June 30 you get FREE advertising for one of those apps or games.

So if you are almost done – push through and get it done!

Happy Coding!

Shake that Camera

I was browsing the educational catalog on the App Hub and I saw something that I had missed previously.  I wanted to point it out and also point out that if you haven’t been to the educational catalog section in a while, you should go browse it for some nice examples.

The little demo I saw was one that shakes the camera.  It also vibrates the controller (or the Phone).  It was pretty easy to take the important pieces of code and modify the Camera object I used in the XELibrary (the library the book uses).

 

Inside the Update method of the game class (i.e. Game1 inside of Game1.cs) you can add the following code:

if ((input.ButtonHandler.WasButtonPressed((int)PlayerIndex.One, Buttons.A) || (input.KeyboardState.WasKeyPressed(Keys.Space))))
{
    camera.Shake(25f, 2f);
}

 

Next, we need to actually create that method (Shake) on the camera.  Since we would want to use this on the FirstPersonCamera and the static Camera we will apply it to the base class Camera.  Add the following variables to Camera.cs:

// We only need one Random object no matter how many Cameras we have
private static readonly Random random = new Random();
 
// Are we shaking?
private bool shaking;
 
// The maximum magnitude of our shake offset
private float shakeMagnitude;
 
// The total duration of the current shake
private float shakeDuration;
 
// A timer that determines how far into our shake we are
private float shakeTimer;
 
// The shake offset vector
private Vector3 shakeOffset;

 

Next, add the following two methods to the Camera.cs file:

/// <summary>
/// Helper to generate a random float in the range of [-1, 1].
/// </summary>
private float NextFloat()
{
    return (float)random.NextDouble() * 2f - 1f;
}
 
/// <summary>
/// Shakes the camera with a specific magnitude and duration.
/// </summary>
/// <param name="magnitude">The largest magnitude to apply to the shake.</param>
/// <param name="duration">The length of time (in seconds) for which the shake should occur.</param>
public void Shake(float magnitude, float duration)
{
    // We're now shaking
    shaking = true;
 
    // Store our magnitude and duration
    shakeMagnitude = magnitude;
    shakeDuration = duration;
 
    // Reset our timer
    shakeTimer = 0f;
}

The first method is just a helper method we need soon.  The second method is the public Shake method on our camera that initializes the values so we can begin shaking the camera’s view.

Finally, in the Update method of Camera.cs add replace the following code at the bottom of the method:

Matrix.CreateLookAt(ref cameraPosition, ref cameraTarget, ref cameraUpVector,
   out view);

With the following code:

// If we're shaking...
if (shaking)
{
   // Move our timer ahead based on the elapsed time
   shakeTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
 
   // If we're at the max duration, we're not going to be shaking anymore
   if (shakeTimer >= shakeDuration)
   {
       shaking = false;
       shakeTimer = shakeDuration;
   }
 
   // Compute our progress in a [0, 1] range
   float progress = shakeTimer / shakeDuration;
 
   // Compute our magnitude based on our maximum value and our progress. This causes
   // the shake to reduce in magnitude as time moves on, giving us a smooth transition
   // back to being stationary. We use progress * progress to have a non-linear fall 
   // off of our magnitude. We could switch that with just progress if we want a linear 
   // fall off.
   float magnitude = shakeMagnitude * (1f - (progress * progress));
 
   // Generate a new offset vector with three random values and our magnitude
   shakeOffset = new Vector3(NextFloat(), NextFloat(), NextFloat()) * magnitude;
 
   // If we're shaking, add our offset to our position and target
   cameraPosition += shakeOffset;
   cameraTarget += shakeOffset;
}
 
Matrix.CreateLookAt(ref cameraPosition, ref cameraTarget, ref cameraUpVector,
   out view);

 

So whe the main game class calls camera.Shake, the flag shaking becomes true and the shaeMagnitude, shakeDuration and shakeTimer are set.  This way when the camera game component has its Update method called, it sees that it needs to shake the camera and adds the game’s total seconds to the shakeTimer and if it has already been shaking too long it sets it to false and resets the shakeTimer.  Assuming it hasn’t been shaking long enough (or even started)  it computes the progress and determines the magnitude of the shaking from that value.  It then uses that magnitude to create an offset with some randomness.  The cameraPosition and cameraTarget then has the offset added to it.  This is what makes the camera shake.  When the view is calculated again it has new values for the camera position and target.

So just a little bit of code allows us to create a cool shaking effect in our games.  Nice.

Happy Coding!

-Chad

Columbia Enterprise Developers Guild talk on HLSL

On March 9th I was able to give a talk down in Columbia, SC at the Columbia Enterprise Developers Guild.  We discussed XNA in general and showed a couple of demos and then dove in and talked about vertex and pixel shaders.  We also discussed how pixel shaders could be used in Silverlight and WPF applications.  We talked briefly about the built in effects in XNA Game Studio 4.0.  AppHub has a great demo on those built-in effects.

Feel free to download the presentation slides from the event.

Windows Phone 7 Hands On Lab–Tombstoning

At my local .NET User Group, Triad Developers Guild, I was able to give a talk on WP7.  Usually the sessions are lecture style, but I tried to do a hands on lab.  Unfortunately, not many folks brought their laptops so for some it was still basically a lecture style session with me doing the lab in front of everyone.  The labs are very good, I’d encourage you to download them and go through them.  The lab we did on Tuesday, February 15th was the Tombstoning, Launcher and Chooser, and then some with XNA Framework.

You can download lab here:

http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&FamilyID=ca23285f-bab8-47fa-b364-11553e076a9a

The files are as follows:

WP7TrainingKitOffline_RTM1.Setup.exe is the full download (both Silverlight and XNA)

WP7SLTrainingKitOffline_RTM.Setup.exe is only the Silverlight labs

WP7XNATrainingKitOffline_RTM.Setup.exe is only the XNA labs

 

Also, Microsoft is running a contest and if you use the following code when you submit your app or game to the Marketplace you could win a Windows Phone 7!

Use code: 5DXDN

Check out http://www.WindowsPhone7Event.com/contest/ for more information!

Happy Programming!

-Chad

Using the Built In Dual Texture Effect in Game Studio 4.0

Since XNA Game Studio Express 1.0 (later the Express was removed from the name) we have had the built-in BasicEffect.  This has allowed developers to create games without actually needing to learn HLSL.  HLSL is awesome, so I’d highly encourage you to learn it.  It is not only beneficial in XNA but also in Silverlight and WPF.  Regardless, if someone is just getting started learning HLSL can slow down the process of getting something on the screen.  Microsoft decided to create the BasicEffect to handle scenarios where creating custom shaders in HLSL is not needed or maybe just not wanted to begin with.

In XNA Game Studio 4.0 Microsoft has added new built in effects.  Currently, Windows Phone 7 does not provide support for custom shaders.  The team found that many scenarios can be handled with the built in effects they built.  They are: BasicEffect, DualTextureEffect, AlphaTestEffect, EnvironmentMapEffect, SkinnedEffect.

This post will discuss the DualTextureEffect.  BasicEffect allows you to use a single texture.  As expected the DualTextureEffect allows you to use two.  It allows you to blend 2 textures together.  A typical purpose for using this texture is to use Light Maps.  The idea behind light maps is to basically figure out your lighting at build time and store those to a texture.  Then apply that light texture to the scene to make it look like you have complex lighting even though none exists.

To actually use the effect is very straightforward.  Simply instantiate the effect and set the camera up normally, set the Texture and Texture2 properties on the effect and apply the effect to the model.  Texture will most likely be your color map (colored texture for your model) and Texture2 will most likely be your light map.  If your second texture was all black, then the resulting image that will be applied to the model will be all black.  If the second texture is all white, then it will use the color as it exists from the other texture.  Any other color will blend – 50% gray will have the color unchanged, >  50% gray and the color becomes brighter, < 50% gray and the color becomes darker.  Shawn Hargreaves has a great article on this topic.

To see Microsoft’s HLSL code in how they created these effects, take a look at the stock effects sample:

http://create.msdn.com/en-US/education/catalog/sample/stock_effects

Running a Game in Full Screen in Windows Phone 7

If you create a game in Windows Phone 7 using XNA you may not want the Application Bar to be displayed.  You can hide that status bar in Windows Phone 7 by setting the GraphicsDeviceManager.IsFullScreen property to true.  The default is false.

public Game1() 
{ 
   graphics = new GraphicsDeviceManager(this); 
   graphics.IsFullScreen = true;