This is the third in a series of tutorials which will allow you to create your own game engine (from initialization, to a fully rotatable, height mapped 3D world!).
In this tutorial, we will use Direct3D to create and render a primitive, as well as learn some more DirectX concepts.
The code from these tutorials is taken from my own game engine: MAGEngine.NET, at different stages in development.
You may use all of the code I provide as how you see fit, except to create another tutorial. You can use it as a sturdy(ish ;)) framework for your own applications, or print loads of copies off so that when I'm rich and famous you can sell them for $100 each ;)
To do this series of tutorials, you will need:
OK, in the last tutorial, we spent a long time discussing various aspects of the Direct3D component, we created a good, solid sample framework, but we never got to render anything � which is the whole concept of Direct3D. In this tutorial, we will:
cObject class to use in our game All 3D worlds - whether it is a character, terrain, or a box - are made out of triangles. And all these triangles are essentially three points, or vertices. So, to render our triangle, we will need to define three of these "points" and send them to be rendered in our OnPaint function. In Managed DirectX, there is a set of structures made to represent different types of these points, known as the CustomVertex class.
From this you, can choose a "point" structure to suit your needs - if you want a textured box which you could rotate, then you would choose PositionTextured; if you want that box to be shaded, then you would choose PositionNormalTextured. For today, we will be creating a static, colored triangle, so we will be using CustomVertex.TransformedColored points.
Transformed indicates that the coordinates we define have been declared as screen coordinates, and do not need to be scaled, rotated, or otherwise.
Now, your initial reaction may be to jump straight into the code and render your triangle - but first, we should create a class to help us with this.
We will be making two classes, one called cObject which contains an array of CustomVertex.TransformedColored(s?), and a bool indicating if we should render the triangle (IsActive). We will then make a class representing a triangle. It will inherit cObject, but will have two functions: an initialization function where it defines the array and any coordinates, and its own render function.
In Direct3D, the best way to render is to use the OnPaint event, as we did in the previous tutorial. But, it will make life a lot easier in the future if we can set up all the framework in OnPaint, and just call this render method. We could even do it within a for() loop for arrays of triangle objects.
The above classes will be declared in a new file called cObject, and are as follows:
public class cObject
{
public CustomVertex.TransformedColored[] itsVertices;
}
public class cTriangle : cObject
{
bool isActive;
//Should this primitive be rendered?
public cTriangle(CustomVertex.TransformedColored[] itsVerts)
{
itsVertices = new CustomVertex.TransformedColored[3];
isActive = true; itsVertices[0] = itsVerts[0];
//Assign the parameter vertices to that of the object
itsVertices[1] = itsVerts[1];
itsVertices[2] = itsVerts[2];
}
public void Render(Device device)
{
device.DrawUserPrimitives(PrimitiveType.TriangleList,
1, itsVertices;);
// Generic code for the primitive to 'render itself'
}
As you can see, the cObject class is fairly simple - only containing an unassigned array of TransformedColored vertices. The cTriangle class only adds the isActive member, and the initialization and render functions.
The Render function, as you can see, calls the function DrawUserPrimitives(). This is a function, obviously used to render primitives. You give it a PrimitiveType - this simply tells DirectX 'how' to render the vertices. There are many examples, and displayed below you can see how they impact the positioning of the primitive:

The other parameters are fairly simple - how many primitives to render (=1) and then the source (or where the primitives to be rendered can be found). So, now that we have this class updated, we only have two more things to do to get our triangle rendered:
cTriangle object
OnPaint method to render the triangle So, with this class created, it should be easy to create an instance of your class - make a public cTriangle object in your window class (I will call mine "Tri" in the samples). Now comes a slightly tricky part which we will resolve in the next tutorial.
We need to create a CustomVertex.TransformedColored array to assign to the cTriangle instance we will be creating and pass through its constructor. To do this, use the following code in your main() method, nothing should be fairly new here:
CustomVertex.TransformedColored[] Verts =
new CustomVertex.TransformedColored[3];
Verts[0] = new CustomVertex.TransformedColored(new
Vector4(100.0f, 100.0f, 0.0f, 1.0f), Color.Red.ToArgb());
Verts[1] = new CustomVertex.TransformedColored(new
Vector4(200.0f, 100.0f, 0.0f, 1.0f), Color.Blue.ToArgb());
Verts[2] = new CustomVertex.TransformedColored(new
Vector4(150.0f, 200.0f, 0.0f, 1.0f), Color.Green.ToArgb());
OK, the only thing slightly strange here should be the Vector4 structure. The last parameter is known as the RHW, which is only used in transformed coordinates as it is used in perspectives. I would highly recommend to not bother about this - we will never be using it again after this tutorial when we use positioned coordinates, and it will always be 1.0 for this tutorial. For this triangle, the Z coordinate will always be 0.0f. The ToArgb() function converts a .NET color to its Alpha-Red-Green-Blue value. For example, White, when converted to ARGB brings the value (0,255,255,255) (ignoring A which is Alpha, or transparency) because of course, white is a mixture of all the colors, whereas Red would convert to (0,255,0,0), and so on.
Now, make a call to your triangle's constructor and pass in the vertices defined above as the parameter. Then, go to the OnPaint event of your form and we will finish this tutorial.
From OnPaint, erase everything in it.
OnPaint will be called in every single frame, every time the display needs to be updated. So, we need to do a number of things:
Invalidate function for .NET The reason for locking and unlocking the GPU during rendering is to reduce errors at run time. When we render, we render to what is called a back buffer. This is an off-screen surface where any data can be stored until we call the device.Present() function to copy it to the on screen surface.
To code, this translates as:
device.Clear(ClearFlags.Target,
System.Drawing.Color.Black, 1.0f, 0);
//Clear display
device.VertexFormat =
CustomVertex.TransformedColored.Format;
//Notify GPU which vertices
device.BeginScene(); //Lock GPU
Triangle.Render(device); //Render primitives
device.EndScene(); //Unlock GPU
device.Present(); //Swap old with new
this.Invalidate(); //call invalidate
This should make up the entire body of the OnPaint function.
If you compile and run this code, you should see a blended-colour triangle on your screen.
OnPaint event so that it can render all initialized triangles without us needing to edit it every time we add or remove one from the array. Please send all emails to xpyder@magclan.cwhnetworks.com. I do have MSN Messenger, my email address for this is jamespraveen@aol.com.
| You must Sign In to use this message board. | ||||||
|
||||||
|
||||||
|
||||||