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