Tutorial 2: Rendering Vertices

Applications written in Microsoft Direct3D use vertices to draw geometric shapes. Each three-dimensional (3-D) scene includes one or more of these geometric shapes. The Vertices tutorial project begins with the initialization procedures of Tutorial 1: Creating a Device and then creates the simplest shape, a triangle, and renders it to the display.

Path

Source location: (SDK root)\Samples\Managed\Direct3D\Tutorials\Tutorial2

Procedure

This tutorial renders a 2-D triangle by using three vertices. This introduces the concept of the vertex buffer, usually a VertexBuffer object that is used to store and render vertices.

Vertices can be defined in many ways through available structures in the CustomVertex custom vertex class. In this case, the vertices are transformed, so the vertices are already in 2-D window coordinates. The point (0,0) is therefore at the upper left corner, the positive x-axis is right, and the positive y-axis is down. These vertices also do not use Direct3D lighting, but instead they supply their own diffuse color. This character is specified by initializing the vertex buffer with the CustomVertex.CustomVertex.TransformedColored structure, as in the following code fragment.

          [C#]
          public class Vertices : Form
{
    // Global variables for this project
    Device device = null; // Rendering device
    VertexBuffer vb = null;
    .
    .
    .
    public void OnCreateDevice(object sender, EventArgs e)
    {
    Device dev = (Device)sender;
    
    // Now create the vertex buffer
    vertexBuffer = new VertexBuffer(
        typeof(CustomVertex.TransformedColored), 3, dev, 0, 
        CustomVertex.TransformedColored.Format, Pool.Default);
    vertexBuffer.Created += 
        new System.EventHandler(this.OnCreateVertexBuffer);
    this.OnCreateVertexBuffer(vb, null);
    }

    public void OnCreateVertexBuffer(object sender, EventArgs e)
    {
    VertexBuffer vb = (VertexBuffer)sender;
    GraphicsStream stm = vb.Lock(0, 0, 0);
    CustomVertex.TransformedColored[] verts =
        new CustomVertex.TransformedColored[3];
    .
    .
    .
    vb.Unlock();
    }
}

In the above code, the VertexBuffer.Lock method is called to grant direct CPU access to the vertex buffer data. Each lock call must be followed by an unlock call. See Locking Resources for more information on locking and unlocking.

The verts object created in the above code is an array of three CustomVertex.TransformedColored structures, one structure for each of the triangle's three vertices. The (X,Y,X), Rhw, and Color fields of each vertex structure are initialized in the following code. The ToArgbLeave Site method is used to provide color data in the required ARGB 32-bit format.

          [C#]
          verts[0].X=150; verts[0].Y=50; verts[0].Z=0.5f; verts[0].Rhw=1; 
verts[0].Color = System.Drawing.Color.Aqua.ToArgb();

verts[1].X=250; verts[1].Y=250; verts[1].Z=0.5f; verts[1].Rhw=1;
verts[1].Color = System.Drawing.Color.Brown.ToArgb();

verts[2].X=50; verts[2].Y=250; verts[2].Z=0.5f; verts[2].Rhw=1;
verts[2].Color = System.Drawing.Color.LightPink.ToArgb();

stm.Write(verts);

The GraphicsStream class (stm object) was introduced in the above two code fragments. A graphics stream is used to bind data to input registers for use by shaders. This code provides the GraphicsStream object direct access to the vertex buffer, or, understood in another way, it places the vertex buffer contents into the graphics stream and advances the current position within the stream by the length of the vertex buffer.

The following code fragment shows how the private Render method is expanded from Tutorial 1 to initialize the stream source, vertex format, and primitives rendering of the Device object. As in Tutorial 1, Render renders to the display as long as the current Vertices object (frm) is valid, or if a system paint event is triggered.

          [C#]
          private void Render()
{
    if (device == null)
    return;
    
    // Clear the back buffer to a blue color (ARGB = 000000ff)
    device.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1.0f, 0);
    // Begin the scene
    device.BeginScene();
    
    // New for Tutorial 2
    device.SetStreamSource(0, vertexBuffer, 0);
    device.VertexFormat = CustomVertex.TransformedColored.Format;
    device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
    
    // End the scene
    device.EndScene();
    device.Present();
}