Model Rendering in Game

Today, I exported my Blender helmet model to AutoDesk FBX format to try to get it to render in my game in real time.  The first problem I encountered was that it could not detect my texture.  This was because I was borrowing the texture from the “boot” folder when I did the mapping in Blender.  Therefore, I had to move the texture I  was using in Blender to a “texture” folder at the same level as my exported FBX model.

After loading the FBX model and texture as content items in my project, I created a new Screen subclass which is the 3D display.  Theoretically, this could run concurrently with the existing 2D game screen.  For now, I just created a new main menu item for the 3D game screen.  Using an example from Microsoft, I created a new method in the 3D game screen which renders the model(s).  The model is first loaded in my main game class, then the new model draw method takes the list of models as a parameter.  It also takes the aspect ratio as a parameter, since that is what the example does, but I may remove it or make it a constant later if it does not change.

screen073

Finally, after I finished setting up my model and I ran the program and all I saw was the blue clear color.  Then I noticed a small speck which I first thought was a piece of dust.  This at least let me know that something was rendering, because removing the model drawing code would also remove the black speck.  I think this was because the example code has the camera Z position at 5000f, which I guess was for a really huge model.  Next I tried removing the lines of code in the effects loop for World, View, and Projection one at a time.  By removing all three, I was able to see a rendering of what looks to be the top side of the helmet.  After thinking about it, this makes since because in Blender the Z axis is up, but in XNA the Y axis is up.  Another possible problem is that some of the transformations in the example code look for a parent bone, which I don’t currently have defined for my helmet.

I remembered having to change the export coordinates when exporting my building objects for TetraCity to OBJ format, so that it makes Y up instead of Z.  In the FBX exporter for Blender 2.6, this option is found in the lower left corner of the file save menu of the exporter.  This is really easy to miss if you’re not looking for it, because previous versions of Blender had most options in a popup dialog box.  The fix is made by setting “Forward” to “-Y Forward” and “Up” to “Z Up”.  Selecting “-Y Forward” should automatically set “Z Up”, which is faster because “Z Up” can not be selected with “-Z Forward” selected.  There are also two options for XNA.  I don’t know what these do, but I went ahead and selected them.  Select “XNA Strict Options” should automatically select the other XNA option.  Even with selecting Z Up option, my model was still displaying as if Y is on the horizontal plane.  Either the exporter is broken or my model is not getting updated in the XNA project.  I tried exporting my model to a new filename, and I imported the new model but I still got the same results.  Therefore, the exporter does not appear to be translating the coordinates appropriately for some reason.  Alternatively, I could fix the rotation in code, but that is just one more additional thing to have to do.

screen074

So to get an object moving around the screen, I basically had to go back to step one from three months ago.  I added my helmet object, and added velocity controls to move it up and down.  Once I figure out how to get my current game coordinates to map to 3D space, then I think most of my game world coordinates should translate over with little effort (hopefully).  There also appears to be some tearing with the polygons, which I think may be due to the Z ordering of the faces, because some of the lower polygons will appear above the higher ones.

screen075

More Armor Models

body01

Using Blender I created models for the body armor, hands, and boots.  By using my same process, I created 20 frame sprites for each of these models and imported those into the game.

screen070

I also finally fixed the problem with the dark rooms.  Previously, when the player entered a dark room, the entire screen would go dark except for the area lit by the radiant ability.  This was a jarring effect, because the lit rooms to the left and right of the dark room were also darkened.  To fix this, I created a new method that draws the light mask for each room.  This may be a little wasteful, because it just draws white for lit rooms.  For the dark room, it draws all dark blocks, except for room boundaries which it draws the light gradient blocks.  One improvement could be made for two continuous dark rooms.  In that case, it will draw a slight light band between the two rooms, but it would really just be continuously dark.

screen071

Last night, I downloaded a recommended program called SFXR, which was created by Dr Petter.  This program can be used to create a wide variety of sound effects, which can be used in games.  I will probably use it to generate sounds for the zapper shooting and jumping.

Helmet Model

helm_render2

Tonight I continued more modeling in Blender.  I would like to go ahead and complete all pieces of armor.  Once all of the armor pieces are complete, there may not be much to do for the player model.  I created a helmet from starting with a cube, using a background image of a helmet I found on the web.  Using multiple loop cuts (Ctrl-R), I was able to make the cube outline the background image.  I also used the loop cuts to make an outline of the center eye piece and mouth opening.  Once each of those were outlined, I extruded inwards to give a carved out appearance.  Since I didn’t have a guide for the sides, top, or bottom, I just added to vertical loop cuts and expanded slightly outward.  The side and back usually don’t have much detail, and the player probably will never see the top or bottom of the helmet.

After reading a few tutorials, I was able to remember how to do UV mapping in Blender.  First, it’s best to have two views open, one for the 3D view and one for the UV/Image Editor.  In the 3D view, I had to set viewport shading to Texture to see the texture mapping in real time.  I selected my helmet object and went into Edit mode.  Now set the selection mode to select Faces, and I selected the faces for the first texture.  I did this by selecting all faces (A key) and then unselecting the faces in the eye pieces and mouth opening (Shift Right Click).  Then I selected Mesh, UV Unwrap, UV Unwrap.  In the UVMap viewport, I selected the plus button to create a new image of size 1024×1024.  When I did this, the unwrapped image appears.

Screenshot from 2012-12-15 00:54:18

Using Gimp I created a seamless image using one of the images from CGTextures.com.  I selected that image and copied, and used that Clipboard pattern to fill a new image of size 1024×1024.  I saved this new image as a PNG, and then selected that image in the UV Map viewport using Image, Open Image.  I translated and rotated the 2D points in the UV map slightly to give the texture map a better appearance.  The texture map on the 3D model updates in real time as the 2D points are being modified.  Next, I did the same process in Gimp to create a 1024×1024 texture for the eyes and mouth.  I unselected all of the faces in the 3D view (A key) and only selected the faces in the eyes and mouth (Shift Right Click).  The free select tool (Cntrl Left Mouse Button) makes selecting multiple faces much faster.  With the new faces selected, I created a new image in the UV Map view by pressing the plus button using size 1024×1024.  Again, I selected Mesh, UV Unwrap, Unwrap to place the selected faces on the 2D UV Map plane.  By selecting Image, Open Image I added my second texture to the UV Map view, which automatically updates the texture on the 3D model.

Screenshot from 2012-12-15 01:04:02

The last tricky part is that even though the textures display in the 3D viewport, the textures will not display when rendered (F12), which is the only way to generate an image file.  Rendering the image will still result in a non-textured image.  The trick is to select the object in Object mode, select the Material tab to display the default material for this object, then scroll down to the Options section and check both Face Textures and Face Textures Alpha.  I don’t have a clue why these are not selected by default if those are required to make the UV map during a render.  After playing with the lighting and cameras, I was able to get a decent render of the helmet that I modeled and textured.

That’s enough for one night, so I will probably wait until tomorrow to do the rotation animation into sprites.  At some point, I would like to try to export the model into Autodesk .fbx format and use the model directly in my game code.  However, this will probably require much effort to convert my 2D sprite based game into a 3D space.  However, I think it can be done, since my game display code is for the most part decoupled from the game logic.  In theory, I should be able to make a new instance of my GameScreen class that does 3D rendering, and be able to switch between 2D sprite mode and 3D rendering mode by just changing the pointer to the GameScreen class instance.