#include<windows.h>
#include<d3d9.h>
#include<d3dx9.h>
LRESULT WINAPI WinProc(HWND mainwindow, UINT msg, WPARAM wParam, LPARAM lParam);
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR CmdLine, INT CmdShow);
HWND mainwindow;
#define SCREENX 1280 //actual resolution used
#define SCREENY 1024
#define FULLSCREEN 1
//Global COM Objects
IDirect3D9* d3dobject; //D3D Com Interface Object
IDirect3DDevice9 *d3ddev; //D3D Device
D3DPRESENT_PARAMETERS d3dparam; //Set parameters to create d3d device
int InitD3D(int fullscreen,int reset);
int Render();
int D3DCleanup();
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR CmdLine, INT CmdShow)
{
MSG msg; //Message
WNDCLASSEX winclass = {sizeof(WNDCLASSEX), //size of structure
CS_CLASSDC, //Class Style
WinProc, //Message Hander
0, 0,
hInst, //Application Instance
NULL, NULL, NULL, NULL, //Icon, Cursor, Brush, Menu
"DX9 Project", NULL};
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
if(!RegisterClassEx(&winclass))
return FALSE;
mainwindow = CreateWindow("DX9 Project", //Window Class Name
"Game Window", //Window Title
WS_OVERLAPPEDWINDOW, //Window Style
0, 0, //x,y coordinate
SCREENX, SCREENY, //size
NULL, NULL, //Parent Window, Menu Handle
hInst, //Instance
NULL);
if(mainwindow==NULL)
return FALSE;
ShowWindow(mainwindow, SW_NORMAL);
UpdateWindow(mainwindow);
ShowCursor(true);
if(InitD3D(FULLSCREEN,0))
{
MessageBox(mainwindow,"Initialization of D3D9 Failed!","Uh Oh!",MB_OK);
return 0;
}
while(msg.message!=WM_QUIT)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
if(Render())
{
MessageBox(mainwindow,"Rendering Failed!","Uh Oh!",MB_OK);
return 0;
}
}
}
UnregisterClass("DX9 Project",hInst);
return 0;
}
LRESULT WINAPI WinProc(HWND mainwindow, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_QUIT:
case WM_DESTROY:
KillTimer(mainwindow,1);
D3DCleanup(); //Delete Textures
PostQuitMessage(0);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE: //Escape
PostMessage(mainwindow,WM_DESTROY,NULL,NULL);
break;
}
default:
return DefWindowProc(mainwindow,msg,wParam,lParam);
}
return 0;
}
int InitD3D(int fullscreen,int reset)
{
if((d3dobject=Direct3DCreate9(D3D_SDK_VERSION))==NULL)
return 1;
D3DDISPLAYMODE d3ddm;
HWND hwnd=mainwindow;
if(FAILED(d3dobject->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
return 1;
ZeroMemory( &d3dparam, sizeof(d3dparam) );
if(fullscreen)
{
d3dparam.Windowed=FALSE;
d3dparam.SwapEffect = D3DSWAPEFFECT_FLIP;
d3dparam.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dparam.BackBufferHeight=SCREENY;
d3dparam.BackBufferWidth=SCREENX;
d3dparam.BackBufferFormat=d3ddm.Format;
d3dparam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
//maybe d3dparam.BackBufferCount = 1;
//maybe d3dparam.SwapEffect = D3DSWAPEFFECT_COPY;
if(FAILED(d3dobject->CheckDeviceType(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,d3ddm.Format,d3ddm.Format,FALSE)))
{
MessageBox(NULL,"Video Mode not supported!","Error",MB_ICONSTOP|MB_OK);
return FALSE;
}
}
else
{
d3dparam.Windowed = TRUE;
d3dparam.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dparam.BackBufferFormat = d3ddm.Format;
d3dparam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;//D3DPRESENT_INTERVAL_ONE
}
if( FAILED( d3dobject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, //Create device
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dparam, &d3ddev)))
return 1;
return 0;
}
int Render()
{
HRESULT tempresult=0;
if(d3ddev->TestCooperativeLevel()!=D3D_OK)
{
tempresult=d3ddev->TestCooperativeLevel();
if(tempresult==D3DERR_DRIVERINTERNALERROR)
{
MessageBox(NULL,"Major Crash","Oh Shit!",MB_OK);
return 1;
}
while(tempresult!=D3DERR_DEVICENOTRESET)
tempresult=d3ddev->TestCooperativeLevel(); //wait until you can reset
if(tempresult==D3DERR_DEVICENOTRESET)
{
while(tempresult!=D3D_OK)
tempresult=d3ddev->Reset(&d3dparam);
}
}
//Set Render States
d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE); //Lighting ON/OFF
d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); //polygon culling mode
d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); //Turn alpha blending ON
d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); //These next two are the type of blending
d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); //type of blending
if(FAILED(d3ddev->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_RGBA(0,255,255,255),1.0f,0)))
return 1;
d3ddev->BeginScene();
d3ddev->EndScene();
d3ddev->Present(NULL,NULL,NULL,NULL);
return 0;
}
int D3DCleanup()
{
//d3ddev->SetTexture(0,NULL);
if(d3ddev != NULL)
int one=d3ddev->Release();
if(d3dobject!= NULL)
int two=d3dobject->Release();
return 0;
}
Odd Lost Device Issue
Ok.. I've read posts, tutorials, looked at example code until my head swelled up and still I cannot figure out what my problem is exactly.
I'm no stranger to Direct3D. I have a 2D platformer that I have gotten into the stages of limited playbility. However, my problem is much more basic than that. I understand the lost devices basics. My device stays lost when I am in fullscreen and is unable to be reset. I know that indicates that a device resource has not been freed, but I see no such resource.
Just to be absolutely certain, I started a new project, with only the barebones to get a blank window up and running. Still the same problem. The program does nothing but initiate the device and clear the screen.
For further information, everythign works fine in windowed mode and I can restore a lost device there. I can also switch from windowed to full screen mode with no problem. But once in full screen mode, D3D keeps telling me I cannot reset the device.
I must have missed something basic somewhere along the line. This is the code in it's entirety. It's only a mere 4 functions, the bare minimum to get a window up and running with restoring the device.
I hope that someone can point out the embarrassing mistake I have made in either the fundementals of D3D or Win32.
If you run the program, it will hang in the beginning of the Render() function waiting for the device to become resetable.
Messages may need to be processed. I'd drop out of the Render() call, and let the message pump run. When not active, you may also want to switch to waiting for messages rather than Peeking as fast as you can. If you don't want to bother making it wait, at least put a Sleep in there, allowing other things to run while you're not active.
Yeah, I agree with above poster.
This part:
Is no good. My guess is the device context isn't ready yet, and you arn't giving the windows messages a chance to prepair it for you. Try this instead:
If you want to structure it better to get rid of the ugly return then go for it, but the point is to get rid of the while statements. If you call reset and it's not working, then the same problem that stopped you the first time will continue to stop you, unless you let the windows messaging do its thing.
Help?
This part:
while(tempresult!=D3DERR_DEVICENOTRESET) tempresult=d3ddev->TestCooperativeLevel();
Is no good. My guess is the device context isn't ready yet, and you arn't giving the windows messages a chance to prepair it for you. Try this instead:
if(tempresult==D3DERR_DEVICENOTRESET){ tempresult=d3ddev->Reset(&d3dparam); return;}
If you want to structure it better to get rid of the ugly return then go for it, but the point is to get rid of the while statements. If you call reset and it's not working, then the same problem that stopped you the first time will continue to stop you, unless you let the windows messaging do its thing.
Help?
That was it guys. Jeez.. I knew it was something basic like that. I've been banging my head on this simple problem for a few days now.
I DID have a sleep() statement in there in my actual game. I forgot to put that in there when I made up the barebones test.
Thanks alot. I was under the impression that you could just loop and wait a bit until the device was ready to be reset. I didn't know it would never become ready unless I let it keep processing messages. Works flawlessly now.
Thanks again.
[Edited by - Nightcrawler99 on April 1, 2005 12:57:27 PM]
I DID have a sleep() statement in there in my actual game. I forgot to put that in there when I made up the barebones test.
Thanks alot. I was under the impression that you could just loop and wait a bit until the device was ready to be reset. I didn't know it would never become ready unless I let it keep processing messages. Works flawlessly now.
Thanks again.
[Edited by - Nightcrawler99 on April 1, 2005 12:57:27 PM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement