Instanced Model

I was feeling good about the progress I have made with the game.  However, one thing I had not tried in some time is running the game on the XBox 360.  When deploying on the XBox, I came across a few problems.  First, the XBox version of the project did not have references to the SkinnedModelProcessor.  After adding a reference, it still returned an error about the library version number.  I figured out that this was because my SkinnedModel project DLL was being compiled for Windows.  In the SkinnedModelProcessor solution, I created a Copy of Project for XBox 360 and added a reference to the DLL created from that in my XBox 360 project instance and it ran correctly.

Unfortunately, I did notice some some slight slowdown on the XBox 360, and the FPS counter usually returned somewhere between 30 and 50 FPS.  I turned off the rendering of the two adjacent rooms, and it went back up to 60 FPS.  This is one reason I don’t like developing on a super powerful computer, because problems like this don’t arise until it’s deployed on a less powerful system like the XBox 360.  After going through my model rendering code, I was able to track down the slowness to the rendering of the “blocks” which make up the game map.  I modified the code so that it renders a block for each map cell, which is the worst case scenario (15 rows * 26 columns = 390 cell blocks).  This significantly lowered the frame rate on the XBox360 to anywhere from 7 FPS to 20 FPS.  The blocks are just six sided cubes with a texture, so the meshes are not complex

screen095

After doing multiple web searches, I was able to find one thread that discusses this problem.  This led me to the Instanced Model example code from Microsoft, which is able to display thousands of models at a time with frame rate not dropping below 60 FPS, even on the XBox 360.  I knew there had to be a way to do this, since the graphics processor is capable of rendering thousands of polygons at a time.  From my previous projects in OpenGL, I learned that this is handled by creating a “display list” in OpenGL, so I figured there had to be an equivalent in XNA.

I didn’t have a chance to modify my code according to the example, since my vacation is over and I have limited time to work on game programming.  Hopefully, I’ll have a chance over the weekend to get this working correctly.  Also, I still have the level 2 and 3 armor sets to add to the game.

3D Text

screen094

Today, I worked on getting the damage numbers to display correctly over each enemy’s head.  As I was working on this, it became apparent that my coordinate system was backwards.  I had noticed this before when I was trying to get the player to move, so I just flipped the sign of the X coordinate of the player.  This was happening because the example I had looked at placed the camera view at a negative Z coordinate.  After reading up more on the XNA 3D coordinate system at Toymaker by Keith Ditchburn, I learned that the positive Z coordinate comes “out” of the screen and the negative Z coordinate goes “into” the screen.  Therefore, my camera should have had a positive Z position value.  I changed this, but now I was seeing the backside of all of my models.  This was because the modification to the SkinnedModelProcessor I made rotated the model by 90 degrees on the X-axis and 180 degrees on the Z-axis.  Removing the Z-axis rotation makes the model face forward, but it is up-side-down.  I had this problem before, which I tried to fix by using a reflection transformation on the Y-plane.  This caused all of the normals to be flipped, which didn’t appear correctly.  After some more trial and error, I found that rotating my model in the processor by -90 degrees (which is the same as 270 degrees) will rotate the model in the correct position.

After fixing the model display, I updated the enemy and player objects to return a Vector3 in a method that returns the position in world coordinates.  This will eliminate the need to do the pixel to world conversion in my GameScreen3D class.  Unfortunately, this pushes it to the “model” classes, which isn’t great either and ideally I would like to convert everything to world coordinates.  However, updating all of the collision detection code will take some time, especially since the XNA Rectangle object doesn’t support floats.

Later, I found another good article by Shawn Hargreaves which explains how to draw text in the 3D world.  The examples were fairly easy to follow, and after some effort I was able to display text values on the screen.  With a little more effort, I was able to get text to follow an enemy on the screen.  His article also describes to to make a billboard, which will display the text facing forward regardless of camera orientation.  I may look into doing that later, along with the sprite optimization suggestions in the article.  However, since the game is happily running at 60 fps I will look into optimizing that later.

screen093

Finally, I worked on modeling the third armor set and second enemy.  I just have the models completed thus far, so I will need to go back and find and apply appropriate textures before adding them to my game.

Camera Movement

http://www.youtube.com/watch?v=2WwGt3QqENc

The camera in the 3D game world can now be moved and rotated.

Since I’ve had a few days off from work, I tried to make as much progress as I could with development of the Blasting Bits game.  I was able to get the new model processor working, and now the player model is animated in the game.  In Blender I can make multiple animations/clips, but unfortunately XNA will only allow one animation to be imported as noted in this article by Shawn Hargreaves.  So for now the player model continuously runs.  There doesn’t appear to be any elegant solutions for having multiple animations in an FBX file.

I added camera controls to the game, so when the player holds the right trigger the left thumbstick will zoom and rotate the game world.  Zoom is basically just the distance the camera is away from the game world.  Initially, I had the camera changes in set increments which appeared jarring when changed.  To fix this, I added three variables which are increment, speed, and target for both rotation and zoom.  When the player changes the camera, the increment value is added (or subtracted) from the target value.  Then for each update, the increment value is added to the current position until it reaches the target value.  This gives a much more smoother effect when rotating or zooming.