Drawing Primitives

Introduction

Primitives in XNA consists of lines and triangle based primitives. Primitives are used to build simple graphical structures in XNA without the use of a DCC tool. The main things needed to rendera primitive are;

  1. an array of vertex information, storing position and other attributes of the vertices
  2. a vertex declaration, telling the graphics card how to interpret the vertex data
  3. DrawUserPrimitives function to instruct the graphics card which primitive to draw

Full project here.

#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion

namespace drawprimitives
{
    /// 
    /// This is the main type for your game
    /// 
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        ContentManager content;

        VertexPositionColor[] vertices = new VertexPositionColor[6];
        VertexDeclaration vertexDeclaration;
        BasicEffect basicEffect;

        float angle;


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            content = new ContentManager(Services);
        }


        /// 
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// 
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here


            basicEffect = new BasicEffect(graphics.GraphicsDevice, null);
            basicEffect.VertexColorEnabled = true;
            basicEffect.View = Matrix.CreateLookAt(new Vector3(0, 0, 500), new Vector3(0, 0, 0), Vector3.Up);

            basicEffect.Projection= Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4.0f,
                (float)graphics.GraphicsDevice.Viewport.Width / (float)graphics.GraphicsDevice.Viewport.Height,
                0.1f,
                100000);

            // create a vertex declaration, which tells the graphics card what kind of
            // data to expect during a draw call. We're drawing using
            // VertexPositionColors, so we'll use those vertex elements.
                       
            vertexDeclaration = new VertexDeclaration(graphics.GraphicsDevice, VertexPositionColor.VertexElements);

            // create our triangle
            // because our triangle consist of 3 lines, we need 6 vertices (for each line the beginning and the ending).
            // notice that we have to send some vertices twice to our graphics card.
            vertices[0].Position = new Vector3(0, 0, 0);
            vertices[0].Color = Color.Red;

            vertices[1].Position = new Vector3(0, 100, 0);
            vertices[1].Color = Color.Red;

            vertices[2].Position = new Vector3(0, 100, 0);
            vertices[2].Color = Color.Red;

            vertices[3].Position = new Vector3(100, 100, 0);
            vertices[3].Color = Color.Red;

            vertices[4].Position = new Vector3(100, 100, 0);
            vertices[4].Color = Color.Red;

            vertices[5].Position = new Vector3(0, 0, 0);
            vertices[5].Color = Color.Red;

            


            base.Initialize();
        }


        /// 
        /// Load your graphics content.  If loadAllContent is true, you should
        /// load content from both ResourceManagementMode pools.  Otherwise, just
        /// load ResourceManagementMode.Manual content.
        /// 
        /// Which type of content to load.
        protected override void LoadGraphicsContent(bool loadAllContent)
        {
            if (loadAllContent)
            {
                // TODO: Load any ResourceManagementMode.Automatic content
            }

            // TODO: Load any ResourceManagementMode.Manual content

        }


        /// 
        /// Unload your graphics content.  If unloadAllContent is true, you should
        /// unload content from both ResourceManagementMode pools.  Otherwise, just
        /// unload ResourceManagementMode.Manual content.  Manual content will get
        /// Disposed by the GraphicsDevice during a Reset.
        /// 
        ///Which type of content to unload.
        protected override void UnloadGraphicsContent(bool unloadAllContent)
        {
            if (unloadAllContent == true)
            {
                content.Unload();
            }
        }


        /// 
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input and playing audio.
        /// 
        /// Provides a snapshot of timing values.
        protected override void Update(GameTime gameTime)
        {
            // Allows the default game to exit on Xbox 360 and Windows
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }


        /// 
        /// This is called when the game should draw itself.
        /// 
        /// Provides a snapshot of timing values.
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;

            // TODO: Add your drawing code here
           

            graphics.GraphicsDevice.VertexDeclaration = vertexDeclaration;
            // tell our basic effect to begin.
            angle += 0.01f;
            basicEffect.World = Matrix.CreateRotationZ(angle);
            basicEffect.Begin();
            basicEffect.CurrentTechnique.Passes[0].Begin();

            graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.LineList, vertices, 0, 3);

            // tell basic effect that we're done.
            basicEffect.CurrentTechnique.Passes[0].End();
            basicEffect.End();

            base.Draw(gameTime);
        }
    }
}