//-----------------------------------------------------------------------------
// Name: FullScreenWndProc()
// Desc: The WndProc funtion used when the app is in fullscreen mode. This is
// needed simply to trap the ESC key.
//-----------------------------------------------------------------------------
LRESULT CALLBACK FullScreenWndProc( HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam )
{
if( msg == WM_CLOSE )
{
CWnd* pWnd=AfxGetMainWnd();
pWnd->PostMessage( WM_CLOSE, 0, 0 );
// User wants to exit, so go back to windowed mode and exit for real
//g_AppFormView->GoWindowed();
//g_D3DApp.GetMainWnd()->PostMessage( WM_CLOSE, 0, 0 );
}
if( msg == WM_SETCURSOR )
{
SetCursor( NULL );
}
if( msg == WM_KEYUP && wParam == VK_ESCAPE )
{
g_3dView->GoWindow();
// User wants to leave fullscreen mode
//g_AppFormView->GoWindowed();
}
BOOL CMy3dXVView::InitDirectX()
{
// 初始化Direct3D
// Cleanup any objects that might've been created before
if( FAILED( Cleanup3DEnvironment() ) )
return E_FAIL;
HRESULT CMy3dXVView::Render3DEnvironment()
{
// Call the app specific function to framemove (animate) the scene
App_FrameMove( g_pd3dDevice, ((FLOAT)clock())/CLOCKS_PER_SEC );
// Call the app specific function to render the scene
App_Render( g_pd3dDevice );
// Show the frame on the primary surface. Note: this is the best place to
// check for "lost" surfaces. Surfaces can be lost if something caused
// them to temporary lose their video memory. "Lost" surfaces simply
// need to be restored before continuing.
// 将帧显示到主表面。注意:这里是检测表面“丢失”的最好地方
if( DDERR_SURFACELOST == ShowFrame() )
RestoreSurfaces();
// Keep track of the frame rate, and output it every 500 milliseconds to
// the appropiate UI control.
static DWORD dwLastTime = 0;
static DWORD dwNumFrames = 0;
dwNumFrames++;
// Set the view matrix
D3DMATRIX matView;
D3DUtil_SetViewMatrix( matView, vEyePt, vLookatPt, vUpVec );
g_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );
// Just for kicks, demonstrate the feature to find a frame and animate it.
// Here, if the user loads a file with a frame named "prop" (such as
// "triplane.x"), this code will find the matrix for that frame and
// animate it.
if( m_pFileObject )
{
CD3DFileObject* pObject = m_pFileObject->FindObject( "prop" );
if( pObject )
{
D3DMATRIX* pmat = pObject->GetMatrix();
D3DUtil_SetRotateZMatrix( *pmat, 5.0f*fTimeKey );
}
}
// TODO: Add your message handler code here
Cleanup3DEnvironment();
}
VOID CMy3dXVView::App_DeleteDeviceObjects(LPDIRECT3DDEVICE7 pd3dDevice)
{
DeleteDeviceObjects();
// Release the material that was created earlier.
if( g_pmtrlObjectMtrl )
g_pmtrlObjectMtrl->Release();
g_pmtrlObjectMtrl = NULL;
}
// If the file was successfully loaded, delete the old one and use this one
// instead.
SAFE_DELETE( m_pFileObject );
m_pFileObject = pFileObject;
// Get the new object position and size
m_fObjectRadius = 0.0f;
m_pFileObject->EnumObjects( CalcFileObjectSizeCB, NULL, (VOID*)&m_fObjectRadius );
//显示模型半径
CHAR buffer[20];
sprintf(buffer,"%4.2f", m_fObjectRadius );
GetDlgItem(IDC_RADIUS_TEXT)->SetWindowText(buffer);
// Set the projection matrix
D3DVIEWPORT7 vp;
g_pd3dDevice->GetViewport(&vp);
FLOAT fAspect = ((FLOAT)vp.dwHeight) / vp.dwWidth;
// Set the dimensions of the backbuffer. Note that if our window changes
// size, we need to destroy this surface and create a new one.
::GetClientRect( hWnd, &g_rcScreenRect );
::ClientToScreen( hWnd, (POINT*)&g_rcScreenRect.left );
::ClientToScreen( hWnd, (POINT*)&g_rcScreenRect.right );
ddsd.dwWidth = g_rcScreenRect.right - g_rcScreenRect.left;
ddsd.dwHeight = g_rcScreenRect.bottom - g_rcScreenRect.top;
// Create the backbuffer. The most likely reason for failure is running
// out of video memory. (A more sophisticated app should handle this.)
hr = g_pDD->CreateSurface( &ddsd, &g_pddsBackBuffer, NULL );
if( FAILED( hr ) )
return hr;
// Note: if using a z-buffer, the zbuffer surface creation would go around
// here. However, z-buffer usage is the topic of a subsequent tutorial.
// Create a clipper object which handles all our clipping for cases when
// our window is partially obscured by other windows. This is not needed
// for apps running in fullscreen mode.
LPDIRECTDRAWCLIPPER pcClipper;
hr = g_pDD->CreateClipper( 0, &pcClipper, NULL );
if( FAILED( hr ) )
return hr;
// Associate the clipper with our window. Note that, afterwards, the
// clipper is internally referenced by the primary surface, so it is safe
// to release our local reference to it.
pcClipper->SetHWnd( 0, hWnd );
g_pddsPrimary->SetClipper( pcClipper );
pcClipper->Release();
// Query DirectDraw for access to Direct3D
g_pDD->QueryInterface( IID_IDirect3D7, (VOID**)&g_pD3D );
if( FAILED( hr) )
return hr;
//-------------------------------------------------------------------------
// Create the z-buffer AFTER creating the backbuffer and BEFORE creating
// the d3ddevice.
//
// Note: before creating the z-buffer, apps may want to check the device
// caps for the D3DPRASTERCAPS_ZBUFFERLESSHSR flag. This flag is true for
// certain hardware that can do HSR (hidden-surface-removal) without a
// z-buffer. For those devices, there is no need to create a z-buffer.
//-------------------------------------------------------------------------
// If we found a good zbuffer format, then the dwSize field will be
// properly set during enumeration. Else, we have a problem and will exit.
if( sizeof(DDPIXELFORMAT) != ddpfZBuffer.dwSize )
return E_FAIL;
// Get z-buffer dimensions from the render target
// Setup the surface desc for the z-buffer.
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ddsd.dwWidth = g_rcScreenRect.right - g_rcScreenRect.left;
ddsd.dwHeight = g_rcScreenRect.bottom - g_rcScreenRect.top;
memcpy( &ddsd.ddpfPixelFormat, &ddpfZBuffer, sizeof(DDPIXELFORMAT) );
// For hardware devices, the z-buffer should be in video memory. For
// software devices, create the z-buffer in system memory
if( IsEqualIID( *pDeviceGUID, IID_IDirect3DHALDevice ) )
ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
else
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
// Create and attach a z-buffer. Real apps should be able to handle an
// error here (DDERR_OUTOFVIDEOMEMORY may be encountered). For this
// tutorial, though, we are simply going to exit ungracefully.
if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsZBuffer, NULL ) ) )
return hr;
// Attach the z-buffer to the back buffer.
if( FAILED( hr = g_pddsBackBuffer->AddAttachedSurface( g_pddsZBuffer ) ) )
return hr;
//-------------------------------------------------------------------------
// End of z-buffer creation code.
//
// Before rendering, don't forget to enable the z-buffer with the
// appropiate D3DRENDERSTATE's.
//-------------------------------------------------------------------------
// Before creating the device, check that we are NOT in a palettized
// display. That case will cause CreateDevice() to fail, since this simple
// tutorial does not bother with palettes.
ddsd.dwSize = sizeof(DDSURFACEDESC2);
g_pDD->GetDisplayMode( &ddsd );
if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 )
return DDERR_INVALIDMODE;
// Create the device. The device is created off of our back buffer, which
// becomes the render target for the newly created device. Note that the
// z-buffer must be created BEFORE the device
if( FAILED( hr = g_pD3D->CreateDevice( *pDeviceGUID, g_pddsBackBuffer,
&g_pd3dDevice ) ) )
{
// This call could fail for many reasons. The most likely cause is
// that we specifically requested a hardware device, without knowing
// whether there is even a 3D card installed in the system. Another
// possibility is the hardware is incompatible with the current display
// mode (the correct implementation would use enumeration for this.)
return hr;
}
BOOL CMy3dXVView::KeyDown()
{
BOOL shift, ctrl;
shift = ctrl = FALSE;
BOOL left, right, up, down;
left = right = up = down = FALSE;
BOOL home, end;
home = end = FALSE;
if (GetAsyncKeyState(VK_RETURN))
{
// 取得Edit框中的值
OnKillfocusEditX();
OnKillfocusEditY();
OnKillfocusEditZ();
OnKillfocusFpsEdit();
}
if ( GetAsyncKeyState(VK_SHIFT) ) shift = TRUE;
if ( GetAsyncKeyState(VK_CONTROL) ) ctrl = TRUE;
if ( GetAsyncKeyState(VK_LEFT) ) left = TRUE;
if ( GetAsyncKeyState(VK_RIGHT) ) right = TRUE;
if ( GetAsyncKeyState(VK_UP) ) up = TRUE;
if ( GetAsyncKeyState(VK_DOWN) ) down = TRUE;
if ( GetAsyncKeyState(VK_HOME) ) home = TRUE;
if ( GetAsyncKeyState(VK_END) ) end = TRUE;
//转动模型
if ( ctrl && left )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fXAxisAngle -= 0.03f;
if ( m_fXAxisAngle < -2*g_PI ) m_fXAxisAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fXAxisAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_MX ))->SetPos(pos);
}
if ( ctrl && right )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fXAxisAngle += 0.03f;
if ( m_fXAxisAngle > 2*g_PI ) m_fXAxisAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fXAxisAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_MX ))->SetPos(pos);
}
if ( ctrl && up )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fYAxisAngle -= 0.03f;
if ( m_fYAxisAngle < -2*g_PI ) m_fYAxisAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fYAxisAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_MY ))->SetPos(pos);
}
if ( ctrl && down )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fYAxisAngle += 0.03f;
if ( m_fYAxisAngle > 2*g_PI ) m_fYAxisAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fYAxisAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_MY ))->SetPos(pos);
}
// 移动Camera
if ( shift && left )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fXViewAngle -= 0.03f;
if ( m_fXViewAngle < -2*g_PI ) m_fXViewAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fXViewAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_CX ))->SetPos(pos);
}
if ( shift && right )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fXViewAngle += 0.03f;
if ( m_fXViewAngle > 2*g_PI ) m_fXViewAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fXViewAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_CX ))->SetPos(pos);
}
if ( shift && up )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fYViewAngle -= 0.03f;
if ( m_fYViewAngle < -g_PI ) m_fYViewAngle = -g_PI;
//
int pos;
pos = (int)(m_fYViewAngle*100/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_CY ))->SetPos(pos);
}
if ( shift && down )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fYViewAngle += 0.03f;
if ( m_fYViewAngle > g_PI ) m_fYViewAngle = g_PI;
//
int pos;
pos = (int)(m_fYViewAngle*100/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_CY ))->SetPos(pos);
}
// Camera到原点的距离
if ( shift && home )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fEyeDistance += 0.1f;
if( m_fEyeDistance > 7.0f ) m_fEyeDistance = 7.0f;
int pos;
pos = 30 + (int)(10.0f*m_fEyeDistance);
((CSliderCtrl*)GetDlgItem(IDC_SLIDER_CD))->SetPos(pos);
}
if ( shift && end )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fEyeDistance -= 0.1f;
if( m_fEyeDistance < -3.0f ) m_fEyeDistance = -3.0f;
int pos;
pos = 30 + (int)(10.0f*m_fEyeDistance);
((CSliderCtrl*)GetDlgItem(IDC_SLIDER_CD))->SetPos(pos);
}
void CMy3dXVView::OnButtonFullscr()
{
// TODO: Add your control notification handler code here
g_bReady = FALSE;
GoFullScreen();
LoadFile( "teapot.x" );
g_bReady = TRUE;
}
BOOL CMy3dXVView::InitDirectXFullScreen()
{
// 初始化Direct3D,全屏幕模式
// Cleanup any objects that might've been created before
if( FAILED( Cleanup3DEnvironment() ) )
return E_FAIL;
// Create the D3D environment, at first, trying the HAL
if( SUCCEEDED( Initialize3DEnvFullScr( m_hwndFullScreen, NULL,
&IID_IDirect3DHALDevice ) ) )
return S_OK;
//MessageBox( "使用硬件加速失败!\n现在尝试使用软件模式", "警告!", MB_OK|MB_ICONWARNING );
// Else, cleanup objects potentially created during the failed
// initialization attempt.
Cleanup3DEnvironment();
// Initialize a surface description structure for the primary surface. The
// primary surface represents the entire display, with dimensions and a
// pixel format of the display. Therefore, none of that information needs
// to be specified in order to create the primary surface.
//-------------------------------------------------------------------------
// Create the z-buffer AFTER creating the backbuffer and BEFORE creating
// the d3ddevice.
//
// Note: before creating the z-buffer, apps may want to check the device
// caps for the D3DPRASTERCAPS_ZBUFFERLESSHSR flag. This flag is true for
// certain hardware that can do HSR (hidden-surface-removal) without a
// z-buffer. For those devices, there is no need to create a z-buffer.
//-------------------------------------------------------------------------
// If we found a good zbuffer format, then the dwSize field will be
// properly set during enumeration. Else, we have a problem and will exit.
if( sizeof(DDPIXELFORMAT) != ddpfZBuffer.dwSize )
return E_FAIL;
// Get z-buffer dimensions from the render target
// Setup the surface desc for the z-buffer.
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ddsd.dwWidth = 800;
ddsd.dwHeight = 600;
memcpy( &ddsd.ddpfPixelFormat, &ddpfZBuffer, sizeof(DDPIXELFORMAT) );
// For hardware devices, the z-buffer should be in video memory. For
// software devices, create the z-buffer in system memory
if( IsEqualIID( *pDeviceGUID, IID_IDirect3DHALDevice ) )
ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
else
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
// Create and attach a z-buffer. Real apps should be able to handle an
// error here (DDERR_OUTOFVIDEOMEMORY may be encountered). For this
// tutorial, though, we are simply going to exit ungracefully.
if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsZBuffer, NULL ) ) )
{
TRACE("Create ZBuffer failed");
return hr;
}
// Attach the z-buffer to the back buffer.
if( FAILED( hr = g_pddsBackBuffer->AddAttachedSurface( g_pddsZBuffer ) ) )
{
TRACE("BackBuffer->AddAttachedSurface failed\n");
return hr;
}
//-------------------------------------------------------------------------
// End of z-buffer creation code.
//
// Before rendering, don't forget to enable the z-buffer with the
// appropiate D3DRENDERSTATE's.
//-------------------------------------------------------------------------
// Before creating the device, check that we are NOT in a palettized
// display. That case will cause CreateDevice() to fail, since this simple
// tutorial does not bother with palettes.
ddsd.dwSize = sizeof(DDSURFACEDESC2);
g_pDD->GetDisplayMode( &ddsd );
if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 )
return DDERR_INVALIDMODE;
// Create the device. The device is created off of our back buffer, which
// becomes the render target for the newly created device. Note that the
// z-buffer must be created BEFORE the device
// Finish by setting up our scene
return App_InitDeviceObjects( g_pd3dDevice );
}
BOOL CMy3dXVView::FullScrKeyDown()
{
BOOL shift, ctrl;
shift = ctrl = FALSE;
BOOL left, right, up, down;
left = right = up = down = FALSE;
BOOL home, end;
home = end = FALSE;
if (GetAsyncKeyState(VK_RETURN))
{
// 取得Edit框中的值
OnKillfocusEditX();
OnKillfocusEditY();
OnKillfocusEditZ();
OnKillfocusFpsEdit();
}
if ( GetAsyncKeyState(VK_SHIFT) ) shift = TRUE;
if ( GetAsyncKeyState(VK_CONTROL) ) ctrl = TRUE;
if ( GetAsyncKeyState(VK_LEFT) ) left = TRUE;
if ( GetAsyncKeyState(VK_RIGHT) ) right = TRUE;
if ( GetAsyncKeyState(VK_UP) ) up = TRUE;
if ( GetAsyncKeyState(VK_DOWN) ) down = TRUE;
if ( GetAsyncKeyState(VK_HOME) ) home = TRUE;
if ( GetAsyncKeyState(VK_END) ) end = TRUE;
//转动模型
if ( ctrl && left )
{
m_fXAxisAngle -= 0.03f;
if ( m_fXAxisAngle < -2*g_PI ) m_fXAxisAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fXAxisAngle*50/2/g_PI)+50;
}
if ( ctrl && right )
{
m_fXAxisAngle += 0.03f;
if ( m_fXAxisAngle > 2*g_PI ) m_fXAxisAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fXAxisAngle*50/2/g_PI)+50;
}
if ( ctrl && up )
{
m_fYAxisAngle -= 0.03f;
if ( m_fYAxisAngle < -2*g_PI ) m_fYAxisAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fYAxisAngle*50/2/g_PI)+50;
}
if ( ctrl && down )
{
m_fYAxisAngle += 0.03f;
if ( m_fYAxisAngle > 2*g_PI ) m_fYAxisAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fYAxisAngle*50/2/g_PI)+50;
}
// 移动Camera
if ( shift && left )
{
m_fXViewAngle -= 0.03f;
if ( m_fXViewAngle < -2*g_PI ) m_fXViewAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fXViewAngle*50/2/g_PI)+50;
}
if ( shift && right )
{
m_fXViewAngle += 0.03f;
if ( m_fXViewAngle > 2*g_PI ) m_fXViewAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fXViewAngle*50/2/g_PI)+50;
}
if ( shift && up )
{
m_fYViewAngle -= 0.03f;
if ( m_fYViewAngle < -g_PI ) m_fYViewAngle = -g_PI;
//
int pos;
pos = (int)(m_fYViewAngle*100/g_PI)+50;
}
if ( shift && down )
{
m_fYViewAngle += 0.03f;
if ( m_fYViewAngle > g_PI ) m_fYViewAngle = g_PI;
//
int pos;
pos = (int)(m_fYViewAngle*100/g_PI)+50;
}
// Camera到原点的距离
if ( shift && home )
{
m_fEyeDistance += 0.1f;
if( m_fEyeDistance > 7.0f ) m_fEyeDistance = 7.0f;
int pos;
pos = 30 + (int)(10.0f*m_fEyeDistance);
}
if ( shift && end )
{
m_fEyeDistance -= 0.1f;
if( m_fEyeDistance < -3.0f ) m_fEyeDistance = -3.0f;
int pos;
pos = 30 + (int)(10.0f*m_fEyeDistance);
}
return TRUE;
}
BOOL CMy3dXVView::GoWindow()
{
g_bReady = FALSE;
// 初始化Direct3D
// Cleanup any objects that might've been created before
if( FAILED( Cleanup3DEnvironment() ) )
return E_FAIL;
HWND hWnd;
hWnd = m_hwndRenderWindow;
TRACE("GoWindow\n");
// Create the D3D environment, at first, trying the HAL
if( SUCCEEDED( Initialize3DEnvironment( hWnd, NULL,
&IID_IDirect3DHALDevice ) ) )
return S_OK;
// Else, cleanup objects potentially created during the failed
// initialization attempt.
Cleanup3DEnvironment();
// Get the current desktop display mode, so we can set up a back
// buffer of the same format
D3DDISPLAYMODE d3ddm;
if( FAILED( m_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
{
return FALSE;
}
// Set up the structure used to create the D3DDevice. Since we are now
// using more complex geometry, we will create a device with a zbuffer.
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
if (m_dwNumMaterials > 0)
{
for (int i = 0; i < (int)m_dwNumMaterials; i++)
{
// Set the material and texture for this subset
m_pD3DDevice->SetMaterial( &m_pMeshMaterials[i] );
m_pD3DDevice->SetTexture( 0, m_pMeshTextures[i] );
// Draw the mesh subset
m_pMeshXModel->DrawSubset( i );
}
}
if( m_pMeshTextures )
{
for( int i = 0; i < (int)m_dwNumMaterials; i++ )
{
SAFE_RELEASE(m_pMeshTextures[i]);
}
SAFE_DELETE(m_pMeshTextures);
}
SAFE_RELEASE(m_pMeshXModel);
m_fXFileOK = FALSE;
}
void CGSD3DScreen::SetupMatrices()
{
// For our world matrix, we will just leave it as the identity
D3DXMATRIX matWorld;
D3DXMatrixRotationY( &matWorld, 0);
m_pD3DDevice->SetTransform( D3DTS_WORLD, &matWorld );
// Set up our view matrix. A view matrix can be defined given an eye point,
// a point to lookat, and a direction for which way is up. Here, we set the
// eye five units back along the z-axis and up three units, look at the
// origin, and define "up" to be in the y-direction.
D3DXMATRIX matView;
D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 0.0f,-5.0f ),
&D3DXVECTOR3( 0.0f, 0.0f, .0f ),
&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
m_pD3DDevice->SetTransform( D3DTS_VIEW, &matView );
// For the projection matrix, we set up a perspective transform (which
// transforms geometry from 3D view space to 2D viewport space, with
// a perspective divide making objects smaller in the distance). To build
// a perpsective transform, we need the field of view (1/4 pi is common),
// the aspect ratio, and the near and far clipping planes (which define at
// what distances geometry should be no longer be rendered).
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
m_pD3DDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
// Get the current desktop display mode, so we can set up a back
// buffer of the same format
D3DDISPLAYMODE d3ddm;
if( FAILED( m_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
{
return FALSE;
}
// Set up the structure used to create the D3DDevice. Since we are now
// using more complex geometry, we will create a device with a zbuffer.
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
if (m_dwNumMaterials > 0)
{
for (int i = 0; i < (int)m_dwNumMaterials; i++)
{
// Set the material and texture for this subset
m_pD3DDevice->SetMaterial( &m_pMeshMaterials[i] );
m_pD3DDevice->SetTexture( 0, m_pMeshTextures[i] );
// Draw the mesh subset
m_pMeshXModel->DrawSubset( i );
}
}
if( m_pMeshTextures )
{
for( int i = 0; i < (int)m_dwNumMaterials; i++ )
{
SAFE_RELEASE(m_pMeshTextures[i]);
}
SAFE_DELETE(m_pMeshTextures);
}
SAFE_RELEASE(m_pMeshXModel);
m_fXFileOK = FALSE;
}
void CGSD3DScreen::SetupMatrices()
{
// For our world matrix, we will just leave it as the identity
D3DXMATRIX matWorld;
D3DXMatrixRotationY( &matWorld, 0);
m_pD3DDevice->SetTransform( D3DTS_WORLD, &matWorld );
// Set up our view matrix. A view matrix can be defined given an eye point,
// a point to lookat, and a direction for which way is up. Here, we set the
// eye five units back along the z-axis and up three units, look at the
// origin, and define "up" to be in the y-direction.
D3DXMATRIX matView;
D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3( 0.0f, 0.0f,-5.0f ),
&D3DXVECTOR3( 0.0f, 0.0f, .0f ),
&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
m_pD3DDevice->SetTransform( D3DTS_VIEW, &matView );
// For the projection matrix, we set up a perspective transform (which
// transforms geometry from 3D view space to 2D viewport space, with
// a perspective divide making objects smaller in the distance). To build
// a perpsective transform, we need the field of view (1/4 pi is common),
// the aspect ratio, and the near and far clipping planes (which define at
// what distances geometry should be no longer be rendered).
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
m_pD3DDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
//-----------------------------------------------------------------------------
// Name: FullScreenWndProc()
// Desc: The WndProc funtion used when the app is in fullscreen mode. This is
// needed simply to trap the ESC key.
//-----------------------------------------------------------------------------
LRESULT CALLBACK FullScreenWndProc( HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam )
{
if( msg == WM_CLOSE )
{
CWnd* pWnd=AfxGetMainWnd();
pWnd->PostMessage( WM_CLOSE, 0, 0 );
// User wants to exit, so go back to windowed mode and exit for real
//g_AppFormView->GoWindowed();
//g_D3DApp.GetMainWnd()->PostMessage( WM_CLOSE, 0, 0 );
}
if( msg == WM_SETCURSOR )
{
SetCursor( NULL );
}
if( msg == WM_KEYUP && wParam == VK_ESCAPE )
{
g_3dView->GoWindow();
// User wants to leave fullscreen mode
//g_AppFormView->GoWindowed();
}
BOOL CMy3dXVView::InitDirectX()
{
// 初始化Direct3D
// Cleanup any objects that might've been created before
if( FAILED( Cleanup3DEnvironment() ) )
return E_FAIL;
HRESULT CMy3dXVView::Render3DEnvironment()
{
// Call the app specific function to framemove (animate) the scene
App_FrameMove( g_pd3dDevice, ((FLOAT)clock())/CLOCKS_PER_SEC );
// Call the app specific function to render the scene
App_Render( g_pd3dDevice );
// Show the frame on the primary surface. Note: this is the best place to
// check for "lost" surfaces. Surfaces can be lost if something caused
// them to temporary lose their video memory. "Lost" surfaces simply
// need to be restored before continuing.
// 将帧显示到主表面。注意:这里是检测表面“丢失”的最好地方
if( DDERR_SURFACELOST == ShowFrame() )
RestoreSurfaces();
// Keep track of the frame rate, and output it every 500 milliseconds to
// the appropiate UI control.
static DWORD dwLastTime = 0;
static DWORD dwNumFrames = 0;
dwNumFrames++;
// Set the view matrix
D3DMATRIX matView;
D3DUtil_SetViewMatrix( matView, vEyePt, vLookatPt, vUpVec );
g_pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );
// Just for kicks, demonstrate the feature to find a frame and animate it.
// Here, if the user loads a file with a frame named "prop" (such as
// "triplane.x"), this code will find the matrix for that frame and
// animate it.
if( m_pFileObject )
{
CD3DFileObject* pObject = m_pFileObject->FindObject( "prop" );
if( pObject )
{
D3DMATRIX* pmat = pObject->GetMatrix();
D3DUtil_SetRotateZMatrix( *pmat, 5.0f*fTimeKey );
}
}
// TODO: Add your message handler code here
Cleanup3DEnvironment();
}
VOID CMy3dXVView::App_DeleteDeviceObjects(LPDIRECT3DDEVICE7 pd3dDevice)
{
DeleteDeviceObjects();
// Release the material that was created earlier.
if( g_pmtrlObjectMtrl )
g_pmtrlObjectMtrl->Release();
g_pmtrlObjectMtrl = NULL;
}
// If the file was successfully loaded, delete the old one and use this one
// instead.
SAFE_DELETE( m_pFileObject );
m_pFileObject = pFileObject;
// Get the new object position and size
m_fObjectRadius = 0.0f;
m_pFileObject->EnumObjects( CalcFileObjectSizeCB, NULL, (VOID*)&m_fObjectRadius );
//显示模型半径
CHAR buffer[20];
sprintf(buffer,"%4.2f", m_fObjectRadius );
GetDlgItem(IDC_RADIUS_TEXT)->SetWindowText(buffer);
// Set the projection matrix
D3DVIEWPORT7 vp;
g_pd3dDevice->GetViewport(&vp);
FLOAT fAspect = ((FLOAT)vp.dwHeight) / vp.dwWidth;
// Set the dimensions of the backbuffer. Note that if our window changes
// size, we need to destroy this surface and create a new one.
::GetClientRect( hWnd, &g_rcScreenRect );
::ClientToScreen( hWnd, (POINT*)&g_rcScreenRect.left );
::ClientToScreen( hWnd, (POINT*)&g_rcScreenRect.right );
ddsd.dwWidth = g_rcScreenRect.right - g_rcScreenRect.left;
ddsd.dwHeight = g_rcScreenRect.bottom - g_rcScreenRect.top;
// Create the backbuffer. The most likely reason for failure is running
// out of video memory. (A more sophisticated app should handle this.)
hr = g_pDD->CreateSurface( &ddsd, &g_pddsBackBuffer, NULL );
if( FAILED( hr ) )
return hr;
// Note: if using a z-buffer, the zbuffer surface creation would go around
// here. However, z-buffer usage is the topic of a subsequent tutorial.
// Create a clipper object which handles all our clipping for cases when
// our window is partially obscured by other windows. This is not needed
// for apps running in fullscreen mode.
LPDIRECTDRAWCLIPPER pcClipper;
hr = g_pDD->CreateClipper( 0, &pcClipper, NULL );
if( FAILED( hr ) )
return hr;
// Associate the clipper with our window. Note that, afterwards, the
// clipper is internally referenced by the primary surface, so it is safe
// to release our local reference to it.
pcClipper->SetHWnd( 0, hWnd );
g_pddsPrimary->SetClipper( pcClipper );
pcClipper->Release();
// Query DirectDraw for access to Direct3D
g_pDD->QueryInterface( IID_IDirect3D7, (VOID**)&g_pD3D );
if( FAILED( hr) )
return hr;
//-------------------------------------------------------------------------
// Create the z-buffer AFTER creating the backbuffer and BEFORE creating
// the d3ddevice.
//
// Note: before creating the z-buffer, apps may want to check the device
// caps for the D3DPRASTERCAPS_ZBUFFERLESSHSR flag. This flag is true for
// certain hardware that can do HSR (hidden-surface-removal) without a
// z-buffer. For those devices, there is no need to create a z-buffer.
//-------------------------------------------------------------------------
// If we found a good zbuffer format, then the dwSize field will be
// properly set during enumeration. Else, we have a problem and will exit.
if( sizeof(DDPIXELFORMAT) != ddpfZBuffer.dwSize )
return E_FAIL;
// Get z-buffer dimensions from the render target
// Setup the surface desc for the z-buffer.
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ddsd.dwWidth = g_rcScreenRect.right - g_rcScreenRect.left;
ddsd.dwHeight = g_rcScreenRect.bottom - g_rcScreenRect.top;
memcpy( &ddsd.ddpfPixelFormat, &ddpfZBuffer, sizeof(DDPIXELFORMAT) );
// For hardware devices, the z-buffer should be in video memory. For
// software devices, create the z-buffer in system memory
if( IsEqualIID( *pDeviceGUID, IID_IDirect3DHALDevice ) )
ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
else
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
// Create and attach a z-buffer. Real apps should be able to handle an
// error here (DDERR_OUTOFVIDEOMEMORY may be encountered). For this
// tutorial, though, we are simply going to exit ungracefully.
if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsZBuffer, NULL ) ) )
return hr;
// Attach the z-buffer to the back buffer.
if( FAILED( hr = g_pddsBackBuffer->AddAttachedSurface( g_pddsZBuffer ) ) )
return hr;
//-------------------------------------------------------------------------
// End of z-buffer creation code.
//
// Before rendering, don't forget to enable the z-buffer with the
// appropiate D3DRENDERSTATE's.
//-------------------------------------------------------------------------
// Before creating the device, check that we are NOT in a palettized
// display. That case will cause CreateDevice() to fail, since this simple
// tutorial does not bother with palettes.
ddsd.dwSize = sizeof(DDSURFACEDESC2);
g_pDD->GetDisplayMode( &ddsd );
if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 )
return DDERR_INVALIDMODE;
// Create the device. The device is created off of our back buffer, which
// becomes the render target for the newly created device. Note that the
// z-buffer must be created BEFORE the device
if( FAILED( hr = g_pD3D->CreateDevice( *pDeviceGUID, g_pddsBackBuffer,
&g_pd3dDevice ) ) )
{
// This call could fail for many reasons. The most likely cause is
// that we specifically requested a hardware device, without knowing
// whether there is even a 3D card installed in the system. Another
// possibility is the hardware is incompatible with the current display
// mode (the correct implementation would use enumeration for this.)
return hr;
}
BOOL CMy3dXVView::KeyDown()
{
BOOL shift, ctrl;
shift = ctrl = FALSE;
BOOL left, right, up, down;
left = right = up = down = FALSE;
BOOL home, end;
home = end = FALSE;
if (GetAsyncKeyState(VK_RETURN))
{
// 取得Edit框中的值
OnKillfocusEditX();
OnKillfocusEditY();
OnKillfocusEditZ();
OnKillfocusFpsEdit();
}
if ( GetAsyncKeyState(VK_SHIFT) ) shift = TRUE;
if ( GetAsyncKeyState(VK_CONTROL) ) ctrl = TRUE;
if ( GetAsyncKeyState(VK_LEFT) ) left = TRUE;
if ( GetAsyncKeyState(VK_RIGHT) ) right = TRUE;
if ( GetAsyncKeyState(VK_UP) ) up = TRUE;
if ( GetAsyncKeyState(VK_DOWN) ) down = TRUE;
if ( GetAsyncKeyState(VK_HOME) ) home = TRUE;
if ( GetAsyncKeyState(VK_END) ) end = TRUE;
//转动模型
if ( ctrl && left )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fXAxisAngle -= 0.03f;
if ( m_fXAxisAngle < -2*g_PI ) m_fXAxisAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fXAxisAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_MX ))->SetPos(pos);
}
if ( ctrl && right )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fXAxisAngle += 0.03f;
if ( m_fXAxisAngle > 2*g_PI ) m_fXAxisAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fXAxisAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_MX ))->SetPos(pos);
}
if ( ctrl && up )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fYAxisAngle -= 0.03f;
if ( m_fYAxisAngle < -2*g_PI ) m_fYAxisAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fYAxisAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_MY ))->SetPos(pos);
}
if ( ctrl && down )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fYAxisAngle += 0.03f;
if ( m_fYAxisAngle > 2*g_PI ) m_fYAxisAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fYAxisAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_MY ))->SetPos(pos);
}
// 移动Camera
if ( shift && left )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fXViewAngle -= 0.03f;
if ( m_fXViewAngle < -2*g_PI ) m_fXViewAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fXViewAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_CX ))->SetPos(pos);
}
if ( shift && right )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fXViewAngle += 0.03f;
if ( m_fXViewAngle > 2*g_PI ) m_fXViewAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fXViewAngle*50/2/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_CX ))->SetPos(pos);
}
if ( shift && up )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fYViewAngle -= 0.03f;
if ( m_fYViewAngle < -g_PI ) m_fYViewAngle = -g_PI;
//
int pos;
pos = (int)(m_fYViewAngle*100/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_CY ))->SetPos(pos);
}
if ( shift && down )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fYViewAngle += 0.03f;
if ( m_fYViewAngle > g_PI ) m_fYViewAngle = g_PI;
//
int pos;
pos = (int)(m_fYViewAngle*100/g_PI)+50;
((CSliderCtrl*)GetDlgItem( IDC_SLIDER_CY ))->SetPos(pos);
}
// Camera到原点的距离
if ( shift && home )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fEyeDistance += 0.1f;
if( m_fEyeDistance > 7.0f ) m_fEyeDistance = 7.0f;
int pos;
pos = 30 + (int)(10.0f*m_fEyeDistance);
((CSliderCtrl*)GetDlgItem(IDC_SLIDER_CD))->SetPos(pos);
}
if ( shift && end )
{
GetDlgItem(IDC_FPS_EDIT)->SetFocus();
m_fEyeDistance -= 0.1f;
if( m_fEyeDistance < -3.0f ) m_fEyeDistance = -3.0f;
int pos;
pos = 30 + (int)(10.0f*m_fEyeDistance);
((CSliderCtrl*)GetDlgItem(IDC_SLIDER_CD))->SetPos(pos);
}
void CMy3dXVView::OnButtonFullscr()
{
// TODO: Add your control notification handler code here
g_bReady = FALSE;
GoFullScreen();
LoadFile( "teapot.x" );
g_bReady = TRUE;
}
BOOL CMy3dXVView::InitDirectXFullScreen()
{
// 初始化Direct3D,全屏幕模式
// Cleanup any objects that might've been created before
if( FAILED( Cleanup3DEnvironment() ) )
return E_FAIL;
// Create the D3D environment, at first, trying the HAL
if( SUCCEEDED( Initialize3DEnvFullScr( m_hwndFullScreen, NULL,
&IID_IDirect3DHALDevice ) ) )
return S_OK;
//MessageBox( "使用硬件加速失败!\n现在尝试使用软件模式", "警告!", MB_OK|MB_ICONWARNING );
// Else, cleanup objects potentially created during the failed
// initialization attempt.
Cleanup3DEnvironment();
// Initialize a surface description structure for the primary surface. The
// primary surface represents the entire display, with dimensions and a
// pixel format of the display. Therefore, none of that information needs
// to be specified in order to create the primary surface.
//-------------------------------------------------------------------------
// Create the z-buffer AFTER creating the backbuffer and BEFORE creating
// the d3ddevice.
//
// Note: before creating the z-buffer, apps may want to check the device
// caps for the D3DPRASTERCAPS_ZBUFFERLESSHSR flag. This flag is true for
// certain hardware that can do HSR (hidden-surface-removal) without a
// z-buffer. For those devices, there is no need to create a z-buffer.
//-------------------------------------------------------------------------
// If we found a good zbuffer format, then the dwSize field will be
// properly set during enumeration. Else, we have a problem and will exit.
if( sizeof(DDPIXELFORMAT) != ddpfZBuffer.dwSize )
return E_FAIL;
// Get z-buffer dimensions from the render target
// Setup the surface desc for the z-buffer.
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ddsd.dwWidth = 800;
ddsd.dwHeight = 600;
memcpy( &ddsd.ddpfPixelFormat, &ddpfZBuffer, sizeof(DDPIXELFORMAT) );
// For hardware devices, the z-buffer should be in video memory. For
// software devices, create the z-buffer in system memory
if( IsEqualIID( *pDeviceGUID, IID_IDirect3DHALDevice ) )
ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
else
ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
// Create and attach a z-buffer. Real apps should be able to handle an
// error here (DDERR_OUTOFVIDEOMEMORY may be encountered). For this
// tutorial, though, we are simply going to exit ungracefully.
if( FAILED( hr = g_pDD->CreateSurface( &ddsd, &g_pddsZBuffer, NULL ) ) )
{
TRACE("Create ZBuffer failed");
return hr;
}
// Attach the z-buffer to the back buffer.
if( FAILED( hr = g_pddsBackBuffer->AddAttachedSurface( g_pddsZBuffer ) ) )
{
TRACE("BackBuffer->AddAttachedSurface failed\n");
return hr;
}
//-------------------------------------------------------------------------
// End of z-buffer creation code.
//
// Before rendering, don't forget to enable the z-buffer with the
// appropiate D3DRENDERSTATE's.
//-------------------------------------------------------------------------
// Before creating the device, check that we are NOT in a palettized
// display. That case will cause CreateDevice() to fail, since this simple
// tutorial does not bother with palettes.
ddsd.dwSize = sizeof(DDSURFACEDESC2);
g_pDD->GetDisplayMode( &ddsd );
if( ddsd.ddpfPixelFormat.dwRGBBitCount <= 8 )
return DDERR_INVALIDMODE;
// Create the device. The device is created off of our back buffer, which
// becomes the render target for the newly created device. Note that the
// z-buffer must be created BEFORE the device
// Finish by setting up our scene
return App_InitDeviceObjects( g_pd3dDevice );
}
BOOL CMy3dXVView::FullScrKeyDown()
{
BOOL shift, ctrl;
shift = ctrl = FALSE;
BOOL left, right, up, down;
left = right = up = down = FALSE;
BOOL home, end;
home = end = FALSE;
if (GetAsyncKeyState(VK_RETURN))
{
// 取得Edit框中的值
OnKillfocusEditX();
OnKillfocusEditY();
OnKillfocusEditZ();
OnKillfocusFpsEdit();
}
if ( GetAsyncKeyState(VK_SHIFT) ) shift = TRUE;
if ( GetAsyncKeyState(VK_CONTROL) ) ctrl = TRUE;
if ( GetAsyncKeyState(VK_LEFT) ) left = TRUE;
if ( GetAsyncKeyState(VK_RIGHT) ) right = TRUE;
if ( GetAsyncKeyState(VK_UP) ) up = TRUE;
if ( GetAsyncKeyState(VK_DOWN) ) down = TRUE;
if ( GetAsyncKeyState(VK_HOME) ) home = TRUE;
if ( GetAsyncKeyState(VK_END) ) end = TRUE;
//转动模型
if ( ctrl && left )
{
m_fXAxisAngle -= 0.03f;
if ( m_fXAxisAngle < -2*g_PI ) m_fXAxisAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fXAxisAngle*50/2/g_PI)+50;
}
if ( ctrl && right )
{
m_fXAxisAngle += 0.03f;
if ( m_fXAxisAngle > 2*g_PI ) m_fXAxisAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fXAxisAngle*50/2/g_PI)+50;
}
if ( ctrl && up )
{
m_fYAxisAngle -= 0.03f;
if ( m_fYAxisAngle < -2*g_PI ) m_fYAxisAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fYAxisAngle*50/2/g_PI)+50;
}
if ( ctrl && down )
{
m_fYAxisAngle += 0.03f;
if ( m_fYAxisAngle > 2*g_PI ) m_fYAxisAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fYAxisAngle*50/2/g_PI)+50;
}
// 移动Camera
if ( shift && left )
{
m_fXViewAngle -= 0.03f;
if ( m_fXViewAngle < -2*g_PI ) m_fXViewAngle = 2*g_PI;
//
int pos;
pos = (int)(m_fXViewAngle*50/2/g_PI)+50;
}
if ( shift && right )
{
m_fXViewAngle += 0.03f;
if ( m_fXViewAngle > 2*g_PI ) m_fXViewAngle = -2*g_PI;
//
int pos;
pos = (int)(m_fXViewAngle*50/2/g_PI)+50;
}
if ( shift && up )
{
m_fYViewAngle -= 0.03f;
if ( m_fYViewAngle < -g_PI ) m_fYViewAngle = -g_PI;
//
int pos;
pos = (int)(m_fYViewAngle*100/g_PI)+50;
}
if ( shift && down )
{
m_fYViewAngle += 0.03f;
if ( m_fYViewAngle > g_PI ) m_fYViewAngle = g_PI;
//
int pos;
pos = (int)(m_fYViewAngle*100/g_PI)+50;
}
// Camera到原点的距离
if ( shift && home )
{
m_fEyeDistance += 0.1f;
if( m_fEyeDistance > 7.0f ) m_fEyeDistance = 7.0f;
int pos;
pos = 30 + (int)(10.0f*m_fEyeDistance);
}
if ( shift && end )
{
m_fEyeDistance -= 0.1f;
if( m_fEyeDistance < -3.0f ) m_fEyeDistance = -3.0f;
int pos;
pos = 30 + (int)(10.0f*m_fEyeDistance);
}
return TRUE;
}
BOOL CMy3dXVView::GoWindow()
{
g_bReady = FALSE;
// 初始化Direct3D
// Cleanup any objects that might've been created before
if( FAILED( Cleanup3DEnvironment() ) )
return E_FAIL;
HWND hWnd;
hWnd = m_hwndRenderWindow;
TRACE("GoWindow\n");
// Create the D3D environment, at first, trying the HAL
if( SUCCEEDED( Initialize3DEnvironment( hWnd, NULL,
&IID_IDirect3DHALDevice ) ) )
return S_OK;
// Else, cleanup objects potentially created during the failed
// initialization attempt.
Cleanup3DEnvironment();