Tutorial 1: Displaying a 3D Model on the Screen

This article details how to use the XNA Framework Content Pipeline to load a 3D model and its associated textures, and it presents the code necessary to display the model on the screen.

The Complete Sample

The code in this tutorial illustrates the technique described in the text. A complete code sample for this tutorial is available for you to download, including full source code and any additional supporting files required by the sample.


In Your First Game: Microsoft XNA Game Studio in 2D, you saw a simple example that used the XNA Framework Content Pipeline to load a sprite, represented by a Texture2D object. You also used the XNA Framework to draw the sprite on the screen. This tutorial goes beyond that simple sample to help introduce you to many concepts that XNA Game Studio makes easy, so you can focus on making fun, interactive games.

This first tutorial will introduce you to the Content Pipeline in a little more detail, and will introduce you to some of the XNA Framework API calls you will use to draw 3D objects on the screen. When you complete this tutorial, you'll have a 3D model drawing on your screen. The model will have textures and lighting. Let's get started!

Step 1: Downloading the Art Assets

The first thing that you will need before you start coding are some art assets to play around with. In this case, you need a 3D model, and an associated texture file so that the model has some detail. These assets will be loaded into your game using the XNA Framework Content Pipeline, which is a feature built right into the Solution Explorer feature of supported version of Microsoft Visual Studio tools.

You can find these assets in this sample file (GoingBeyond1_Tutorial_Sample.zip). Download the sample file now and extract its contents to a directory on your local drive.

Step 2: Creating the New Project

Now that the art assets are available to you, the next step is to create the actual code project that you will be writing.

  • Click the File menu, and then click New Project to create a new project. A dialog box will appear with a tree list on the left pane, marked Project Types.

  • Select the XNA Game Studio 3.0 tree node underneath the Visual C# node. A set of available projects will appear in the right pane.
  • In the right pane of the dialog box, click either Windows Game (3.0) or Xbox 360 Game (3.0), depending on whether you are developing on the Xbox 360 or Windows. If you develop for Xbox 360, be sure you have a membership in the XNA Creators Club as described in Connecting to Your Xbox 360 Console with XNA Game Studio 3.0 Otherwise, you will not be able to play your game!
  • Type a name for your game into the Name field, and a path to where you want the game files stored in the Location field.
  • Click OK.

The code for your new game will be displayed. The project already contains many of the methods that are needed to start and run a game. Right now, however, you need to make sure your art assets are being loaded. Then you can modify the game to display them on the screen. Follow these steps to get some art into your project.

  • Make sure you can see the Solution Explorer for your project on the right side of the window. If you cannot see it, click the View menu, and then click Solution Explorer. When it appears, you will see files associated with your project in a tree structure.
  • In Solution Explorer, look for a node named Content. This is where you will store the art and audio for your game. You must add two folders underneath this one.
  • Right-click the Content node, click Add, and then click New Folder. This will create a new folder under the Content node. Name this folder Models.
  • Repeat the last step, creating a new folder under the Content node. This time, call the folder Textures.

Your project structure should look similar to this:


You are now ready to add the art from the previously downloaded sample file. The first is a 3D model that will go into this new Content\Models folder, and the second is a texture that will be drawn on the 3D model; this will go in the Content\Textures folder. The files you need are included in the Content sub-project from the GoingBeyond1_Tutorial_Sample.zip file. To add them:

  • Right-click the Models folder in the Solution Explorer, click Add, and then click Existing Item. Using the dialog box that appears, browse back to the path you extracted the contents of the sample file to and find the Contents\Models folder. Select p1_wedge.fbx. If you cannot see any files, make sure you change the Files of type selection box to read Model Files. Click OK.
  • Now, copy the texture associated with the model into the Textures folder. To do this, open a Windows Explorer window and browse to the Content\Textures folder of the extracted sample. Copy wedge_p1_diff_v1.tga, and then browse to your project folder, then into the Content\Textures folder, and paste in the file you just copied.

Note that you do not see the texture you added in Solution Explorer. When you add a model, the textures that the model uses do not need to be added to the Content Pipeline. If you need to add textures that you will access manually (such as textures used for 2D sprite drawing), do so via Solution Explorer. Otherwise, you can simply copy the texture files to the appropriate folder.

When the files are added to the project, the Content Pipeline automatically identifies them as content files and sets the appropriate processors to run when you build your project. This will happen silently; you will not need to do anything. If you would like to learn more about the Content Pipeline, see Content Pipeline.

