Some C++ Debugging Advice – use #ifdef
If you are an experienced c++ programmer you can stop reading, nothing I cover here will be of any use to you. I’m just writing a little post on a simple little preprocessor trick that c++ programmers have been using for years. Using the #ifdef directive to tag blocks of debugging code.
So lets we have a function that does something like searching through a tree, while debugging we’d like to lets say have a counter to count all the nodes visited during the search but of course in the released version we don’t need this counter using up precious resources. lets have some example code:
double counter;
void treeSearch::visitNode(node* n)
{
... some code ...
counter++;
}
Some beginner programmers would probably do this:
bool debugMode = false;
double counter;
void treeSearch::visitNode(node* n)
{
... some code ...
if ( debugMode) counter++;
}
Yeh, that works but now every time you visit a node, the program evaluates an if statement, not to mention the memory for the counter has still been allocated. Yes in this case memory cost is pretty negligible but that is not always the case. So how can we improve upon this? The answer is by using basic pre-processor directives, more specifically conditional inclusions (#ifdef). Simply put these directives mark code for inclusion into the program during compile time if some condition is met.
so our code would now look as follows:
#ifdef _DEBUG
double counter;
#endif
void treeSearch::visitNode(node* n)
{
... some code ...
#ifdef _DEBUG
counter++;
#endif
}
So now those lines will only be included if _DEBUG is defined, what this means is that the counter variable and the code that increments it doesnt get compiled, and your program is as fast as possible and still has debugging functions. You can set the _DEBUG flag in your code manually by using the define directive: #define _DEBUG, or if your IDE supports it, multiple compile profiles, one of which defines _DEBUG before compiling. Visual studio by default defines _DEBUG when compiling using the Debug profile.
So that was a very simple and brief tutorial on something pretty much most C++ programmers know, but i posted it just in case some didnt
My attempt at a DX10 game engine… Name Ideas
So I’ve started with developing the AI test bed for my masters experiments, and since I kinda wanted something that looked nice, I basically started developing a game engine without knowing it
I’ve been working on it for around a week now, and have a very basic renderer and a basic camera system going… The next step will be developing the scene graph and spatial data structures needed for rendering. I’ve been doing so much reading on scene graphs and so one that it’s coing out my ears and yet I’m not any closer to having an idea on a good solution. I could probably do my entire masters on scene graphs and spatial sorting.
Anyways I’m going to discontinue my DX10 tutorials since all the future tutorials will anyways be based off of my engine, so I’m going to start a new series of tutorials on building a very basic dx0 game engine.
The amount of files in the projects are growing and I need to come up wiht a nice name so i can start encapsulating the classes in namespaces, and have a nice uniform naming across the components, since the engine is going to be super super simple i was thinking as using one of the following as the engine name:
- Cimplicity
- basikEngine
- CimplEngine
- SimplEngine
- engineBasix
Any other suggestions?
DirectX 10 Tutorial 5: Basic Meshes
Since my car has been broken for the last two days, I’ve taken off work and have been working on my Masters degree, since part of my Masters involves building a small “game engine” for AI testing, I’ve been doing some more DX10 work, so its convenient for me to quickly slap together a few more tutorials.
Mesh Basics
I covered the basics of indexed buffers and the depth testing in the last tutorial, in this short tut, I’m going to cover the basics of directX meshes. A mesh is a data structure that contains all the vertex and index buffers needed to draw an object. It’s a neater method of drawing objects as we’ll see.
There are four steps to using meshes:
- Create the mesh
- Fill the Mesh with the index and vertex data necessary
- Commit the mesh to the device
- Draw the mesh
So let’s create a new mesh, first things first, we’ll define an ID3DX10Mesh* pointer called pMesh.
//create mesh
if ( FAILED( D3DX10CreateMesh( pD3DDevice, vertexInputLayout, 2, "POSITION", 8, 12, D3DX10_MESH_32_BIT, &pMesh) ) ) return fatalError("Could not create mesh!");
//vertices for a cube
vertex v[8];
v[0] = vertex( D3DXVECTOR3(-1,1,-1), D3DXVECTOR4(1,0,0,1) ); //front top left
v[1] = vertex( D3DXVECTOR3(1,1,-1), D3DXVECTOR4(0,1,0,1) ); //front top right
v[2] = vertex( D3DXVECTOR3(-1,-1,-1), D3DXVECTOR4(0,0,1,1) ); //front bottom left
v[3] = vertex( D3DXVECTOR3(1,-1,-1), D3DXVECTOR4(1,1,0,1) ); //front bottom right
v[4] = vertex( D3DXVECTOR3(-1,1,1), D3DXVECTOR4(1,0,0,1) ); //back top left
v[5] = vertex( D3DXVECTOR3(1,1,1), D3DXVECTOR4(0,1,0,1) ); //back top right
v[6] = vertex( D3DXVECTOR3(-1,-1,1), D3DXVECTOR4(0,0,1,1) ); //back bottom left
v[7] = vertex( D3DXVECTOR3(1,-1,1), D3DXVECTOR4(1,1,0,1) ); //back bottom right
//create indexes for a cube
unsigned int i[36] = { 2,0,3,3,1,0,
3,1,7,7,5,1,
6,4,2,2,0,4,
7,5,6,6,4,5,
0,4,1,1,5,4,
6,2,7,7,3,2 };
//insert data into mesh and commit changes
pMesh->SetVertexData(0, v);
pMesh->SetIndexData(i, 36);
pMesh->CommitToDevice();
Now we use D3DX10CreateMesh to create the mesh, the parameters are the d3d device, the vertex input layout, number of elements in the vertex layout, the name of the element that stores the vertex position, number of vertices, number of faces, mesh flag and finally the output mesh pointer.
There is a little trick here, remember how before we had triangle strips? Here we don’t, we have to specify every single triangle (referred to as a face in the mesh) by hand. So our index list looks a bit different from before.
To add the vertex data and index data, we simply use the mesh SET methods, a mesh can have multiple vertex buffers and so when you set a vertex buffer, you need to specify in which slot you wish to store it. The index data SET method simply takes the index array and the number of indexes in it.
The final step is to commit the mesh, every time you make a change to a mesh you need to commit it to the device before the changes will be taken into effect.
Drawing the Mesh
So how do we draw a mesh?
for( UINT p = 0; p < techDesc.Passes; p++ )
{
//apply technique
pBasicTechnique->GetPassByIndex( p )->Apply( 0 );
pMesh->DrawSubset(0);
}
How simple is that? We use the draw subset method of the mesh interface to draw the mesh, the value given to the method specifies with attribute group to draw, attribute groups for meshes will be covered in a later tutorial, for now just specify 0. And that’s how to create and draw a basic mesh.
I’ve updated the draw code to render a bunch of spinning cubes just for fun:

Source Code
Source code: tutorial5.zip
DirectX 10 Tutorial 4: Indexed Buffers and Depth Testing
Okay so it’s been a while since my last tutorial, and I apologize for that. We dealt with textures in the last tutorial, and many of you might be wondering while I handled that so early? Well mainly because D3D 10 isn’t exactly an API designed for beginners, so a critical feature required for any scene rendering (depth testing or z-buffering) is done in D3D by use of a depth stencil texture, covering textures before depth testing makes sense in this case. Remember guys I’m not going to spoon feed you, these tutorials expect you to read the SDK docs for details on the variable types and the methods, these tutorials are just to give you a running start.
Indexed Buffers
Before I get to Depth Testing, let’s draw something a little more complicated that a quad, how about a cube. Using the same method as in tutorial 3 the code to draw a six sided cube is as follows:
//CUBE DRAW METHOD 1
//------------------------------------------------------------
//lock vertex buffer for CPU use
pVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**) &v );
//vertices for a cube
v[0] = vertex( D3DXVECTOR3(-1,-1,-1), D3DXVECTOR4(1,0,0,1) );
v[1] = vertex( D3DXVECTOR3(-1,1,-1), D3DXVECTOR4(0,1,0,1) );
v[2] = vertex( D3DXVECTOR3(1,-1,-1), D3DXVECTOR4(0,0,1,1) );
v[3] = vertex( D3DXVECTOR3(1,1,-1), D3DXVECTOR4(1,1,0,1) );
v[4] = vertex( D3DXVECTOR3(1,-1,-1), D3DXVECTOR4(1,0,0,1) );
v[5] = vertex( D3DXVECTOR3(1,1,-1), D3DXVECTOR4(0,1,0,1) );
v[6] = vertex( D3DXVECTOR3(1,-1,1), D3DXVECTOR4(0,0,1,1) );
v[7] = vertex( D3DXVECTOR3(1,1,1), D3DXVECTOR4(1,1,0,1) );
v[8] = vertex( D3DXVECTOR3(-1,-1,1), D3DXVECTOR4(1,0,0,1) );
v[9] = vertex( D3DXVECTOR3(-1,1,1), D3DXVECTOR4(0,1,0,1) );
v[10] = vertex( D3DXVECTOR3(-1,-1,-1), D3DXVECTOR4(0,0,1,1) );
v[11] = vertex( D3DXVECTOR3(-1,1,-1), D3DXVECTOR4(1,1,0,1) );
v[12] = vertex( D3DXVECTOR3(-1,-1,1), D3DXVECTOR4(1,0,0,1) );
v[13] = vertex( D3DXVECTOR3(-1,1,1), D3DXVECTOR4(0,1,0,1) );
v[14] = vertex( D3DXVECTOR3(1,-1,1), D3DXVECTOR4(0,0,1,1) );
v[15] = vertex( D3DXVECTOR3(1,1,1), D3DXVECTOR4(1,1,0,1) );
v[16] = vertex( D3DXVECTOR3(-1,-1,1), D3DXVECTOR4(1,0,0,1) );
v[17] = vertex( D3DXVECTOR3(-1,-1,-1), D3DXVECTOR4(0,1,0,1) );
v[18] = vertex( D3DXVECTOR3(1,-1,1), D3DXVECTOR4(0,0,1,1) );
v[19] = vertex( D3DXVECTOR3(1,-1,-1), D3DXVECTOR4(1,1,0,1) );
v[20] = vertex( D3DXVECTOR3(-1,1,-1), D3DXVECTOR4(1,0,0,1) );
v[21] = vertex( D3DXVECTOR3(-1,1,1), D3DXVECTOR4(0,1,0,1) );
v[22] = vertex( D3DXVECTOR3(1,1,-1), D3DXVECTOR4(0,0,1,1) );
v[23] = vertex( D3DXVECTOR3(1,1,1), D3DXVECTOR4(1,1,0,1) );
pVertexBuffer->Unmap();
//send vertices down pipeline
for( UINT p = 0; p < techDesc.Passes; p++ )
{
//apply technique
pBasicTechnique->GetPassByIndex( p )->Apply( 0 );
//draw 5 quads
pD3DDevice->Draw( 4, 0 );
pD3DDevice->Draw( 4, 4 );
pD3DDevice->Draw( 4, 8 );
pD3DDevice->Draw( 4, 12 );
pD3DDevice->Draw( 4, 16 );
pD3DDevice->Draw( 4, 20 );
}
The code above produces the following cube (I’ve added rotation and moved the camera – take a look at the code for more details), noticed the depth problem, whatever face got drawn last is on top irrespective of whether it is obscure by another face.
Image 1 – No Depth Testing
So as you can see to draw our cube we need to define each vertex and add it to the vertex buffer, then call the draw method 6 times. Each draw call draws a single triangle list with 4 vertices, drawing each face. So in this method we send 24 vertices down the pipeline and use 4 draw calls. This is a little crazy just to draw a single cube with only 8 vertices. There must be a simple more efficient method of doing this and there is: indexing.
What indexing does is let you pass a vertex buffer containing all the key vertices down the pipeline, and also a list of the order the vertices must be drawn in. So for our cube you’ll send the 8 vertices down the pipeline followed by a list of the order to draw them in. It’ll be a bit clearer once you see the code and of course read the index buffer sections in the SDK docs.
//lock vertex buffer for CPU use
pVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**) &v );
//vertices for a cube
v[0] = vertex( D3DXVECTOR3(-1,1,-1), D3DXVECTOR4(1,0,0,1) ); //front top left
v[1] = vertex( D3DXVECTOR3(1,1,-1), D3DXVECTOR4(0,1,0,1) ); //front top right
v[2] = vertex( D3DXVECTOR3(-1,-1,-1), D3DXVECTOR4(0,0,1,1) ); //front bottom left
v[3] = vertex( D3DXVECTOR3(1,-1,-1), D3DXVECTOR4(1,1,0,1) ); //front bottom right
v[4] = vertex( D3DXVECTOR3(-1,1,1), D3DXVECTOR4(1,0,0,1) ); //back top left
v[5] = vertex( D3DXVECTOR3(1,1,1), D3DXVECTOR4(0,1,0,1) ); //back top right
v[6] = vertex( D3DXVECTOR3(-1,-1,1), D3DXVECTOR4(0,0,1,1) ); //back bottom left
v[7] = vertex( D3DXVECTOR3(1,-1,1), D3DXVECTOR4(1,1,0,1) ); //back bottom right
pVertexBuffer->Unmap();
//create indexes for a cube
unsigned int* i = NULL;
pIndexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**) &i );
//front face
i[0] = 2;
i[1] = 0;
i[2] = 3;
i[3] = 1;
i[4] = 0xffffffff; //start new strip
//right face
i[5] = 3;
i[6] = 1;
i[7] = 7;
i[8] = 5;
i[9] = 0xffffffff;
//left face
i[10] = 6;
i[11] = 4;
i[12] = 2;
i[13] = 0;
i[14] = 0xffffffff;
//back face
i[15] = 7;
i[16] = 5;
i[17] = 6;
i[18] = 4;
i[19] = 0xffffffff;
//top face
i[20] = 0;
i[21] = 4;
i[22] = 1;
i[23] = 5;
i[24] = 0xffffffff;
//bottom face
i[25] = 6;
i[26] = 2;
i[27] = 7;
i[28] = 3;
pIndexBuffer->Unmap();
//send vertices down pipeline
for( UINT p = 0; p < techDesc.Passes; p++ )
{
//apply technique
pBasicTechnique->GetPassByIndex( p )->Apply( 0 );
//draw 5 quads - 29 indexes = 4 indexes x 6 faces + 5 breaks
pD3DDevice->DrawIndexed( 29, 0, 0 );
}
Wow! That’s a lot of code! Well not really once you look at it, we add the 8 key vertices to the vertex buffer exactly as before. Then we map the index buffer in exactly the same way as the vertex buffer and start filling it with the indexes of vertices in the vertex buffer. So for the front face we’re telling it, draw the front bottom left vertex, then the front top left vertex, then the front bottom right and finally the front top right. Now whats the 0xffffffff mean? Well that indicates that a new line list or triangle list must be started at that point, It does the same job as calling a draw call for each face without any of the overhead.
So lets do some basic maths on what we saved by using indexing rather than the standard vertex buffer method. We had a vertex buffer filled with 24 vertices (each vertex weighing in at 224bits) so the vertex buffer 672bytes large. In the second case the vertex buffer is 224bytes, and we have an index buffer with 29 32bit ints (116bytes) so a total of: 340bytes. That’s nearly 50% reduction in memory used, not to mention we are only using a single draw call compared to 4 draw calls when using just a vertex buffer.
So how do we create the index buffer? Well in DX10 all buffers are the same so we create an index buffer the in the same manner we created a vertex buffer with a few minor changes:
//create vertex and index buffers (space for 100 entries)
//---------------------------------------------------------------------------------
//create vertex buffer
UINT numVertices = 100;
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DYNAMIC;
bd.ByteWidth = sizeof( vertex ) * numVertices;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
if ( FAILED( pD3DDevice->CreateBuffer( &bd, NULL, &pVertexBuffer ) ) ) return fatalError("Could not create vertex buffer!");
//create index buffer
//change buffer desc bytewidth to index type
bd.ByteWidth = sizeof( unsigned int ) * numVertices;
if ( FAILED( pD3DDevice->CreateBuffer( &bd, NULL, &pIndexBuffer ) ) ) return fatalError("Could not create index buffer!");
//set vertex and index buffers
UINT stride = sizeof( vertex );
UINT offset = 0;
pD3DDevice->IASetVertexBuffers( 0, 1, &pVertexBuffer, &stride, &offset );
pD3DDevice->IASetIndexBuffer( pIndexBuffer, DXGI_FORMAT_R32_UINT, offset );
We still use the createBuffer method to create the index buffer, we just change the bytewidth since the buffer stores 32bit unsigned ints. Once the buffer is created we bind it to the Input Assembly by calling the IASetIndexBuffer method ( all we need to specify is a pointer to the buffer, the format of the indexes, and the offset, in case we wish to use only a set portion of the buffer ).
Depth Testing (Z-buffering)
I’m not going to explain in depth what depth testing/depth buffering/z-buffering is (its covered in almost all beginner graphics tutorials), you guys can use google for that , but here’s a quick link to the basics: http://en.wikipedia.org/wiki/Z-buffer.
In DX10, depth testing is accomplished by making use of a depth stencil, there is a nicely detailed section in the SDK docs regarding the Output-Merger Stage, and here they cover how DX10 accomplishes the depth stencil test internally.
So lets just briefly go over what depth testing is, we have a depth buffer that stores the distance for each pixel in the screen to the camera, so for every pixel we draw from the pixel shader, we compare it’s distance to the camera to the distance stored in the depth buffer, if the new pixel is closer than the distance in the depth buffer then it is drawn and the depth buffer is updated with that pixels distance. That way we only draw the closest visible objects to the viewer, obstruction further objects.
So lets enable this in DX10:
//dx manager members
ID3D10Texture2D* pDepthStencil;
ID3D10DepthStencilView* pDepthStencilView;
bool dxManager::createRenderTargetsAndDepthBuffer( UINT width, UINT height )
{
//try to get the back buffer
ID3D10Texture2D* pBackBuffer;
if ( FAILED( pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*) &pBackBuffer) ) ) return fatalError("Could not get back buffer");
//try to create render target view
if ( FAILED( pD3DDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTargetView) ) ) return fatalError("Could not create render target view");
pBackBuffer->Release();
//create depth stencil texture
D3D10_TEXTURE2D_DESC descDepth;
descDepth.Width = width;
descDepth.Height = height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = DXGI_FORMAT_D32_FLOAT;
descDepth.SampleDesc.Count = 1;
descDepth.SampleDesc.Quality = 0;
descDepth.Usage = D3D10_USAGE_DEFAULT;
descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
if( FAILED( pD3DDevice->CreateTexture2D( &descDepth, NULL, &pDepthStencil ) ) ) return fatalError("Could not create depth stencil texture");
// Create the depth stencil view
D3D10_DEPTH_STENCIL_VIEW_DESC descDSV;
descDSV.Format = descDepth.Format;
descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0;
if( FAILED( pD3DDevice->CreateDepthStencilView( pDepthStencil, &descDSV, &pDepthStencilView ) ) ) return fatalError("Could not create depth stencil view");
//set render targets
pD3DDevice->OMSetRenderTargets( 1, &pRenderTargetView, pDepthStencilView );
return true;
}
First we add two new members in the dxmanager class, a ID3D10Texture2D depth stencil pointer and a depth stencil view pointer. Then we create a new texture and assign it to the depth stencil pointer. After this we create a view to the texture by making use of a depth stencil view desc, sort of like the way we created texture views.
The final step is to modify the Output manager’s render targets to include the depth stencil, this automatically enables depth testing. Once we run the program, we get this result:
Image 2 – Depth Testing Enabled
So that’s basically it for this short tutorial, I’m sorry its so short and simple, I’m just flooded with other work right now. I’m going to be covering meshes and lighting in the next several tutorials.
Source Code
Source Code + VS2k8 project files: tutorial4.zip
DirectX 10 Tutorial 3 – Textures
So it’s been sometime since the last tutorial and I apologize for that, I’ve been busy wrapping up my exams for my second degree and finishing off a mini thesis for one of my subjects. So now that it’s all over with I‘ve sat down and done a small tutorial on dx10 texturing.
A lot of other tutorials leave texturing for later on in the tutorial but I’m going to do it now because it’s so simple and further illustrates the point of shader programs and what role they play.
Texturing?
So what is texturing? You can think of it like applying wallpaper to a blank wall, you take an image and attach it to an object in your scene. Well that’s not entirely true, what texturing actually does is use an image as a reference for what color an object is. Where before we set the color for each vertex and then let the API automatically interpolate the colors between vertices now we’re giving it an image to sample for those colors.
I’m not going to go into great detail regarding mipmaps and so on since it isn’t really necessary at this point, hopefully I’ll have the time to come back to it at a later stage and even if I don’t google is your friend
Texturing occurs in the pixel shader stage of the pipeline, just before fragments are rasterized and so the bulk of the texturing code (all 1 line of it) needs to be done in HLSL.
There is one last thing I need to cover before I can get into the code, as I said earlier we give a object an image to use as a reference for the colors on the surface defined in the object but how does the API know which pixel in the image to use for a set of world co-ordinates on the surface? Well this is actually quite simple.

