Alt-Tab kicking my butt

Started by
7 comments, last by JimboC 21 years, 8 months ago
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]
Advertisement
im messing with alt-tab myself. while we''re on the topic, can anyone please tell me how to detect switching?
spraff.net: don't laugh, I'm still just starting...

  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]
quote:Original post by atcdevil
That works for me
That''s fine for detecting that the app has lost focus, but how do you recover afterward?

I was responding to the person who posted after you, I''m using Direct Draw so my methods of recovery, probably won''t help you. Sorry about that.
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!
actdevil:
Not him, but it WILL interest me !! Could you please tell me how do you handle that with ddraw ?
Darkhaven Beta-test stage coming soon.
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.
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
Member of the Unban Mindwipe Society (UMWS)

This topic is closed to new replies.

Advertisement