Intel sponsors gamedev.net search:
The site is presently in a read-only mode while we perform some internal maintenance. Thank you for your patience.
Control Panel Register Bookmarks Who's Online Active Topics Stats FAQ Search
GameDev.Net Discussion Forums Frequently Asked Questions (for individual forums) Back to the Forums
Current Server Time - 1:06:27 AM
FAQ - DirectX and XNA
Body
Welcome
Last updated: December 15, 2005

Any questions, comments or updates can be sent to the DirectX forum moderator via private messages (preferable) or email.

Many thanks to the people who helped with the compilation of this FAQ:

Cell-, circlesoft, Coder (now known as “Muhammad Haggag”), CrazedGenius, DirectXXX, Endurion, Erzengeldeslichtes, IFooBar, JohnBSmall, mastaba, Namethatnobodyelsetook (aka ntnet), Pipo DeClown, Promit, psykr, Raloth, and superpig, to name but a few.

This FAQ does 2 things:
1 - Covers the rules for posting in the DirectX forum, and
2 - Provides answers for frequently asked technical questions regarding the DirectX API.

If you ever find yourself wanting to post a thread in the DirectX forum, make sure you search this FAQ first.


Posting rules
If you have a question you need to ask, follow these rules to get the best response:

Read this FAQ first to make sure your question hasn't already been answered. Search it.

If you post something that is answered in the FAQ you will be notified, and your thread will be closed. If you repeat it several times your warning level will be increased, and if you keep at it you will be suspended.

Do some research before posting. That doesn't mean you should consider posting a last resort, but if you've not even bothered to google for your answer, why should we do it for you?

Post in the right forum. In the DirectX forum, the questions should be about implementation issues with the Microsoft DirectX API.
If your question is pretty basic, e.g. “What is DirectX” or “How do I start using DirectX”, then you’ll probably find better answers in this FAQ or in the For Beginners forum.

If your question is more about graphics, networking or physics techniques in general (e.g. collision), the Graphics Programming and Theory, Multiplayer and Network Programming, and Math and Physics forums are more appropriate.

Use a subject line that accurately describes your problem. Avoid subject lines like:
- Problem! I need help!

- DirectX is broken

- Help PLZ PLZ PLZ PLZ

Use something like:
- Extremely low frame rates with shadow volumes

- Determining Z Buffer depths supported

- Flickering when using D3DPRESENT_INTERVAL_IMMEDIATE

- [MDX] Rotating the texture on a point-sprite

Choosing an accurate subject line helps people identify your thread quickly, and potentially replying.

If you're using Managed DirectX, stick MDX somewhere in the title. The reason is twofold:
1 – A lot of people don't use MDX, so you'll save them some time by showing that you're using MDX upfront.

2 – Those that use MDX typically scourge the forum in search for MDX topics, so you’ll catch their attention.

When writing the question, write as clearly as possible.
Proper grammar will help avoid misunderstanding, and is good netiquette. If you take the time to write your post properly, people will be happier to take the time to answer it.

Include all the information that might be needed for people to give a good answer, including the version of DirectX you are using, as well as the SDK version, and any details about your hardware that you think might apply to the problem. If you don't give enough information, people won't be able to help you.

If you post source code:
- Make sure to cut out stuff that isn't relevant. If you want us to take a look at your render loop, don't include your collision detection system.


- If you'd like to get syntax highlighting on your code – making it easier for people to read and understand – use [source][/source] tags, as explained in the GDNet Forums FAQ.


- If the code you are posting is fairly small – say, 4 or 5 lines, and not too wide – then you can wrap it in [code][/code] tags; that will preserve all your tabs and spacing and display the code in mono-spaced font, but you’ll get no syntax highlighting. Please don't use code tags for very long lines of text.

You can find detailed formatting information in GDNet Forums FAQ.

If you post code without source tags, I'll fix it for you the first time and leave a notification. The second time it happens, I'll delete the code. After that it'll be warnings and suspensions.

One of the things people seem to frequently forget: when posting about a “won't compile/build” type problem, tell us what the reported error is!

Copying and pasting from the compiler output is fine. However, if you've got a lot of it, use source tags.

Finally, and possibly most importantly: Nobody here is being paid to help you. Be polite and courteous, and you're more likely to get help.

If you don’t get replies
If you posted a thread and people haven’t replied to you, don’t bump it until at least 24 hours have passed with no replies.


Table of contents


Links to other resources


DirectX Overview
- What is DirectX?
- How do I get started with DirectX? What do I need?
- I've heard about this thing called OpenGL. What does it have to do with DirectX?
- I heard that DirectX uses COM. Is that bad?
- Which version of DirectX should I use?
- Should I learn DirectDraw or Direct3D first?


Common, non-component-specific questions
- I'm having major problems building my DirectX programs. What could be the problem?
- I'm having major problems building my DirectX programs with VC++ 6. What could be the problem?
- I'm getting "unresolved external symbol" errors when building, but the missing symbol seems to be part of DirectX rather than part of my own code. How do I fix these?
- What's the DirectX Control Panel for?


DirectX Debugging
- How do I debug a DirectX application?
- Should I use the Debug or Release runtimes? What's the difference?


DirectX Setup/Installation questions
- Which version of DirectX do various versions of Windows come with?
- How do I discover which version of DirectX is installed on a system?
- How do I rig my setup program to install DirectX?


Direct3D


General
- What is Direct3D?
- What's the difference between HAL and REF devices, and between hardware and software vertex processing?
- How do I cope with people Alt-Tabbing away from my app, or the machine going into suspend mode and stuff like that?
- How do I change the display mode while the app is running?
- What are the default values for all the render states?
- I want to learn how to program with shaders, but I can't really find many references out there. Can you give me some good ones?
- I want my camera to move in the direction that it is pointing. How would I do that?


D3DX
- What is D3DX?
- I'm using the Debug runtime and I've got the Direct3D debugging level on full, but I'm not getting any error messages from D3DX. Why?


2D
- How do I do 2D graphics with Direct3D?
- I want to draw my JPG (or BMP, PNG, etc) image to screen. How can I do that?
- Should I use the ID3DXSprite interface for doing 2D stuff or not?
- How do I use ID3DXSprite?
- How do I get rid of black borders around sprites whose dimensions aren't powers-of-2? *
- Should I use the ID3DXFont interface for doing 2D text or not?
- How do I make a GUI (Graphical User Interface) in DirectX?
- I have a texture that I am applying to a quad with the same pixel dimensions on the screen as the texture, but the image comes out blurry. What's wrong?


3D Models and Animation
- What 3D file format should I use for Direct3D?
- I'm trying to use Direct3D and/or D3DX to animate my models, but it is very hard. Are there any free libraries that simplify this a bit?
- How do I load/parse X files?
- What is skeletal animation?


Colors and Lighting
- How is the color at a vertex determined?
- How do I use Direct3D to handle lighting in my programs?
- What is tangent space? How do I compute its basis vectors?


Vertex/Index Buffers and DrawPrimitive
- Is it better to use one vertex buffer, or many?
- Is it better to use one call to Draw[Indexed]Primitive or many?
- How do I change the size of a vertex buffer or add objects to it? What should I do if my data is always changing?
- Which should I use - the DrawPrimitive family of functions, or the DrawPrimitiveUP family?
- How does DrawIndexedPrimitive work? What do the various parameters mean?



Performance and Framerate
- Why did my framerate drop so much when switching from D3D8 to D3D9?
- Why does my fullscreen application have low FPS?
- My app runs at 1000 fps when I'm not rendering anything. But as soon as I render one polygon, it drops down to 500 fps! What's the problem?
- Why is render-to-texture so slow?


DirectDraw
- What is DirectDraw?
- Where did DirectDraw go in DirectX8/9?
- I still want to use DirectDraw for my 2D applications, but it's not included with the SDK anymore, and Microsoft doesn't have any of the older SDKs available for download anymore. What should I do?


DirectInput
- What is DirectInput?
- Where is DirectInput9?
- What is the difference between buffered mode and immediate mode in DirectInput?
- How do I scan for caps/signs?*


DirectSound
- What is DirectSound?


DirectMusic
- What is DirectMusic?


DirectPlay
- What is DirectPlay?
- Where has DirectPlay gone since the Summer Update 2004 SDK?


DirectShow
- What is DirectShow?
- Where has DirectShow gone since the Summer Update 2004 SDK?


DirectSetup
- What is DirectSetup?
- How do I use DirectSetup to install DirectX on a machine?
- How do I use DirectSetup to check the version of DirectX installed on a machine?
- How do I test to make sure my DirectX-installing program works properly?




Links to other resources


Must-visit resources
- The Official DirectX FAQ
- DirectX SDK Docs - The online version
- DIRECTXDEV mailing list - The official Microsoft mailing list for DirectX


Article/Tutorial/Sample sites
- The Z-Buffer - Managed DirectX resources
- Pieter Germishuys - Managed DirectX tutorials
- The Inner Realm - Managed DirectX resources
- Drunken Hyena - tutorials, code, utilities, and games
- Triple Buffer - Tutorials, code, and a DirectX framework
- Code Sampler - collection of code samples
- C-Unit DirectX Tutorials - A series of beginner tutorials for DirectX and Managed DirectX 9.
- Tom's DX FAQ - Tom Forsyth’s DirectX FAQ
- Vectiva's Managed DirectX tutorials
- Andy Pike's DirectX8 Tutorials – covering 2D, 3D, sound, music, and input
- 32Bits
- Two Kings game development
- Gamedev.net's DirectX Articles section
- GDOD - Gamedev DirectX Online Discussion - IRC-based DirectX lectures/talks, logs available
- NVidia Developer's FAQ - contains a fair amount of DirectX-related information for NVidia's systems
- NeXe - NeXe's tutorials (hosted by Gamedev.net)
- Wazoo Enterprises - Erik Yuzwa's "Borg cube" tutorials
- Mr GameMaker - DirectX discussion forums
- XDev.ru - Mr Snow DirectX column
- Ultimate Game Programming
- GameTutorials: Recently, the site began charging for tutorials - so be prepared to pay a small fee if you're willing to learn from there.


DirectX Engines
- OGRE3D - an open source 3D engine which supports DirectX
- Radon Labs - creators of the open source "Nebula Device" engine which supports DirectX
- Irrlicht - open source game engine which supports DirectX
- NeoEngine - open source3 D engine which supports DirectX
- Revolution3D – free 3D engine built on DirectX
- The Urgh! Engine – free 3D engine built on DirectX
- 3DLevel - VB.NET engines built on DirectX
- JTGame - C++/DirectX game framework
- CatMother - source code and content for a (now defunct) commercial project using DirectX




DirectX Overview


What is DirectX?
DirectX is a set of technologies made by Microsoft for the Windows family of operating systems that provide real-time multimedia and gaming services to programs: graphics, sound, music, input (mouse/keyboard/joystick/etc), networking, and movie playback.

There have been several versions; at the time of writing, DirectX is at version 9.0c.

Most games for Windows nowadays use DirectX in some form or another. It is also the technology which powers Microsoft's Xbox.

There are two parts to DirectX: the 'runtime' and the 'SDK' (Software Development Kit). Both are free.

The runtime is what your players need to have on their computers in order to play your game or run your application. The SDK is what you need to make games or applications that use DirectX.

Windows XP comes with the DirectX 8 runtime automatically installed; it's a 4 MB download if players don't have it. Windows XP SP2 comes with DirectX 9. You can check “Which version of DirectX do various versions of Windows come with?” for details.

The SDK, on the other hand, is over 200 MB in size, and it contains all the headers and libraries you need, plus documentation, samples, tutorials, and tools. Players don't need the SDK, only the runtime.


How do I get started with DirectX? What do I need?
You'll need:
- A compiler and linker such as Microsoft's Visual C++ (if you have VC++ 6, read “I'm having major problems building my DirectX programs. , , Borland's C++ Builder, or Dev-C++.
- The DirectX SDK, which you can download from the Microsoft Developer Network (MSDN).

One thing you ought to check - the SDK usually sets it up for you, but just to be safe - make sure that the most recent include/library paths are at the top of their lists in the search paths. The reason for this is that some development tools - specifically Visual C++ - come with an old version of the DirectX headers and libraries (around version 6 , I think). If the new paths were further down the list than the old ones, then there's a risk the old ones would be used by accident.


I've heard about this thing called OpenGL. What does it have to do with DirectX?
OpenGL is another technology that can be used for graphics. It is not part of DirectX; it does the same stuff as Direct3D, but in different ways.

Which one should you use, you ask? Well, neither OpenGL nor Direct3D is inherently faster or better; you're doing the same thing with either one, the important thing is your graphics card. Some have better driver support for Direct3D than for OpenGL, while for others it's the other way around.

If you don't have a graphics card with 3D acceleration features, then it depends on the software rendering support of the latest drivers for each. There are some other things to consider when picking which one to use:

- Direct3D can only be used on Windows platforms, while OpenGL is supported on Windows, Mac, and a large number of Unix derivatives, including Linux. There are versions of both OpenGL and Direct3D for mobile phones.

- Direct3D is updated every 2 months (along with the rest of DirectX), sometimes with major changes. But it is always backwards compatible, meaning that if you're using version 8 when version 9 comes out, you can carry on using version 8 without any problems.

Because of the frequent updates, Direct3D always supports the newest features of the hardware accelerators, and provides software emulation for a lot of them; features are quicker to be standardized than OpenGL, because OpenGL standards have to be agreed on by a committee of representatives from a number of companies, and that usually takes longer to do.

However, DirectX doesn't have any support for features that aren't official, while OpenGL has an extension mechanism that allows you to use certain features on certain graphics cards before it's been agreed how they'll officially work.

- Windows officially only supports OpenGL version 1.1, while Windows 98 and later all support DirectX9.0c.

- Using OpenGL means using a function-oriented interface, while using Direct3D means using an object-oriented interface.

A more complete comparison can be found here and here.

If you're worried about which one to learn, and which one the pros use, the answer is that more often than not they'll use both. The underlying math and 3D programming theory is the same for each of them, so if you learn that, you should do fine with both of them.

Oh, and apart from Direct3D, all the DirectX components can be used alongside OpenGL. If you want to use DirectInput for joystick input and OpenGL for your
graphics, that's fine.

If you want more information about OpenGL, the OpenGL Forum FAQ might be a good place to start.


I heard that DirectX uses COM. Is that bad?
COM is a Microsoft technology that runs throughout Windows. It's basically to do with software reuse, and about breaking programs down into components that can be reused throughout the system. COM itself is a pretty big topic, but you only need to know a little of it to work with DirectX, and that little bit is easy to learn.


Which version of DirectX should I start with?
The latest. It's the most stable, has the most features, and has the most documentation. You're going to want to learn it eventually, so instead of starting with an old version and then having to learn a whole load of new stuff when you switch, you might as well start with the latest version.


Should I learn DirectDraw or Direct3D first?
The only real reason for making a DirectDraw-only game these days is if you want to support archaic hardware. DirectDraw's functionality is extremely limited compared to Direct3D, and there's very little in the way of DirectDraw-only hardware out there (I mean very, very little) - and practically none amongst the gamers who will be playing your game.

If Microsoft actually dropped it from DirectX in version 8, you've got to consider that they did that because it's an obsolete technology, and there are now much better ways of doing things.


I'm having major problems building my DirectX programs. What could be the problem?
Well, first thing you should do is make sure you have your compiler and linker correctly set up, so that they can find the header and library files in the DirectX SDK (MSDN has some information on how to do this).

Also, if you're using VC++ 6, it is not supported starting from the December 2004 SDK, so you either have to upgrade, or use another SDK (Like the October 2004 SDK with the extras package that comes with it).


I'm getting "unresolved external" errors when building, but the names seem to be part of DirectX rather than part of my own code. How do I fix these?
First, check that you're linking with the libraries for the components you're using - d3d9.lib, dinput8.lib, and so on.

Also, an important part of COM programming is the concept of a GUID (Globally Unique IDentifier, or indeed its cousin UUID - Universally Unique IDentifier). A GUID is used to tell COM interfaces and objects apart from each other; the Direct3D object has its own GUID, as does the IDirect3D 9interface, as does the IDirect3D 8interface, and so on.
For DirectX, these GUIDs are stored in DXGUID.LIB, so you need to check that you're linking with it as well.


What's the DirectX Control Panel for?
The DirectX Control Panel (in the same place as all your other control panels, though you may need to switch to 'classic' view to see it) lets you:
- Switch between the Debug and Release runtimes
- Change the level of debugging output you get for each component
- Change various things about the way DirectX behaves

Most of the panel you don't need to touch, but you should familiarize yourself with how to switch runtimes and how to change the debug levels.


How do I debug a DirectX application?
More or less the same way you debug anything else. However, there are some useful DirectX-specific things I should mention here.

First, the DirectX debug runtime can be configured to print out debugging messages, which are often extremely useful. Through the DirectX Control Panel, you can set the level of messages that you want; the highest level will tell you about anything and everything that DirectX does, while the lower levels will only tell you about particularly important events, like errors. To view the messages, you need a debug viewer; Microsoft Visual Studio has one built in - the "Debug" pane –, while people using other setups could use a utility like DebugView.

For a more detailed look at setting up for Debugging output, try:
- Drunken Hyena's tutorial on the subject.
- NeXe: Debugging

There are different kinds of message DirectX will send the debugger:
- INFO messages are just DirectX being informative
- WARN messages usually aren't dangerous but should alert you to when something isn't performing as well as it could
- ERROR messages are actual problems.

The messages you see will depend on the settings in the control panel - for standard development, you probably want all the output levels ramped up to full, and also to turn on the Maximum Validation button.

When you're trying to find out why a specific function is failing and the debug output is no help, you need to work with return codes. More or less all the functions in the DirectX API return HRESULTs, the standard COM return type. Given an HRESULT hr,

