|
|
|
|
|
In this chapter, we are going to create the device. In short, a device is a direct link to your graphical adapter. It is an object that gives you direct access to the piece of hardware inside your computer.
To start, you have to link to the most common DirectX header files by simple adding these lines to your #include block:
#include<d3d9.h>
#include<d3dx9.h>
If this gives an error, the solution is in the next paragraph. Normally it shouldn’t be a problem to compile your project now, as the installation of the DirectX SDK should automatically add the DirectX header map to the include list of Visual Studio. However, sometimes it doesn’t, so run your code now to see if everything is still OK. If you’re all fine, skip the next paragraph, HOWEVER, if in the near future you’re experiencing errors like ‘cannot open include file: d3d9.h’ or ‘LNK2019: unresolved external symbol _Direct3DCreate9@4’, the solution to these errors is in the next 2 paragraphs.
Let’s do what the installation of the SDK should have done for us. I’ll explain this for MS Visual Studio, for other IDEs this should be pretty much the same. Go to the Tools menu and choose Option. Under Projects and Solutions, you’ll find the VC++ Directories. Now at the top right, let him Show directories for the Include files. There, click the yellow map to add an entry, click the ‘tree point button’ and navigate to your SDK files, which are by default installed into C:\Program Files\Microsoft DirectX 9.0 SDK, and select the Include folder. Do the same for the Lib folder, which you should add under Library files. Choose the x64 only if you know you have o ne of these latest PCs, otherwise choose x86. Okay, you should be ready to go.
In the header files we find all the declarations of the functions we will use, now we still have to link to the .lib files, that actually contain the implementations of the functions. Open the Project menu and choose the bottom option, the project Properties. Expand Configuration Properties, choose Linker and then Input. For the first line, Additional Dependencies, add the files d3d9.lib and d3dx9.lib, simply separated from each other by a space.
We will define a new method, the InitialzeDevice method, that links the device to our screen. You can already define the interface of the method, which takes the handle of our window and returns a pointer to the device for later use:
LPDIRECT3DDEVICE9 InitializeDevice(HWND han_WindowToBindTo) { }
First, let’s check if the DirectX runtime files have been installed on the user’s pc. You’ll try to obtain an LPDIRECT3D9 object, which can be used to check the capabilities of your graphics card. If this however is NULL, DirectX isn’t installed so the user should be warned about this. This is done by the following code:
LPDIRECT3D9 p_dx_Object; p_dx_Object = Direct3DCreate9(D3D_SDK_VERSION); if (p_dx_Object == NULL) { MessageBox(han_WindowToBindTo,"DirectX Runtime library not installed!","InitializeDevice()",MB_OK); }
Remark that now you also know how to display a messagebox! You simply have to pass it a reference to your window, the text, the title and the buttons to be displayed.
Now we are actually going to link to our Device. First, we need to configure some parameters. For this, we are going to fill a D3DPRESENT_PARAMETERS structure, done by this code:
D3DPRESENT_PARAMETERS dx_PresParams; ZeroMemory( &dx_PresParams, sizeof(dx_PresParams) ); dx_PresParams.Windowed = TRUE; dx_PresParams.SwapEffect = D3DSWAPEFFECT_DISCARD; dx_PresParams.BackBufferFormat = D3DFMT_UNKNOWN;
First the whole structure is cleared, because random data might still be in its memory from previous use. Then we say we don’t want full screen (yet), and use the easiest settings. Note however that a D3DPRESENT_PARAMETERS structure has plenty of parameters, which you can find in the help file, installed with the SDK.
Next we are going to link to the device, by invoking the CreateDevice method from the p_dx_Object. This method takes a load of parameters, links to the device and returns a pointer to it. Of course, we need a variable to store the pointer in, we’ll call this variable p_dx_Device. The following code could do the job:
LPDIRECT3DDEVICE9 p_dx_Device; p_dx_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, han_WindowToBindTo, D3DCREATE_HARDWARE_VERTEXPROCESSING, &dx_PresParams, &p_dx_Device);
The first parameter is not 0 only of you have multiple graphics adapters in your system. The second indicates that you have a true hardware graphics card. Then you pass the window you want to bind your device to. Since you have a hardware graphics card, you indicate that it’s fast enough even to do all the processing on the hardware. In the end, you pass the D3DPRESENT_PARAMETERS you filled as well as the place where to put device into memory.
This should work OK if you have a pretty new graphics card installed in your computer. If you’re working on an older computer or a laptop, chances are that this might throw an error, and the NULL pointer will be returned by the CreateDevice method. In that case, you’ll have to use the Reference device, which is enabled in software and simulates all DirectX features, but is a LOT slower than real hardware support.
Replace the last line by this code, it’ll check if there was a problem linking to a hardware device, and if so, it will link to the Reference software emulator.
if (FAILED(p_dx_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, han_WindowToBindTo, D3DCREATE_HARDWARE_VERTEXPROCESSING, &dx_PresParams, &p_dx_Device))) { if (FAILED(p_dx_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, han_WindowToBindTo, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &dx_PresParams, &p_dx_Device))) { MessageBox(han_WindowToBindTo,"Failed to create even the reference device!","InitializeDevice()",MB_OK); } }
That should do the job! I’ve encountered only one pc so far that didn’t even support the Reference emulator, but this was a a high-end measuring device equipped with a x86 CPU. Now our InitialiseDevice method needs to return the pointer to the device:
return p_dx_Device;
Which concludes our InitialiseDevice method. Now, in our WinMain method, we have to call this InitialiseDevice method and store the pointer to de device it returns:
LPDIRECT3DDEVICE9 p_Device = InitializeDevice(han_Window);
Add this line directly below your call to the NewWindow method, as it needs the handle to our window. Also, before your call to DestroyWindow, you have to release the memory your device occupies:
p_Device->Release();
OK, now we’ve properly initialised and released our device. Although you still won’t see a difference when you compile the code, a link to your hardware has been established. This is very basic, and we’ll use it in every following part of this DirectX Tutorial.

