XNA for C#
DirectX 9 for C#
DirectX 9 for C++
DirectX 9 for VB
Forum
   2D Series finished!
My Book: Out Now!
      
       Go to section on this site

Additional info


Latest Forum posts

 Texture on a 3d Object
  Posted by: ToastbrotX
  When: 10/09/2010 at 10:23:08

 Unable to Build
  Posted by: Rich_Zap
  When: 09/09/2010 at 15:39:33

 HLSL calculating normals
  Posted by: Rich_Zap
  When: 09/09/2010 at 15:34:56

 Texture on a 3d Object
  Posted by: ToastbrotX
  When: 09/09/2010 at 11:14:19

 DRIVER ERROR XBOX 360
  Posted by: Anonymous
  When: 09/09/2010 at 01:12:47

 Reflection problem in corners ...
  Posted by: Anonymous
  When: 08/09/2010 at 21:03:35

 Texture on a 3d Object
  Posted by: radulph
  When: 08/09/2010 at 17:34:01

 InvalidDataException???
  Posted by: Anonymous
  When: 08/09/2010 at 09:10:36

 Unable to Build
  Posted by: Anonymous
  When: 08/09/2010 at 07:49:36

 Suggestion to change a few lines
  Posted by: Insomnica
  When: 06/09/2010 at 14:37:05


Ads

Textures

Up till now, the only way we’ve seen to add some color to our scene is to declare separate vertices for every different color. Of course, this is not the way today’s great games are being made. XNA supports a very efficient way of adding color and images to the scene: you can simply put an image on a triangle. Such images are called textures.

As a first example, we’re going to draw 1 simple triangle, and cover it with a texture. You can find a sample texture here (link) (you can download the image as a file by right-clicking on the image, and selecting Save Image). Import the image into the Content entry of your XNA Solution Explorer, just as you’ve done for your effect file.

When you click on the file in the Content entry of your Solution Explorer, you can see in the property box at the bottom-right of your screen that this asset has the name ‘riemerstexture’. You can change this to your liking, but leave it like this for now.

In our code, we are going to add a new variable to hold this texture image. Add this line to the top of your code:

 Texture2D texture;
 Now find the LoadContent method in your code. Add this line under the line where you load your effect file:

texture = Content.Load<Texture2D> ("riemerstexture");
This line binds the asset we just loaded in our project to the texture variable!

With our texture loaded into our XNA project, it’s time to define 3 vertices, which we’ll be storing in an array. As our vertices will need to be able to store both a 3D position and a texture coordinate (explained below), the vertex format will be VertexPositionTexture, so declare this variable at the top of your code. We also need to have a new VertexDeclaration, as we need to tell the graphics card what kind of information is stored in each vertex:

 VertexPositionTexture[] vertices;
 VertexDeclaration texturedVertexDeclaration;

Next we’ll be defining the 3 vertices of our triangle in our SetUpVertices method we’ll create:

 private void SetUpVertices()
 {
     vertices = new VertexPositionTexture[3];
 
     vertices[0].Position = new Vector3(-10f, 10f, 0f);
     vertices[0].TextureCoordinate.X = 0;
     vertices[0].TextureCoordinate.Y = 0;
 
     vertices[1].Position = new Vector3(10f, -10f, 0f);
     vertices[1].TextureCoordinate.X = 1;
     vertices[1].TextureCoordinate.Y = 1;
 
     vertices[2].Position = new Vector3(-10f, -10f, 0f);
     vertices[2].TextureCoordinate.X = 0;
     vertices[2].TextureCoordinate.Y = 1;
 
      texturedVertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements);
 }

As you see, for every vertex we first define its position in 3D space. Notice again that we have defined our vertices in a clockwise way, so XNA will not cull them away (see the “World Space” chapter in series 1).

The next 2 settings are very important, as they define which point in our texture image we want to correspond with the vertex. These coordinates are simply the X and Y coordinates of the texture, with the (0,0) texture coordinate being the top left point of the texture image, the (1,0) texture coordinate the top-right point and the (1,1) texture coordinate the bottom-right point of the texture.

The last line creates the VertexDeclaration suited for the VertexPositionTexture.

Don’t forget to call the SetUpVertices method from your LoadContent method:

 SetUpVertices ();

OK, we have our vertices set up, and our texture image loaded into a variable. Let’s draw the triangle!

