Sunday, October 17, 2010

XBOX 360 Port kicking!

Screen shot of the Shoot Editor running on Windows with OpenGL
Since creating the iPhone port, I added more features to the engine such as a Particle System and Skyboxes, then I decided to start an XBOX 360 port. Here are the steps I took:

- I bought an XBOX 360 elite and an XNA creators club annual membership

- At first, I went with an approach that turned out to be a development "cul-de-sac".. I had decided to use my C++ engine from C#/XNA, using the Common Language Runtime (CLR) feature of Visual Studio. This looked good in theory, and started good as my initial tests to invoke C++ from C# and vice versa worked fine. On the C++ side, I used the CLR syntax to access XNA objects, in particular the GraphicsDevice object. A big part of the work was on resource loading, were I made the engine use XNA's ContentManager for loading resources instead of accessing the file system directly. I also made sure the Projection and View matrices generated by the engine work as expected in XNA. However when I got to the stage of testing the rendering, I could not get a single polygon to render correctly. After checking everything, I gave up on this approach, with the conclusion that there should be a security layer within XNA that prevents C++ code invoked through CLR from accessing the Graphics Device. I still think this but I am note sure at all, so if anyone knows about this please let me know. I later found out that the rendering was broken because I wasn't updating the XNA projection matrix correctly, but this approach still didn't work because I found the C# compact framework on the X360 simply doesn't support running native code through CLR! So this is a closed case.

- Then I resorted to a second approach: rewrite the engine in C#! It was a bit disappointing to do this, specially that my point was to keep a C++ core across all platforms. But too bad the XBOX C++ SDK is not accessible to indies. To balance the duplication in code I made it a top priority to keep the game level data absolutely the same across all platforms. This will enable me to develop primarily on the Windows port using the Editor, generate the game levels, then load them with the C# version of the engine. Yes I am gonna have to port the game-play code from C++ to C#, but it seems acceptable to me as those languages are very similar and I already picked up practices to make the porting as easy as possible.

- Writing the C# port, and working with XNA in general, was smoother than I thought, and I truly respect Microsoft for that. Since XNA already has a lot utility classes and support for resources (meshes, textures, ect.), I only had to rewrite a thin skeleton of engine classes: Mainly the entity system and the serialization system.

- I hammered through it smoothly until I started working on the 3D entities. Since I decided to use XNA's content manager to load 3D models, and since it does not support the MilkShape 3D format that is used on other platforms of the engine, I had to find a 3D format that I can use on all platforms. After a short attempt at using Autodesk's FBX SDK which seemed gigantic and over-engineered, I decided to use the .X format, since I found some code for loading .X files in OpenGL. The code was from Mr. Paul Coppens, it seemed a bit outdated, but it was short and came with samples. So now thanks to the XBOX port, Windows/OpenGL and iPhone ports support .X meshes too.

- On a final note, did you know that XNA has a Right-Handed coordinate system? This caused me trouble as I assumed it would be Left-Handed like DirectX, and I spent some time dealing with a virtually inverted Z axis, by doing things such as scaling the view matrix by -1 in the Z direction, changing the culling mode, etc. After few failures, I finally got the 3D scene to show exactly the same on all platforms, and realized that XNA is in fact Right-Handed like OpenGL! A late reading of the XNA documentation confirmed this. Unfortunately there are always things to learn the hard way.

No comments:

Post a Comment