Read and Write VertexBuffer and IndexBuffer Data With GraphicsStreams

This example demonstrates how to use GraphicsStream objects to fill and retrieve data from a VertexBuffer and IndexBuffer objects.

[C#]
In the following C# code example, a VertexBuffer object is created using a flexible vertex format (FVF) type defined by the PositionNormalTexVertex structure. The vertex buffer data is then locked using its offset and size in bytes. A GraphicsStream object is returned which is derived from StreamLeave Site and can be used in a similar fashon. In the code example, the Write method is used to copy data into the stream from an array of vertex data.
The second part of the method shows use of GraphicsStream using unsafe data access. The InternalDataPointerGraphicsStream.InternalData property returns a void pointer to the vertex buffer data. In this code example, the data is cast to an array of PositionNormalTexVertex structures which makes data manipulation more readable.

using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

public struct PositionNormalTexVertex
{
    public Vector3 Position;
    public Vector3 Normal;
    public  float Tu0, Tv0;
    public static readonly VertexFormats FVF = VertexFormats.Position | VertexFormats.Texture1;
}
public class Example
{
    public unsafe void  GraphicsStreamReadWrite()
    {
        //Create a vertex buffer in the managed pool
        VertexBuffer vb = new VertexBuffer(typeof(PositionNormalTexVertex), 100, device, Usage.None, PositionNormalTexVertex.FVF, Pool.Managed);

        //First, fill an array of PositionNormalTexVertex elements with data.
        PositionNormalTexVertex[] vertices = new PositionNormalTexVertex[50];
        for(int i=0; i<50; i++)
        {
            //fill the vertices with some data...
            vertices[i].Position = new Vector3(3f,4f,5f);
        }

        //The size of the verticies are 32-bytes each (float3 (12) + float3 (12) + float(4) + float(4))
        //To lock 50 verticies, the size of the lock would be 1600 (32 * 50)
        GraphicsStream vbData =  vb.Lock(0,1600, LockFlags.None);

        //copy the vertex data into the vertex buffer
        vbData.Write(vertices);

        //Unlock the VB
        vb.Unlock();


        //This time, lock the entire VertexBuffer
        vbData =  vb.Lock(0, 3200, LockFlags.None);

        //Cast the InternalDataPointer (a void pointer) to an array of verticies
        PositionNormalTexVertex* vbArray = (PositionNormalTexVertex*) vbData.InternalDataPointer;

        for(int i=0; i<100; i++)
        {
            //perform some operations on the data
            vbArray[i].Tu0 = i;
            vbArray[i].Tv0 = vbArray[i].Tu0 * 2;

            Console.WriteLine(vbArray[i].Tv0.ToString());
        }

        //Unlock the buffer
        vb.Unlock();
        vb.Dispose();
    }
}