Downtime

•7 July 2009 • Leave a Comment

I havent really updated this blog in forever, I’ve been swamped with work. Its not helping matters that my band is also completing our full-length album release so thats also taking up a fair chunk of my time.

The last few months have been crazy, I’ve been reading so much about pathfinding in games and I’ve learnt so much, I’ve started writing my masters thesis but I’m finding it extremely difficult and time consuming, writing has never been a strong point, never mind academic writing. I’ve spent around 2 weeks writing and re-writing and only have 3 completed pages of my introduction.

Its and interesting field and I have a few ideas on extending a few common algorithms to provide faster and better quality results, but as with all things research related there is always the chance that my “optimizations” might end up making things worse, as Adam Savage says “Failure is always an option”.

Looking at the directx 11 specs, tech demos, etc I cant help but feel excited, I kinda just wanna lock myself in a room and play with it :) My directx 10 tutorials kinda stopped coming as my workload increased and I’m sorry about that, I’ll try my best to find the time to perhaps write a new tutorial or two.

Anyways I had a bit of time before a meeting at work and realized I havent touched this blog in a while so decided to show it some love :)

The “Perfect” Post Apocalyptic RPG

•18 May 2009 • 3 Comments

 Before I continue I just need to state for the record that I am a fallout (originals) fanboi. In my opinion Fallout 1/2 are the pinnacle of post apocalyptic cRPGs, actually probably the pinnacle of cRPGs in general, I can’t think of a single cRPG I’ve played through more times that the fallout games. Baldur’s Gate 1 and 2, are probably second on my list. In the last decade there hasn’t been a single game that has even come close to removing them from the top spots on the list of my all time favorite games.

So I’ve been thinking a bit about some of the recent games I’ve played and all the things that I liked and I found lacking in them. So I’m gonna outline what I feel the games did right and what they did wrong. Then I’m gonna give a basic description of what I feel would make my perfect post apocalyptic (gonna refer to it as PA from now on) RPG.

Let’s start with the classics:

Fallout 1/2

What They Did Right

Um, pretty much everything… haha, okay typical fanboi comment aside, what made those games that great? One thing stands out above everything else, the writing! Yes the setting design and the art style was amazing as well but it got outshined by the quality of the writing. The depth of characters, the locations, the back stories, the quests, the little jokes thrown in randomly, all these things fleshed out the game. Ironically the weakest story in both games was the main plot. I played those games just for the dialogues and the characters. The only other game that came close to the depth of the world and the dialogue was Baldur’s Gate 2.

Let me just go on a little bit of a rant now, to a large extent during the time period that the games were made, gaming was still a small exclusive past time. Most gamers of that period were male, and older, and usually a little geeky. There was no massive casual gaming culture as we knew , the console age was just starting and PC games were still in large, the smart gamers choice. I kinda feel that this contributed greatly to the depth of writing present in the original fallout games, when there was more focus on that sort of thing, and much less focus on large explosions, instant action and shiny graphics in games. Storylines were appreciated and dialogue sequences weren’t skipped just to get to the next level of killing hordes of nazi/aliens/etc. I miss those days, but maybe that’s just me.

Let’s move onto the combat and character systems in Fallout, the combat was a slow strategic affair, more a kin to a game of chess rather than a quake deathmatch. That again was indicative of the times, turn based combat was pretty common in games at the time and so no one complained. I personally loved the slower more thoughtful approach to combat. It made battles all the more epic since at the end you felt like you had not only outgunned your opponents but out thought them as well.

The character system was the now familiar SPECIAL system, which was based if I recall correctly on the GURPS system. I’m not gonna go into detail about the system, but it was basically a standard DnD style character attributes system. In addition to the character stats you had a list of skills, ranging from combat skills to dialogue skills, and perks. Anyone that’s played fallout3 will be familiar with both these. I really preferred the more open approach to character development found here in comparison to the rigid DnD character systems that pigeonholed your character from the start.

