Wednesday, 6 October 2010

XNA 4.0 from XNA 3.1

Last night my code finally compiled in XNA 4.0.  I had reached a good point last Friday and thought I had some time so I decided then was a good time to upgrade.  For those reading this who are not familiar with XNA.  It is the game development framework that Microsoft has provided for Indie and hobby developers.  It is based on C# and is the only way for hobby programmers to release games on the Xbox 360.

XNA 4.0 is the latest version.  It has some improvements but also some pain converting from the older version.  In all it has taken me about 20 hours to get this far.

As you can see from that picture it is not right.  Most of the mess is caused by the change to defaulting to precomputed alpha.  Although I have changed my code I still need to change the graphics or the way I use them to suit that.  Something new for me to learn.

The unexpected problem is that the model of the space ship is showing it's insides on the outside.  I'm sure I will work out how to fix it but at the moment it is a bit frustrating!

What I wanted to write here was just a list of all the things I have had to do to convert from XNA 3.1 to XNA 4.0.  Partly to let off steam and hopefully to help some other people doing the same.  I've included some useful links as well.

- The conversion to XNA 4.0 did not get all the references right.
I had to manually remove them and re-add them.  This cannot be done from within the IDE it was necessary to edit the project file with a text editor.  Very quick and painless.

Remove and re-add References.  Most can be added back using Visual Studio but a couple have to be manually edited:
mscorlib (can not add back with VS edit .csproj file)
System.Core (can not add back with VS edit .csproj file)

To add back missing items see the following post:

The .csproj file needs to be edited manually using a text editor.  Remember to close Visual Studio first.

The following image shows the syntax for the .csproj file:

- I've changed all the colours where I set the alpha to the new syntax.
I have not, as yet, changed the graphics to match.  Hence the mess in the above picture.
Changed new Color(colour, alphaByte) [0 to 255] to colour * alphaFloat [0.0 to 1.0]

- Several changes to the shader effect files
AdderssU and V only support: Wrap, Clamp and Mirror.
Border and BorderColor are gone.
Set all the Mip, Mag and Min filters on the shadowmaps to Point.  Not sure why but unless I do that I get an exception when running the game.
The new effect shader compiler is also much fussier on Windows.  It enforces the minimum number of instruction slots for each shader model, e.g. PS 3 can have a minimum of 512 instruction slots.  My graphics card could have more but the compiler does not let me use them.  The Xbox 360 compiler is virtually unchanged and so my old shader code compiled for the Xbox but not for Windows.  I've had to reduce the quality of the shadows on Windows to fit within the 512 limit in one pass.  I've added a compiler directive #if defined(XBOX360) so I can do that.

- Re-wrote the way the sky is drawn.  The new Creators Club sample no longer uses a separate effect file.
[Edit: had to re-instate the old version because the new one did not work with my terrain!] 

- Changed the exception in the Skinned model prosessor to a warning about not having any animations.
My models already have separate animations so the skinned models need to be loaded even though they do not have any animations included with them.
- I have temporarily removed my built in screen shot class.  Resolve back buffer has been removed and it is now necessary to use a RenderTarget to get the screenshot.  As this puts unnecessary code in  to my draw loop I have not done it yet.
The screenshots are only for my benefit and they were not going to be in the finished game so it's no loss.

- Removed all Depth Stencil buffers and added back the type in the RenderTarget2D where necessary.
Reading about this was more confusing than just doing it.  The new XNA 4.0 method is much easier.

- VertexDeclarations are also no longer needed.
All you need is: graphicsDevice.SetVertexBuffer(vertexBuffer);
Lots of lines deleted.

- The syntax for drawing user primitives has been simplified
Most of my code now just reads something similar to the following, instead of all the Begin() and End() methods, just:

- Replaced my particle system with a version based on the new sample because the old sample was based on point sprites which are no longer supported.
Fairly easy change but as yet untested.
[Edit: needed further work to get it working nicely.]

- Changed every SpriteBlendMode.AlphaBlend to BlendState.AlphaBlend.
There were a lot of them in my code but easy to find and replace.

- On one page I used a Scissor test and the syntax has change to use RasterizerState.ScissorTestEnabled

- The Texture load and save functions have been improved.
I have changed all my BMP files to now use PNG.
[Edit: this saved as pre-multipled alpha which was not what I needed so I have had to change one file format.]

- Lots of changes on the storage side of things.
There is no TitleLocation anymore.
I have had to use the Manifest example for some lists:
I have changed how the StorageContainer is accessed for saving user files:
For my editor I have used .NET System.IO file methods and a semi hard coded path to the same place as the user storage location in Windows.  This is because the Path attribute from the StorageContainer has been removed.
I could have used any location for the editor but that one keeps everything in one known place.
A useful method is:

- The syntax for turning on Antialising has changed or at least the method I was using has gone.  The method I now use is:
graphicsDevice.PreferMultiSampling = true;
[Edit: this needed a lot more work see the future post.]

That's what I have done so far.  The game works but looks awful so I still have lots more work to do to get back to where I was with the older version a week ago!

[Edit:  After I did my conversion I found better tutorials: ]

No comments: