# D3DX - ALT + TAB / Drawing stuff

This is a discussion on D3DX - ALT + TAB / Drawing stuff within the Game Programming forums, part of the General Programming Boards category; Direct X is confusing me in several ways. Let me first introduce my code to you, problematic code I believe ...

1. ## D3DX - ALT + TAB / Drawing stuff

Direct X is confusing me in several ways. Let me first introduce my code to you, problematic code I believe is bolded. I have a square that is made of 4 vertices. Like this.

Code:
```    struct { float x, y, z; } temp [] =
{
{ -0.9f, -0.9f, 0.0f },
{ -0.9f, -0.7f, 0.0f },
{ -0.8f, -0.9f, 0.0f },
{ -0.8f, -0.7f, 0.0f }
};```
I got some code from a tutorial that sets up some stuff like this in an initialization routine.

Code:
```    mpd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
mpd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

D3DXMATRIX mProjection;
XD3DXMatrixPerspectiveFovLH( &mProjection, 45.0f, 640.0f / 480.0f, 0.1f, 100.0f );
mpd3dDevice->SetTransform( D3DTS_PROJECTION, &mProjection );```
I have a routine that creates the vertex buffer.

Code:
```int Direct3D::RetrievePool( void )
{
if( FAILED( mpd3dDevice->CreateVertexBuffer
( sizeof vertices, D3DUSAGE_WRITEONLY, D3DFVF_XYZ, D3DPOOL_DEFAULT, &mpdvBuf, 0) ) )
{
return 0;
}

LPVOID pVertices = 0;

if( FAILED( mpdvBuf->Lock( 0, 0, &pVertices, 0 ) ) )
{
return 0;
}

CopyMemory(pVertices, vertices, sizeof vertices);

mpdvBuf->Unlock();

return 1;
}```
And then I render things like this

Code:
```int Direct3D::RenderDxScene( void )
{
HRESULT coop = mpd3dDevice->TestCooperativeLevel();

switch(coop)
{
case D3DERR_DEVICELOST:
OutputDebugString( TEXT( "Device lost" ) );
return 1;

case D3DERR_DEVICENOTRESET:
mpdvBuf->Release();
if( FAILED( mpd3dDevice->Reset( &md3dpp ) ) )
{
OutputDebugString( TEXT( "Reset failed" ) );
return 0;
}
RetrievePool();
break;

default:;
}

mpd3dDevice->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(0.2f, 0.2f, 0.2f, 1.0f), 1.0f, 0 );

if( FAILED( mpd3dDevice->BeginScene() ) )
{
return 0;
}

D3DXMATRIX mWorld;
XD3DXMatrixTranslation( &mWorld, 0.0f, 0.0f, 2.0f );

mpd3dDevice->SetTransform( D3DTS_WORLD, &mWorld );
mpd3dDevice->SetStreamSource( 0, mpdvBuf, 0, sizeof(float) * 3 );
mpd3dDevice->SetFVF( D3DFVF_XYZ );
mpd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 4 );

if( FAILED( mpd3dDevice->EndScene() ) )
{
return 0;
}

mpd3dDevice->Present( 0, 0, 0, 0 );

return 1;
}```
So.

When I draw it as a triangle list, like there, it only ends up being a right triangle facing to the right.
When I draw it as a pointlist, it is 4 points in the shape of a square.
When I draw it as a triangle fan, it is a solid square but with a big fingery thing pointing to the center (see attachment)

Okay. So that's wierd. Now the alt+tab thing. The documentation is a little confusing. http://msdn.microsoft.com/library/de...st_devices.asp

What I tried doing, was just letting it not try to render the scene if it acknowledges the device is lost (D3DERR_DEVICELOST). But if I get a D3DERR_DEVICENOTRESET, I assume that I need to do stuff then, so I guess I need to release anything allocated in the D3DPOOL_DEFAULT so I call release, then I restore settings, and then I try to lock/unlock resources again in that retrievepool thing.

1) As it is, with that strategy, nothing will be drawn on the screen when I return to it.
2) If I do not call retrievepool again, then the app crashes (I suppose using the vertex buffer which has been released)

This confuses me. Hmm.

2. XD3DXMatrixPerspectiveFovLH( &mProjection, 45.0f, 640.0f / 480.0f, 0.1f, 100.0f );
Your problem is in this line of code. The second parameter to this function is expressed in radians, not euler angles.

If you want a 45 degree horizontal field of view you do this:

45*PI/180

Put the result in the second parameter and your problem will be fixed.

The problem is that you are specifying a viewing angle of far more than 360 degrees. A 360 degree viewing angle would be D3DX_PI*2 or 6.28. You are specifying 45 which turns out to be somewhere in the neighborhood of 15 PI values or a (15*180) degree field of view.

Try this:
Code:
```//Not sure why you have XD3DX???
D3DXMatrixPerspectiveFovLH( &mProjection, D3DX_PI*0.5f, 640.0f / 480.0f, 0.1f, 100.0f );```
Here is what I'm using on my latest project:
Code:
```D3DXMatrixPerspectiveFovLH(&matProj,
1.2217f,
5.0f,
50000.0f)```