Another excellent design feature in the fallout games was the option to not fight! You could make it through a massive part of the game without firing a shot. This allowed me to replay the game several times with entirely different experiences. I played as a standard gunfighter character that just slaughtered everyone, then I played as a smooth talker, and realized how much additional depth the game had, and how much content I had missed out on by just gunning my way through everything. The level design was also excellent, there was no repetition between areas, you never got bored exploring. Items were also pretty scarce and so you had a sense of achievement when scavenging. There were tons of different weapons, different ammo types, different armors, etc.

The enemies were varied and tough, at no point did I feel like a god prancing through the world invulnerable, there was always some brotherhood of steel paladin or some super mutant to cut me back down to size.

What They Did Wrong

I honestly can’t really think of anything to complain about here. There were several glitches with quests not working properly and other miscellaneous bugs but those are not design problems. Design wise I can’t think of anything that could have been better. So

I’ve fanboi’d myself out so let’s move onto the best modern PA games: Fallout 3 and STALKER, seeing as we’re in a fallout mood we’ll start with fallout 3.

Fallout 3

What They Did Right

Their world design on the surface is excellent, wandering out in the DC wasteland from a first person viewpoint was excellent. I found the experience quite immersive. The various locations were quite well designed as well but there was some pretty major problems in regards to the world when you look at it in a little more depth, but I’ll get to that. The first person view and the graphics were again quite good and really help immerse the player in the environment, I found the combat system fun (it had some problems) for the most part, and really didn’t mind the VATS add on, it was fun blowing off parts in slow motion.

What They Did Wrong

(WARNING: bethesda fans should stop reading now)

When will bethesda realize that p&p RPG systems DONOT work well in first person? The obviously didn’t learn the lesson from morrowind or oblivion. Why bother giving the player the illusion of aim, when it had no effect on damage. How many times was the player stormed in oblivion by an enemy with 6 arrows sticking out his face? Seriously, it just shatters any immersion the player has with the game. The same happens in FO3, it didn’t matter if you shot someone in the face or in the foot, emptying a clip into an enemies face at close range only to have them still come at you is just stupid! Having a PnP character system in a realtime FPS game is stupid, what is it used for? just calculating whether you hit and how much damage you did? Uh, that’s what aim and distance is for, seeing as its already an FPS and chances are they already do an intersection test to see whether they should run a weapon hit check. Shooting a monster at point blank range and not hitting is ridiculous, and just ruins that sense of immersion once again.

The locations in the game while well designed from the outside lacked any sort of depth, a settlement with 6 people in it? seriously? Even megaton with its masses of people (read 20) only had 3 or 4 worth talking to. Just like every other recent bethesda game, there was a massive lack of depth. The levels were repetitive, if I had to see another sewer / subway I was going to scream. They just made a shallow simple hack and slash game and called it fallout. Yeh, it was fun for a while, until I ran through my bazilionth tunnel.

Also there were some consistency issues I had with the game, they’d be destroyed building and cars everywhere, the aftermath of a nuclear attack, and yet all the cars energy packs seem to have made it out okay, even though the cars themselves were destroyed. Also the addition of the nuke launcher?! Seriously?! I cna only think both those items were added in for the console “instant gratification” players take like “lotsa splosions!”. Weapons were not varied enough, and also items were everywhere, I don’t think I ever ran out of stimpacks or ammo. Obviously in a desolate wasteland, every single fridge or box will have tons of ammo and stuff in it, since no-one would bother looting (sarcasm!). Power armor was strewn everywhere, you never struggled for weapons or armor. Then they threw in a half baked recipe system that never really worked, the items you made were mediocre at best and you never really needed them anyways, again another stupid left over from oblivion.