Click here to go to the forum on this chapter!
Or click on one of the topics on this chapter to go there: d3dx9math.inl Switching to target: default
Compiling: mai...Need help setting up VC++ Hey!
I have just joined this forum because I ha...DirectX Memory Leak I can compile and run your code fine. But after it...Compiling errors with d3d header files. when I try to include d3d9.h and d3dx9.h I get err...Error with Direct3DCreate9 The Direct3D9 object is created but when I try to ...error compiling?? when i try to compile the file it gives me this er...Error on examples #3 and above Every time I use attempt to compile your code, I g...
This is the code you should have up to this point:
#include<windows.h>
#include<d3d9.h>
#include<d3dx9.h>
int int_AppRunning = 1;
LRESULT CALLBACK OurWindowProcedure(HWND han_Wind,UINT uint_Message,WPARAM parameter1,LPARAM parameter2) { switch(uint_Message) { case WM_KEYDOWN: { int_AppRunning = 0; break; } break; }
return DefWindowProc(han_Wind,uint_Message,parameter1,parameter2); }
HWND NewWindow(LPCTSTR str_Title,int int_XPos, int int_YPos, int int_Width, int int_Height) { WNDCLASSEX wnd_Structure;
wnd_Structure.cbSize = sizeof(WNDCLASSEX); wnd_Structure.style = CS_HREDRAW | CS_VREDRAW; wnd_Structure.lpfnWndProc = OurWindowProcedure; wnd_Structure.cbClsExtra = 0; wnd_Structure.cbWndExtra = 0; wnd_Structure.hInstance = GetModuleHandle(NULL); wnd_Structure.hIcon = NULL; wnd_Structure.hCursor = NULL; wnd_Structure.hbrBackground = GetSysColorBrush(COLOR_BTNFACE); wnd_Structure.lpszMenuName = NULL; wnd_Structure.lpszClassName = "WindowClassName"; wnd_Structure.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
RegisterClassEx(&wnd_Structure);
return CreateWindowEx(WS_EX_CONTROLPARENT, "WindowClassName", str_Title, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, int_XPos, int_YPos, int_Width, int_Height, NULL, NULL, GetModuleHandle(NULL), NULL); }
LPDIRECT3DDEVICE9 InitializeDevice(HWND han_WindowToBindTo) { LPDIRECT3D9 p_dx_Object; LPDIRECT3DDEVICE9 p_dx_Device; p_dx_Object = Direct3DCreate9(D3D_SDK_VERSION); if (p_dx_Object == NULL) { MessageBox(han_WindowToBindTo,"DirectX Runtime library not installed!","InitializeDevice()",MB_OK); } D3DPRESENT_PARAMETERS dx_PresParams; ZeroMemory( &dx_PresParams, sizeof(dx_PresParams) ); dx_PresParams.Windowed = TRUE; dx_PresParams.SwapEffect = D3DSWAPEFFECT_DISCARD; dx_PresParams.BackBufferFormat = D3DFMT_UNKNOWN; if (FAILED(p_dx_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, han_WindowToBindTo, D3DCREATE_HARDWARE_VERTEXPROCESSING, &dx_PresParams, &p_dx_Device))) { if (FAILED(p_dx_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, han_WindowToBindTo, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &dx_PresParams, &p_dx_Device))) { MessageBox(han_WindowToBindTo,"Failed to create even the reference device!","InitializeDevice()",MB_OK); } } return p_dx_Device; }
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreviousInstance,LPSTR lpcmdline,int nCmdShow) { MSG msg_Message; HWND han_Window = NewWindow("DirectX C++ Tutorial",100,100,500,500);
LPDIRECT3DDEVICE9 p_Device = InitializeDevice(han_Window);
while(int_AppRunning) { if(PeekMessage(&msg_Message,han_Window,0,0,PM_REMOVE)) { DispatchMessage(&msg_Message); } }
p_Device->Release();
DestroyWindow(han_Window); return 0; }
- Website design & XNA + DirectX code : Riemer Grootjans - ©2003 - 2008 Riemer Grootjans
|
|
|
|
|