Model files contain path information for the textures they use. The ship model you recently added to your project expects to find its texture in a Textures folder that exists alongside the folder the model is in. This will be true for all models used in this tutorial. Models you create or retrieve from other sources may have different path requirements and therefore may require different folder setups. Determine the correct texture paths by examining the model files, or compiling the model as part of your game using XNA Game Studio and noting any Content Pipeline path errors that are returned.

At this point, you are ready to code.

Step 3: Load the Model by Using the Content Pipeline

Take a look at the code for Game1.cs. It should still be on your screen from opening up your project. You will see a lot already done for you. Each of the methods already in the code are waiting for you to drop in your own calls to the XNA Framework. For now, start by modifying the LoadContent method.

  • In the code, find the LoadContent method.
  • Modify the code (including adding the lines shown above the method) to look like this:

    // Set the 3D model to draw.
    Model myModel;
    // The aspect ratio determines how to scale 3d to 2d projection.
    float aspectRatio;
    protected override void LoadContent()
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);
        myModel = Content.Load<Model>("Models\\p1_wedge");
        aspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;

In that step, you have told the Content Pipeline to load your model into your game when LoadContent is called at the beginning of your game. Note how you have to pass in the path to the asset relative to your project directory. Also note that there is no extension on the asset anymore. The name of the asset can be anything you want, but by default it is the name of the asset file minus its extension. To see more information on how to change the name of your asset, see Game Asset Properties.

The code now loads the model. Your next step is to get it showing on the screen.

Step 4: Display the Model on the Screen (and Make It Rotate)

You will want to modify two of the methods in your Game1.cs file.

  • In the Draw method, you will draw the model on the screen with texture and lighting.
  • In the Update method, you will make the model change its orientation based on time, so it appears to rotate over time.

Do the harder work first—drawing the model. The first step is to use some XNA Framework methods to set up the model's position and lighting.

  • In the code, find the Draw method.
  • Modify the code (including adding the lines shown above the method) to look like this:

    // Set the position of the model in world space, and set the rotation.
    Vector3 modelPosition = Vector3.Zero;
    float modelRotation = 0.0f;
    // Set the position of the camera in world space, for our view matrix.
    Vector3 cameraPosition = new Vector3(0.0f, 50.0f, 5000.0f);
    protected override void Draw(GameTime gameTime)
        // Copy any parent transforms.
        Matrix[] transforms = new Matrix[myModel.Bones.Count];
        // 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.World = transforms[mesh.ParentBone.Index] * Matrix.CreateRotationY(modelRotation)
                    * Matrix.CreateTranslation(modelPosition);
                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.

This code uses helper methods provided by the XNA Framework to set up the necessary 3D math and lighting to display the model on the screen. Use the World matrix to change the position of the model in the world, the View matrix to change the position and direction of the camera (your eye), and the Projection matrix to control how the view of the 3D world is turned into a 2D image (projected) on your screen.

The call to CopyAbsoluteBoneTransformsTo and associated code inside the setup of the World matrix are not strictly necessary for this model. However, when using more complicated models, which often use hierarchical structure (where mesh positions, scales, and rotations are controlled by "bones"), this code ensures that any mesh is first transformed by the bone that controls it, if such a bone exists. The mesh is then transformed relative to the bone transformation.

If you compile and run your code now, you will see your model on the screen! It is a spaceship with detail texture. But if you can resist the urge to compile your project and run, you can easily make the model rotate in real-time so you can see all of it:

  • In the code, find the Update method.
  • Modify the code (including adding the lines shown above the method) to look like this:

    protected override void Update(GameTime gameTime)
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        modelRotation += (float)gameTime.ElapsedGameTime.TotalMilliseconds * MathHelper.ToRadians(0.1f);

And that's it. Compile and run your project by hitting the F5 key or clicking the Debug menu, and then clicking Start Debugging.



You did it. There is a lot to making games, but you have taken the first step. A 3D model with lighting and movement in real time. From here, there is no limit to where you could go!

For simplicity's sake, we took some shortcuts that could be optimized for better performance. An obvious improvement would be to precalculate the View and Projection matrices instead of calculating them every time Draw is called, since they do not change. Try out this optimization as a first step. When you are ready to make your game interactive, go to the next tutorial.


Ideas to Expand

Got the urge to tinker with the project a bit? Try these ideas.

Community Additions