- SUCCEEDED(hr) will be true if hr indicates an 'ok,' that the function you got it from didn't fail.
- FAILED(hr) will be true if hr indicates a failure.
- DXGetErrorString9(hr) will return a string which is the name of the constant that hr represents. If hr were D3DERR_DEVICELOST, the string would be "D3DERR_DEVICELOST".
- DXGetErrorDescription9(hr) will return a string which describes the error code in hr. If hr were D3DERR_DEVICELOST, the string would be something like "The device has been lost but cannot be reset at this time. "

The last thing to mention is that many people find it difficult to debug full-screen applications, because you can't see the debugger. There's three ways around that:

1 - Set up multiple monitors. This will allow you to run your game fullscreen on one monitor, and view the debugger on the other monitor. Many of the recent cards have 'multi-head' support (i.e. they'll support more than one monitor on that single card), but if yours doesn't, you'll need a second video card (probably PCI) to drive the second monitor. It doesn't need to be a good card - a TNT or something
similar will be both fine and cheap.

2 - Use remote debugging. This means that you run your DirectX application fullscreen on one computer, and use a network connection to debug it from another machine. This may be the most impractical method, as it requires a second computer, a network connection, and (possibly most importantly) a debugging environment that supports remote debugging. Microsoft Visual Studio does, but not many others do.

3 - Change your application to run in a window - Probably the easiest solution .


Should I use the Debug or Release runtimes? What's the difference?
The debug runtime is the same as the release runtime, except that it:
- does a load of parameter validation that the runtime doesn't do, and
- makes sure that certain things (like the backbuffer) get cleared to garbage values so that you're forced to ensure you're using them correctly, and
- gives debugging output, and
- is slightly slower.

When you're developing with DirectX, always, always, always use the debug runtime. However, you may want to switch back to the Release runtime when you use the machine for other things (i.e. playing games), and you should always test your app against the Release runtime before releasing it.


Which version of DirectX do various versions of Windows come with?
Try Michalson's handy reference table:


Windows DirectX
--------------------
95 None
95B DX3 (Supports up to DX8)
NT DX2
NT SP4 DX3
98 DX5
98SE DX6
ME DX7.1
2000 DX7.1
XP DX8.1

XP SP2 DX9



All systems after 95B can be upgraded to the latest version.


How do I discover which version of DirectX is installed on a system?
DirectSetup provides a function you can use for this, DirectXSetupGetVersion.


How do I rig my setup program to install DirectX?
First, you'll need the "redistributable runtime" to be packaged with your game - that's basically the files that make up a given version of DirectX for gamers, you'll find them in the SDK. Then you can use DirectSetup to handle all the rest for you.




Direct3D - General


What is Direct3D?
Direct3D is a library of objects for working with the graphics hardware. As the name suggests, it's primarily geared towards 3D graphics, though 2D graphics are perfectly possible as well.


What's the difference between HAL and REF devices, and between hardware and software vertex processing?
HAL (Hardware Abstraction Layer) devices and REF (REFerence rasterizer) devices are the two main types of D3D device; the first is based around hardware support, and is very fast but might not support everything; while the second uses no hardware acceleration, so is very slow, but is guaranteed to support the entire set of D3D features in the correct way.

In general you'll only ever need to use HAL devices, but if you're playing with some advanced feature that your card doesn't support (for example, the latest shader stuff) then you might need to fall back to REF. If I were you, though, I'd consider investing in a new graphics card; for most of the stuff you'd want to use it for, REF is so slow that it's almost painful.

The other time you might want to use REF is if the HAL device is producing some weird results - that is, you're sure your code is correct, but the result is not what you're expecting. The REF device is guaranteed to behave correctly, so you may wish to test your app on the REF device and see if the weird behaviour continues. If it doesn't, it means that either
(a) Your app is assuming that the graphics card supports something that it doesn't, or
(b) It's a driver bug.

If it still doesn't work with the REF device, then it's an app bug, i.e. one of yours. (True, it could be a REF bug, but that's so rare as to be worth discounting. The Direct3D team implemented the REF rasterizer in a very straightforward way that isn't prone to bugs, and while the result is slow, it's also solid).

Hardware versus Software vertex processing only really applies to HAL devices. When you push vertices through the pipeline, they need to be transformed (by the world, view, and projection matrices in turn) and lit (by D3D's built-in lights) - this processing stage is known as T&L (for Transform&Lighting). Hardware vertex processing means this is done in hardware, if the hardware supports it; ergo, Software vertex processing is done is software. The general practice is to try creating a Hardware T&L device first, and if that fails try Mixed, and if that fails try Software. (If software fails, give up and exit with an error).


How do I cope with people Alt-Tabbing away from my app, or the machine going into suspend mode, or stuff like that?
When your app loses control of the screen, the D3D Device becomes in a state known as lost. When a device is lost, it will appear to be working - functions will seem to have SUCCEEDED() - but nothing will actually come out on the screen. The only exception to that is IDirect3DDevice9::Present() - it will fail with the code D3DERR_DEVICELOST.

There are two ways to check for a lost device: check the return value of IDirect3DDevice9::Present() for D3DERR_DEVICELOST, or call IDirect3DDevice9::TestCooperativeLevel(). The second of these is preferred; if you use the first then you might not find out until the end of the cycle, which means you've wasted an entire cycle drawing stuff that won't get seen.

TestCooperativeLevel() will return one of three things:
- D3D_OK (it's not lost)
- D3DERR_DEVICELOST (it is lost, but you can't get it back yet - pause your game and wait until it's ready)
- D3DERR_DEVICENOTRESET (it's lost and you can get it back now).

It's perfectly OK to call TestCooperativeLevel() at the beginning of each frame.

Once the device has been lost and you're ready to get it back, you have to reset it - just like changing the display mode.


How do I change the display mode while the app is running?
It's quite likely that you'll want to change the display mode in your game - for example, when someone has changed the setting in the Options menu - and if possible you want to do it without quitting and restarting. So, Direct3D lets you do a sort of 'RecreateDevice' call, through IDirect3DDevice9::Reset(). Reset() takes a D3DPRESENT_PARAMETERS structure, just like CreateDevice(), which specifies the desired resolution and presentation settings.

If you're restoring a lost device, you'll probably use the same D3DPRESENT_PARAMETERS as when you called CreateDevice(); you can either store them from the first time around, or get them from Direct3D (you get a pointer to the swap chain through IDirect3DDevice9::GetSwapChain() first, and then use IDirect3DSwapChain9::GetPresentParameters()).

One thing you must do before Resetting a device: you have to release all D3DPOOL_DEFAULT resources, and then recreate them after calling Reset(). You're also not guaranteed to keep any of your device states (renderstates, texturestates, etc).


What are the default values for all the render states?
In|Framez has written a sample .FX file which shows off all the render states available to an effect, along with their defaults.

I want to learn how to program with shaders, but I can't really find many references out there. What are some good ones?

Books
ShaderX2: Introductions and Tutorials
ShaderX2: Tips and Tricks
GPU Gems

SDKs
nVidia SDK8 .0
HLSL Workshop in DXSDK

Websites
nVidia Developer site
ATI Developer site
Cg Shaders has a lot of great tutorials and tons of shader source code.
Code Sampler


I want my camera to move in the direction that it is pointing. How would I do that?
Grab the _31, _32, and _33 members of your camera matrix. These represent the camera's unit forward vector if the matrix is orthonormal. If not, you'll need to normalize the vector. Scale the vector with the distance you want the camera to move, displace the camera with it, and you're done.

Example:

D3DXVECTOR3 forward(camera_matrix._31, camera_matrix._32, camera_matrix._33);
camera_position += displacement * forward;






Direct3D - D3DX


What is D3DX?
Direct3DX (or D3DX for short) is a library of helper functions and objects designed to make 2D and 3D programming easier. There's a fair amount of math stuff there, along with objects for sprites, fonts, meshes, texturing, animation, and certain complex techniques like Precomputed Radiance Transfer.


I'm using the Debug runtime, I've got the Direct3D debugging level on full, but I'm not getting any error messages from D3DX. Why?
To get debug output from D3DX, make sure you're linking with "d3dx9d.lib" instead of "d3dx9.lib". As usual, use the latter for a Release build because it's faster.




Direct3D - 2D


How do I do 2D graphics with Direct3D?
Since DirectDraw was removed in DirectX8, this is a question that comes up quite a lot.

First, be aware that you don't have to use the most recent versions of all the DirectX components - you can still use DirectDraw7 alongside DirectInput8 or DirectPlay8, and it will still work. However, you're better off using Direct3D9 for it because today's graphics cards are geared towards 3D. So, you get extra features and better performance compared to DirectDraw.

You can still apply most of your 2D graphics concepts to 2D in Direct3D - sprites, pixel coordinates, and so on. However, you don't tend to work with individual pixels any more; instead, you use vertices and polygons. The key technique is known as 'textured quads' - a rectangular polygon that is textured ('wallpapered,' if you will) with the texture (image) of your sprite. You move that quad around on the screen, and the texture will go with it. If you set up the texture so that the space around your sprite is transparent, then it will be impossible to tell that it's on a textured quad, rather than being drawn in regular 2D.

There are a few other things you need to be aware of. In a regular 3D application, a perspective projection is applied - that means that objects further from the camera are made smaller. Unless you're aiming for some kind of special effect, you usually don't want that in 2D - so instead, you want to use an orthographic projection' in which things will stay their original size no matter how far from the camera you place them.
There are functions in the D3DX library for creating orthographic projection matrices, and then you use the SetTransform() function to put the matrix into the pipeline.

Also, the fact that you're using textured quads rather than plain surfaces gives you certain functionality for free - for example, rotating/scaling your sprites. It used to be tough in DirectDraw, but in Direct3D you can just stick a rotation matrix into the world transform, and voila, your sprite is rotated.

It's also possible to freely mix 2D and3 D. You draw your 3D scene with a regular perspective projection, and then switch to an orthographic projection and draw some textured quads on top. That's the common approach used for drawing things like health displays in games.

Finally, you don’t have to write the textured-quads approach yourself. Check out ID3DXSprite, which does it for you.


I want to draw my JPG (or BMP, PNG, etc...) image to screen. How can I do that?
The simplest, and probably fastest, way would be to use ID3DXSprite. It batches everything so it makes as few DrawPrimitive calls per frame as possible, which can really improve performance (especially if you are rendering a lot of quads). Check the next question.


Should I use the ID3DXSprite interface for doing 2D stuff?
Yes, you should.

It's fast, and it uses textured quads, which is what you'd be doing on your own anyway. If you want to do some crazy effects then maybe do it yourself, but don't be steered away from ID3DXSprite because you've heard that it's slow or impractical. It is neither of those things.

If you want to get the best possible performance out of it, then it's recommended that you try and put all your sprite images on one texture and use texture coordinates to pull them out, instead of using separate textures; using a single texture means that the card doesn't have to switch textures (a slow operation) and allows Direct3D to batch the sprites more efficiently.


How do I use ID3DXSprite?


// Load-time
(1) Create the ID3DXSprite object, using the D3DXCreateSprite factory function.
(2) Load your textures
// Run-time
(1) Call ID3DXSprite::Begin()
(2) For each texture you want to render
(a) Build the translation matrix
(b) Call ID3DXSprite::Draw()
(3) Call ID3DXSprite::End()


If you're using ID3DXSprite, use the D3DXSPRITE_ALPHABLEND flag when calling ID3DXSprite::Begin().


Should I use the ID3DXFont interface for doing 2D text?
Again, yes. It's fast and efficient, and it's unlikely that you could do better by hand.


How do I make a GUI (Graphical User Interface) in DirectX?
The DirectX SDK has a GUI framework. It has support for many basic controls, including:
- Command buttons
- Labels
- Checkboxes
- Radio Buttons
- List boxes
- Static Text boxes
- Edit Boxes (IME Enabled and not)
- Sliders
- Drop-Down boxes

The IME edit boxes are even capable of inputting using Windows IME. IME, or Input Method Editor, takes input from the keyboard and, when you press a specific key (usually spacebar) converts it to other characters, and if you hit the key again it will list the available alternate characters for what you spelled. This is useful for complex alphabets such as East Asian (Japanese, Chinese, Korean, etc) character sets where there are literally thousands of characters in each language. It even renders the IME Window in Direct3D while suppressing Windows' default IME Window (which tends to corrupt your graphics otherwise). , , without any conversions.

Also, the GUI is easy to use. It uses a simple system of callbacks for events that occur (i.e. Hover, KeyPress, Checked, etc)

A nice thing about it is that all the source code is contained right in the sample framework!

If you’re going to develop your own GUI library, check out the Developing a GUI Using C++ and DirectX series. It's excellent.


I have a texture that I am applying to a quad with the same pixel dimensions on the screen as the texture, but the image comes out blurry. What's wrong?
This occurs because you are not directly mapping texels to pixels. Check the following section in the SDK documentation:
DirectX Graphics->Programming Guide->Getting Started->Direct3D Textures->Texture Coordinates->Directly Mapping Texels to Pixels




Direct3D - 3D Models and Animation


What 3D file format should I use for Direct3D?
Direct3D doesn't require you to use any particular single file format for 3D models. Provided you can get the 3D data out of the file, and turn it into triangles for the renderer, then that's all it cares about.

Use the formats that are as obscure as you want. Design your own if it'll suit what you're trying to achieve better.

Having said that, D3DX provides very strong support for a file format known as 'X Files,' with the extension .X, so if you want to avoid writing your own model loader code (or downloading yet another library), you might want to look into using it. The X file format even supports animation, and it has exporters for most modeling packages.


I'm trying to use Direct3D and/or D3DX to animate my models, but it is very hard. Are there any free libraries that simplify this a bit?
Yes, there is. A file format called DirectMesh has been created especially for use with DirectX. It caters to those who want to add animation to their application, but don't want the headaches that normally come along with it. You can get the DirectMesh SDK here.


How do I load/parse XFiles?
IFooBar has written a couple of fine tutorials about this. You can find them here.


What is skeletal animation?
Check this thread.




Direct3D - Colors and Lighting


How is the color at a vertex eventually determined?
The color at a vertex depends on three things: whether there is a D3DFVF_DIFFUSE element in the vertex structure, whether the D3DRS_COLORVERTEX state is set, and whether the D3DRS_LIGHTING state is set:


D3DRS_LIGHTING
| D3DRS_COLORVERTEX
| | D3DFVF_DIFFUSE in vertex
| | | Result
----------------------------
0 0 0 White
0 1 0 White
0 1 0 White
0 1 1 Vertex Color
1 0 0 Material Color * Light
1 0 1 Material Color * Light
1 1 0 Material Color * Light
1 1 1 (Material Or Vertex Color) * Light



The last of those - (Material Color or Vertex Color) * Light – is determined by a set of four render states:
- D3DRS_DIFFUSEMATERIALSOURCE
- D3DRS_AMBIENTMATERIALSOURCE
- D3DRS_SPECULARMATERIALSOURCE
- D3DRS_EMISSIVEMATERIALSOURCE

Each of them can be set to:
(a) D3DMCS_MATERIAL, which uses the value from the material
(b) D3DMCS_COLOR1, which uses the vertex's diffuse color value
(c) D3DMCS_COLOR2, which uses the vertex's specular value

There is no way to get material color effects without enabling lighting.


How do I use Direct3D to handle lighting in my programs?
Direct3D provides a small number of lights that you can turn on and off at will. A light can be one of three types, can affect the color of the scene in three ways, and can have a number of properties depending on the type of light, such as position and direction. Be warned that the built-in lighting model is very basic - you don't get shadows or reflections or anything like that, and the number of lights available to you is usually in single figures. For more advanced lighting, you might want to look into other techniques, light mapping (the technique used by Quake3, amongst others).

Light colors break down into four parts: Ambient, Diffuse, Specular, and Emissive. Ambient light is the general light level that falls uniformly throughout your scene, like daylight in an outdoor scene; diffuse light is the standard 'color' of a material; specular light (or specular highlights) are the bright spots you see on shiny objects; and emissive light is light 'emitted' by a material. (Note that emissive light doesn't light anything else; only the material that emits it. You can use it to make something appear to be glowing).

There are four render states that affect lighting: D3DRS_LIGHTING, which enables/disables the Direct3D lighting system; D3DRS_AMBIENT, which sets the level of ambient light present in the scene; D3DRS_SPECULARENABLE, which turns specular highlights on/off; and D3DRS_LOCALVIEWER, which controls whether specular highlights should be faked or if the actual positions of the light and viewer can be taken into account. Most of the time D3DRS_LOCALVIEWER should be TRUE; you set it to FALSE when you're using an orthogonal projection, assuming you're using specular highlights at the same time.


What is tangent space? How do I compute its basis vectors?
This article by Philip Taylor on per-pixel lighting covers tangent space in one of its sections.

Here you can find sample tangent space calculation code.

D3DXComputeTangent can also be used.

The following is a description of tangent space and why it’s needed by Namethatnobodyelsetook:

“One thing that nobody ever seems to mention is what, conceptually, the S (tangent) and T (binormal) vectors are doing. We see code snippets using them to transform a light vector... but why? To get it into tangent space... but why? What does it mean?

The S and T tangent vectors describe how the texture is applied to the object. Lets say you made a bump-map which has a thin vertical stripe in it. Such as this pattern of heights:


000122221000
000122221000
000122221000
000122221000


Ok, now let’s texture-map a quad, except, let’s texture-map it side ways, i.e. rotated 90 degrees...rotated 90 degrees...just for fun.


00000000
00000000
11111111
22222222
22222222
11111111
00000000
00000000


Let’s create tangent vectors of our new sideways object.... I'm not going to walk through it. You know they represent direction of texture coordinates on the object. The results will be (0,1,0) and (-1,0,0). Great. How does this help?

Ok, so, lets say we have a light vector (0,1,0) hitting our object. We transform this light vector using S-Tangent, T-Tangent, and Normal.


0,1,0
0,1,0 x -1,0,0 = -1,0,0
0,0,1



Thus, our light vector has been transformed such that applying the texture sideways is cancelled out.

Then we dot3 with our normal map, and we're done.”




Direct3D - Vertex/Index Buffers and DrawPrimitive


Is it better to use one vertex buffer, or many?
In general, you should minimize the number of vertex buffers you use. The cost of switching vertex buffers is fairly high. While it's not as bad as it used to be in DirectX 7, it should still be avoided if possible.

Try to group everything static using the same FVF into a single vertex buffer if you can fit it. That is, put everything of your terrain into a single buffer, all models into another, particles into a third, etc. You are not limited to having a single "object" per vertex buffer. For example, suppose you have two models, 100 vertices each. You can put all 200 vertices into a single buffer. When you want to render model A, simply render vertices 0 through 99. When you want to render model B, render vertices 100 through 199.

The exception to this comes with index buffers. Only the newest hardware comes with support for index buffers in hardware. Everything else stores the indices in software and sends them along with the call to DrawIndexedPrimitive. If your bottleneck is the bandwidth to the video card then try to stay within 65535 vertices per index buffer so that you may use16 -bit indices, even if it requires you to call SetStreamSource more often.


Is it better to use one call to Draw[Indexed]Primitive or many?
One.

Every call to Draw*Primitive is considered a "batch". It is important to try to "batch" everything together. If you can, group everything using the same texture and material and render it all with one call. However, do not worry about the number of triangles per batch; worry about the number of batches per second. Often, Direct3D can just send the Draw*Primitive command straight through to the video card as a single piece of data, which means less bandwidth usage and more time for your app to get on with other things.


How do I change the size of a vertex buffer or add objects to it? What should I do if my data is always changing?
You can never change the size of a vertex buffer after it's been created. However, what you may want to use - and what you will want to use if your data is changing frequently - is a dynamic vertex buffer.

The basic technique is to create a vertex buffer, specifying the dynamic flag, with enough room for a decent number of objects (or your single object if its data is constantly changing). In regular situations, calling Lock() is slow, but the dynamic flag tells the driver that you will be calling Lock() frequently on the buffer so the driver is able to store it optimally in memory.

A particle engine is a good example of a system that would use a dynamic vertex buffer. For every frame, you call Lock on the vertex buffer, and start filling it up with vertices. If you run out of room in the buffer and you still have more particles left, you unlock it, call Draw*Primitive, lock the buffer once again, and repeat. MSDN has some information on how to optimize this process.


Which should I use - the DrawPrimitive family of functions, or the DrawPrimitiveUP family?
Both construct primitives for the pipeline. However, the big difference is in their source data - DrawPrimitive takes it from the current streams (vertex buffers), which DrawPrimitiveUP takes it from a pointer you pass in (your own array).

If you're drawing less than around 100 vertices, Direct3D automatically copies the vertices into it's own private vertex buffer, so the DrawPrimitiveUP call is actually 'translated' into a DrawPrimitive call, plus a memcpy (and if it's less than 100 vertices, that memcpy probably won't be significant).

Dan Baker (on the Microsoft Direct3D team) says: "Using DrawPrimUP for very small loads isn't any different then creating a Dynamic Vertex Buffer And filling it yourself - except an extra memcopy (that is negligible since the loads are small). If you are just using it to do UI quads or sprites, then its fine. "


"

Tom Forsyth (at RAD Game Tools) also points out: "DIPUP is not a bad call to make if the data is already in the CPU cache - for example if you have just generated the data for a particle system or something. "


How does DrawIndexedPrimitive work? What do the various parameters mean?
It works like this (pseudo-code):


idxptr = &indexbuffer[startIndex];
loop for each primitive
{
index = *idxptr++;
// nVidia hardware does not contain these "assert"s.
assert (index >= MminIndex);
assert (index < (MinIndex + NumVertices);
vertex = vertexBuffer[index + BaseVertexIndex];
}


You can find a longer explanation with examples here: DrawIndexedPrimitive Demystified




Direct3D - Performance and Fps


- Why did my framerate drop so much when switching from D3D8 to D3D9?


- Why does my fullscreen application have low FPS?
The key change is in the meaning of D3DPRESENT_INTERVAL_DEFAULT, when you're setting up your D3DPRESENT_PARAMTERS structure.

Previously, it meant D3DPRESENT_INTERVAL_IMMEDIATE - that is, flip the buffers as soon as Present() is called - but in D3D9 it's been changed to mean D3DPRESENT_INTERVAL_ONE, which means that Present() will wait for the vertical retrace. As a result, the renderer's framerate gets limited to the screen's refresh rate.

To fix the problem, simply use D3DPRESENT_INTERVAL_IMMEDIATE instead of D3DPRESENT_INTERVAL_DEFAULT.


My app runs at 1000 fps when I'm not rendering anything. But as soon as I render one polygon, it drops down to 500 fps! What's the problem?
There is no problem. Frames per second is not a good indicator of performance once you get above a certain range. A drop of 100 fps to 50 fps is many times more severe than a drop from 1000 fps to 500 fps. As soon as you push any vertices to the card (and make DrawPrimitive or DrawIndexedPrimitive calls), you are instantly going to lose a lot of frames per second. It doesn't really matter though, because the human eye can't even pick up the difference.

A better indicator of performance would be frame-time. Check Robert Dunlop's article:
FPS vs Frametime.


Why is render-to-texture so slow?
Check which pool the texture has been created in. If it's D3DPOOL_MANAGED you've got a problem - Direct3D tries to keep a local (system memory) copy of all MANAGED textures so that they can be restored on a device Reset(); as a result, whenever you render to the texture, it has to be read back from the video card into system memory, which is a major performance hit. Instead, create render target textures in D3DPOOL_DEFAULT.





DirectDraw


What is DirectDraw?
DirectDraw is a library of objects for working with 2D graphics and video surfaces. It lets you access frame buffers directly, working pixel-by-pixel if you want. It doesn't include any 3D functionality, and was merged into Direct3D in DirectX8 .0.


Where did DirectDraw go in DirectX8 /9?
Dedicated 2D functionality is no longer part of DirectX; it was dropped after version 7.

The new technique is to use quads (rectangular shapes) that are aligned in a plane parallel to the screen, so they look 2D. However, unlike DirectDraw, you get all the benefits of hardware 3D support - including things like alpha blending and free rotation. Surfaces, and accessing video memory directly, are still supported as part of Direct3D, so dynamic textures are still achievable.


I still want to use DirectDraw for my2 D applications, but it's not included with the SDK anymore, and Microsoft doesn't have any of the older SDKs available for download anymore. What should I do?
You can still use DirectDraw7 - it is still a part of DirectX. However, all development for it has ceased, so Microsoft has stopped including documentation for it. Since DirectX is backwards compatible, you can still compile your DirectDraw applications with the latest SDK. Also, if you want older SDKs, try this site.




DirectInput


What is DirectInput?
DirectInput is a library of objects for collecting input from the user - via the mouse, keyboard, joysticks, gamepads... pretty much any 'game controller' you can think of. It also provides a system for 'action mapping,' which allows you to connect up buttons and axis on the controllers to actions within your game very easily.


Where is DirectInput9?
There is no DirectInput version 9. When they released DirectX9 they hadn't needed to make any changes to the DirectInput API, so rather than just duplicate version 8 as version 9, they left it at 8. Don't worry, there's nothing wrong with using version 8 alongside version 9 of the other components (or indeed, using any version of DirectInput with any other version of the other components).


What is the difference between buffered mode and immediate mode in DirectInput?
Immediate mode gives you a current snapshot of the device. It tells you the current state of every button and axis at that current point in time. Buffered mode, however, is a list of all events that occurred - events such as keyup, keydown, axis moved, etc.

Here is an example of retrieving buffered input:

// keyboard is the IDirectInputDevice8 object
DIDEVICEOBJECTDATA data[8];  // You can change this if you want
DWORD numElements;

if( FAILED( keyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), data, &numElements, 0 ) ) )
{
   // Handle lost keyboard
}

for( int i =0 ; i < numElements; i++ )
{
   if( data[i].dwOfs == DIK_A )
   {
      // Test A key      
      if( data[i].dwData & 0x80)
      {
         // A has been pressed
      }
      else
      {
         // A has been released
      }
   }
}





// keyboard is the IDirectInputDevice 8object
char keys[256];  // Array to hold keystates in

if( FAILED( keyboard->GetDeviceState( sizeof( keys ), LPVOID(&keys) ) )
{
    // The keyboard has been lost, try to re-aquire here
    // and perform error handling
}

if( keys[DIK_A] & 0x80)
{
    // The 'A' key is down
}




Check if one of the shifts - DIK_LSHIFT or DIK_RSHIFT - pressed or the caps lock - DIK_CAPITAL - is turned on.




DirectSound


What is DirectSound?
DirectSound is a library of objects for recording and playing sounds with very low latency, and for allowing your game a high level of control over the sound pipeline. It also includes a system for 3D sounds - playing the sound in such a way that it seems to come from a specific direction - and a system for applying effects to sounds; like 'echo' and 'garble'.




DirectMusic


What is DirectMusic?
DirectMusic is a high-level set of objects, built on top of DirectSound, that allow you to play sound and music without needing to get quite as low-level as DirectSound. There's also strong support for 'dynamic soundtracks' - having music which changes in response to events in the game.




DirectPlay


What is DirectPlay?
DirectPlay is a library of objects for networked games. It provides systems for transferring data between games, as well as objects for locating games on a network, and 'lobbying' (having players meet up in a chat-room style environment and then automatically launch your game from within it).


Where has DirectPlay gone?
DirectPlay is deprecated (it may be reincarnated later on the XNA platform). You can still use it, but Microsoft isn't updating it anymore.




DirectShow


What is DirectShow?
DirectShow is a large collection of objects for working with multimedia data. " " For example, you have filters that read data from a file, and filters which compress/decompress video streams, and filters that render video to the screen. The number of filters is pretty immense, though, and it includes a framework for writing your own if what you want to do isn't present.


Where has DirectShow gone?
DirectShow is now part of the Platform SDK.




DirectSetup


What is DirectSetup?
DirectSetup is an extremely simple library of functions for installing DirectX on a machine. It also provides a way to check the version of DirectX that is present.


How do I use DirectSetup to install DirectX on a machine?
You use the DirectXSetup() function from dsetup.lib. Just pass in the HWND of your install program if you've got one, the path to the "redistributable runtime" (a set of files included in the SDK - you have to put them somewhere that your setup program can reach them, such as on your game's CD), the appropriate flag, and you're done - the function will tell you if everything went ok and if the machine needs to be restarted. There are other functions in the DirectSetup API that will let you do things like setup a callback function to keep you informed of the process, or display the DirectX EULA to the user. Such functions are all documented in the SDK.


How do I use DirectSetup to check the version of DirectX installed on a machine?
Use the DirectXSetupGetVersion() function. It gives you two numbers - a version number and a revision number. To get the number you want out of that, use the LOWORD() macro on the version number. A more detailed explanation follows...

The version number is the part you'll usually be interested in. It's made up of the 'major' and 'minor' versions - the major version in the top two bytes, and the minor version in the bottom two. The major version has been 4 since DirectX5; while the minor version is the one people usually refer to when talking about DirectX. So, for example, DirectX6 has a version number of 0x00040006.

The revision number allows you to find out which point-release you're using: DirectX8.1 for Windows XP, for example, has a revision code of 0x0001032A; while DirectX8.2 has a revision code of 0x00020386. All the codes are listed in the SDK, in the documentation page for the function DirectXSetupGetVersion.


How do I test to make sure my DirectX-installing program works properly?
Pass the flag DSETUP_TESTINSTALL when you call DirectXSetup().
It'll do a "simulated install" - check that it can find all its files and that they're all valid, etc, without actually installing anything.

All times are ET (US)

Moderators/Admin: Edit FAQ