Still with me huh? Mebbe my last tutorial wasn’t so boring after all, or is it that you just want to make DirectXGraphics actually do something huh? Heh, whatever the cause, unfortunately, there’s a LOT more theory in this one, and less code...
First of all, for the sake of those who don’t know, I’m sure you’ll want to know what a vertex (plural vertices) even is!
Well, to put it in it’s simplest terms, a vertex is a point in 3D space. For instance, the planet earth could be a vertex, the sun another, and pluto the third. This is all we really need to make the simplest kind of polygon possible. A triangle. Yes, now we’re going to write an addition to our original code to make it render a single triangle.
When you’re dealing with DirectX however, a vertex can have more properties than just an X, Y, and Z location. It also can have a Normal, which tells us which way it’s facing, and a colour value. There are other possibilities, but for the purpose of these tutorials, these are all we’ll be using.
Now... when you’re creating vertices, you can either let DirectX transform (slide the vertex up and down, back and front) and light (colour the vertex) itself, or choose to do them yourself.
Unfortunately, transformation (The basis of 3D animation) and lighting is a little more advanced than you’re probably ready for, those are actually for parts 3 and 4, so keep with us. In the meantime, we’re going to take the simple way and do it all ourselves. Doing it ourselves means we don’t need to define a light in 3D space and we won’t need to find out where the camera is in order to actually show it.
Right! That’ll do for the theory for now :) what we’re going to do next is create a FVF, a Flexible Vertex Format. Because there are soooo many possibilities to how vertices are created, DirectX lets us make out own Vertex Formats, which I think is pretty cool.
So open up a copy of your tutorial from before (or the same copy if you’d like...) and right up the top, let’s add in our user defined type-FVF
Private Type typUDVertex |
Okay, so first of all, our vertex will have an X component on the screen, a Y component on the screen, a Z theoretical position, this will always be a value between 1 and 0 (Depending on how the window is defined and it’s actual position in 3D space) the vertex will either be facing towards the user, or away from them, and lastly, a 32-bit colour.
No problems? I should hope not! :) This is only the start.
Next we’re going to edit our objects declarations and add in our vertex buffer to the list.
Dim devDG as Direct3DDevice8 |
And lastly in the declarations, a constant which will tell our DirectXGraphics device how our FVF is set out!
Dim ProgramExiting as Boolean |
Okay, that was pretty quick and painless huh? Well, just to confuse you, I’m going to explain how the hell you define your vertices and what the hell those two constants we "or"ed together do.
[D3DFVF_XYZRHW] |
Easy? Well, now that we’ve set up our program for our new vertices, let’s initialise our Vertex Buffer and set up a triad of vertices huh? In the demo tutorial, I’ve placed it just after the D3DInit function, just for clarity, but it doesn’t matter where you put it...
End Function |
Okay, that’s a pretty simple initialisation function compared to the DirectXGraphics initialisation... and three times easier to explain too Phew.
The very first line is a familiar error checking line, if an error occurs in any DX calls, it’ll bomb out with an error message.
Next we’ve got two declarations,
Vertices(2) Which is a FVF, and is where we will temporarily store our vertices until they are passed into our Vertex Buffer.
VertexSize, which in a second will have the size of one array element placed in it. Since when we place the information in the vertex Buffer, it’s going to want to know how much information it’s going to be able to grab. Like giving a blind man his food. He’ll get angry at you if he’s expecting a three course meal and you just give him a bowl of Jelly (Jello for you americans/canadians :P)
The next line is where just that happens, we grab the (Len)gth of one element and place it in VertexSize. That lines a no-brainer.
The next three lines take some vertex data and put it into our little vertex array. For those of you who tried to run the program would probably have noticed that "CreateVertex" isn’t defined. That’s because that’s a small function I wrote to simplify things. We’ll make that in two seconds.
Basically, we’re just passing into each "vertices" element an x, y, z, rhw, and colour, as we specified in our FVF.
Okay, now we’ve got another of those weird DirectXGraphics methods... This line actually creates the Vertex Buffer into something usable, and it’s going to want to know a couple of things.
object.CreateVertexBuffer(LengthInBytes As Long, Usage As Long, FVF As Long, Pool As CONST_D3DPOOL) As Direct3DVertexBuffer8 |
Okay, I hope the basic parts of that, (not the pooling stuff and usage) are understandable. Pretty much you’d use 0 for the usage, and either D3DPOOL_DEFAULT or D3DPOOL_MANAGED as the pooling.
Anyway, back to the topic, our last major line, is the line which submits our buffer data to our brand new vertex buffer.
D3DVertexBuffer8SetData(VBuffer As Direct3DVertexBuffer8, Offset As Long, Size As Long, Flags As Long, Data As Any) As Long |
The next line just says, if no errors occurred, then it was successful, so set the function to true (Successful) and exit the sub.
Following that is the error checking code, where, if an error was raised, set the function to false (Failed) and exit the sub.
Right, now that we’ve gotten the initialisation off the ground let’s get rid of that nasty function not defined...
End Function |
This function is pretty easy to comprehend, basically what we’re doing, is passing parameters to a with statement. Which is storing the information as the functions return. Basically this means you’re saving yourself about 15 lines of code. And makes it easier to read, which is always important.
It’s very important to note that if you ever decide to use a function like this in your own programs, you’ll need to change it to reflect the FVF that you use... if you don’t use un-lit vertices, you don’t need the .color line, because it won’t exist in the FVF...
Having said that, let’s head back into our Sub Form_Load and put in our initialisation commands and declarations we’ll need for the next bit:
Private Sub Form_Load |
This is almost exactly the same as the one just above it calling the D3DInit function, except that it’s got a different Error message.
On a small unimportant note, feel free to change the name of your new project, because you’re creating vertices in this one, not devices.
Only two things left now, drawing the graphics on the screen, and cleaning up after ourselves...
I didn’t explain the top three lines which we added, they were to help us render our picture, since when we’re rendering the vertices, it will need to know once more how big the elements are. So we’ve declared a single element and a variable to store the size, followed by the third line actually working out the size of the element.
Now, time to paint! Remember in the last tutorial, I pointed out that all rendering must be done between a .StartScene and a .EndScene? Well, let’s start coding between them.
devDG.BeginScene |
Goodie, three new DirectXGraphics commands to explain! The first two are Incredibly simple to explain.
.SetStreamSource simply tells the DirectXGraphics device where its going to get the vertex information from. I suppose they call it a stream because it’s like a streamer (a party ribbon), where you could write a long line of text on It and everything you wrote would be one after the other.
object.SetStreamSource(StreamNumber As Long, StreamData As Direct3DVertexBuffer8, Stride As Long) |
Next we have the .SetVertexShader which just tells the DirectXGraphics device, what the FVF is.
object.SetVertexShader(VertexShaderHandle As Long) |
And lastly, the .DrawPrimitive method. This actually renders a vertex buffer from a screen onto the backbuffer. It has a few options that will take a little to explain, specifically the part about the primitive type.
When Drawing Primitives, you can render them in a number of different ways, you can render by points, called a point list, and looks something like this:

Next we have line lists. These are singular lines joined by only two vertices, for example:

Thirdly, we have line stips. Similar to Line lists, this is one continuous line which turns at each vertex:

Next we have Triangle lists, which turns 6 points into two separate triangles:

Two more to go. Triangle Strips, also known as a wireframe, these give users a detailed look at what exactly they are looking at:

Finally, we have the triangle fan, which looks like one of those Japanese fans which we all probably have made as children:

Okay, hopefully now you’ll have an idea of what DirectX Primitives are and what they can do. Having explained that, let’s have a look at the .DrawPrimitive Command Syntax.
object.DrawPrimitive(PrimitiveType As CONST_D3DPRIMITIVETYPE, StartVertex As Long, PrimitiveCount As Long) |
No Problems! We could run the program now... But we’ve left an open opportunity for a memory leak, so lets finish off out shut down subroutine...
Private Sub Form_Unload(Cancel as Integer) |
Woo hoo! We’re done for the second part. Now I know this part won’t be as boring as you’d first thought, because when you run this program, you’re not just going to get a boring triangle. It would be a boring triangle if we were using lighting from DirectX, but we’re not. We’ve coloured every vertex and instead we've got a tripping interpolated triangle.
Next we’re going to take out our program’s ability to transform for itself, and work on animation, using DirectXGraphics’s transformation abilities. Starting to get a little more interesting huh?
If there is any information here guys that you know that I don’t, or if you find a better way to explaining something please don’t hesitate to E-Mail me at CodeWarrior@octa4.net.au