The enemies were ridiculously easy to kill, supermutants going down with something ridiculous like three shots from a hunting rifle. I think by around level 14, nothing in the game could touch me, I’d maxed out my gun skills, my speech skills, my repair skills, and was busy maxing out my energy weapons skills. The quests were simple and linear, no back stories, no depth: “fetch me 30 nuka cola bottles”, why? because the NPC collects them of course. Why would I even give a damn? The moral choices were clear as night and day with the exceptions of the ghouls and tenpenny tower (kudos on that one guys). The characters were shallow and uninteresting. Trying to talk your way through things was pointless, it always boiled down to a fight. I honestly got bored 3/4 of the way through and didn’t bother finishing it.

The game can be simply described as a PA hack and slash, they might as well have foregone the quests entirely and just gone the diablo route. All in all it was a fun, simple, flashy, repetitive game without any sort of depth.

STALKER: SOC and CS

What they did right

 (I do realize stalker is not an RPG but it had a lot of RPGesque elements)

No stupid character system to calculate hits and so on, these guys were smart enough to realize that FPS and hit checks don’t work so well. You shoot a guy in the head he goes down, shoot him in the body, you’ll need to shoot him again.

Amazing environment, beautifully done, I don’t think any game has managed to capture that sense of desolation and abandonment as well as STALKER did.

 Excellent weapon range and customization options, excellent item range and artifact options. Pretty much every aspect in regards to weapons and items in the game was excellent. Items were scarce, health packs were pretty rare, various ammo types were extremely rare, artifacts were obviously rare, basically everything you carried, you had worked hard to acquire.

 The enemies were tough from the start till the end, you never once felt overpowering and untouchable.

What They Did Wrong

Infinite enemies, that was the one thing that pissed me off about both games, you’d killed everything in an area leave, come back literally 3 minutes later and the area would be repopulated with enemies. It just made the game annoying especially when travelling across multiple areas, you’d have geared up at a vendor, then by the time you got to your objective you’d be at half health with no health packs and no ammo.

CS introduce a broken faction system, which was interesting if it had worked! I should put this in the things they did right but since it never really worked I have no idea what it was supposed to do.

Terrible incomprehensible storyline and endings, I finished both games and really have no idea what the hell was going on. I had to go read the damn wikipedia page to get an idea of the storyline I had just played. I’ll put it down to a poor translation from russian to english. The game had so much potential for storytelling, tons of stalkers huddled around camp fires that could tell you rumors or interesting stories. They made use of it once or twice but not enough. The quests were all just fetch quests. Simple task / reward affairs, again so much potential especially in regards to the faction system. I really felt that having quests to go weaken enemy factions strongholds would have been excellent, so much potential for inter faction politics. Instead they made a open world FPS till you reached a certain point, where you couldn’t go back and followed a per defined route to an end mission that left you entirely unsatisfied. It’s like being led to a candy store through a rough ghetto, only to go inside and be given a stick of celery.

So now we come to my perfect PA RPG

My personal perfect PA RPG

Okay, so after lots of thinking, I actually think STALKER is an excellent base for a great PA RPG, but with some heavy modifications. Let’s just take stalker as a based and fallout’ify it a bit :) This is not going to be a full design doc, that I’m working on in my spare time but rather an idea of the things that I think would make a great game.

The World

The world present in stalker was excellent, it was well designed but severely underused. There were so many areas that could have been excellent little sub plot triggers or quest locations. Like the pump house in Clear Sky, great location, well modeled and designed and absolutely no reason to be there.

The world should be just like the stalker world, open and varying, there was next to no repetition across areas in stalker, unlike in the “seen one subway tunnel seen em all” fallout 3.

The Gameplay

Fallout 3 made me see that FPS is an excellent format for a PA game, you want to be able to feel that sense of destruction, emptiness, hopelessness that would be present in such a world, where fallout 1/2 portrayed that feeling through the rich writing, fallout 3 out did them in that regard with the magnificent vistas of destruction (pity that was all there practically was, an outside image).

In regards to the character system, I don’t think that a strict pen and paper style character system has any place in a first person game, it’s too restrictive and like I mentioned tends to destroy some of that sense of immersion. I’d suggest a system of skills, where you can increase the skills with each level. I’d also suggest reducing the number of skills to the bare minimum:  light weapons, heavy weapons, first aid, repair, speech, electronics.

