Introduction

This is an introductory article for XNA development, discussing tools and the minimum amount of code to start using the XNA Game Studio with simple models created in Blender.

Tools

To write applications (such as games) using the XNA Game Studio, you must download and install a variety of tools. Since Microsoft changes its website frequently, these links are not guaranteed to work. If you don't get to the download pages, use Google to search for the new links using the appropriate keywords.

This article is written using:

Visual Studio C# 2005 Express Edition with SP1

XNA Game Studio Express 1.0 Refresh

XNA Framework 1.0 Refresh

Blender 2.44

Python 2.51

Visual Studio Express

XNA development, as of the writing of this article, can only be done using Visual Studio Express.

XNA

Modeling Tool

If you're going to be doing anything "serious" with XNA, you will quickly discover that you need a modeling tool to create your 3D models. I recommend Blender (which is free) or AutoDesk Maya, which is $2000. Guess which tool I'll be mentioning in this and other articles?

Plug-Ins

Blender automatically detects the Python installation, so no further work on your part is necessary.

Tutorials

Tutorials on XNA and Blender are quite abundant and the Microsoft and Blender sites respectively and on numerous third party sites. Simply Google and you will find many resources. I started by going through the Microsoft tutorial on displaying a 3D model. Be aware of the aspect ratio bug which I describe here. It's not fatal, but it will lead to stretched objects if you use the Microsoft tutorial as a basis for working with models created in Blender.

Creating a Windows XNA Project

Launch Visual Studio C# 2005 Express Edition.

Creating the Windows Game Project

Create a Windows Game project by selecting the Windows Game project icon:

Enter a name for the project and click on OK.

Create a Model Folder

Models (spaceships, people, objects, etc.) typically live in a Content\Models folder. Right click on the project and add the Content folder and Models sub-folder, so your project tree looks like this:

If you build and run this project, you will get a window with a blue field.

Create a Model in Blender

Launch Blender. Blender starts with a cube as an initial model, although since you're looking at the cube from the top, it looks like a square:

To see that it's actually a cube, click on the numpad 0 (with numlock on) and you will see:

Export the Model

XNA cannot load Blender files, so rather, you must export your Blender model to an FBX format. You can read a little bit about FBX here. Basically it's an open standard, platform independent 3D file format created by AutoDesk. You can also export to DirectX (.x) format, however this brings up a complicated options dialog, whereas the FBX export does not.

The Blender UI will be a bit weird to Windows users, so here's the walkthrough:

On the menu bar at the top, click on File (do not try to use the keyboard with the typical Alt-F keystroke combo!)

Move the mouse down to Export

Move the mouse over to Autodesk FBX

A dialog will appear with two textboxes, the first showing the path and the second for entering the filename. Click on the second edit box and type in "cube" (without the quotes).

Click on the Export FBX button or press the Enter key twice.

Import the Model into XNA

The model is now ready for importing into XNA:

Go back to the XNA Game Studio and right click on the Models folder and select "Add / Existing Item...".

In the file types, select "Content Pipeline Files"

Navigate to the Blender folder and select the cube.fbx file.

Add the Code to Render the Model

Rendering the model involves:

Defining where the model is

Defining where the camera is

Defining the camera orientation

Loading the model into the content pipeline

Drawing the model

All of this work will be done in the game1.cs file and the Game1 class.

Defining Where the Model Is

For simplicity, the model is placed at world coordinates (0, 0, 0). Create a field for the model position:

protected Vector3 modelPosition = Vector3.Zero;

Defining Where the Camera Is

Create a field for the camera position:

protected Vector3 cameraPosition = new Vector3(0.0f, 0.0f, 10.0f);

How did I arrive at these values? The vector consists of the x, y, and z axis position of the model. X is left-right, Y is up-down, and Z is in-out. If you look at the screenshots of the cube above, you will notice a grid. Each grid line represents one unit, therefore the cube is a 2 units wide, 2 units long, and 2 units tall. The camera is position ten units away from the world center (0, 0, 0) which creates a reasonably sized rendering of the cube.

Note that you do not specify the file extension. The XNA Game Studio will load the appropriate file, as the model is actually compiled to a different file extension from the FBX file that you added to the Content\Models folders.

While we're here, let's also get the aspect ratio of the viewport (our window) as this is necessary for rendering the model so that it looks like a cube. Add the field:

When you run the program, you will get a cube rendered on the blue field:

The following is a brief description of what is going on in the above method. Each of these subtopics deserves considerably more description that I have provided, but I feel that is outside the scope of this beginner article.

Bones

The code above is the basic rendering loop for all models in the game. XNA uses a skeletal animation technique which you can read about here.

CopyAbsoluteBoneTransformsTo flattens the bone hierarchy and puts the bones into an array so that the parent bone matrix can be quickly acquired inthis assignment:

"cs">effect.World = transforms[mesh.ParentBone.Index];

Alternatively, you could write this as:

"cs">effect.World = mesh.ParentBone.Transform;

However, since each mesh in the child needs to access its parent bone transform (so that the mesh builds on the transform of the parent bone) indexing is ultimately faster than asking the parent bone to recalculate its transform every time.