If we look at the above picture, for a 128×128 pixel texture which we want to use for the quad on the right. The first we need to do is set up some sort of coordinate system for the texture. We use the letters u and v for the two axes, please notice that v increases in a downwards direction, u and v are known as texture coordinates. This is because in an image, the first pixel is the top left image and the last pixel is the bottom right. Another restriction on this coordinate system is that u and v are real numbers ranging from 0 to 1 where 1 is 100% of the texture dimension. So the texture coordinates u=0.5, v=0.5 will return the center pixel in a texture.
Okay to attaching this texture to an object defined by a set of vertices in world space, we need to add a piece of information to each vertex: the texture coordinate of that vertex in respect to the texture. So for any two vertices, the API will sample the color values of the texture between the texture coordinates specified for each vertex. At any point in the object it will have a texture coordinate, to calculate what pixel to use in the image as the color reference is simple. The pixel coordinates x,y are simply calculated as such: x= round(u*(textureWidth-1)), y= round(v*(textureHeight-1)). Simple huh?
In the above image we want to use the entire texture for the quad and so specify the u,v coordinates accordingly. We also show the corresponding pixel coordinates for a point on the object with u,v coordinates: (0.2,0.3). Okay so that an idiots guide to texturing theory. Let’s dig into the code.
The first thing we need to do is take tutorial 2 and modify it for texturing. We remove the rotation for the triangle and add an extra vertex to generate a quad as in the below image:

The code for the quad is:
v[0] = vertex( D3DXVECTOR3(-1,-1,0), D3DXVECTOR4(1,0,0,1)); v[1] = vertex( D3DXVECTOR3(-1,1,0), D3DXVECTOR4(0,1,0,1)); v[2] = vertex( D3DXVECTOR3(1,-1,0), D3DXVECTOR4(0,0,1,1)); v[3] = vertex( D3DXVECTOR3(1,1,0), D3DXVECTOR4(1,1,0,1));
Loading the Textures
So let’s load our textures, our first step is setting up storage for our textures and a way to pass it through to the shader program:
std::vector<ID3D10ShaderResourceView*> textureSRV; ID3D10EffectShaderResourceVariable* pTextureSR;
Textures are loaded as ID3D10 resources, to which you need to create a view; a view tells DX how to access a particular resource. Since a texture is a shader resource that’s the type of view we need. The second variable is how we pass the texture id to the HLSL shaders.
So how do we load a texture from an image file? Well if you thought it would be a complicated and involved process you’re wrong, it’s a single function call (D3DX10CreateShaderResourceViewFromFile), and the code to load multiple textures into our texture storage is below.
vector<string> filenames;
filenames.push_back("textures/t1.bmp");
filenames.push_back("textures/t2.bmp");
filenames.push_back("textures/t3.bmp");
//load textures
for ( int i=0; i < (int) filenames.size(); i++ )
{
textureSRV.push_back(NULL);
if ( FAILED( D3DX10CreateShaderResourceViewFromFile( pD3DDevice, filenames[i].c_str(), NULL, NULL, &textureSRV[i], NULL ) ) )
{
char err[255];
sprintf_s(err, "Could not load texture: %s!", filenames[i].c_str());
return fatalError( err );
}
}
That function merges two steps, the creation of the texture and the resulting view to it, in one. Okay so now we’ve loaded the texture now what? Well we need to modify our vertex struct to support texture coordinates, texture coordinates have two dimensions, u and v, horizontal and vertical respectively. To attach a texture to a polygon you need to specify what part of the texture you want to put over the polygon.
struct vertex
{
D3DXVECTOR3 pos;
D3DXVECTOR4 color;
D3DXVECTOR2 texCoord;
}
We use a 2d vector to specify the u,v coordinates for each vertex. So this also means the code for the qaud has changed to:
v[0] = vertex( D3DXVECTOR3(-1,-1,0),D3DXVECTOR4(1,0,0,1),D3DXVECTOR2(0.0f, 1.0f) ); v[1] = vertex( D3DXVECTOR3(-1,1,0),D3DXVECTOR4(0,1,0,1),D3DXVECTOR2(0.0f, 0.0f) ); v[2] = vertex( D3DXVECTOR3(1,-1,0),D3DXVECTOR4(0,0,1,1),D3DXVECTOR2(1.0f, 1.0f) ); v[3] = vertex( D3DXVECTOR3(1,1,0),D3DXVECTOR4(1,1,0,1),D3DXVECTOR2(1.0f, 0.0f) );
Since we changed the vertex struct we also need to modify the inputlayout accordingly, remember that the input layout tells DX what each vertex looks like. All we need to change is the input_element_desc for the input layout:
D3D10_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D10_INPUT_PER_VERTEX_DATA, 0 }
};
Last step is to tell the API which texture to which just before we draw an object. Since in most basic cases we will only be using a single texture (multi-texturing comes later) we only need a single texture shader resource variable which we just update to the texture we want.
//set texture pTextureSR->SetResource( textureSRV[textureIndex] );
Okay so now if we run the program we get… The exact same thing as before. Why?! Well this is obvious since we havent touched the pixel shader program at all.
Texturing using the Pixel Shader
So lets just tweak the shader program (basicEffect.fx), first thing we need to do is specify a texture variable for the shader as such:
Texture2D tex2D;
Then we create a samplerState, remember when I said earlier that we sample the texture to get a color at a specific set of u,v coordinates, a texture resource resource in HLSL has a sample method that samples that texture and returns the value at a specific point, now the way in which it sample that texture is done via the sampleState object. This object sets all the parameters for the default sampler. A very basic samplerState is show below:
SamplerState linearSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
It has three elements: a filter which specifies how the sampling is to be done over the texture, in our case we’re just doing a basic linear sampling (all the sampling states and their descriptions are available in the SDK docs, the addressU and addressV specify how to handle u and v values that lie outside the 0 to 1 range.
Remember how I said that u and v are in the range 0 to 1, well that’s not exactly true, sometimes to want to texture an object using 4 smaller versions of a texture rather than stretching the texture to fit the the object. The below image shows what happens for a few common addressU , addressV values:

There are other state variables for the samplerState object, once again all the info necessary is in the sdk docs.
Now we need to modify the vs_input and ps_input structs to handle the extra 2d texcoord variable:
struct VS_INPUT
{
float4 Pos : POSITION;
float4 Color : COLOR;
float2 Tex : TEXCOORD;
};
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
float2 Tex : TEXCOORD;
};
And the vector and pixel shaders accordingly. The only difference in the pixel shader is that for texturing we need to return the sampled color and not the vertex color. We use the sample method on the texture object , the sampler state we defined earlier and the texture coordinates we specified earlier.
PS_INPUT VS( VS_INPUT input )
{
PS_INPUT output;
output.Pos = mul( input.Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Color = input.Color;
output.Tex = input.Tex;
return output;
}
float4 textured( PS_INPUT input ) : SV_Target
{
return tex2D.Sample( linearSampler, input.Tex );
}
float4 noTexture( PS_INPUT input ) : SV_Target
{
return input.Color;
}
We also create two new techniques “full” and “texturing disabled”:
technique10 full
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, textured() ) );
}
}
technique10 texturingDisabled
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, noTexture() ) );
}
}
Then we load these two techniques exactly as we did in the previous tutorial. If we compile and run the program we’re presented with a now textured quad.