I’d suggest health to remain the same as when the player starts out, so that the game is equipment based more so that stat based. I’d like to struggle to acquire my equipment and know that without it I’m pretty much as vulnerable as at the start of the game.

The combat system should also be a bit modified, I think that in additions to the skills there should be a proficiency list of all the weapons in the game. When you first find a weapon you should not have any skill in using it, an M4 is nothing like an AK so the assumption made in most games so far is that it is. I’d suggest introducing a system similar to that in dungeon siege 2, where the more you use a weapon type like an M4 the more proficient you get in using it. Start off with a massive crosshair and insane recoil and slowly reduce both these with use.

The weapons skills should affect the learning rate of each weapon. This game mechanic will further tie you to certain weapons and make the game inventory centric.

Characters shouldn’t be able to master all the weapons in the game, and so it should give them incentive to replay with different load outs. I’d also suggest various levels of specialization (beginner, intermediate, expert, marksman, etc) with each weapon, so once you cross over into a new level you unlock a special function like automatic fire, or three round burst, or allows you to use different ammo type…

The Weapons, Armor and Items

The range available in stalker was excellent, and the upgrade/customization system present in Clear Sky was the best I’ve seen in any game to date. I’d say keep a similar range of weapons. Perhaps add in some more ammo types and armors. Add in helmets and add helmet customizations. Perhaps even add extras like pants, boots etc, which affect things like stealth, stamina, etc… This adds the option for random generation of items (diablo style).

Players like customization, and the game should provide them to create entirely custom characters and loadouts. Have character skills affect the efficacy of items, good first aid gives you more health from health packs, better repair better repairs items, pretty much the way the fallout games handled the link between skills and items.

The Enemies

Enemies should be like the player, and their difficulty should depend on their equipment and skill sets as well, ie. a tough enemy must have high end armor and be at the max weapon level with a good quality customized weapon while an easy enemy must be wearing light armor and still be figuring out which end of the gun the bullets come out of.

At no point should the player feel invincible or fragile, obviously with better equipment, the weaker enemies will pose no challenge. The player must also be rewarded for good aim, and as such feel that he can take down tougher enemies if gets the right shots in. Getting a lucky shot in always feels so rewarding. Perhaps add the VATS system in as well just for some spice, calculate the chance to hit based on distance and weapon skill.  

The Storyline / Quests

Now the most important part of any RPG is the story, the characters and the quest. I’d suggest making it a very open “main” plot, something like the player’s brother needs money for an operation and the player entered the zone to raise the cash. Something that is a goal to work towards but that doesn’t restrict the player from the start. The game should be all about exploring the game world, learning about all the characters, the back stories, the politics. The player should be able to leave a lasting effect on the world. Having an ending like fallout’s with a slideshow of all the areas you visiting and how your actions affected them would be amazing.

The game should be like a long TV action series,  lots of character, lots of dialogue, lots of action.

Try to avoid stupid things like simple fetch quests, make them a little bit more elaborate, it will take a bit of thought, but that’s what you’re paying your game designers/writers for.  Make it interesting, make the choices have consequences, ie, “if you do a job for boss a, against boss b, boss b’s thugs might rob you of your belongings” etc… I think that multi part elaborate quests are what should be done rather than simple boring task. I recently finished GTA4 and towards the end of the game, I didn’t even bother watching the cut scenes, cause they boiled down to 4-5minute speeches to tell you to go to “point x” and kill “person y”.  Keep things interesting.

The game shouldn’t be about instant gratification, it should be a game where the player sits down and can’t stop playing for hours. I hate it when I sit down with a game and after an hour I’m about to throw my keyboard out the window when I’ve been given my 45th go to the other side of the map and kill/fetch something quest (ie STALKER, far cry 2, GTA 4).

Conclusion