Go to our Draw method, and add this code after our call to the Clear method:

 Matrix worldMatrix = Matrix.Identity;
 effect.CurrentTechnique = effect.Techniques["Textured"];
 effect.Parameters["xWorld"].SetValue(worldMatrix);
 effect.Parameters["xView"].SetValue(viewMatrix);
 effect.Parameters["xProjection"].SetValue(projectionMatrix);
 effect.Parameters["xTexture"].SetValue(texture);
 effect.Begin();
 foreach (EffectPass pass in effect.CurrentTechnique.Passes)
 {
     pass.Begin();
 
      device.VertexDeclaration = texturedVertexDeclaration;
     device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, 1);
 
     pass.End();
 }
 effect.End();

As usual, we indicate which technique we want the graphics card to use to render the triangle to the screen. We need to instruct our graphics card to sample the color of every pixel from the texture image. This is exactly what the Textured technique of my effect file does, so we set it as active technique.

As explained in Series 1, we need to set the World matrix to identity so the triangles will be rendered where we defined them, and View and Projection matrices so the graphics card can map the 3D positions to 2D screen coordinates.

Finally, we pass our texture to the technique. Then we actually draw our triangle from our vertices array, as done before in the first series.

Running this should already give you a textured triangle, displaying half of the texture image! To display the whole image, we simply have to expand our SetUpVertices method by adding the second triangle:

 private void SetUpVertices()
 {
      vertices = new VertexPositionTexture[6];
 
      vertices[0].Position = new Vector3(-10f, 10f, 0f);
      vertices[0].TextureCoordinate.X = 0;
      vertices[0].TextureCoordinate.Y = 0;
 
      vertices[1].Position = new Vector3(10f, -10f, 0f);
      vertices[1].TextureCoordinate.X = 1;
      vertices[1].TextureCoordinate.Y = 1;
 
      vertices[2].Position = new Vector3(-10f, -10f, 0f);
      vertices[2].TextureCoordinate.X = 0;
      vertices[2].TextureCoordinate.Y = 1;
 
      vertices[3].Position = new Vector3(10.1f, -9.9f, 0f);
      vertices[3].TextureCoordinate.X = 1;
      vertices[3].TextureCoordinate.Y = 1;
 
      vertices[4].Position = new Vector3(-9.9f, 10.1f, 0f);
      vertices[4].TextureCoordinate.X = 0;
      vertices[4].TextureCoordinate.Y = 0;
 
      vertices[5].Position = new Vector3(10.1f, 10.1f, 0f);
      vertices[5].TextureCoordinate.X = 1;
      vertices[5].TextureCoordinate.Y = 0;
 
      texturedVertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements);
 }

We simply added another set of 3 vertices for a second triangle, to complete the texture image. Don’t forget to adjust your Draw method so you render 2 triangles instead of only 1:

 device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, 2);

Now run this code, and you should see the whole texture image, displayed by 2 triangles!




DirectX Tutorial 2 - Textures

If you appreciate the amount of time I spend creating and updating
these pages, feel free to donate -- any amount is welcome !



Click here to go to the forum on this chapter!