If we change the texture co-ordinates to :
v[0] = vertex( D3DXVECTOR3(-1,-1,0), D3DXVECTOR4(1,0,0,1), D3DXVECTOR2(0.0f, 2.0f) ); v[1] = vertex( D3DXVECTOR3(-1,1,0), D3DXVECTOR4(0,1,0,1), D3DXVECTOR2(0.0f, 0.0f) ); v[2] = vertex( D3DXVECTOR3(1,-1,0), D3DXVECTOR4(0,0,1,1), D3DXVECTOR2(2.0f, 2.0f) ); v[3] = vertex( D3DXVECTOR3(1,1,0), D3DXVECTOR4(1,1,0,1), D3DXVECTOR2(2.0f, 0.0f) );
The result is this:

You can download the source code for this tutorial below. In the code you’ll notice that I add a method to swap the texture on the quad by modifying the textureIndex when I set the texture and to disable texturing by using the “texturingDisabled” technique instead of “Full”. Take a look at the wndProc method to see the controls and how they work.
I hope you’ve enjoyed this tutorial, I’ve already started working on the 4th one which will be about meshes and index buffers. I’m going to slowly write the turorials and build upon each one towards the final goal of rendering a field of thousands of blades of waving grass. I feel its pretty pointless to show you all the section seperately without explaining how they all link up together.
Source Code
Download the visual studio 2008 project: dxTutorial3.zip
DirectX 10 Tutorial 2: Basic Primitive Rendering
Okay I managed to find sometime and wrote a very basic second tutorial that introduces the main concepts behind primitive rendering in DX10. This tutorial builds upon the base code of tutorial 1 so check that out if you haven’t already.
Also I need to mention that I’m not writing these tutorials for complete beginners, I expect you to at least have a very basic understanding of graphics programming and the terminology involved. I’m not going to go into a lot of detail regarding terms like culling, rasterizing, fragments etc.
One last aside before the tutorial, what makes DX10 different to DX and openGL 2.0 is the removal of the fixed function pipeline. Now what the hell does that all mean? Well in directx9 and openGL, they had default ways of handling vertices, colors, texture co-ordinates etc. You’d pass through a vertex and a color and it would know what to do. It also handled lighting and other effects. In DX10 these defaults were removed and the core API has been simplified and reduced, this allows you to have full control over each pipeline stage and removes any past limitation on number of light sources and so on, but it has a major downside, the complexity and difficulty has now increased.
If we take lighting for example, before a hobbyist could enable lighting with a few function calls and would get a satisfactory result now for the same effect, the hobbyist would have to write pixel and vertex shaders using the phong (or other) equations to manually calculate the effect of lighting.
Basic Rendering and first steps into HLSL
Okay enough of that, let’s dig in. To render something there are several steps we need to take:
- Generate the vertices
- Send the vertices to the pipeline
- Apply any transformations need to the vertices (vertex shader)
- Set the vertex color (pixel shader)
Seems pretty simple? If only. The first addition to the code is the loading of an HLSL (high level shader language) effect file; this file will define the vertex and pixel shaders we will be using. The contents of the effect file are:
matrix World;
matrix View;
matrix Projection;
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR0;
};
PS_INPUT VS( float4 Pos : POSITION, float4 Color : COLOR )
{
PS_INPUT psInput;
Pos = mul( Pos, World );
Pos = mul( Pos, View );
psInput.Pos = mul( Pos, Projection );
psInput.Color = Color;
return psInput;
}
float4 PS( PS_INPUT psInput ) : SV_Target
{
return psInput.Color;
}
technique10 Render
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, VS() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PS() ) );
}
}
Its pretty simple, the vertex shader applies the matrix transformation by multiplying the vertex by the world, view and projection matrices we’ve declared in the file, and then it sends the tansformed vertex to the pixel shader which simply returns the color to the rasterizer, which draws it out on our frame.
We also define a Render technique which specifies which pixel/vertex shader programs we need to run for it. The effect file can contain multiple pixel/vertex shaders functions and techniques. Each technique can also feature multiple passes.
Loading the HLSL Effect File
Now to load the effect file we do the following:
if ( FAILED( D3DX10CreateEffectFromFile( "basicEffect.fx",
NULL,
NULL,
"fx_4_0",
D3D10_SHADER_ENABLE_STRICTNESS,
0,
pD3DDevice
NULL, NULL,
&pBasicEffect,
NULL, NULL ) ) ) return fatalError("Could not load effect file!");
pBasicTechnique = pBasicEffect->GetTechniqueByName("Render");
//create matrix effect pointers
pViewMatrixEffectVariable = pBasicEffect->GetVariableByName( "View" )->AsMatrix();
pProjectionMatrixEffectVariable = pBasicEffect->GetVariableByName( "Projection" )->AsMatrix();
pWorldMatrixEffectVariable = pBasicEffect->GetVariableByName( "World" )->AsMatrix();
What the above code does is load the effect file and creates an effect from it, it compiles the effect file on load, so any syntax errors in the file will cause this step to fail, so catching the error here is extremely important!
Then we create a pointer to the “Render()” technique defined in the file. This technique is what we will use for rendering, it defines what the pixel and vertex shader will do for any vertices pumped into the pipeline.
The last steps are to set up pointers to the effect matrix variables we declared in the effect file so we can update them during runtime. HLSL variables aren’t limited to just matrices, and there are lots of things you can achieve using HLSL but I’ll leave that research up to you!
So now we’ve loaded the effect file which defines the vertex and pixel shader parts of the pipeline, so now let’s deal with the input assembly stage. We define a basic vertex struct as follows:
struct vertex
{
D3DXVECTOR3 pos;
D3DXVECTOR4 color;
vertex( D3DXVECTOR3 p, D3DXVECTOR4 c ) : pos(p), color(c) {}
};
Now we need to tell DX10 and more specifically the technique how to handle this vertex type, this is done via an InputLayout. First thing we do is fill out an input element desc structure. This defines the format of the vertex. The parameters are present in the SDK docs, but the important one is the byte offset parameter, as you will notice for the second structure the offset is 12 since the first element consists of 3 4byte variables.
D3D10_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT,0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 }
};
The next step is getting the description of the pass and creating the input layout. Since each pass in a technique will take in the same input format, we just get the first pass in the technique and use that to create the input layout. Once the layout is created we set it as the active input layout. This is important since you may need to process multiple types of vertices and may need to swap input layouts as needed.
UINT numElements = 2;
D3D10_PASS_DESC PassDesc;
pBasicTechnique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
if ( FAILED( pD3DDevice->CreateInputLayout( layout,
numElements,
PassDesc.pIAInputSignature,
PassDesc.IAInputSignatureSize,
&pVertexLayout ) ) ) return fatalError("Could not create Input Layout!");
// Set the input layout
pD3DDevice->IASetInputLayout( pVertexLayout );
Vertex Buffers
Phew, nearly done with the initialization, the last major thing we need to do is create the vertex buffer. The vertex buffer is a buffer that stores vertices before pumping them through to the video card, think of it as a waiting line for a carnival ride, people queue up until the ride is ready and then they get on, while the ride is busy, more people will queue up and so on.
There are several ways to efficiently use the vertex buffers, one of which is using the map function with the D3D10_MAP_WRITE_DISCARD flag but that’s something I’ll get to later.
So let’s create the vertex buffer. As expected the first step is filling out a DESC structure, the important parameters are the usage parameter which specifics what type of buffer to create, we want to be able to update it during runtime so we make it a dynamic buffer, and the CPUaccessFlag which specifies the type of access the CPU is granted to the buffer, again since we wish to update it during runtime, we allow writing by the CPU.
Then we create the vertex buffer and set the Input Assembler to use it. The parameters and their descriptions are once again found in the SDK documentation.
//create vertex buffer (space for 100 vertices)
//---------------------------------------------
UINT numVertices = 100;
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DYNAMIC;
bd.ByteWidth = sizeof( vertex ) * numVertices;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
if ( FAILED( pD3DDevice->CreateBuffer( &bd, NULL, &pVertexBuffer ) ) ) return fatalError("Could not create vertex buffer!");;
// Set vertex buffer
UINT stride = sizeof( vertex );
UINT offset = 0;
pD3DDevice->IASetVertexBuffers( 0, 1, &pVertexBuffer, &stride, &offset );
Setting up the Rasterizer
In my example I render a spinning triangle, but by default DX10 enables backface culling, this results in my triangle being visible only half the time so I want to disable that, since culling occurs during the rasterizer stage I need to create a custom rasterizer state and set the pipeline to use that:
D3D10_RASTERIZER_DESC rasterizerState; rasterizerState.CullMode = D3D10_CULL_NONE; rasterizerState.FillMode = D3D10_FILL_SOLID; rasterizerState.FrontCounterClockwise = true; rasterizerState.DepthBias = false; rasterizerState.DepthBiasClamp = 0; rasterizerState.SlopeScaledDepthBias = 0; rasterizerState.DepthClipEnable = true; rasterizerState.ScissorEnable = false; rasterizerState.MultisampleEnable = false; rasterizerState.AntialiasedLineEnable = true; ID3D10RasterizerState* pRS; pD3DDevice->CreateRasterizerState( &rasterizerState, &pRS); pD3DDevice->RSSetState(pRS);
NOTE: you may have noticed that all the d3d device function are preceded by a label for which stage of the pipeline they affect, pretty nice of the developers to do that
Okay wow, we’ve gone through a lot just to set up the pipeline to render, and we havent even rendered anything yet. Jeez! I’m sure you openGL kids are screaming murder at this point, and I agree it is a bit more effort but to be honest after working in DX10 for the last couple of weeks I cant even imagine going back to openGL, while openGL might require less code, its so much messier.
Meet the Matrices
Damn I got side tracked, onto the rendering, first step lets create a world matrix, this defines the position and orientation of the object in the world, at a later stage every object in our scene will have its own world matrix.
//create world matrix static float r; D3DXMATRIX w; D3DXMatrixIdentity(&w); D3DXMatrixRotationY(&w, r); r += 0.001f;
then we update the effect variables, using the pointers we created earlier
//set effect matrices pWorldMatrixEffectVariable->SetMatrix(w); pViewMatrixEffectVariable->SetMatrix(viewMatrix); pProjectionMatrixEffectVariable->SetMatrix(projectionMatrix);
Filling the Vertex Buffer
Now the meat and potatoes of the whole tutorial, updating the vertex buffer. The first we do is lock the buffer, this allows us to safely write to the buffer without worrying about having any vertices being sent down the pipeline while we’re busy updating.
This function returns a pointer to the block of memory storing the vertex data. I’ve used a “discard” flag, which simply means that any previous data in the buffer must get discarded, if the buffer was busy being used to feed vertices into the pipeline, the map call will return a pointer to a new empty block of memory and discard the previous block once its finished being used. There are various other flags that I’ll probably cover in later tutorials but for now lets leave it at that.
Using our return pointer we set three vertices. We then unlock the buffer.
//fill vertex buffer with vertices UINT numVertices = 3; vertex* v = NULL; //lock vertex buffer for CPU use pVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**) &v ); v[0] = vertex( D3DXVECTOR3(-1,-1,0), D3DXVECTOR4(1,0,0,1) ); v[1] = vertex( D3DXVECTOR3(0,1,0), D3DXVECTOR4(0,1,0,1) ); v[2] = vertex( D3DXVECTOR3(1,-1,0), D3DXVECTOR4(0,0,1,1) ); pVertexBuffer->Unmap();
Input Assembly
The next step is telling the Input Assembly what type of primitive we’re drawing using the set topology function.
// Set primitive topology pD3DDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );
Finally using our technique pointer we get a Description of it and then process all the passes present in the technique. For each pass, we send through the vertices present in the vertex buffer using the draw command specify the number of vertices to draw and the start index in the vertex buffer.
Drawing the scene (finally)
DX10 can only have one active vertex buffer at a time so if you have multiple buffers remember to load the correct one before you do any draw calls. The fact that there is an offset hints that you can store multiple objects in a single buffer and then draw them all using mutiple consecutive draw calls.
//get technique desc
D3D10_TECHNIQUE_DESC techDesc;
pBasicTechnique->GetDesc( &techDesc );
for( UINT p = 0; p < techDesc.Passes; ++p )
{
//apply technique
pBasicTechnique->GetPassByIndex( p )->Apply( 0 );
//draw
pD3DDevice->Draw( numVertices, 0 );
}
So that’s it, we’ve reached the end of the second tutorial, we’ve covered a lot of ground and I apologize that I haven’t gone too in depth regarding the functions and their parameters but I don’t have the time right now for in depth tutorials and I feel that a little bit of research and self study would be more beneficial than me spoon feeding you in these tutorials.

