-
|
|
[C++] Problem with LPDIRECT3D9->CreateDevice()
|
Hi,
I can't find an answer anywhere else so I hope I can ask a c++ question here.
After working with xna I got to DirectX c++, but I'm unable to create a LPDIRECT3DDEVICE9 because LPDIRECT3D9->CreateDevice() returns D3DERR_INVALIDCALL. The Error occurs in Ini() at runtime.
That's my code:
| #include "Main.h" |
| void Render(); |
| void Move(float ftime); |
| LRESULT CALLBACK MSGProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); |
| void Exit(); |
| void Ini(); |
| LPDIRECT3D9 g_p3D3; |
| LPDIRECT3DDEVICE9 g_pd3dDevice; |
| |
| HWND hwnd; |
| |
| int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd ) { |
| WNDCLASSEX wc; |
| ZeroMemory(&wc, sizeof(WNDCLASSEX)); |
| wc.cbSize = sizeof(WNDCLASSEX); |
| wc.style = CS_HREDRAW | CS_VREDRAW; |
| wc.lpfnWndProc = (WNDPROC)MSGProc; |
| wc.hInstance = hInstance; |
| wc.hCursor = LoadCursor(NULL, IDC_ARROW); |
| wc.hbrBackground = (HBRUSH)COLOR_WINDOW; |
| wc.lpszClassName = "WindowClass1"; |
| |
| RegisterClassEx(&wc); |
| hwnd = CreateWindowEx(NULL, |
| "DirectX9Test2", |
| "DirectX9Test2", |
| WS_OVERLAPPEDWINDOW, |
| 300, |
| 300, |
| 500, |
| 400, |
| NULL, |
| NULL, |
| hInstance, |
| NULL); |
| ShowWindow(hwnd, nShowCmd); |
| |
| Ini(); |
| |
| MSG msg; |
| float fTime = 0.0f; |
| DWORD dwTimeS, dwTimeE; |
| ZeroMemory(&msg, sizeof(MSG)); |
| while(GetMessage(&msg, NULL, 0, 0)) |
| { |
| // translate keystroke messages into the right format |
| TranslateMessage(&msg); |
| |
| // send the message to the WindowProc function |
| DispatchMessage(&msg); |
| Render(); |
| Move(fTime); |
| dwTimeE = timeGetTime(); |
| fTime = (float) (dwTimeE - dwTimeS) / 1000.0f; |
| } |
| Exit(); |
| // return this part of the WM_QUIT message to Windows |
| return msg.wParam; |
| } |
| LRESULT CALLBACK MSGProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { |
| switch(message) |
| { |
| case WM_DESTROY: |
| { |
| PostQuitMessage(0); |
| return 0; |
| } break; |
| } |
| return DefWindowProc (hWnd, message, wParam, lParam); |
| } |
| |
| void Render() { |
| g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0 ); //program crashes 'cause g_pd3dDevice is NULL |
| g_pd3dDevice->BeginScene(); |
| g_pd3dDevice->EndScene(); |
| g_pd3dDevice->Present(NULL, NULL, NULL, NULL); |
| |
| } |
| |
| void Move(float fTime) { |
| |
| } |
| |
| void Ini() { |
| g_p3D3 = Direct3DCreate9(D3D_SDK_VERSION); |
| if(!g_p3D3) { |
| MessageBoxA(hwnd, "Error @ Ini @ Direct3DCreate9", "Error", MB_OK); |
| } |
| D3DPRESENT_PARAMETERS d3dpp; |
| ZeroMemory( &d3dpp, sizeof(d3dpp) ); |
| d3dpp.Windowed = TRUE; |
| d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; |
| d3dpp.hDeviceWindow = hwnd; |
| |
| HRESULT hres = g_p3D3->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp, &g_pd3dDevice ); |
| if(FAILED(hres)) { |
| if (hres == D3DERR_DEVICELOST) |
| { |
| MessageBoxA(hwnd, "Error @ Ini @ CreateDevice: DEVICELOST ", "Error", MB_OK); |
| } |
| else if (hres == D3DERR_DEVICENOTRESET) { |
| MessageBoxA(hwnd, "Error @ Ini @ CreateDevice: DEVICENOTRESET ", "Error", MB_OK); |
| } |
| else if (hres == D3DERR_DEVICEREMOVED) { |
| MessageBoxA(hwnd, "Error @ Ini @ CreateDevice: DEVICEMOVED ", "Error", MB_OK); |
| } |
| else if (hres == D3DERR_INVALIDCALL /*=true*/) { |
| MessageBoxA(hwnd, "Error @ Ini @ CreateDevice: INVALIDCALL ", "Error", MB_OK); |
| } |
| else if (hres == D3DERR_NOTAVAILABLE) { |
| MessageBoxA(hwnd, "Error @ Ini @ CreateDevice: NOTAVAILABLE ", "Error", MB_OK); |
| } |
| else if (hres == D3DERR_OUTOFVIDEOMEMORY) { |
| MessageBoxA(hwnd, "Error @ Ini @ CreateDevice: OUTOFVIDEOMEMORY ", "Error", MB_OK); |
| } |
| |
| } |
| |
| } |
| |
| void Exit() { |
| g_pd3dDevice->Release(); |
| g_p3D3->Release(); |
| } |
|
|
-
|
|
Re: [C++] Problem with LPDIRECT3D9->CreateDevice()
|
Presentation Parameters.
You need to setup your D3DPRESENT_PARAMETERS with more data than you are currently providing.
Make sure that you set values for all fields in the struct.
|
|
-
|
|
Re: [C++] Problem with LPDIRECT3D9->CreateDevice()
|
Check that hwnd is valid (non NULL). When i run your code, RegisterClassEx fails with GetLastError saying "The system cannot find the file specified", and of course window creation fails and hwnd is null.
|
|
-
|
|
Re: [C++] Problem with LPDIRECT3D9->CreateDevice()
|
Hi,
The 2nd parameter of CreateWindowEx function must be the name of the WNDCLASSEX (in this case WindowClass1) but u have given DirectX9Test2. Make both same it will work.
| wc.lpszClassName = "WindowClass1"; |
| |
| RegisterClassEx(&wc); |
| hwnd = CreateWindowEx(NULL, |
| "WindowClass1", |
| "DirectX9Test2", |
| WS_OVERLAPPEDWINDOW, |
| 300, |
| 300, |
| 500, |
| 400, |
| NULL, |
| NULL, |
| hInstance, |
| NULL); |
|
|
-
|
|
Re: [C++] Problem with LPDIRECT3D9->CreateDevice()
|
Errors of this kind are almost always accompanied by an explanation message from D3D's debug output. To activate and see these messages, please read:
http://www.inframez.com/papers/d3dforums.htm
I'm quoting the relevant section here:
DirectX has an excellent feature called the Debug Runtime. This allows DirectX to report errors and warnings to you while running your program under the debugger. With this feature on, almost every DirectX function call failure is accompanied by a helpful output message that is displayed in Visual Studio’s Output Window. This message will tell you why DirectX thinks your call is invalid, so you can correct the situation and run your program again.
To setup this feature, open the DirectX Control Panel, under the Debug/Retail D3D Runtime group box, make sure that the Use Debug Version of Direct3D option is selected. On the left, crank up the Debug Output Level slider all the way towards More (I personally leave it just one tick before the end). Note that a similar setup can be done for other DirectX components as well.
Managed DirectX applications have one more step left before this finally works, which is to Enable Unmanaged Debugging for the project. Follow this link on MSDN for the exact steps:
http://msdn2.microsoft.com/en-us/library/tdw0c6sf(VS.80).aspx
Unmanaged applications would want to link against the debug version of the D3DX library also, which gives important information for all D3DX function calls. Just make sure you link against D3DX9D.lib instead of D3DX9.lib in your Debug project configuration.
After you get this setup, just run your app through the debugger (press F5 to run it, instead of Ctrl+F5), and watch the Output pane in VS.NET...
I hope this helps...
Wessam Bahnassi Microsoft DirectX MVP
|
|
|