Post navigation

Getting started with XNA – Drawing a 3D Model

In the previous tutorials, we’ve learned how to draw primitives and 2D textures. It’s time we step up to drawing a 3D model. To start with this tutorial you’ll need the following source code. It’s just an empty project containing our heads up display. Our 3D model is also located in the content folder. When you click on the forklift.fbx file, notice that it uses the Autodesk FBX – XNA Framework importer and Model – XNA Framework processor.
Forklift.fbx is a 3d model which has been exported from 3D Studio Max. You can find screenshots of the model and the export below.

So let’s get started! Add a class to your project and call it Forklift.cs. Then adjust the class so it inherits from DrawableGameComponent. This makes sure that our LoadGraphicsContent, Update and Draw method will be called automatically. When you’re writing a full game, you’ll probably write your own component based system, but for this tutorial, DrawableGameComponent will do just fine.public class Forklift : DrawableGameComponent

Then we’ll add 3 variables to our class. The first containing the content manager, which will load our content. The second a variable which will contain our model, and last but not least, a variable which will contain the bone transforms of our model (the transform of each bone relative to the parent bone). // A variable containing our content manager
private ContentManager _content;
// Our model
private Model _model;
// Array holding all the bone transform matrices for the entire model.
// We could just allocate this locally inside the Draw method, but it
// is more efficient to reuse a single array, as this avoids creating
// unnecessary garbage.
Matrix[] _boneTransforms;

Then add the following constructor, where we’ll pass the Game class to the base class and save a reference to our content manager: public Forklift(Game game, ContentManager content)
: base(game)
{
_content = content;
}

Now there are 2 things we have to do left: load the model and draw it. We’ll load the model in the LoadGraphicsContent method. protected override void LoadGraphicsContent(bool loadAllContent)
{
_model = _content.Load("Content/forklift");
// Allocate the transform matrix array.
_boneTransforms = new Matrix[_model.Bones.Count];

In the first line, we load our model using the content manager and store it in de _model variable. In the second line we make an instance of our _boneTransforms matrix, and give it the number of bones in the model as size. In the third line, I’m just rotating the model 90 degrees, so we’ll see it from the side instead of from the front. The last line is just there so we’d see the model better ;-).

That’s it! Our model is loaded, now let’s draw it.
Drawing the model will of course be done in the Draw method. First we’ll copy our absolute bone transforms to our _boneTransforms matrix. Then we’ll loop over all the model’s meshes, and draw them using their effects. An effect is a shader, which tells your graphics card how to draw stuff. Everything in XNA has to be drawn using shaders. We’ll pass the world, view and projection to this shader, and enable default lighting, so our model is lit properly. More on world, view and projection in our camera tutorial. public override void Draw(GameTime gameTime)
{
_model.CopyAbsoluteBoneTransformsTo(_boneTransforms);
// Draw the model.
foreach (ModelMesh mesh in _model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = _boneTransforms[mesh.ParentBone.Index];
effect.View = Matrix.CreateLookAt(new Vector3(1000, 500, 0),
new Vector3(0, 150, 0),
Vector3.Up);

If using XNA Game Studio 4.0, simply change references to LoadGraphicsContent to LoadContent. You don’t need any boolean any more.

Also, this tutorial only mentions the new Class. You can analyze “the complete source code”, but it’s so easy to add three lines yourself to the Game1 class:
1. Add a field to the top of the class:
ContentManager content;
2. Set the field in the constructor Game1() :
content = new ContentManager(Services);
3. Finally, add this line to Initialize()
this.Components.Add(new Forklift(this, content));

No Software to Buy – You never have to download or fiddle witth complicated software.
Multiple and fractional distillation methods are needed to impact
on the perfformance of your cell phone safe? Cell phone calls cannot be placed through paranormal means.