This guide explains necessary code changes to run
the Microsoft XNA Game Studio Creator’s Guide code in XNA 2.0. Since this book was released when XNA Refresh
1.0 was available, some of the code stopped working under the XNA 2.0 release.
Microsoft anticipated that people like us would be affected and provided an upgrade wizard here:
The upgrade wizard that does a pretty good job of
porting your XNA 1.0 refresh projects to XNA 2.0. The upgrade wizard does not change your
code. Instead, it switches the
assemblies used by your project to make it possible to run your XNA 1.0
solution in 2.0 framework. Unfortunately
though, some code changes may still be required for each project to run after
using the upgrade wizard. Once you have
a close look at the code changes needed though I think you will agree they are
fairly minimal. This article explains
which code changes are required. Of
course, you can always download the migrated code at:
Microsoft XNA Game
Studio Creator’s Guide 2.0 Solutions
LoadGraphicsContent()
and UnloadGraphicsContent()
Adding
Content to the Project in the Solution Explorer
This
first section discusses code changes that are required in all projects. Thankfully, these modifications were simple
and the base code ran immediately without further changes after running the
migration wizard.
All Microsoft Game Studio Creator’s Guide projects were
affected by the changes made for loading and unloading media content such as
images, graphics, and audio.
The
LoadGraphicsContent() and
UnloadGraphicsContent() methods have been deprecated and since these
methods were used in the base code all solutions have been affected. Currently though, on the PC at least, the
LoadGraphicsContent() and UnloadGraphicsContent() methods can still be included
in your and you will only receive warnings when you compile your projects. The only changes you need to make to fix this
are to:
·
Move any instructions that load content from the
LoadGraphicsContent() method to Initialize() method so your media files are
still loaded when the application begins.
·
After moving your instructions to load your media content to
Initialize() delete the LoadGraphicsContent() method.
·
Delete the UnloadGraphicsContent() method.
Another
significant change is that the Audio, Shaders, Images, and Models folders must
now be listed under the content node.
The upgrade wizard actually does this for you by creating a copy of the
Audio, Images, Models, and Shaders folders under the Content node for you. However, it leaves the original folder
references as well. The project will
compile and run with two references to the same folders. However, you can remove the original
reference by right clicking each folder and choosing ‘Exclude from
project’. This will remove the reference
without deleting the folder and contents within. In the end, your Images, Audio, Models, and Shaders
will only appear under the Content node.
The figure below shows an Images, Models, and Shaders directories being
referenced only from the Content node in the migrated solution.

This
next section explains changes that are specific to each solution if any are
required after using the migration wizard.
It lists the chapters, methods, and instructions within each that are
affected along with required changes.
Users
are no longer given control over resource access through the ResourceUsage and
ResourceManagementMode classes.
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx device
typeof(short),
// set type to short
shrtIndexArray.Length, // int size in bytes
ResourceUsage.WriteOnly, // memory use
options
ResourceManagementMode.Automatic);
Becomes:
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx device
typeof(short), // set type to short
shrtIndexArray.Length, // short size in bytes
BufferUsage.WriteOnly );
Setting
the data in the index buffer has become easier.
mIB.SetData<short>( shrtIndexArray,
0, // element start
shrtIndexArray.Length, // element count
SetDataOptions.None); // options
Becomes:
mIB.SetData(shrtIndexArray);
// options
The
buffer used here to store the vertex data is not dynamic since it is only
loaded once and the same data is used each frame. Because of this the method init_dynamic_vb()
really should be init_static_vb().
Since
the ability to control how the vertex buffers are accessed using the
ResourceUsage and ResourceManagementMode properties have been disabled;
mVB = new
VertexBuffer(
gfx.GraphicsDevice, // gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS * NUM_ROWS, // element count
ResourceUsage.Dynamic | ResourceUsage.WriteOnly,
ResourceManagementMode.Manual); // memory use
Becomes:
mVB = new VertexBuffer(
gfx.GraphicsDevice, // gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS * NUM_ROWS,
// element count
BufferUsage.WriteOnly); // memory use
Setting
the data inside the buffer is easier now too.
You now only need to pass the array to the SetData() method and XNA can
figure out the length and other options for you.
mVB.SetData<VertexPositionColorTexture>
(mVertGrid, 0, mVertGrid.Length,
SetDataOptions.None);
Becomes:
mVB.SetData(mVertGrid);
XNA
2.0 has changed mechanism for tracking time between draws and updates which has
slightly altered the behavior of the GameTime class. As such, it is recommended that time be
tracked during the Update() event rather than the Draw() event. If you do this, the time between frames might
be so fast that the ElapsedGameTime property may register as a 0. This happens with the existing code which
maintains the timer during Update().
double dblMS = (double)gameTime.ElapsedRealTime.Milliseconds;
Becomes:
double dblMS = (double)gameTime.ElapsedGameTime.Milliseconds;
XNA
2.0 gives the ability to distinguish between a dynamic and static vertex
buffer. By default the vertex buffer is
static.
private VertexBuffer mVB; //
dynamic vertex storage
Becomes:
private DynamicVertexBuffer mVB;
Setting
the data in the vertex buffer is a lot easier.
XNA 2.0 can figure out the array start and length if you only pass in
the array object. However, you need to
release the buffer before resetting it.
mVB.SetData<VertexPositionColorTexture>(
mVertGrid, 0, mVertGrid.Length, SetDataOptions.None);
Becomes:
gfx.GraphicsDevice.Vertices[0].SetSource(null, 0, 0);
mVB.SetData(mVertGrid);
The texture in the stationary layer does not shift
across the texture. However, the Y
position of each indexed vertex rises and falls to create the wave effect. Because of this, the vertex buffer must be
reset.
XNA 2.0 makes it easier to reset the vertex buffer.
However, you must release the buffer before storing new data in it or the
surface height will not be updated.
mVB.SetData<VertexPositionColorTexture>(
mVertGrid, 0, mVertGrid.Length, SetDataOptions.None);
Becomes:
gfx.GraphicsDevice.Vertices[0].SetSource(null, 0, 0);
mVB.SetData(mVertGrid);
With XNA 2.0,
you no longer need to set the ResourceUsage and ResourceManagement properties
for specifying how to access the buffer.
Because of this;
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx device
typeof(short), // set type to short
shrtIndexArray.Length, // int size in bytes
ResourceUsage.WriteOnly, //
memory use options
ResourceManagementMode.Automatic);
Becomes:
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx
device
typeof(short), // set type to short
shrtIndexArray.Length, // short size in bytes
BufferUsage.WriteOnly);
Setting the
data in the index buffer is a lot easier.
All you need to do is pass in the index
buffer array and XNA 2.0 can figure out the
rest.
mIB.SetData<short>(
shrtIndexArray,
0, // element start
shrtIndexArray.Length, // element count
SetDataOptions.None); // options
Becomes:
mIB.SetData(shrtIndexArray);
With
XNA 2.0 the vertex buffer storage is set up slightly differently. Resource management is no longer necessary
for the buffer set up. It has been
replaced with BufferUsage to set up how the buffer is used.
mVB = new VertexBuffer(
gfx.GraphicsDevice,
//
gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS *
NUM_ROWS, // element
count
ResourceUsage.Dynamic | ResourceUsage.WriteOnly,
ResourceManagementMode.Manual);
//
memory use
Becomes:
// initialize dynamic vertex buffer that can be
updated at run time
mVB = new DynamicVertexBuffer(
gfx.GraphicsDevice, // gfx device
// create space for all elements
(NUM_COLS *
NUM_ROWS) * VertexPositionColorTexture.SizeInBytes,
// memory use
BufferUsage.WriteOnly | BufferUsage.Points );
Setting the data in the
vertex buffer is a lot easier.
mVB.SetData<VertexPositionColorTexture>
(mVertGrid,
0, mVertGrid.Length, SetDataOptions.None);
Becomes:
int size = VertexPositionColorTexture.SizeInBytes;
mVB.SetData(mVertGrid, 0, NUM_ROWS *
NUM_COLS);
Setting the data in the
vertex buffer only requires you to pass the vertex array.
mVB.SetData<VertexPositionColorTexture>
(mVertGrid, 0, mVertGrid.Length, SetDataOptions.None);
Becomes:
mVB.SetData(mVertGrid);
No changes are needed here.
However, since the GameTime behaviour has changed due to handling of
Update() and Draw() event, the texture sprite example had to be modified. For this sprite heads up display example the
time tracking is triggered from Update().
As a result, the following instruction inside the Timer() method can be
left as is:
double dblMS = (double)gameTime.ElapsedRealTime.Milliseconds;
With
the resource management requirements dropped from XNA 2.0;
mVB = new VertexBuffer(gfx.GraphicsDevice,
mvtPtSprite.Length * 32,
ResourceUsage.WriteOnly, ResourceManagementMode.Automatic);
Becomes:
mVB = new VertexBuffer(gfx.GraphicsDevice,
mvtPtSprite.Length * 32,
BufferUsage.WriteOnly);
As explained
for the changes needed for chapter 9, the initializing the index buffer no
longer requires resource management.
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx device
typeof(short),
// set type to short
shrtIndexArray.Length, // int size in bytes
ResourceUsage.WriteOnly, //
memory use options
ResourceManagementMode.Automatic);
Becomes:
mIB = new IndexBuffer(gfx.GraphicsDevice, // our
gfx device
typeof(short),
// set type to short
shrtIndexArray.Length, // short size in bytes
BufferUsage.WriteOnly);
Setting the
data in the index buffer has become
easier.
mIB.SetData<short>( shrtIndexArray,
0, // element start
shrtIndexArray.Length, // element count
SetDataOptions.None); // options
Becomes:
mIB.SetData(shrtIndexArray);
// options
The
changes explained here have already explained in chapter 9 and are identical to
chapter 9. The buffer used here to store
the vertex data is not dynamic since it is only loaded once and the same data is
used each frame. Because of this the
method init_dynamic_vb() really should be init_static_vb().
Since
the ability to control how the vertex buffers are accessed using the
ResourceUsage and ResourceManagementMode properties have been deprecated with XNA
2.0;
mVB = new VertexBuffer(
gfx.GraphicsDevice, // gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS * NUM_ROWS, // element count
ResourceUsage.Dynamic |
ResourceUsage.WriteOnly,
ResourceManagementMode.Manual);
//
memory use
Becomes:
mVB = new VertexBuffer(
gfx.GraphicsDevice, // gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS * NUM_ROWS, // element count
BufferUsage.WriteOnly); // memory use
Setting the
data inside the buffer is easier now too. You now only need to pass the array to the
SetData() method and XNA can figure out the
length and other options for you.
mVB.SetData<VertexPositionColorTexture>
(mVertGrid, 0, mVertGrid.Length, SetDataOptions.None);
Becomes:
mVB.SetData(mVertGrid);
Like
many examples in the book, the pixel shader point light solution begins with
the solution from the index buffer solution from chapter 9. These changes were already explained earlier
and they are necessary here as well.
Since users are no longer given control over resource access through the
ResourceUsage and ResourceManagementMode classes.
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx device
typeof(short), // set type to short
shrtIndexArray.Length, // int size in
bytes
ResourceUsage.WriteOnly, // memory use options
ResourceManagementMode.Automatic);
Becomes:
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx device
typeof(short), // set type to short
shrtIndexArray.Length, // short size in bytes
BufferUsage.WriteOnly );
Setting the
data in the index buffer has become
easier.
mIB.SetData<short>( shrtIndexArray,
0, // element start
shrtIndexArray.Length, // element count
SetDataOptions.None); // options
Is replaced
with:
mIB.SetData(shrtIndexArray);
// options
The
changes explained here have already explained in chapter 9 and are identical to
chapter 9. The buffer used here to store
the vertex data is not dynamic since it is only loaded once and the same data
is used each frame. Because of this the
method init_dynamic_vb() really should be init_static_vb().
Since
the ability to control how the vertex buffers are accessed using the
ResourceUsage and ResourceManagementMode properties have been deprecated with
XNA 2.0;
mVB = new VertexBuffer(
gfx.GraphicsDevice, // gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS * NUM_ROWS, // element count
ResourceUsage.Dynamic | ResourceUsage.WriteOnly,
ResourceManagementMode.Manual);
//
memory use
Becomes:
mVB = new VertexBuffer(
gfx.GraphicsDevice, // gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS * NUM_ROWS, // element count
BufferUsage.WriteOnly); // memory use
Setting
the data inside the buffer is easier now too.
You now only need to pass the array to the SetData() method and XNA can
figure out the length and other options for you.
mVB.SetData<VertexPositionColorTexture>
(mVertGrid,
0, mVertGrid.Length, SetDataOptions.None);
Becomes:
mVB.SetData(mVertGrid);
Like
the pixel shader point light example, the changes needed here are identical to
those required in chapter 9 to build and initialize the index buffer and vertex
buffer.
Like
many examples in the book, the pixel shader point light solution begins with
the solution from the index buffer solution from chapter 9. These changes were already explained earlier
and they are necessary here as well.
Since users are no longer given control over resource access through the
ResourceUsage and ResourceManagementMode classes.
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx device
typeof(short),
// set type to short
shrtIndexArray.Length, // int size in bytes
ResourceUsage.WriteOnly, // memory use
options
ResourceManagementMode.Automatic);
Changes to:
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx device
typeof(short),
// set type to
short
shrtIndexArray.Length, // short size in bytes
BufferUsage.WriteOnly
);
Setting the
data in the index buffer has become
easier.
mIB.SetData<short>( shrtIndexArray,
0, // element start
shrtIndexArray.Length, // element count
SetDataOptions.None); // options
Becomes:
mIB.SetData(shrtIndexArray);
// options
The
changes explained here have already explained in chapter 9 and are identical to
chapter 9. The buffer used here to store
the vertex data is not dynamic since it is only loaded once and the same data
is used each frame. Because of this the
method init_dynamic_vb() really should be init_static_vb().
Since
the ability to control how the vertex buffers are accessed using the
ResourceUsage and ResourceManagementMode properties have been deprecated with
XNA 2.0;
mVB = new VertexBuffer(
gfx.GraphicsDevice, // gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS * NUM_ROWS, // element count
ResourceUsage.Dynamic |
ResourceUsage.WriteOnly,
ResourceManagementMode.Manual); // memory use
Becomes:
mVB = new VertexBuffer(
gfx.GraphicsDevice, // gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS * NUM_ROWS, // element count
BufferUsage.WriteOnly); // memory use
Setting
the data inside the buffer is easier now too.
You now only need to pass the array to the SetData() method and XNA can
figure out the length and other options for you.
mVB.SetData<VertexPositionColorTexture>
(mVertGrid, 0, mVertGrid.Length, SetDataOptions.None);
Becomes:
mVB.SetData(mVertGrid);
The
upgrade wizard does not update references to the Microsoft.Xna.Framework.Content.Pipeline
component.
Also,
the wizard does not update references to the any game libraries that you create
to load your content.
These
old references need to be removed. And
new ones must be added.
For
details with screenshots see Migrating
Content Processors.
As
explained in chapter 22, the upgrade wizard does not migrate the MD2Importer
content processor. After using the
wizard you will notice the warning icons placed beside the references to the
content processor.

