Archived

This topic is now archived and is closed to further replies.

JimboC

Alt-Tab kicking my butt

Recommended Posts

I've got a problem when my application tries to recover from an Alt-Tab. Basically, everything appears to work, except the graphics don't render anymore. I'm initialising D3D as follows:
        
HRESULT InitD3D( HWND hWnd )
{
    if( NULL == ( g_pD3D = Direct3DCreate8( D3D_SDK_VERSION ) ) )
	{
		SetError ( "Unable to Create D3D Object." );
                return E_FAIL;
	}

    D3DDISPLAYMODE d3ddm;
    if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
	{
		SetError ( "Unable to get previous screen resolution." );
                return E_FAIL;
	}

    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
	
	d3dpp.BackBufferWidth = Width;
	d3dpp.BackBufferHeight = Height;
	d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
	d3dpp.BackBufferCount = 1;
	d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.hDeviceWindow = hWnd;
	d3dpp.Windowed = FALSE;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
	d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	d3dpp.Flags = 0;    

    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) )
    {
		SetError ( " Unable to create D3D Device." );
		return E_FAIL;
    }

	DeviceWidth = Width;
	DeviceHeight = Height;
	g_pSavedPresentParameters = d3dpp;

	if ( FAILED ( g_pd3dDevice->GetBackBuffer ( 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface ) ) )
	{
		SetError ( "Unable to acquire Back Buffer" );
		return E_FAIL;
	} 	

    g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );


    return S_OK;
}
  
I initialize graphics like such:
  
...                  
LPD3DXBUFFER pSShipMtrlBuf;

if( FAILED( D3DXLoadMeshFromX( "Space Ship.x", D3DXMESH_MANAGED, g_pd3dDevice, NULL,
                               &pSShipMtrlBuf, &SpaceShipNumMat, &SpaceShipMesh ) ) )
{
    SetError ("Unable to load space ship mesh");
    return E_FAIL;
}
d3dxMaterials = (D3DXMATERIAL*)pSShipMtrlBuf->GetBufferPointer();
SpaceShipMaterials = new D3DMATERIAL8[SpaceShipNumMat];
SpaceShipTextures  = new LPDIRECT3DTEXTURE8[SpaceShipNumMat];
for( DWORD i=0; i<SpaceShipNumMat; i++ )
{
    SpaceShipMaterials[i] = d3dxMaterials[i].MatD3D;
    SpaceShipMaterials[i].Ambient = SpaceShipMaterials[i].Diffuse; // Change This Later?

    if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, d3dxMaterials[i].pTextureFilename, &SpaceShipTextures[i] ) ) )
    {
        SetError ( "Unable to create texture for the space ship." );
        SpaceShipTextures[i] = NULL;
    }
}

pSShipMtrlBuf->Release();
...
  
And I'm running the following code before I render:
  
            
HRESULT ValidateDevice ()
{
    HRESULT R = NULL;
	R = g_pd3dDevice -> TestCooperativeLevel ();
	if ( FAILED ( R ) )
	{
		if ( R == D3DERR_DEVICELOST )
			return E_FAIL;

		if ( R == D3DERR_DEVICENOTRESET )
		{
			g_pBackSurface->Release ();
			if ( FAILED ( g_pd3dDevice->Reset ( &g_pSavedPresentParameters ) ) )
			{
				SetError ( "Could Not Reset Device." );
				PostQuitMessage ( E_FAIL );
				return E_FAIL;
			}
			
			if ( FAILED ( g_pd3dDevice->GetBackBuffer ( 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface ) ) )
			{
				SetError ( "Unable to re-acquire Back Buffer" );
				PostQuitMessage ( 0 );
				return E_FAIL;
			} 	

			g_pd3dDevice->Clear ( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB ( 0, 0, 0 ), 0.0f, 0);
		}
	}

	return S_OK;
}
    
It seems to me that by using D3DXMESH_MANAGED when I load the mesh and D3DXCreateTextureFromFile both should be in the D3DPOOL_MANAGED and should resore by themselves. I've also tried releasing all mesh resources and reloading, but still nothing. I've spent two days on this and can't see what I'm doing wrong. The DirectX documentation has too much Microsoft-ese to really make since and I've tried everything I've seen posted in this forum for this. Any ideas? [edited by - JimboC on July 30, 2002 2:01:30 PM]

Share this post


Link to post
Share on other sites

  
case WM_ACTIVATEAPP:
if(wParam == TRUE) {
//alt-tabbed into your app

}
else if(wParam == FALSE) {
//alt tabbed out of your app

}
break;


That works for me

[edited by - atcdevil on July 30, 2002 4:17:28 PM]

Share this post


Link to post
Share on other sites
atcdevil:
Sorry, I was getting frustrated with my problem. Didn''t mean to be short with you.

It seems I figured my problem out as well. Turns out that when someone Alt-Tabs out of my application, the lighting gets turned off when I reset the device. I turned it back on and everything was fine. #*$%@ black background!

Share this post


Link to post
Share on other sites
You can call RestoreAllSurfaces (or just Restore for each surface). However to tell if a surface is lost look at IsLost(), it returns true if its lost, false if its not. And then reload all the bitmaps/pictures/etc.

Share this post


Link to post
Share on other sites
Jimbo: Your entire device is reset - all the transform matrices, lights, non managed resources (surfaces (inc. textures), VBs & IBs), current vertex shader, and prob. several other things i''ve forgotten.


Steve
DirectX Programmer
Soon to be the new Bill Gates

Share this post


Link to post
Share on other sites