It’s been a pretty heavy week for me learning and re learning C++. Having been a C# developer for so many years, going back to C++ has been…interesting. From the perspective of a C# developer taking up C++, you realize just how lazy you can be in C#, C++ does not afford you that luxury, you have to keep your eye on the ball at all times.
I am pretty sure that the post(s) I am writing now, will have a lot of C++ faux pa’s in as well as DirectX11 ones too, but these are my creations after a week of spare time using C++ and DirectX 11, so please, if you are a solid C++ and/or DirectX 11 person, don’t judge me to harshly, if you see I have done something particularly daft, then please point it out in the comments and we can all learn from my mistakes, but be nice :P
I’d also like to thank at this point Ed Powel for all his help. Ed is another blogger from the old XNA-UK site, but his day job is C++, so I have leant on him a fair bit, and I will continue to do so, thanks Ed.
With that caveat, Ill begin…
My first few posts, while work as a whole are kind of my working out as I have been going through this process and I dare say, will continue to be, but in this post I am going to try and set out a simple framework that I can then use moving forward.
Where to start..
I am going to start with a new project, for a proto engine if you like, same sequence of events we used two posts ago for creating the project, this time, once you have set the Include and Library folders we need to add the following for this project to the Linker->Input->Additional Dependencies section:
Where are we going to start with this proto engine framework? I think a good place to start with when coming up with a framework is a definition of interfaces. As Ed points out in his new blog on the subject, (where I am cross posting these by the way :P) there are a few ways of doing it, I am using Microsoft’s __interface extension in my code as I am targeting Microsoft platforms.
At this point I only have a few, one to describe my graphics device object, one to describe a world object, one to describe my camera objects, one to describe an object that has an update method and finally one to describe an object that can be rendered or drawn. I dare say these will change as I learn more, but that’s great, it will just lead to more blog posts :)
Create a header fill and call it Interfaces, this is where we will keep them all.
Add the following headers
Now we will create the interfaces.
So in here, we have an initialization method, functions to get various member variables (I know, C++ does not have Properties!!), a method to clear the device etc..
This interface has most of the things we will need to place and object in the 3D world, position, orientation, a way to translate and rotate the object etc..
In here, two get methods to get the cameras projection and view matrix and some setters for world up and dimensions.
In this interface an Update method, I am passing a float for elapsed time, but at this point, I am not using it, and it may well get dropped all together.
Finally in this last interface, we have a draw call described, looking at this as I write up the post, I should probably replace the ID3D11DeviceContext with my new IRC3DGraphicsDevice interface, bit for this set of posts it will do fine.
We have already created a device in earlier post, so Ill just cover the bits I have added so that, that code will play well with this framework. Create a new class called RC3DGraphicsDevice, this time we are going to also specify that we are going to derive from a base class, now I know it’s an interface, we can put our interface in here too
If you take a look in the RC3DGraphicsDevice header file, it will look something like this
As you can see, the wizard has added out include file, and set our class up so that it is implementing our interface. Now, personally I don’t like that layout, so Ill tidy it up a bit. We can now populate our class definition with the methods from the interface. In C# you can right click the instance and tell the IDE to do it all for you, as far as I can see in VS2012 RC for a C++ project, you can’t, so I have copied and pasted it from the Interfaces.h file.
We now need to back these methods up with some member variables and the actual function bodies. First of all we need the variables for the methods to work with, add a protected section to the class and add them in like this
So, now we create and populate the function bodies in the RC3DGraphicsDevice.cpp file
Now, this GraphicsDevice class is a bit ridged, in that a lot of the elements in the Initialize we would want to pass them in as parameters or have them as objects in there own right, but for this simple framework, this will suffice.
We need some way of representing objects in the world, so again, create a class called RC3DBaseObject, and set the base class to IRC3DBaseObject
We are also going to implement the IUpdateable interface
As before, copy over the function stubs from the interface, and put some member variables in place.
Now to the RC3DBaseObject.cpp file and populate the function bodies.
As you can see we are using the default constructor (ctor) to pre populate the position, scale and orientation.
Also, my Translate and Rotate methods, taken from my XNA implementation, I guess I could have made the distance parameter a XMVECTOR to save a parse, and I think I need to look into the XMFLOATn and XMVECTOR data types.
You can’t really render any 3D goodies without some sort of camera, so we will create one now based on the interface we have already defined. This camera class is taken from my XNA samples and ported to C++, it was a pretty simple thing to do really. Now as I keep harping on, I am new to DirectX11, so I kind of figured out the objects and methods I needed to use, so if there is a better way of doing some of the stuff I am doing, then please, let me know.
Again we will create a new class called RC3DCamera and set the base class to IRC3DCamera
We are also going to derive from the RC3DBaseObject class, this way our camera class will have all the goodies from that base class.
And again we can copy the method stubs over, this time we are going to add a (ctor) override, we are also going to override the Update method from the RC3DBaseObject class
And again we need to get some member variable to back them up.
Now, to add the function bodies in the RC3DCamera.cpp file :)
Now we have a simple framework to work with, in the next post Ill put a primitive game class together and we can then create a test object and render it. What we have covered here wont compile by the way, unless you implement a WinMain function, if you do you will get the following compiler error(s)
So, next post we will get rendering some stuff, and we can even get to take a look at our first DirectX 11 shader :)
As ever, comments are more than welcome…