Tutorial 2 - Rendering a triangleBy Pieter Germishuys, January 4 2006 |
Here we are again. Ready for another tutorial? That's good. Let's get started then.
Today we are going to discuss quite a few things. This will be a very huge step so buckle up.
Firstly. Let us assume that you know a little about 3d coordinate spaces. If not, the DirectX API documentation has a nice section on them.
I really thought about this and decided to start from the very beginning. an Atom (Vertex). This is your building block very much like it's the building block for anything in the world we live in. We are really just simulating the world aren't we?
a Vertex is a point. a Vertex has an x, y and z coordinate, other than that it can also have color and a normal vector (do not worry about this too much now). a Vector is a quantity that has magnitude and direction. Now that we know what a point is how do we use them? We aren't really going to be drawing points on the screen, cause that's just plain boring so what we are going to do is draw a triangle. a Triangle is defined by 3 points.
In fig1.0 you will see that each point has a vertex. You are probably thinking but what about the lines? Direct3d helps us in that sense as it has a few ways of connecting the vertices. For the purpose of the exercise we are going to be using a TriangleStrip. a TriangleStrip takes the first 3 vertices and connects them. The vertices will be specified in a clockwise-winding. Consider fig1.1. | |
Fig1.1 shows the points that we will be specifying for Direct3d. The easiest way to accomplish this would be to use an array wouldn't it? But we also need to tell Direct3d what information is stored. This is where the Flexible Vertex Format comes in. It's a structure that tells Direct3d what order we stored the data in. Managed Direct3d really makes it easy. So let's dive in. |
We will first create a method called createTriangle where we will be creating the vertices and storing them in an array and after that into a buffer where Direct3d will read and render them from.
Firstly we create an array of CustomVertex.PositionColored which is a predefined class and tells Direct3d that our array data will be holding values in the following order, (x, y, z) and a color. Next we use the constructor of this class to create a vertex at each point using the points in fig 1.0. Following that we have something called a vertex buffer. a Vertex Buffer is exactly what it says it is. It's a buffer that holds vertices. Direct3d can read and write to this buffer depending on what we want to do. Let's look at how we create this buffer.
public VertexBuffer(Type, int, Device, Usage, VertexFormats, Pool);
The first parameter to the constructor is a Type the vertex buffer will be holding.
The second parameter is an integer and will be the number of vertices the buffer will hold.
Third is our Direct3d device.
Fourth is a Usage flag. This will specify how we will be using the buffer. We are just going to write to it. We specify Usage.WriteOnly.
Fifth is our Vertex Format.
Sixth describes how the vertex buffer should be handled in memory. We ask Direct3d to manage it for us.
Let's move on. The GraphicsStream object that we created is a way of accessing the buffer's memory. We need to be able to write to the memory of this buffer to get those triangle points in there. So when we call the Lock() method it returns the vertex buffer memory. We then write the array to the stream and then Unlock() the vertex buffer.
private VertexBuffer vb; public void createTriangle() { ??????CustomVertex.PositionColored[] triangle = new CustomVertex.PositionColored[3]; //create an array of 3 vertices ??????//using the CustomVertex.PositionColored constructor to set each vertex ??????triangle[0] = new CustomVertex.PositionColored(-0.1f, 0.0f, 1.0f, Color.Blue.ToArgb()); ??????triangle[1] = new CustomVertex.PositionColored(-0.1f, 0.2f, 1.0f, Color.Red.ToArgb()); ??????triangle[2] = new CustomVertex.PositionColored(0.1f, 0.0f, 1.0f, Color.Green.ToArgb()); ??????vb = new VertexBuffer(typeof(CustomVertex.PositionColored), 3, direct3d.XilathDevice, Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Managed); ??????GraphicsStream stm; //our GraphicsStream object that we will use to access the ??????//lock the VB. Locks a range of vertex data and obtains the vertex buffer memory and stores?it in the GraphicsStream object (stm) ??????stm = vb.Lock(0, 0, LockFlags.None); ??????stm.Write(triangle); //write the triangle array to the GraphicsStream Object ??????vb.Unlock(); //unlock the VertexBuffer, we are finished writing the data to it. } |
Let's render our triangle.
SetStreamSource() basically sets the vertex buffer.
The first parameter is the number of streams we will be using.
The second parameter is the Vertex Buffer object.
Third is the offset from the beginning of the buffer to the beginning of the vertex data (bytes).
VertexFormat describes to the device what vertex format we will be drawing.
DrawPrimitives() takes 3 parameters.
First is the primitive type. Ours is PrimitiveType.TriangleStrip.
Second is the index of the first vertex to load.
Third is the number of primitives to render.
public void Render() { ??????direct3d.BeginRender(Color.Black); //render our scene with the background as black ??????direct3d.XilathDevice.SetStreamSource(0, vb, 0); ??????direct3d.XilathDevice.VertexFormat = CustomVertex.PositionColored.Format; ??????direct3d.XilathDevice.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 1); ????? direct3d.FinishRender(); //finish rendering our scene } |
Files for this tutorial
Filename | Size |
? tut2.rar | 101.1 KB |