Or click on one of the topics on this chapter to go there:
  • Texture on a 3d Object
          Hi, I want to put an image on a 3d Object. How c...
  • InvalidOperationException error help!
          When I compile the code it is fine,however when it...
  • scaling textures
          I am using a bmp file as a texture for a mesh of a...
  • NullReferenceExeption
          Compiling goes well, but when I try to run the app...
  • Error loading "riemerstexture".
          `Error loading "riemerstexture". File not found....
  • Doesn't work
          When I debug the game it highlights the line:
  • Indices?
          Hey there, I was wondering if we didn't use indic...
  • Code brings up blank screen
          Hi, Excellent tutorials :) I'm having a bit o...



    You’ll notice the small gap between both triangles... This is of course because we defined the positions of the vertices that way, so you can actually see the image is made out of two separate triangles.

    You can try these exercises to practice what you've learned:
  • Try to remove the gap between the triangles.
  • Play around with the texture coordinates in the SetUpVertices method, it’s worth it!! You can choose any value between 0 and 1.
    The code for displaying this texture:

     using System;
     using System.Collections.Generic;
     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.Net;
     using Microsoft.Xna.Framework.Storage;
     
     namespace XNAseries2
     {
      public class Game1 : Microsoft.Xna.Framework.Game
      {
      GraphicsDeviceManager graphics;
      GraphicsDevice device;
     
      Effect effect;
      Matrix viewMatrix;
      Matrix projectionMatrix;
     
      Texture2D texture;
     
      VertexPositionTexture[] vertices;
      VertexDeclaration texturedVertexDeclaration;
     
      public Game1()
      {
      graphics = new GraphicsDeviceManager(this);
      Content.RootDirectory = "Content";
      }
     
      protected override void Initialize()
      {
      graphics.PreferredBackBufferWidth = 500;
      graphics.PreferredBackBufferHeight = 500;
      graphics.IsFullScreen = false;
      graphics.ApplyChanges();
      Window.Title = "Riemer's XNA Tutorials -- Series 2";
     
      base.Initialize();
      }
     
      protected override void LoadContent()
      {
      device = graphics.GraphicsDevice;
     

    effect = Content.Load<Effect> ("effects");

    texture = Content.Load<Texture2D> ("riemerstexture");
     
      SetUpVertices();
      SetUpCamera();
      }
     
      private void SetUpVertices()
      {
      vertices = new VertexPositionTexture[6];
     
      vertices[0].Position = new Vector3(-10f, 10f, 0f);
      vertices[0].TextureCoordinate.X = 0;
      vertices[0].TextureCoordinate.Y = 0;
     
      vertices[1].Position = new Vector3(10f, -10f, 0f);
      vertices[1].TextureCoordinate.X = 1;
      vertices[1].TextureCoordinate.Y = 1;
     
      vertices[2].Position = new Vector3(-10f, -10f, 0f);
      vertices[2].TextureCoordinate.X = 0;
      vertices[2].TextureCoordinate.Y = 1;
     
      vertices[3].Position = new Vector3(10.1f, -9.9f, 0f);
      vertices[3].TextureCoordinate.X = 1;
      vertices[3].TextureCoordinate.Y = 1;
     
      vertices[4].Position = new Vector3(-9.9f, 10.1f, 0f);
      vertices[4].TextureCoordinate.X = 0;
      vertices[4].TextureCoordinate.Y = 0;
     
      vertices[5].Position = new Vector3(10.1f, 10.1f, 0f);
      vertices[5].TextureCoordinate.X = 1;
      vertices[5].TextureCoordinate.Y = 0;
     
      texturedVertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements);
      }
     
      private void SetUpCamera()
      {
      viewMatrix = Matrix.CreateLookAt(new Vector3(0, 0, 30), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
      projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 0.2f, 500.0f);
      }
     
      protected override void UnloadContent()
      {
      }
             protected override void Update(GameTime gameTime)
             {
                 base.Update(gameTime);
             }
     
     
     
      protected override void Draw(GameTime gameTime)
      {
      device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.DarkSlateBlue, 1.0f, 0);
     
      Matrix worldMatrix = Matrix.Identity;
      effect.CurrentTechnique = effect.Techniques["Textured"];
      effect.Parameters["xWorld"].SetValue(worldMatrix);
      effect.Parameters["xView"].SetValue(viewMatrix);
      effect.Parameters["xProjection"].SetValue(projectionMatrix);
      effect.Parameters["xTexture"].SetValue(texture);
      effect.Begin();
      foreach (EffectPass pass in effect.CurrentTechnique.Passes)
      {
      pass.Begin();
     
      device.VertexDeclaration = texturedVertexDeclaration;
      device.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, 2);
     
      pass.End();
      }
      effect.End();
     
      base.Draw(gameTime);
      }
      }
     }
     


    Google
     
    Webwww.riemers.net


    If you appreciate the amount of time I spend creating and updating
    these pages, feel free to donate -- any amount is welcome !



    - Website design & XNA + DirectX code : Riemer Grootjans -
    ©2003 - 2008 Riemer Grootjans
  • Translations

    This site in English
    This site in Korean
    This site in Czech

    Microsoft MVP Award



    2007 - 2009 MVP Award
    DirectX - XNA

    Contents

    News
    Home
    Forum
    XNA 2.0 Recipes Book (8)
    Chapter 1
    Chapter 2
    Chapter 3
    Chapter 4
    Chapter 5
    Chapter 6
    Chapter 7
    Chapter 8
    XNA 3.0 Recipes Book (8)
    Chapter 1
    Chapter 2
    Chapter 3
    Chapter 4
    Chapter 5
    Chapter 6
    Chapter 7
    Chapter 8
    Downloads
    Extra Reading (3)
    Matrices: geometrical
    Matrix Mathematics
    Homogenous matrices
    Community Projects (1)
    Team Project (1)
    News
    Tutorials (160)
    XNA 3.0 using C# (89)
    2D Series: Shooters! (22)
    Starting a project
    Drawing fullscreen images
    Positioning images
    SpriteBatch.Draw()
    Rotation
    Keyboard input
    Writing text
    Angle to Direction
    Direction to Angle
    Smoke trail
    Manual texture creation
    Random terrain
    Texture to Colors
    Coll Detection Overview
    Coll Detection Matrices
    Putting CD into practice
    Particles
    Additive alpha blending
    Particle engine
    Adding craters
    Sound in XNA
    Resolution independency
    3D Series 1: Terrain (13)
    Starting a project
    The effect file
    The first triangle
    World space
    Rotation - translation
    Indices
    Terrain basics
    Terrain from file
    Keyboard
    Adding colors
    Lighting basics
    Terrain lighting
    VertexBuffer & IndexBuffer
    3D Series 2: Flightsim (14)
    Starting point
    Textures
    Loading the floorplan
    Creating the 3D city
    Loading a Model
    Ambient and diffuse
    Quaternion camera
    Flight kinematics
    Collision detection
    Adding targets
    Point sprites
    Alpha blending
    Skybox
    Camera delay
    3D Series 3: HLSL (18)
    Starting point
    HLSL introduction
    Vertex format
    Vertex shader
    Pixel shader
    Per-pixel colors
    Textured triangle
    Triangle strip
    World transform
    World normals
    Per-pixel lighting
    Shadow map
    Render to texture
    Projective texturing
    Real shadow
    Shaping the light
    2D screen processing
    Preshaders
    3D Series 4: Adv. terrain (19)
    Starting code
    Mouse camera
    Textured terrain
    Multitexturing
    Adding detail
    Skydome
    The water technique
    Refraction map
    Reflection map
    Perfect mirror
    Ripples
    The Fresnel term
    Moving water
    Specular highlights
    Billboarding
    Region growing
    Billboarding renderstates
    Perlin noise
    Gradient skybox
    Short Tuts (3)
    Run XNA on older pcs
    MessageBox in XNA
    Normal generation
    DirectX using C# (54)
    Series 1:Terrain (14)
    Opening a window
    Linking to the Device
    Drawing a triangle
    Camera
    Rotation - Translation
    Indices
    Terrain creation
    Terrain from file
    DirectInput
    Importing bmp files
    Colored vertices
    DirectX Light basics
    Mesh creation
    Mesh lighting
    Series 2: Flightsim (19)
    Starting code
    Textures
    The floorplan
    Creating the 3D City
    Meshloading from file
    Ambient light
    Action
    Flight kinematics
    Collision detection
    Skybox
    Texture filtering
    Adding targets
    Point sprites
    Alpha blending
    DirectSound
    Sounds in 3D
    Playing MP3 files
    Displaying text
    Going fullscreen
    Series 3: HLSL (19)
    Starting point
    HLSL Introduction
    Vertex Shader
    Shaded triangle
    Pixel Shader
    Textured Triangle
    Triangle Strip
    World transform
    Adding normals
    The first light
    Shadow mapping
    Render To Texture
    Projective texturing
    The first shadow
    Shaping the light
    Preshaders
    Multiple lights
    Adjusting Z values
    Finishing touch
    Short Tuts (2)
    Resizing problem
    Checking Device caps
    DirectX using C++ (15)
    Series 1: Terrain (15)
    Opening a window
    Ending the game loop
    Linking to the Device
    Clearing your window
    Drawing a triangle
    Culling
    Camera
    Rotation - Translation
    Indices
    Terrain creation
    Terrain from file
    DirectInput
    Importing .bmp files
    Adding colors
    DirectX Light basics
    DirectX using VB (2)
    Series 1: Intro (2)
    The first triangle
    Rotation - translation
    -- Tree view --


    Thank you!

    Support this site --
    any amount is welcome !

    Stay up-to-date

    I don't have the time to keep a News section, so stay informed about the updates by clicking on this RSS file!