The Microsoft DirectX SDK contains a set of APIs for programming games on Microsoft Windows platforms. Things have been changing a lot recently with new APIs coming from the Xbox SDK and some of the old APIs moving or disappearing all together. For details please see the 'How is DirectX changing' answer.
The latest version of the SDK is DirectX 9.0 (April Update 2005) and the related redistributable is DirectX 9.0c*. Note: the next version is due in June.
Make sure you uninstall previous versions of the SDK before installing the latest version (really do this as I know from experience the problems that can occur if you do not!). Once installed go to the DirectX icon in Control Panel and turn on debug mode.
* The redistributable is provided with the SDK so you can include it with your game to make sure the user has the correct DirectX library files. Most users should automatically receive the latest version of DirectX as part of their Windows update process e.g. Windows service pack 2 installs the DirectX 9.0c files. Note however that new releases of the SDK do often change support libraries. See D3DX DLLs for details.
The help system that comes with the DirectX SDK is actually very good and should be your first place to look for help. Additionally the sample applications are great at showing an example of how to do something. You will also be surprised as to how much DirectX can do for you. If you want to do some graphic functions have a look in the SDK help first, there's a good chance there is a helper function in there (look at the D3DX functions).
There is a Microsoft FAQ on DirectX available as well here: DirectX FAQ. There are also some newsgroups dedicated to DirectX, and many web sites, see the resources page. Also check out Microsoft's DirectX Developer Area.
Firstly let me say that both are very useful to know. DirectX is a collection of APIs including APIs for graphics, music, audio, input, networking and multimedia. OpenGL is dedicated to graphics. So to compare the two makes no sense, we can however (tentatively) compare OpenGL with Direct3D:
As you can see there are pros and cons for each and really you should just learn both and use whichever is appropriate. You could even, if you wish, use OpenGL for graphics and the other APIs of DirectX for input, networking etc. If you are looking for a career in the games industry I would advise you to learn DirectX.
Firstly make sure you have the include and library paths set correctly in your IDE. For Visual Studio 6 go to the tools menu - options - directories and make sure the paths are set correctly for the SDK, e.g. they may be c:\dx90sdk\include and c:\dx90sdk\lib. Also make sure they are first in their lists. Use the black arrows to move them to the top. More detailed steps are shown in the next answer below:
If you have .net 2003 the DirectX set up should automatically fill in the path details.
Other link errors can be due to you forgetting to add a library to the project - settings - link - object / library modules text box (For Visual Studio 6) or the equivalent in .net.
These settings are to point Viz at the correct directories for using DirectX. Note that Visual Studio .net 2003 / 2005 folder settings should have been set up correctly for you during the DirectX install, these notes are only for the old Visual Studio 6.
And that's it. You should only ever have to do this once.
The first thing to do is to check the debug output in Viz, DirectX puts warnings and errors there that can help you find a problem. This requires you have DirectX in debug mode (it can be changed via the control panel - the number of warnings you get is controlled by the slider). In addition in the latest versions of the SDK you need to define D3D_DEBUG_INFO to get full messages (put it in project-settings preprocessor definitions).
DirectX provides a means of getting a DirectX error string. Each DirectX function returns a HRESULT, you can pass that to an error function to get an error string and then output it to the debug pane or the window. Note: OutputDebugString sends output to the debug pane in Viz.
The two functions are DXGetErrorString(hr),DXGetErrorDescription(hr)
Note: these functions replace the older DXGetErrorString9 and DXGetErrorDescription9 functions. Also the files are renamed from Dxerr9.h and the link file Dxerr9.lib to Dxerr.h and Dxerr.lib
To use these functions you must include Dxerr.h and link to Dxerr.lib (put it in the project - settings - link - object / library modules text box).
hr=D3DXCreateTextureFromFile( gDevice, d3dxMaterials[i].pTextureFilename, &m_meshTextures[i] );
sprintf(buf, "Error: %s error description: %s\n",DXGetErrorString(hr),DXGetErrorDescription(hr));
Note: rather than using the C-style printf code above you should prefer to use C++ Strings.
There are also functions in Dxerr.h that will display the error for you without having to do the above. Simply call:
DXTRACE_ERR(TEXT("My error description"),hr)
So the above example could now be written more neatly as:
if (FAILED(hr=D3DXCreateTextureFromFile( gDevice, d3dxMaterials[i].pTextureFilename, &m_meshTextures[i] )))
DXTRACE_ERR(TEXT("Failed to create texture"),hr);
Since you are constantly having to check the HRESULT from DirectX calls it makes sense to write one error function to handle them all rather than repeating the above each time. I have a class that is full of static helper functions which includes a function to check if a hr value is failed. If you create a macro you can even pass in the file and line number that the problem occurred on. e.g.
#define CheckHr(hr) CheckForDxError(__FILE__,__LINE__,hr)
The file and line are provided by the compiler and allow you to output where the problem occurred. In addition if you output them correctly you can double click on the error in the output pane of Viz and be taken to the line in question. Your function may then look something like this:
void CheckForDxError(const char *file, int line, HRESULT hr)
// Get the direct X error and description
sprintf(desc,"(DX) %s - %s",DXGetErrorString(hr),DXGetErrorDescription(hr));
// Output the file and line number in the correct format + the above DX error
sprintf(buf,"%s(%d) : Error: %s\n", file, line, desc);
// Cause the debugger to break here so we can fix the problem
Also see the answer below:
If you try to use the watch window to find out more about the Direct3D interfaces you will likely see lots of rubbish. To allow you to drill down the interfaces (with the loss of some speed - so just enable in debug mode) define this before including d3d9.h :
Every DirectX object you have obtained must be released before your application closes. This can include the Direct3D object, the device, textures, vertex buffers, index buffers, state blocks, sprites, fonts etc. Luckily every object implements the COM IUnknown set of interfaces which include a Release() function, so the process is the same to release everything e.g.
You must release things in the correct order. So the device and object are released last.
Advanced: If you have searched and searched and still cannot find what it is that you have failed to release there is one further, advanced, trick that can help. You will have some sort of leak message like:
Direct3D9: (ERROR) :Memory Address: 003b4b3c lAllocID=1 dwSize=00003524,ReturnAddr=00cb7346 (pid=00000108)
Go to the DirectX properties dialog box in control panel and make sure it is in debug mode. Then in the 'debugging box', in the part which says 'brake on AllocID' fill in the IAllocId in your error message. Run the game and you should then see which items are not releasing. The IAllocID of 1 is probably the main DirectX object and is not being released due to something later so check against the higher id numbers first.
Note: Visual Studio .net 2003 / 2005 has much better auto complete capabilities. This answer was written for Visual Studio Version 6.
Auto complete is a capability of Viz that means when you type a pointer and the -> or a . from an instance you get a drop down list of variables and functions, which is very useful! Unfortunately it does not always work well with libraries. You can get it to work in most cases for DirectX by actually including in your project the DirectX header files. So under the file tab add the DirectX header files so they are included in the project. After doing this do a complete rebuild and auto complete will now work in most cases. The new .net environment handles auto complete fine already.
Look at the error where it shows the path of the d3dtypes.h, if it is indicating it is in the visual studio directory then this is the problem. Visual studio comes with a very old version of DirectX so you have to make sure you use the one in the c:\dx90sdk (or where your version is installed) directory. To do this in Visual Studio 6.0 go to Tools/Options and select the directories tab, select Include Files in the Show Directories For drop down list and make sure the DirectX path is first on the list, use the arrows to move it to the top if it is not. Do the same for Library Files. See also Link Errors.
This is from a post by Phil Taylor of Microsoft on the Directxdev mailing list. I have edited it slightly for readability:
" Some one should store this somewhere for when it gets asked again :-).
Alex, Craig, and Eric burst onto stage at CGDC 1995 and showed a beta of the GamesSDK v1, with DDraw, DSound, DInput, and DPlay. The logo used was the radiation symbol, the internal code-name was "The Manhattan Project" and the technology was smoking hot compared to any previous Windows graphics API.
They got a standing o, as no one had ever seen an MS library delivering refresh-rate graphics. It was quite a scene, and the BBQ and open rides at Great America contributed to the feeling that something great was happening.
Summer of 1995 MS bought RenderMorphics with the intent of adding a 3D API to the GSDK. I know this because I was at Kaleida labs who was a source licensee of RL, and I was the 3D developer for ScriptX, both Mac and Windows. Thus Kaleida and I was notified about the transaction.
GSDK v1 shipped in Oct 1995, just after Windows 95 shipped in August 1995.
The famous Judgement day Halloween party complete with Gwar in the Haunted House at the Redwest parking lot celebrated the event.
The day after Judgement day, "The Aftermath" was held to brief developers on D3D. At that time a beta of D3D was made available. The immediate mode API was always called D3D. The higher-level RL API was renamed to be D3D Retained Mode.
At some point a 2nd version of RL was indeed made available, but at the cost of being COM-ified. RL lost a bit of its performance with this architectural change. But D3D IM and accessing 3D HW is where the action was anyway.
DX 2.0 shipped in June 1996. The Games SDK was indeed renamed at this point, but still used the old radiation symbol logo. It contained updates to the original 4 APIs. D3D IM and RM were aimed at DX 3.0.
DX 3.0 shipped August "43" ( Sept 12 to the rest of us ) because Eric promised it would ship in August. D3D IM with execute buffers and D3D RM were in that release.
The release plan Alex, Craig, and Eric had outlined before the community at CGDC 96 and again at Meltdown Aug '96 showed:
DX 4 was basically a bug fix release to make sure DX 3 actually worked on real 3D HW since the Voodoo 1 HW release was going to be after DX 3 shipped.
Similar fix-ups have happened since. After a lot of discussion, saner heads prevailed and convinced the 3 that a release right before Christmas would be a bad idea in terms of consumer satisfaction and game developer sales, since there would be little testing and a high likelihood of bad experiences and returns.
So the question was what to do about release numbers. Since a DX 5 release in 97 was already on tap, it was decided to skip DX 4 and go to DX 5. That way the community got the expected release in 97.
At the same time, both Japanese and German geographies provided feedback that the radiation symbol logo was not appropriate for those geographies.
Kevin Dalles was product manager at the time ( before Kevin Bachus ) and produced the 4-arm logo over winter 96-97. The logo change was unrelated to any release vehicle.
As a retrospective flashback, Alex started appearing down in the valley at Ken Nicholsons "GamePC Consortium" meetings ( which I attended ) and was talking about graphics acceleration, "Funstones" as a benchmark to measure graphics performance, etc - all a huge big hint he was cooking something up back in Redmond. http://www4.tomshardware.com/smoke/20000120/smoke-01.html captures some of that perspective. Although I have to say WinG wasnt that laughable, just limited to 8-bit modes which wasn't enough. DDraw accelerated all modes by comparison, which made it way more valuable. And the perspective on how RL become D3D IM is a bit limited in that its accurate enough for RM but doesn't hit enough data points for the IM API. And D3D definitely was not "jumped on" by 3Dfx, ATI, and nVidia. 3Dfx did all they could to counter-evangelise Glide. ATI and nVidia were helpful true. Nor is Rich Seidner's "Crushed by MS" totally true - I worked with Rich at Kaleida and thus know quite a bit about what really happened. So don't read Omits' article or any of these articles and believe all of it.
All that and I didn't mention the spaceship at all :-) " Phil Taylor, 20 October 2004, Directxdev mailing list.
For the recent history of changes to DirectX see the DirectX 9.0c page.
Update 2012: the DirectX SDK has not been updated recently. It appears it is to move from being an individual SDK into being part of the Platform SDK.
Things have been changing a lot recently with new APIs coming over from the XBox SDK (XInput, XACT, XAudio2) and some of the old APIs moving or disappearing all together. The traditional APIs were Direct3D, DirectShow, DirectInput, DirectPlay, DirectSound and DirectSetup. Recent changes though mean:
Shader model 4 is only supported by DirectX 10 running on Vista, it provides:
This is a library that provides enhanced DirectX extensions under Vista. It is not really needed and I would not advise any bothers to learn it as Direct3D 10 is a better API that also runs on Vista.