3. Okay. I also realized that the 3rd param is the aspect ratio, so I changed that. All the dx utitlity functions I use are function pointers prepended with 'X' (should be a temporary thing). Now my code is

Code:
`XD3DXMatrixPerspectiveFovLH( &mProjection, D3DX_PI*0.5f, mnWidth / mnHeight, 5.0f, 100.0f );`
Where mnWidth / mnHeight is 320 / 200. The result is silghtly different, probably just looking at the messed up polygon with a different perspective.

4. I was being wierd. I realized that the 3rd parameter of drawprimitive is not the number of vertices, but the number of triangles being rendered. Then I also had to rearrange the order of the vertices in order to make the trianglefan display properly.

Code:
```    struct { float x, y, z; } temp [] =
{
{ -0.8f, -0.7f, 0.0f },
{ -0.9f, -0.7f, 0.0f },
{ -0.9f, -0.9f, 0.0f },
{ -0.8f, -0.9f, 0.0f }

};

...

mpd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );```

5. Oh yeah. But, I think this is still relevant to the thread, the alt+tab still does not work! It is blank when I return to the app from an alt+tab!

6. It's rude to bump. Are there any (other than 'lost device') google buzzwords I can get on the alt+tab thing? I feel like I'm following MSDN's instructions using TestCooperativeLevel and then releasing the vertex buffer, retrieving the device, and then getting back the vertex buffer. Evidently, this is not all that needs to be done.

7. To be more precise, this is what happens. This is my render routine.

Code:
```int DxContainer::RenderDxWindow( float delta_t )
{
HRESULT coop = m_pd3dDevice->TestCooperativeLevel();

switch( coop )
{
case D3DERR_DEVICELOST:
OutputDebugString( TEXT("Device lost\n") );
return 1;

case D3DERR_DEVICENOTRESET:
{
if( FAILED( m_pd3dDevice->Reset( &m_d3dPresentParams ) ) )
{
OutputDebugString( TEXT("Reset failed\n") );
}
}
break;

default:;
}

// Do rendering stuph

return 1;
}```
I press alt+tab and I get a lost device notification from TestCooperativeLevel. The I switch back into it and I get 'Reset failed' dealios.

The present params are declared as D3DPRESENT_PARAMETERS DxContainer::m_d3dPresentParams
The device is declared as LPDIRECT3DDEVICE9 DxContainer::m_pd3dDevice. They are initialized like this in an initialization routine.

Code:
```    if( fs )
{
m_d3dPresentParams.Windowed             = FALSE;
m_d3dPresentParams.BackBufferFormat     = D3DFMT_X8R8G8B8;
m_d3dPresentParams.BackBufferWidth      = m_nWidth;
m_d3dPresentParams.BackBufferHeight     = m_nHeight;
}
else
{
m_d3dPresentParams.Windowed             = TRUE;
m_d3dPresentParams.BackBufferFormat     = d3ddm.Format;
}

m_d3dPresentParams.EnableAutoDepthStencil   = TRUE;
m_d3dPresentParams.AutoDepthStencilFormat   = D3DFMT_D16;

if( FAILED( m_pd3dInterface->CreateDevice(
dwBehaviorFlags, &m_d3dPresentParams,
&m_pd3dDevice ) ) )
{
::OutputDebugString( TEXT("CreateDevice\n") );
return 0;
}```

8. I have been using this tutorial (among others) that explains how to respond to a lost device. It is a little in depth and takes a while to fully understand, but it works. It breaks the initializatin into two functions. One for D3DPOOL_MANAGED and one for
D3DPOOL_DEFAULT.

I am still tring to understand some of it myself, but I hope it helps.

9. I only use the default pool but looking at this code:

Code:
```void CFramework::OnRenderFrame()
{
if ( !m_active || (m_pGraphics->GetDevice() == NULL) )
{
return;
}

// Check for lost device
HRESULT result = m_pGraphics->GetDevice()->TestCooperativeLevel();
if ( FAILED( result ) )
{
if ( result == D3DERR_DEVICELOST )
{
Sleep( 50 );
return;
}
else
{
OnLostDevice();
if ( m_pGraphics->Reset() == D3DERR_DEVICELOST )
{
// Device is lost still
Sleep( 50 );
return;
}
else
{
OnResetDevice();
}
}
}

if ( m_pGameApp != NULL )
{
m_pGameApp->OnRenderFrame( m_pGraphics->GetDevice() );
}
}```
I feel like I am doing the exact same thing. I can check the reset for the D3DERR_DEVICELOST but this condition never occurs. It actually fails with something like -2005530516 when I treat the HRESULT as an integer (no idea). I release resources on device lost, and then would reallocate them once the device reset succeeded if it ever did, but it duzn't. I have my presentparams located in an instance variable that are first initialized so that they are passed to createdevice, and I do not change them. This should not be a problem, and this whole thing confuses me.