I’m actually hoping that these tutorials may serve as just a reference for your own code or just give you ideas and insight for your own projects.
Source Code
The source code and VS2k8 project for the tutorial can be found here: tutorial2.zip
Multiple High Resolution Timer Class for Windows – C++
Earlier i had posted a tutorial on doing high resolution timing on windows and i’d given a very basic class to act as a timer, now i found when doing my graphics work i often needed multiple timers and so i just extended my baby timer class a little to support multiple timers.
So you can create as many timers as you need on the fly (the controller class acts as a big timer vector) and also get a pointer back for each timer if you wish to create a easily readable shortcut ie.
HRTimer* animationTimer = timers[5];
hope you find it useful: MHRTimer.h
DirectX 10 Tutorial 1: Setting up the D3D10 device
Introduction
So if you read my review of Wendy Jones’ book, you know my feelings on the state of DX10 tutorials and books, I want to try and maybe help some people out with tutorials in getting started with DX10, I am by no means an expert and the tutorials will basically cover everything that I’ve learnt so far. They will not be rehashes of the SDK tutorials nor Wendy Jones’ book. I’m hoping to slowly build up a dxManager wrapper class that can be easily used for some basic D3D apps. So let’s get started with the most basic topic: setting up the D3D device for drawing.
Note: The DX10 SDK tutorials are excellent, they are a must read and my early tutorials will be a concatenation of the information found in them!
Win32
The entry point of most 3D tutorials is win32 and so I’m not going to rewrite all those tutorials. If you want an excellent win32 tutorial Google forger’s win32 tutorials, they are the best I’ve found. Basically a simple win32 window consists of two things: the window and the window processing function (acts as an event handler). Inside of the tutorial project I’ve attached you’ll see three functions that create a window: the winMain function, the initialize window function and the wndProc, the functions are very basic and so I’m not going to go into any more detail. There are plenty of tutorials available online if you want more detail on win32.
dxManager
Before I start with the directX initialization stuff, I just want to cover something: the dxManager class. Most tutorials you’ll find will have the directX variables as global with a few global functions in a single file to render a simple triangle. Even Wendy Jones does so in her book, but I’m not, simply because it’s a terrible practice, its messy, inextensible and just plain silly. I’m going to instead create a dxManager class to wrap all my directX functions and just neaten things up.
In later tutorials you’ll see the justification for this more clearly. Enough of me prattling on, let’s dig in.
3D basics
Okay let just cover some very basic concepts about 3D graphics, the graphics API (directX/openGL) is what you’ll use to draw your objects out to the screen. The API is basically a layer that sits between your graphics card and you, you tell the layer what to do and the layer then tells the card.
The card makes use of a pipeline structure to display objects, I’m not going to go into the justifications about this since Google is your friend. Basically there a few key stages (their names differ across APIs), below is a diagram of the stages in DX10 followed by a brief description (taken from the SDK docs):
- Input-Assembler Stage - The input-assembler stage is responsible for supplying data (triangles, lines and points) to the pipeline.
- Vertex-Shader Stage – The vertex-shader stage processes vertices, typically performing operations such as transformations, skinning, and lighting. A vertex shader always takes a single input vertex and produces a single output vertex.
- Geometry-Shader Stage - The geometry-shader stage processes entire primitives. Its input is a full primitive (which is three vertices for a triangle, two vertices for a line, or a single vertex for a point). In addition, each primitive can also include the vertex data for any edge-adjacent primitives. This could include at most an additional three vertices for a triangle or an additional two vertices for a line. The Geometry Shader also supports limited geometry amplification and de-amplification. Given an input primitive, the Geometry Shader can discard the primitive, or emit one or more new primitives.
- Stream-Output Stage – The stream-output stage is designed for streaming primitive data from the pipeline to memory on its way to the rasterizer. Data can be streamed out and/or passed into the rasterizer. Data streamed out to memory can be recirculated back into the pipeline as input data or read-back from the CPU.
- Rasterizer Stage - The rasterizer is responsible for clipping primitives, preparing primitives for the pixel shader and determining how to invoke pixel shaders.
- Pixel-Shader Stage – The pixel-shader stage receives interpolated data for a primitive and generates per-pixel data such as color.
- Output-Merger Stage - The output-merger stage is responsible for combining various types of output data (pixel shader values, depth and stencil information) with the contents of the render target and depth/stencil buffers to generate the final pipeline result.
The aim of this tutorial is to set up the D3D device to be ready for later tutorials. We will set up the swap chain, the D3D device, the render target, the viewport and finally just set up a view and projection matrix for the future.
The SwapChain and the D3D device
This is what is written in the SDK regarding the swapchain: “An IDXGISwapChain interface implements one or more surfaces for storing rendered data before presenting it to an output.” What this basically means is that you will set up a few “frames” or “buffers” to which you will draw and then swap out when you’re finished drawing. This is how you enable double or triple buffering in DX10.
Once we’ve set up our swapchain we create a D3D device with that swapchain, pretty simple.
To achieve this we need to fill out a DXGI_SWAP_CHAIN_DESC structure and then call D3D10CreateDeviceAndSwapChain to create our swap chain and our D3D device. The function parameters are in the SDK docs and I’m not going to describe what each one does since I’m pretty sure you can read it yourself. You will need pointers to both a swap chain interface and a D3D device interface. Here’s the code to set up and create the swap chain and D3D device.
//Set up DX swap chain
//--------------------------------------------------------------
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
//set buffer dimensions and format
swapChainDesc.BufferCount = 2;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;;
//set refresh rate
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
//sampling settings
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.SampleDesc.Count = 1;
//output window handle
swapChainDesc.OutputWindow = *hWnd;
swapChainDesc.Windowed = true;
//Create the D3D device
//--------------------------------------------------------------
if ( FAILED( D3D10CreateDeviceAndSwapChain( NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
0,
D3D10_SDK_VERSION,
&swapChainDesc,
&pSwapChain,
&pD3DDevice ) ) ) return fatalError("D3D device creation failed");
The RenderTarget
The render target describes what the format of output of the output merger stage will be. This output format is the same the format of the swapchain buffers. So what we need to do is get all the details from the swapchain about its buffer format and use that to create a render target.
//Create render target view
//--------------------------------------------------------------
//try to get the back buffer
ID3D10Texture2D* pBackBuffer;
if ( FAILED( pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer) ) ) return fatalError("Could not get back buffer");
//try to create render target view
if ( FAILED( pD3DDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTargetView) ) ) return fatalError("Could not create render target view");
//release the back buffer
pBackBuffer->Release();
//set the render target
pD3DDevice->OMSetRenderTargets(1, &pRenderTargetView, NULL);
Note: Something that should be mentioned here is the “Release” call, basically all resources are semi-managed, basically resources are only freed once nothing is using them, whenever a resource is used an internal counter is incremented (semaphore) , once something doesn’t need the resource any more the counter is decremented. Once this counter reaches 0, the resource is freed. Here we don’t need the pBackBuffer resource any longer so we release it, if nothing else is using it then the resource is freed.
The Viewport
The viewport converts vertex positions to render target positions; this is the key step in the rasterizer stage. Creating this structure is really simple, it basically takes the height and width of your window and the starting positions of the window (usually 0 and 0). The depth variables should be set to 0 and 1 for min and max respectively. Once you have multiple viewports this will change but don’t worry about that for now.
//create viewport structure viewPort.Width = width; viewPort.Height = height; viewPort.MinDepth = 0.0f; viewPort.MaxDepth = 1.0f; viewPort.TopLeftX = 0; viewPort.TopLeftY = 0; //set the viewport pD3DDevice->RSSetViewports(1, &viewPort);
The View and Projection Matrices
Okay now we’re nearly done, the last thing we need to set up is the view and projection matrices. The view matrix basically positions and orients the camera in the scene. The matrix usage and transformations will be covered in the next tutorial.
The projection matrix basically defines the range of the view from the camera. This is explained extremely well in the 4th tutorial in the SDK docs! I really suggest reading it. It can also apply perspective to the scene; this basically allows near objects to be large and far objects to be small. In our case we’re going to set up a basic perspective projection with a view angle of 45 degrees and a max depth of 100 units. The near depth must not be set to 0, I will explain why in a later tutorial regarding picking and unprojecting co-ordinates.
// Set up the view matrix //-------------------------------------------------------------- D3DXVECTOR3 eye(0.0f, 0.0f, -5.0f); D3DXVECTOR3 view(0.0f, 0.0f, 1.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f)); D3DXMatrixLookAtLH( &viewMatrix, eye, view, up ); //Set up projection matrix //-------------------------------------------------------------- D3DXMatrixPerspectiveFovLH(&projectionMatrix, (float)D3DX_PI * 0.5f, (float)width/height, 0.1f, 100.0f);
Rendering of the Scene
Okay so we’ve set up our D3D device, let just output something. Unfortuneatly in DX10 doing that isnt all that simple and there are several more stage we need to do before we can proceed. So for now lets just clear the screen and flip the buffers.
//clear scene pD3DDevice->ClearRenderTargetView( pRenderTargetView, D3DXCOLOR(0,0,0,0) ); //SCENE RENDERING GOES HERE!!! //flip buffers pSwapChain->Present(0,0);
Conclusion
So that’s it for my first tutorial! I didn’t cover a lot of material but I’ve set up the base for the rest of the tutorials, and time-permitting I’ll put up several more in the coming weeks.
Source Code
Tutorial 1 VS2k8 project and Source Code: tutorial1.zip
FPT Toolkit and my first steps into win32
The screenshot above is my latest little project, a windows based tool for the decomposition of image using my fast pulse transform (FPT) technique. It needed to have a few features like file IO, pulse selections and highlighting of pulses. I’ve never done any sort of c++ winapi programming before apart from some windows forms stuff in c#. I figured since i’m busy messing around with win32 in my openGL and directX adventures, i might as well just use that. :/
Probably not the smartest decision, since the bare win api is c based and not c++ based and so the way the api is structured is based on c techniques. I’ll be honest and it took me a day or two to get used to it and to figure out how most things occurs and now i’ve pretty much got the gist of it. Now it comes down to using the msdn docs to find out what the flag values i need are, and trying to figure out when specific messages are sent. I’ve got a very basic grasp of it at the moment. I wish i could spend more time messing around with it but i need to focus on this semester and finish learning directx 10. And even so once that is done, i think i’m gonna focus on learning MFC or windows forms even as it seems the bulk of development is done using these APIs. From what i can see most window game dev toolsets are developed in MFC.
So some last words about my app… i couldn’t for the life of me figure out how the fuck DIBs and HBITMAPS work (creating DIBs programmatically at least – the conversion from DIB to HBITMAP was simple enough) so i had to use openGL to display my 2D images (haha, oh well its not like people don’t have openGL videos cards these days). I just got the pulse selection and reconstruction saving working, just need to finish the highlighting section and its done (for now). I need to sit and think logically about what i want for the highlighting interface and then code it.
I have struggled these last few days trying to learn winapi programming from scratch using nothing more than google and the MSDN docs but at the same time I’ve learnt a lot and so its been worth it! OH and for a development environment: visual studio 2008 + vista 64 is a dream come true
C++ Back Propagation Neural Network Code v2
There was a lot of feedback on my neural network implementation, mostly regarding architectural suggestion so i sat down and rewrote my neural network implementation, its pretty elegant now. I seperated the training of the network from the actual network itself and so i have a basic feed forward network, a data set reader and a neural network trainer. I also renamed several data structures to make things more understandable, also i wasnt lazy and used proper header files and includes
Below is an updated class diagram of the new version:
here’s the updated implementation (with a VS2k8 solution):