This
actually is a simple fix since you only need to fix these references. To start, remove the original
references. Then, right click the
MD2Importer project in the Solution Explorer and choose Build. Next, add new references under the References
nodes for your main project and also under the Content node. In the end, your project solution references
should be similar to the listing shown in this next figure.

You
may also have to specify which project is the startup project. To be sure, for the example shown above right
click the MGHWin_23_animatedLamp project and choose SetAsStartUpProject.
For
more detail on migrating content processors see Migrating
Content Processors.
With
XNA 2.0 you now need to distinguish between dynamic and static vertex
buffers. This is a good thing though
because it helps you optimize use of the memory. Because of this, you now have to declare the
vertex buffer as dynamic for the animated lamp example. Inside MD2.cs;
public VertexBuffer
vertexBuffer;
Becomes:
public DynamicVertexBuffer
vertexBuffer;
With
buffer and resource management changes to XNA 2.0, inside the
initializeVertexBuffer() method in MD2.cs:
vertexBuffer = new VertexBuffer(gfx,
VertexPositionNormalTexture.SizeInBytes *
modelVerts.Length,
ResourceUsage.Dynamic,
ResourceManagementMode.Manual);
Becomes:
vertexBuffer = new DynamicVertexBuffer(gfx,
VertexPositionNormalTexture.SizeInBytes*modelVerts.Length,
BufferUsage.WriteOnly | BufferUsage.Points);
When updating the vertex buffer in XNA 2.0, the
buffer needs to be released before data in it can be updated. As such, in the updateModel() method in
MD2.cs;
vertexBuffer.SetData<VertexPositionNormalTexture>(modelVerts);
Becomes:
gfx.Vertices[0].SetSource(null,
0, 0);
vertexBuffer.SetData(modelVerts);
The
changes needed for this example are identical to changes implemented for the
animated lamp example.
With
XNA 2.0 you now need to distinguish between dynamic and static vertex
buffers. This is a good thing though
because it helps you optimize use of the memory. Because of this, you now have to declare the
vertex buffer as dynamic for the animated lamp example. Inside MD2.cs;
public VertexBuffer
vertexBuffer;
is
replaced with:
public DynamicVertexBuffer
vertexBuffer;
With
buffer and resource management changes to XNA 2.0, inside the
initializeVertexBuffer() method in MD2.cs:
vertexBuffer = new VertexBuffer(gfx,
VertexPositionNormalTexture.SizeInBytes
* modelVerts.Length,
ResourceUsage.Dynamic,
ResourceManagementMode.Manual);
Becomes:
vertexBuffer = new DynamicVertexBuffer(gfx,
VertexPositionNormalTexture.SizeInBytes
* modelVerts.Length,
BufferUsage.WriteOnly | BufferUsage.Points);
When updating the vertex buffer in XNA 2.0, the
buffer needs to be released before data in it can be updated. As such, in the updateModel() method in
MD2.cs;
vertexBuffer.SetData<VertexPositionNormalTexture>(modelVerts);
Becomes:
gfx.Vertices[0].SetSource(null,
0, 0);
vertexBuffer.SetData(modelVerts);
When
updating your audio project you will have to adjust your reference to the audio
*.xap file. Details are here:
Since
the terrain uses a content processor you will first have to update this since
the upgrade wizard does not do it for you.
For more detail on migrating content processors see Migrating
Content Processors.
Like
many examples in the book, the pixel shader point light solution begins with
the solution from the index buffer solution from chapter 9. These changes were already explained earlier
and they are necessary here as well.
Since users are no longer given control over resource access through the
ResourceUsage and ResourceManagementMode classes.
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx device
typeof(short), // set type to short
shrtIndexArray.Length, // int size in bytes
ResourceUsage.WriteOnly, // memory use options
ResourceManagementMode.Automatic);
Becomes:
mIB = new IndexBuffer(gfx.GraphicsDevice, // our gfx
device
typeof(short),
//
set type to short
shrtIndexArray.Length, // short size in bytes
BufferUsage.WriteOnly);
Setting
the data in the index buffer has become easier.
mIB.SetData<short>(shrtIndexArray,
0, // element start
shrtIndexArray.Length, // element count
SetDataOptions.None); // options
Becomes:
mIB.SetData(shrtIndexArray);
// options
The
changes explained here have already explained in chapter 9 and are identical to
chapter 9. The buffer used here to store
the vertex data is not dynamic since it is only loaded once and the same data
is used each frame. Because of this the
method init_dynamic_vb() really should be init_static_vb().
Since
the ability to control how the vertex buffers are accessed using the
ResourceUsage and ResourceManagementMode properties have been deprecated with
XNA 2.0;
mVB = new VertexBuffer(
gfx.GraphicsDevice, // gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS * NUM_ROWS, // element count
ResourceUsage.Dynamic | ResourceUsage.WriteOnly,
ResourceManagementMode.Manual);
//
memory use
Becomes:
mVB = new VertexBuffer(
gfx.GraphicsDevice, // gfx device
typeof(VertexPositionColorTexture), // vertex type
NUM_COLS * NUM_ROWS, // element count
BufferUsage.WriteOnly); // memory use
Setting
the data inside the buffer is easier now too.
You now only need to pass the array to the SetData() method and XNA can
figure out the length and other options for you.
mVB.SetData<VertexPositionColorTexture>
(mVertGrid,
0, mVertGrid.Length, SetDataOptions.None);
Becomes:
mVB.SetData(mVertGrid);