Getting started with XNA – Primitives: the basics part 1

Because every object in 3d is drawn using triangles, you should know how to perform this basic task. In this chapter, we’ll go about drawing primitives, such as triangles and squares, with different techniques. So let’s start by creating a new project and naming it. Then add a class to it called TriangleLineList and make it inherit from DrawableGameComponent.
public class TriangleLineList: DrawableGameComponent

The reason we do this is because XNA is component based. This means that a whole architecture has been set up for you, so you can keep your game class well-organized. This will become more clear as we go on in the tutorial, where you will see that a lot of the methods in our TriangleLineList class will be called automatically by our game.

Ok, the next step is to create a constructor.
public TriangleLineList(Game game)
: base(game) { }

Now, we will add some variables to our TriangleLineList. First off all, we’ll need to add a BasicEffect. A BasicEffect is just a class that will contain the shader our graphics card will need to draw our triangle. Just like in DirectX 10, you need a shader for everything you want to draw. Luckily, XNA has provided a BasicEffect class, which contains some logic, so we don’t have to write a shader ourselves (for now). More on shaders in our separate section that will come soon.
// a basic effect, which contains the shaders that we will use to draw our
// primitives.
BasicEffect basicEffect;

A triangle is defined by 3 points, which is defined by a Vector3, containing the X, Y and Z coordinate (3D space), and maybe some additional information, such as color. Such a point is called a vertex. XNA has some vertex structures embedded, and one of them is perfect for this example: VertexPositionColor. So let us add this to our class.
// an array of the vertices that have to be drawn
VertexPositionColor[] vertices = new VertexPositionColor[6];

You might wonder why we need 6 vertices to draw a triangle, which only has 3 corners. That’s because in this example, we’ll use a LineList to draw. This means that the triangle will be drawn using separate lines. A triangle has 3 lines, which all have a starting and ending point, so 3 * 2 = 6.

The graphicsdevice has to know what type of vertices to expect. That’s why we have to add a VertexDeclaration variable. the vertex declaration that will be set on the device for drawing will be created automatically using VertexPositionColor’s vertex elements.
VertexDeclaration vertexDeclaration;

Ok, now we’re ready to initialize our variables. Since we inherit from DrawableGameComponent, there is a function that will be called automatically when your content has to be loaded, the perfect function to initialize our variables that have to be re-initialized after our graphics card has lost focus. So override this function: LoadGraphicsContent.
protected override void LoadGraphicsContent(bool loadAllContent)
{
base.LoadGraphicsContent(loadAllContent);
}

The first thing we’ll do in that subroutine is initializing our BasicEffect and make sure that is allows vertex colors.
basicEffect = new BasicEffect(GraphicsDevice, null);
basicEffect.VertexColorEnabled = true;

When you’re trying to display something on the screen, you need to position it. Because we’re only drawing 2D, we’ll have to find a way to tell the graphics card that. That’s where the BasicEffect comes in again. Add this code below the previous code:
// projection uses CreateOrthographicOffCenter to create 2d projection
// matrix with 0,0 in the upper left.
basicEffect.Projection = Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width,
GraphicsDevice.Viewport.Height, 0,
0, 1);

Bare with me, we’re almost there. Now we need to declare our vertices and draw the damn thing. First things first: initialize our VertexDeclaration and initialize our vertices:
// 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(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(50, 100, 0);
vertices[0].Color = Color.Red;

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

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


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

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

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

Notice that we have to send some vertices to our graphics card twice! That’s because we are drawing our triangles by the individual lines. In the next example, we’ll fix this.
Also make sure that you set up your vertices in a clockwise order. If not, you won’t see your triangle. This is because XNA (and DirectX) doesn’t draw things unless they are in clockwise order. The reason for this is that XNA thinks that things that are defined counter-clockwise are not facing the camera, and thus needn’t to be drawn. You can undo this by changing the renderstate of the graphics device:
GraphicsDevice.Renderstate.CullMode = CullMode.None;

Now the only thing to do left, is draw our triangle and add it to the components of our game class.
To draw the triangle, we need to override the draw method, so it will be called automatically.

public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
// prepare the graphics device for drawing by setting the vertex declaration
GraphicsDevice.VertexDeclaration = vertexDeclaration;
// tell our basic effect to begin.
basicEffect.Begin();
basicEffect.CurrentTechnique.Passes[0].Begin();

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

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

When you are drawing something, the first thing you need to do is tell the graphics card that you are ready to start drawing (basicEffect.Begin();). Because a shader (in our case the BasicEffect) can have multiple passes, we tell that we want to use the first one. More on shaders later. Then we have to draw our triangle. Notice that the last parameter is 3, because we are drawing 3 lines.

Ok, now go to your game class, and in the Initialize method, add the following code:
// add our components to this game.
// because XNA is component based, the Draw, Update, Initialize en LoadGraphicsContent of those objects
// will be called automatically, so no need to set up a whole object model. This is done for you.
this.Components.Add(new TriangleLineList(this));

When you press F5 now, a triangle should pop up.
Our first triangle

This concludes the first part of the basics. In the second part, we’ll see other ways of drawing, so we don’t have to send our vertices twice to our graphics card. In the third part, we’ll draw rectangles and introduce the index buffer concept.

You can download the source here.