How many bones do you think this model has? If you answer 1, because you think there's just one model, then you would be partly correct. However, there is always a root that defines the topmost parent of the bone tree:

Model Meshes

A model consists of meshes (read about meshes in the Blender documentation). How many meshes do you think the cube has? The expected answer would be 6--one mesh for each face of the cube. However, the cube model only has one mesh! What is confusing is actually the local variable named mesh, which instead should be called modelMesh, as there is a single mesh to represent the entire model. So one has to be clear about the difference between XNA ModelMesh instances and Blender meshes.

The XNA Mesh for the cube:

consists of 1 ModelMeshPart object which has 8 vertices, which is the number of vertices in the cube (the above model has 51 vertices).

As a second example, an object like this:

(in which the quad--square--meshes have been converted to triangles for one face and one of the triangles has been extruded) still is represented as only one model mesh in the XNA model.

Effects

This line of code:

foreach (BasicEffect effect in mesh.Effects)

is an shorthand way of saying (again note we're dealing with the model mesh part):

The World property establishes the world matrix for this model mesh (from the perspective of the model's world), which is typically a combination of the parent bone transforms and any local transforms applied just to this bone.

The View property establishes the orientation of the camera--its position, where it's looking, and its orientation.

The Projection property establishes how the camera projects its view onto the screen--the field of view, the aspect ratio of the viewport, and the boundaries (in distance) of what the camera can see: the near plane and the far plane.

Each model mesh requires the World property to be set to reflect any changes in the parent bone and any local changes. The View and Projection properties need to be set whenever the camera position and orientation changes. In this simple example, we could pre-calculate those values:

Animating the Model

The above screenshot of the cube looks utterly boring and not like a cube at all. Getting an object to rotate on its own is one of the simplest forms of animation. The following code will rotate the cube around the X and Y axis, giving it some nice spin. First, add:

protectedfloat modelRotation = 0.0f;

to the Game1 class. This field is used for holding the rotational angle.

In the Update method, add the line to increment the model rotation based on the elapsed time between updates:

Conclusion

This article encapsulates the research and experimentation that I've done to get a basic understanding of XNA and how to use a tool such as Blender to start developing models that XNA can render. I've been blogging about my trials and tribulations here, and I will continue to do so as I make progress on this concept that I'm developing. I'm primarily interested in using XNA as a rendering space rather than game development, but I may just for fun diverge and put together a simple game that I wrote years ago in Windows 3.1.

Howdy! I am running Visual C# 2010 Express and I have Blender v. 2.57 (At least that's what the readme said). I am trying to follow the steps that you outlined above and I have encountered a couple problems:

2) Before that, it was saying something about the file not being found--? Dunno, didn't capture that one, and it's not doing it again.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace WindowsGame3
{
///<summary>/// This is the main type for your game
///</summary>publicclass Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
protected Vector3 modelPosition = Vector3.Zero;
protected Vector3 cameraPosition = new Vector3(0.0f, 0.0f, 10.0f);
protected Model myModel;
protectedfloat aspectRatio;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
///<summary>/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
///</summary>protectedoverridevoid Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
///<summary>/// LoadContent will be called once per game and is the place to load
/// all of your content.
///</summary>protectedoverridevoid LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
}
protectedoverridevoid LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
myModel = Content.Load<Model>("Content\\Models\\cube");
}
aspectRatio = ((float)graphics.GraphicsDevice.Viewport.Width) /
((float)graphics.GraphicsDevice.Viewport.Height);
}
///<summary>/// UnloadContent will be called once per game and is the place to unload
/// all content.
///</summary>protectedoverridevoid UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
///<summary>/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
///</summary>///<paramname="gameTime">Provides a snapshot of timing values.</param>protectedoverridevoid Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
///<summary>/// This is called when the game should draw itself.
///</summary>///<paramname="gameTime">Provides a snapshot of timing values.</param>protectedoverridevoid Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
Matrix[] transforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(transforms);
// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in myModel.Meshes)
{
// This is where the mesh orientation is set, as well as our camera and
// projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index];
effect.View = Matrix.CreateLookAt(cameraPosition, Vector3.Zero,
Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f);
}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
base.Draw(gameTime);
}
}
}

Not sure what I'm doing wrong. I exported it from Blender with the .fbx extension, and I imported it into VS Express 2010 into the Models folder. So it's there, in the project.