This rant got to be super long and I apologize, It isn’t as detailed as I’d like it to be but if it was it would take another 15 or more pages and I doubt you’d want to read that much. I hope that people would agree with some of the things I’ve said or might even have better ideas. The comment box is just below, please use it :)

Some C++ Debugging Advice – use #ifdef

•27 April 2009 • 1 Comment

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 :)

IE8 Brief Performance

•21 March 2009 • Leave a Comment

so it got released yesterday and there’s a lot of speculation regarding performance, so I just briefly timed the load timed of a few of my favorite sites:

ie ff
wordpress 8 15
facebook 8.8 9.1
xs forums 9.6 13
cnn.com (uncached) 18 28.2
myspace 5 8
myspace login 27 26.7

IE8 seems to do okay, my tests arent super scientific or even done properly, just a quick test between the latest stable FF3 and IE8 on my machine. The memory usage of IE8 seems crazy tho: 60mb for two had across 2 processes. Earlier it was sitting at around 210 for 3 tabs open with 4 processes running.

I’m sure they’ll be some in depth performance reviews in the future, and I’ll be looking forward to it…

My attempt at a DX10 game engine… Name Ideas

•13 March 2009 • 4 Comments

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 :P

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

•24 February 2009 • 5 Comments

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.

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:

1. Create the mesh

2. Fill the Mesh with the index and vertex data necessary

3. Commit the mesh to the device

4. 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.

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:

image11

Source code: tutorial5.zip

DirectX 10 Tutorial 4: Indexed Buffers and Depth Testing

•23 February 2009 • 1 Comment

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.

image1Image 1: Cube with 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)

//———————————————————————————

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!”);

//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:

image2
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:  tutorial4.zip

It’s been a while

•27 January 2009 • 2 Comments

It feels like its been forever since I posted on my blog. I’ve been very busy rolling our the new CMS for the department of computer science at the University of Pretoria. The system was a complete rewrite of the legacy system we had in place. That old system was falling apart and was tearing at the seams for the last year. The  rewrite took me and the two part time guys at work around 2 and a half months to complete. It’s around 90% complete and sitting at over 17000 lines of code. I’m now taking the next few days off to recoup since I’d been working 65+ hour weeks for the last month.

What are my plans for this year? Well I’m starting my masters, I’m lucky that the masters here is a research masters and involves no coursework. I’ve selected a topic with some help from some developers in the game industry (huge thanks to Chris Jurney), I’ll be doing my masters on pathfinding in destructable environments. I’m also going to continue working on the DPT, and trying to apply it to real world problems (I’m currently busy using it to do automatic alaysis of aerial photos).

I’m going to carry on with my DX10 tutorials, and try and get a good solid background in graphics as well as AI. I’m planning on trying to make a small complete game this year just to have something I can show case.  There is also one last pet project that has been on the back burner for over a year now, I’m finally gonna sit down and complete the design document for my idea of a post-apocalyptic RPG.

I’ll hopefully be posting a new dx10 tutorial or my work on aerial photographic analysis within the next week or so!

Bobby – over and out!

Bad start to the new year!

•4 January 2009 • Leave a Comment

So i just returned from my trip to the USA. I presented a paper at the ICPR (international conference on pattern recognition) conference. The trip was amazing, it’s been my first vacation in close to 8 years. I really managed to unwind. While i was there i saw a gtx260 core 216 video card for $300 which is around $150 cheaper than here and i couldnt resist. Buying the card meant that i could move my 8800gtx to my work machine and have two high end workstations instead of one, so i did.

The card worked beautifully until yesterday when i rebooted my machine and the card was dead! FUCK! So now i have to go through the process of an international RMA with eVGA (thankfully they have that option). Sigh… I cant seem to catch a break :(

DirectX 10 Tutorial 3 – Textures

•29 November 2008 • 6 Comments

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.

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 :P

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.

image1

 

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: 

image2

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));

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.

So lets just tweak the shader program, 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:

image31 

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.

image4

 

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:

image5

 

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.

Download the visual studio 2008 project: dxTutorial3.zip