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.

ForkliftForklift WireframeForkliftForklift WireframeForklift Export

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];

//rotate the model 90 degrees
_model.Root.Transform *= Matrix.CreateRotationY(MathHelper.ToRadians(90));

base.LoadGraphicsContent(loadAllContent);
}

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);

effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
GraphicsDevice.Viewport.Width / GraphicsDevice.Viewport.Height,
10,
10000);

effect.EnableDefaultLighting();
}

mesh.Draw();
}

base.Draw(gameTime);
}

If you want to know why exactly you have to draw a model like this, check out this post on Shawn Hargreaves Blog.
That’s it! When you run the project, you should see the image shown below.
Drawing a 3D Model

As usual, you can download the complete source code.

In the next tutorials, we’ll animate the model and put in a camera.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

20 thoughts on “Getting started with XNA – Drawing a 3D Model

  1. Pingback: 3D Game Programming - Getting started with XNA - Animating a 3D Model - XNA News and Tutorials - DirectX News and Tutorials

  2. Could you tell me where I can get this model? I’m really interested in it and I would like to export it myself so the scale is not as big as it is right now.

    Thanks!

  3. 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));

    Great tutorial.

  4. This tutorial looks awesome. I’m excited to see how ContentManager is used, but the download links are not working. Would you mind emailing me the complete source?

  5. I want to to thank you for this excellent read!
    ! I absolutely enjoyed every bit of it. I have you book-marked to look at new stuff
    you post…

  6. 40 Mins Free Cell Phone Number Search – How To Find Freee Cell Phone NumbersPlaying” Magic” on my guitar with a corpuscle
    phoneNeed I cell tower leasing say more?

    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.

  7. Hey I know this is off topic but I was wondering if you knew of any widgets
    I could add to my blog that automatically tweet my newest twitter updates.
    I’ve been looking for a plug-in like this for quite some time and was
    hoping maybe you would have some experience with something like this.

    Please let me know if you run into anything.
    I truly enjoy reading your blog and I look forward to your new updates.

  8. Whats up are using WordPress for your site platform?

    I’m new to the blog world but I’m trying to get started
    and set up my own. Do you need any html coding expertise to make your
    own blog? Any help would be greatly appreciated!

  9. Does your blog have a contact page? I’m having problems locating it
    but, I’d like to shoot you an e-mail. I’ve
    got some ideas for your blog you might be interested
    in hearing. Either way, great blog and I look forward to seeing it develop over
    time.

  10. Hey there I am so delighted I found your website, I really found you by
    error, while I was researching on Askjeeve for something else,
    Anyhow I am here now and would just like to say cheers for
    a fantastic post and a all round entertaining blog (I also love the theme/design), I don’t have time to read through it all at the moment
    but I have saved it and also added your RSS feeds, so when I have time I
    will be back to read a great deal more, Please
    do keep up the fantastic work.

  11. Great weblog here! Also your site loads up fast!

    What web host are you using? Can I get your associate link in your host?
    I want my website loaded up as fast as yours lol

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>