Using a Basic Effect with Texturing

Demonstrates how to create and draw a simple quad—two triangles that form a rectangle or square—using DrawUserIndexedPrimitives.

This sample introduces the Quad class, which is used to construct a quad with a list of vertices and indices suitable for drawing with DrawUserIndexedPrimitives. The sample also demonstrates how to use BasicEffect to render the quad and to apply a texture to the primitive. For more information about BasicEffect, see Creating a Basic Effect.

Bb464051.graphics_TexturedQuad(en-us,XNAGameStudio.41).jpg

Complete Sample

The code in the topic shows you the technique for creating and drawing a quad. You can download a complete code sample for this topic, including full source code and any additional supporting files required by the sample.

Download TexturedQuad_Sample.zip.

Textured Quad

To create a quad

  1. Determine the location of each of the four vertices in the quad.

    The Quad constructor calculates the four corners given the origin, width, height, and facing information supplied by the caller.

    public Quad( Vector3 origin, Vector3 normal, Vector3 up, 
        float width, float height )
    {
        Vertices = new VertexPositionNormalTexture[4];
        Indexes = new short[6];
        Origin = origin;
        Normal = normal;
        Up = up;
    
        // Calculate the quad corners
        Left = Vector3.Cross( normal, Up );
        Vector3 uppercenter = (Up * height / 2) + origin;
        UpperLeft = uppercenter + (Left * width / 2);
        UpperRight = uppercenter - (Left * width / 2);
        LowerLeft = UpperLeft - (Up * height);
        LowerRight = UpperRight - (Up * height);
    
        FillVertices();
    }
    
  2. Determine the UV coordinates for the texture you want to apply to the quad.

    Note

    UV coordinates are derived from texture coordinates that are mapped into values along a u-axis and a v-axis. The u represents width, and v represents height.

    The Quad constructor calls FillVertices, which assigns UV coordinates ranging from (0,0) to (1,1), and makes the entire texture appear on the quad.

    private void FillVertices()
    {
        // Fill in texture coordinates to display full texture
        // on quad
        Vector2 textureUpperLeft = new Vector2( 0.0f, 0.0f );
        Vector2 textureUpperRight = new Vector2( 1.0f, 0.0f );
        Vector2 textureLowerLeft = new Vector2( 0.0f, 1.0f );
        Vector2 textureLowerRight = new Vector2( 1.0f, 1.0f );
    
  3. Determine the normals for your vertices.

    FillVertices copies the normal vector you provide to each vertex.

    // Provide a normal for each vertex
    for (int i = 0; i < Vertices.Length; i++)
    {
        Vertices[i].Normal = Normal;
    }
    
  4. Copy the position and texture coordinate data to your vertex array.

    // Set the position and texture coordinate for each
    // vertex
    Vertices[0].Position = LowerLeft;
    Vertices[0].TextureCoordinate = textureLowerLeft;
    Vertices[1].Position = UpperLeft;
    Vertices[1].TextureCoordinate = textureUpperLeft;
    Vertices[2].Position = LowerRight;
    Vertices[2].TextureCoordinate = textureLowerRight;
    Vertices[3].Position = UpperRight;
    Vertices[3].TextureCoordinate = textureUpperRight;
    
  5. Fill out the index buffer to determine what order your vertices are drawn by the graphics hardware.

    Drawing two triangles requires four vertices, but six index entries if you are using a PrimitiveType.TriangleList. The indices are specified in clockwise order. XNA is a right-handed coordinate system so triangles drawn in counter-clockwise order are assumed to be facing away from the camera which causes them to be culled.

        // Set the index buffer for each vertex, using
        // clockwise winding
        Indexes[0] = 0;
        Indexes[1] = 1;
        Indexes[2] = 2;
        Indexes[3] = 2;
        Indexes[4] = 1;
        Indexes[5] = 3;
    }
    

To draw a quad

  1. In your game's Initialize method, create a new Quad object specifying the location, the normal (the direction the quad faces), the Up vector, and the width and height of the quad.

    You can also create a view and projection matrix to use when rendering.

    Quad quad;
    VertexDeclaration vertexDeclaration;
    Matrix View, Projection;
    protected override void Initialize()
    {
        quad = new Quad(Vector3.Zero, Vector3.Backward, Vector3.Up, 1, 1);
        View = Matrix.CreateLookAt(new Vector3(0, 0, 2), Vector3.Zero,
            Vector3.Up);
        Projection = Matrix.CreatePerspectiveFieldOfView(
            MathHelper.PiOver4, 4.0f / 3.0f, 1, 500);
    
        base.Initialize();
    }
    
  2. In your game's LoadContent method, load the texture you want to apply to the quad using the ContentManager.

  3. Create and initialize a new BasicEffect object.

  4. Set TextureEnabled to true, and assign the texture to draw to the Texture property.

    Texture2D texture;
    BasicEffect quadEffect;
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);
        texture = Content.Load<Texture2D>("Glass");
        quadEffect = new BasicEffect(graphics.GraphicsDevice);
        quadEffect.EnableDefaultLighting();
    
        quadEffect.World = Matrix.Identity;
        quadEffect.View = View;
        quadEffect.Projection = Projection;
        quadEffect.TextureEnabled = true;
        quadEffect.Texture = texture;
    
  5. In LoadContent, create a VertexDeclaration for the vertex type used to define the quad, which included position, normal and texture coordinates.

    vertexDeclaration = new VertexDeclaration(new VertexElement[]
        {
            new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
            new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
            new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
        }
    );
    
  6. Use DrawUserIndexedPrimitives in each EffectPass to draw the quad.

  7. Use the Vertices and Indices properties on the Quad structure to supply the primitive data, and specify two triangles to draw.

    GraphicsDevice.Clear(Color.CornflowerBlue);
    
    foreach (EffectPass pass in quadEffect.CurrentTechnique.Passes)
    {
        pass.Apply();
    
        GraphicsDevice.DrawUserIndexedPrimitives
            <VertexPositionNormalTexture>(
            PrimitiveType.TriangleList,
            quad.Vertices, 0, 4,
            quad.Indexes, 0, 2);
    }
    

See Also

Concepts

3D Pipeline Basics

Tasks

Creating a Basic Effect

Reference

BasicEffect
VertexDeclaration
DrawUserIndexedPrimitives