Very good article! Being new to XNA (I'm using v4) this was a good start. I'm not familiar with prior versions of XNA and there are minor differences between your article and how VS 2010 creates a default XNA v4 project. For example: the machine generated code I got for LoadGraphicsContent and UnloadGraphicsContent don't have any parameters; and the SDK creates one project for code and a separate project for content. Would you consider updating your article?

As for other modelling tools (I'm a beginner here too), I found Anim8or to be the easiest to use. It's the most intuitive and has a standard UI. It doesn't export to FBX but it was a minor extra step to convert it externally so VS could import it.

This tutorial is awesome. However you might want to mention at the top that this does not work with the newest release(2.46) of blender. That is the release I used and the program continued to display a blank screen so instead I installed the 2.44 release.

Nice article, I stumbled upon it while I was looking on how to display a cursor in a XNA game.
I almost implemented the class you also used until I learned that the Game class has a property "IsMouseVisible". I thought you might wanna know. Or were you making a custom cursor?

I case you are interested, here are some other free modelers besides Blender.wings3d/[^]anim8or/[^]

Again a nice article - nice to see Blender mentioned. The teens on my son's FIRST robotics team (#1746) use it for animation and some design. I've been trying to get them to work with the XNA and MS Robotics kits to do some work that will get them all into the real life issues of Game Design (They all want to be Game Programmers - unusual huh?).

Now Marc, here's the important part, run - don't walk - run to the local high school and become a mentor for the school's robotics team (you'll love it believe me) and register the team for the FIRST organization. Teach them how to design and build software right (you don't want to know what processes they get taught) using XNA, Robotics, and the Express' tools and I'll see you at the World Championship in Atlanta.

Welcome to the club - The reality is that the American School system is interested only in providing the nation with followers. You might be interested to note, that that goal is explicitly stated in the original documents when the national school system was set up.

The general attitude I find in teachers (both aware and unaware) is that they are there to teach the curriculum. I was fortunate that I went to a school in England. Back then and there the teachers taught us the subject. There is a difference - can you figure it out? I was also taught to think (a moderately useful skill).

End of rant - back to the mentoring - I'll be happy to help you get it off the ground (maybe even some sponsorship if our budget allows). If you can't get the P or the school board to go for it then go private. Get your son and some of his friends to come to your place once a week for 3-4 hours, and teach them to MOD games (start with Civilization IV which provides the core engine source code, XML config and Python scripting). Then go from there (be sure to earn enough that week to provide Pizza and fizzy stuff). Another angle is to speak to some local businesses who might be willing and able to provide a room, computers, and some funding.

Hey, I just had a thought, if everybody here at CP donated $1 we'd have enough to help fund a number of FIRST teams - and help Rex.

Hi Marc,
Nice article. Blender is getting better every day (although their UI takes some getting used to). You might want to also check out some NURBS modeling tools such as Rhinoceros 3D link[^] (be sure to review their galleries).

NURBS provides better compatibility with CAM packages than most mesh-based tools (Rhino can do both). Game modeling is a blast, but I also like to create models of things I can fabricate in the real world. There is a whole industry springing up around DIY / hobbiest CNC mills and routers (controllers, parts, software, etc.) that can be driven by CAM apps and some can be built for a few hundred dollars.

Rhino has a very nice scripting environment (vbs) and two free SDKs (C++ and .NET). You can use either to create some really fantastic tools or computer generated models. There are many professionals (see the forums) who use rhino as a visualization tool for business, academics, architecture, prototypes, etc. I use rhino models in business graphics and PowerPoint presentations to good effect.

I'm so glad to see an XNA article involving Blender + XNA, as I, like a lot of other developers I'd imagine, choose to learn to model in Blender rather than fork out thousands of dollars for a commercial modeling tool.

I'd really, really love to see an article on skeletal animation using Blender + XNA. Would seem like a natural progression for this article too. What'd ya say Marc?

Mainly, as an opportunity to learn an up-and-coming technology. The concept is quite silly--I want to use 3D to organize and express concepts in a rather different way than is currently done with typical designers. Currently, I feel that designers (like for applications--forms, schemas, whatever) emphasize the properties of objects. The concept I want to work on emphasizes the relationships between objects. But the my concept is general enough to apply to other things, like neurons, people, etc.

Your concept sounds fascinating. I think it's such a shame that 3D outside of games rarely turns out that practical except for narrow domains like building/parts architecture, etc. Why can't real-life computing be more like the 3D Operating systems of Hollywood? hehe
Jokes aside, it sounds like a fun and interesting concept.

I myself am working on a non-game related project requiring 3D animation so if I beat you to the skeleton animation in xna I'll be sure to share my code.

Visual interfaces (as opposed to pretty forms) are gaining ground and if designed well are very very good. It's only a short step to a "realistic" 3D environment.

What is going to prompt that small step? The kids today spend large amounts of time in a 3D environment - their games. As they progress into the workplace they will expect and demand interfaces that finally (hopefully) leave the 3270/VT100 concepts behind.

3D interfaces have been tried before, but it is only recently that the technologies, tools, and more importantly public acceptance has been available and present.

Now to reality: if you really want to see such interfaces then read and learn the following statement:

"The world is moving so fast these days that the man who says it
can't be done is generally interrupted by someone doing it."
- Harry Emerson Fosdick

I have installed Microsoft XNA Express on a day when it was released (it was something like 7th march or something) and then I have started searching for articles, I found loads of articles but none talked about creating .FBX or .X files.
You have answered to at least 2-3 questions that I had first time and didn`t found any answer. Eventually this lead me to removing of XNA ... This article rises my desire to install XNA Express and try it bit more. I was thinking about some small game like FPS or race game. Just have to find someone who knows to work with blender or other 3D tool like lightwave/3d max/maya

Can you supply links to sites with good tutorial/sample coverage.
I hope that you will make few more articles about XNA!