0001:
0002:
0003:
0004:
0005:
0006: #define STRICT
0007: #include <windows.h>
0008: #include <windowsx.h>
0009: #include <mmsystem.h>
0010: #include <stdio.h>
0011: #include <tchar.h>
0012: #include <D3D9.h>
0013: #include "DXUtil.h"
0014: #include "D3DUtil.h"
0015: #include "D3DEnumeration.h"
0016: #include "D3DSettings.h"
0017: #include "D3DApp.h"
0018: #include "resource.h"
0019:
0020:
0021:
0022:
0023:
0024:
0025:
0026: static CD3DApplication* g_pD3DApp = NULL;
0027:
0028:
0029:
0030:
0031:
0032:
0033:
0034:
0035: CD3DApplication::CD3DApplication()
0036: {
0037: g_pD3DApp = this;
0038:
0039: m_pD3D = NULL;
0040: m_pd3dDevice = NULL;
0041: m_hWnd = NULL;
0042: m_hWndFocus = NULL;
0043: m_hMenu = NULL;
0044: m_bWindowed = true;
0045: m_bActive = false;
0046: m_bDeviceLost = false;
0047: m_bMinimized = false;
0048: m_bMaximized = false;
0049: m_bIgnoreSizeChange = false;
0050: m_bDeviceObjectsInited = false;
0051: m_bDeviceObjectsRestored = false;
0052: m_dwCreateFlags = 0;
0053:
0054: m_bFrameMoving = true;
0055: m_bSingleStep = false;
0056: m_fTime = 0.0f;
0057: m_fElapsedTime = 0.0f;
0058: m_fFPS = 0.0f;
0059: m_strDeviceStats[0] = _T('\0');
0060: m_strFrameStats[0] = _T('\0');
0061:
0062: m_strWindowTitle = _T("D3D9 Application");
0063: m_dwCreationWidth = 400;
0064: m_dwCreationHeight = 300;
0065: m_bShowCursorWhenFullscreen = false;
0066: m_bStartFullscreen = false;
0067:
0068: Pause( true );
0069:
0070:
0071:
0072:
0073:
0074:
0075: #if defined(_DEBUG) || defined(DEBUG)
0076: m_bClipCursorWhenFullscreen = false;
0077: #else
0078: m_bClipCursorWhenFullscreen = true;
0079: #endif
0080: }
0081:
0082:
0083:
0084:
0085:
0086:
0087:
0088:
0089: LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
0090: {
0091: return g_pD3DApp->MsgProc( hWnd, uMsg, wParam, lParam );
0092: }
0093:
0094:
0095:
0096:
0097:
0098:
0099:
0100: bool CD3DApplication::ConfirmDeviceHelper( D3DCAPS9* pCaps, VertexProcessingType vertexProcessingType,
0101: D3DFORMAT backBufferFormat )
0102: {
0103: DWORD dwBehavior;
0104:
0105: if (vertexProcessingType == SOFTWARE_VP)
0106: dwBehavior = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
0107: else if (vertexProcessingType == MIXED_VP)
0108: dwBehavior = D3DCREATE_MIXED_VERTEXPROCESSING;
0109: else if (vertexProcessingType == HARDWARE_VP)
0110: dwBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING;
0111: else if (vertexProcessingType == PURE_HARDWARE_VP)
0112: dwBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
0113: else
0114: dwBehavior = 0;
0115:
0116: return SUCCEEDED( g_pD3DApp->ConfirmDevice( pCaps, dwBehavior, backBufferFormat ) );
0117: }
0118:
0119:
0120:
0121:
0122:
0123:
0124:
0125:
0126: HRESULT CD3DApplication::Create( HINSTANCE hInstance )
0127: {
0128: HRESULT hr;
0129:
0130:
0131: m_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
0132: if( m_pD3D == NULL )
0133: return DisplayErrorMsg( D3DAPPERR_NODIRECT3D, MSGERR_APPMUSTEXIT );
0134:
0135:
0136:
0137:
0138: m_d3dEnumeration.SetD3D( m_pD3D );
0139: m_d3dEnumeration.ConfirmDeviceCallback = ConfirmDeviceHelper;
0140: if( FAILED( hr = m_d3dEnumeration.Enumerate() ) )
0141: {
0142: SAFE_RELEASE( m_pD3D );
0143: return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
0144: }
0145:
0146:
0147:
0148: if( m_hWnd == NULL)
0149: {
0150:
0151: WNDCLASS wndClass = { 0, WndProc, 0, 0, hInstance,
0152: LoadIcon( hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON) ),
0153: LoadCursor( NULL, IDC_ARROW ),
0154: (HBRUSH)GetStockObject(WHITE_BRUSH),
0155: NULL, _T("D3D Window") };
0156: RegisterClass( &wndClass );
0157:
0158:
0159: m_dwWindowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME |
0160: WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE;
0161:
0162:
0163: RECT rc;
0164: SetRect( &rc, 0, 0, m_dwCreationWidth, m_dwCreationHeight );
0165: AdjustWindowRect( &rc, m_dwWindowStyle, true );
0166:
0167:
0168: m_hWnd = CreateWindow( _T("D3D Window"), m_strWindowTitle, m_dwWindowStyle,
0169: CW_USEDEFAULT, CW_USEDEFAULT,
0170: (rc.right-rc.left), (rc.bottom-rc.top), 0,
0171: LoadMenu( hInstance, MAKEINTRESOURCE(IDR_MENU) ),
0172: hInstance, 0 );
0173: }
0174:
0175:
0176:
0177: if( m_hWndFocus == NULL )
0178: m_hWndFocus = m_hWnd;
0179:
0180:
0181: m_dwWindowStyle = GetWindowLong( m_hWnd, GWL_STYLE );
0182: GetWindowRect( m_hWnd, &m_rcWindowBounds );
0183: GetClientRect( m_hWnd, &m_rcWindowClient );
0184:
0185: if( FAILED( hr = ChooseInitialD3DSettings() ) )
0186: {
0187: SAFE_RELEASE( m_pD3D );
0188: return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
0189: }
0190:
0191:
0192: DXUtil_Timer( TIMER_START );
0193:
0194:
0195: if( FAILED( hr = OneTimeSceneInit() ) )
0196: {
0197: SAFE_RELEASE( m_pD3D );
0198: return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
0199: }
0200:
0201:
0202: if( FAILED( hr = Initialize3DEnvironment() ) )
0203: {
0204: SAFE_RELEASE( m_pD3D );
0205: return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
0206: }
0207:
0208:
0209: Pause( false );
0210:
0211: return S_OK;
0212: }
0213:
0214:
0215:
0216:
0217:
0218:
0219:
0220:
0221:
0222:
0223: bool CD3DApplication::FindBestWindowedMode( bool bRequireHAL, bool bRequireREF )
0224: {
0225:
0226:
0227: D3DDISPLAYMODE primaryDesktopDisplayMode;
0228: m_pD3D->GetAdapterDisplayMode(0, &primaryDesktopDisplayMode);
0229:
0230: D3DAdapterInfo* pBestAdapterInfo = NULL;
0231: D3DDeviceInfo* pBestDeviceInfo = NULL;
0232: D3DDeviceCombo* pBestDeviceCombo = NULL;
0233:
0234: for( UINT iai = 0; iai < m_d3dEnumeration.m_pAdapterInfoList->Count(); iai++ )
0235: {
0236: D3DAdapterInfo* pAdapterInfo = (D3DAdapterInfo*)m_d3dEnumeration.m_pAdapterInfoList->GetPtr(iai);
0237: for( UINT idi = 0; idi < pAdapterInfo->pDeviceInfoList->Count(); idi++ )
0238: {
0239: D3DDeviceInfo* pDeviceInfo = (D3DDeviceInfo*)pAdapterInfo->pDeviceInfoList->GetPtr(idi);
0240: if (bRequireHAL && pDeviceInfo->DevType != D3DDEVTYPE_HAL)
0241: continue;
0242: if (bRequireREF && pDeviceInfo->DevType != D3DDEVTYPE_REF)
0243: continue;
0244: for( UINT idc = 0; idc < pDeviceInfo->pDeviceComboList->Count(); idc++ )
0245: {
0246: D3DDeviceCombo* pDeviceCombo = (D3DDeviceCombo*)pDeviceInfo->pDeviceComboList->GetPtr(idc);
0247: bool bAdapterMatchesBB = (pDeviceCombo->BackBufferFormat == pDeviceCombo->AdapterFormat);
0248: if (!pDeviceCombo->IsWindowed)
0249: continue;
0250: if (pDeviceCombo->AdapterFormat != primaryDesktopDisplayMode.Format)
0251: continue;
0252:
0253:
0254:
0255: if( pBestDeviceCombo == NULL ||
0256: pBestDeviceCombo->DevType != D3DDEVTYPE_HAL && pDeviceCombo->DevType == D3DDEVTYPE_HAL ||
0257: pDeviceCombo->DevType == D3DDEVTYPE_HAL && bAdapterMatchesBB )
0258: {
0259: pBestAdapterInfo = pAdapterInfo;
0260: pBestDeviceInfo = pDeviceInfo;
0261: pBestDeviceCombo = pDeviceCombo;
0262: if( pDeviceCombo->DevType == D3DDEVTYPE_HAL && bAdapterMatchesBB )
0263: {
0264:
0265: goto EndWindowedDeviceComboSearch;
0266: }
0267:
0268: }
0269: }
0270: }
0271: }
0272: EndWindowedDeviceComboSearch:
0273: if (pBestDeviceCombo == NULL )
0274: return false;
0275:
0276: m_d3dSettings.pWindowed_AdapterInfo = pBestAdapterInfo;
0277: m_d3dSettings.pWindowed_DeviceInfo = pBestDeviceInfo;
0278: m_d3dSettings.pWindowed_DeviceCombo = pBestDeviceCombo;
0279: m_d3dSettings.IsWindowed = true;
0280: m_d3dSettings.Windowed_DisplayMode = primaryDesktopDisplayMode;
0281: m_d3dSettings.Windowed_Width = m_rcWindowClient.right - m_rcWindowClient.left;
0282: m_d3dSettings.Windowed_Height = m_rcWindowClient.bottom - m_rcWindowClient.top;
0283: if (m_d3dEnumeration.AppUsesDepthBuffer)
0284: m_d3dSettings.Windowed_DepthStencilBufferFormat = *(D3DFORMAT*)pBestDeviceCombo->pDepthStencilFormatList->GetPtr(0);
0285: m_d3dSettings.Windowed_MultisampleType = *(D3DMULTISAMPLE_TYPE*)pBestDeviceCombo->pMultiSampleTypeList->GetPtr(0);
0286: m_d3dSettings.Windowed_MultisampleQuality = 0;
0287: m_d3dSettings.Windowed_VertexProcessingType = *(VertexProcessingType*)pBestDeviceCombo->pVertexProcessingTypeList->GetPtr(0);
0288: m_d3dSettings.Windowed_PresentInterval = *(UINT*)pBestDeviceCombo->pPresentIntervalList->GetPtr(0);
0289: return true;
0290: }
0291:
0292:
0293:
0294:
0295:
0296:
0297:
0298:
0299:
0300:
0301: bool CD3DApplication::FindBestFullscreenMode( bool bRequireHAL, bool bRequireREF )
0302: {
0303:
0304:
0305:
0306: D3DDISPLAYMODE adapterDesktopDisplayMode;
0307: D3DDISPLAYMODE bestAdapterDesktopDisplayMode;
0308: D3DDISPLAYMODE bestDisplayMode;
0309: bestAdapterDesktopDisplayMode.Width = 0;
0310: bestAdapterDesktopDisplayMode.Height = 0;
0311: bestAdapterDesktopDisplayMode.Format = D3DFMT_UNKNOWN;
0312: bestAdapterDesktopDisplayMode.RefreshRate = 0;
0313:
0314: D3DAdapterInfo* pBestAdapterInfo = NULL;
0315: D3DDeviceInfo* pBestDeviceInfo = NULL;
0316: D3DDeviceCombo* pBestDeviceCombo = NULL;
0317:
0318: for( UINT iai = 0; iai < m_d3dEnumeration.m_pAdapterInfoList->Count(); iai++ )
0319: {
0320: D3DAdapterInfo* pAdapterInfo = (D3DAdapterInfo*)m_d3dEnumeration.m_pAdapterInfoList->GetPtr(iai);
0321: m_pD3D->GetAdapterDisplayMode( pAdapterInfo->AdapterOrdinal, &adapterDesktopDisplayMode );
0322: for( UINT idi = 0; idi < pAdapterInfo->pDeviceInfoList->Count(); idi++ )
0323: {
0324: D3DDeviceInfo* pDeviceInfo = (D3DDeviceInfo*)pAdapterInfo->pDeviceInfoList->GetPtr(idi);
0325: if (bRequireHAL && pDeviceInfo->DevType != D3DDEVTYPE_HAL)
0326: continue;
0327: if (bRequireREF && pDeviceInfo->DevType != D3DDEVTYPE_REF)
0328: continue;
0329: for( UINT idc = 0; idc < pDeviceInfo->pDeviceComboList->Count(); idc++ )
0330: {
0331: D3DDeviceCombo* pDeviceCombo = (D3DDeviceCombo*)pDeviceInfo->pDeviceComboList->GetPtr(idc);
0332: bool bAdapterMatchesBB = (pDeviceCombo->BackBufferFormat == pDeviceCombo->AdapterFormat);
0333: bool bAdapterMatchesDesktop = (pDeviceCombo->AdapterFormat == adapterDesktopDisplayMode.Format);
0334: if (pDeviceCombo->IsWindowed)
0335: continue;
0336:
0337:
0338:
0339: if (pBestDeviceCombo == NULL ||
0340: pBestDeviceCombo->DevType != D3DDEVTYPE_HAL && pDeviceInfo->DevType == D3DDEVTYPE_HAL ||
0341: pDeviceCombo->DevType == D3DDEVTYPE_HAL && pBestDeviceCombo->AdapterFormat != adapterDesktopDisplayMode.Format && bAdapterMatchesDesktop ||
0342: pDeviceCombo->DevType == D3DDEVTYPE_HAL && bAdapterMatchesDesktop && bAdapterMatchesBB )
0343: {
0344: bestAdapterDesktopDisplayMode = adapterDesktopDisplayMode;
0345: pBestAdapterInfo = pAdapterInfo;
0346: pBestDeviceInfo = pDeviceInfo;
0347: pBestDeviceCombo = pDeviceCombo;
0348: if (pDeviceInfo->DevType == D3DDEVTYPE_HAL && bAdapterMatchesDesktop && bAdapterMatchesBB)
0349: {
0350:
0351: goto EndFullscreenDeviceComboSearch;
0352: }
0353:
0354: }
0355: }
0356: }
0357: }
0358: EndFullscreenDeviceComboSearch:
0359: if (pBestDeviceCombo == NULL)
0360: return false;
0361:
0362:
0363:
0364: bestDisplayMode.Width = 0;
0365: bestDisplayMode.Height = 0;
0366: bestDisplayMode.Format = D3DFMT_UNKNOWN;
0367: bestDisplayMode.RefreshRate = 0;
0368: for( UINT idm = 0; idm < pBestAdapterInfo->pDisplayModeList->Count(); idm++ )
0369: {
0370: D3DDISPLAYMODE* pdm = (D3DDISPLAYMODE*)pBestAdapterInfo->pDisplayModeList->GetPtr(idm);
0371: if( pdm->Format != pBestDeviceCombo->AdapterFormat )
0372: continue;
0373: if( pdm->Width == bestAdapterDesktopDisplayMode.Width &&
0374: pdm->Height == bestAdapterDesktopDisplayMode.Height &&
0375: pdm->RefreshRate == bestAdapterDesktopDisplayMode.RefreshRate )
0376: {
0377:
0378: bestDisplayMode = *pdm;
0379: break;
0380: }
0381: else if( pdm->Width == bestAdapterDesktopDisplayMode.Width &&
0382: pdm->Height == bestAdapterDesktopDisplayMode.Height &&
0383: pdm->RefreshRate > bestDisplayMode.RefreshRate )
0384: {
0385:
0386:
0387: bestDisplayMode = *pdm;
0388: }
0389: else if( pdm->Width == bestAdapterDesktopDisplayMode.Width )
0390: {
0391:
0392: bestDisplayMode = *pdm;
0393: }
0394: else if( bestDisplayMode.Width == 0 )
0395: {
0396:
0397: bestDisplayMode = *pdm;
0398: }
0399: }
0400:
0401: m_d3dSettings.pFullscreen_AdapterInfo = pBestAdapterInfo;
0402: m_d3dSettings.pFullscreen_DeviceInfo = pBestDeviceInfo;
0403: m_d3dSettings.pFullscreen_DeviceCombo = pBestDeviceCombo;
0404: m_d3dSettings.IsWindowed = false;
0405: m_d3dSettings.Fullscreen_DisplayMode = bestDisplayMode;
0406: if (m_d3dEnumeration.AppUsesDepthBuffer)
0407: m_d3dSettings.Fullscreen_DepthStencilBufferFormat = *(D3DFORMAT*)pBestDeviceCombo->pDepthStencilFormatList->GetPtr(0);
0408: m_d3dSettings.Fullscreen_MultisampleType = *(D3DMULTISAMPLE_TYPE*)pBestDeviceCombo->pMultiSampleTypeList->GetPtr(0);
0409: m_d3dSettings.Fullscreen_MultisampleQuality = 0;
0410: m_d3dSettings.Fullscreen_VertexProcessingType = *(VertexProcessingType*)pBestDeviceCombo->pVertexProcessingTypeList->GetPtr(0);
0411: m_d3dSettings.Fullscreen_PresentInterval = D3DPRESENT_INTERVAL_DEFAULT;
0412: return true;
0413: }
0414:
0415:
0416:
0417:
0418:
0419:
0420:
0421:
0422: HRESULT CD3DApplication::ChooseInitialD3DSettings()
0423: {
0424: bool bFoundFullscreen = FindBestFullscreenMode( false, false );
0425: bool bFoundWindowed = FindBestWindowedMode( false, false );
0426:
0427: if( m_bStartFullscreen && bFoundFullscreen )
0428: m_d3dSettings.IsWindowed = false;
0429: if( !bFoundWindowed && bFoundFullscreen )
0430: m_d3dSettings.IsWindowed = false;
0431:
0432: if( !bFoundFullscreen && !bFoundWindowed )
0433: return D3DAPPERR_NOCOMPATIBLEDEVICES;
0434:
0435: return S_OK;
0436: }
0437:
0438:
0439:
0440:
0441:
0442:
0443:
0444:
0445: LRESULT CD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
0446: LPARAM lParam )
0447: {
0448: switch( uMsg )
0449: {
0450: case WM_PAINT:
0451:
0452: if( m_pd3dDevice && !m_bActive && m_bWindowed &&
0453: m_bDeviceObjectsInited && m_bDeviceObjectsRestored )
0454: {
0455: Render();
0456: m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
0457: }
0458: break;
0459:
0460: case WM_GETMINMAXINFO:
0461: ((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
0462: ((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
0463: break;
0464:
0465: case WM_ENTERSIZEMOVE:
0466:
0467: Pause( true );
0468: break;
0469:
0470: case WM_SIZE:
0471:
0472: if( m_bWindowed && m_hWnd != NULL )
0473: m_dwWindowStyle = GetWindowLong( m_hWnd, GWL_STYLE );
0474:
0475: if( SIZE_MINIMIZED == wParam )
0476: {
0477: if( m_bClipCursorWhenFullscreen && !m_bWindowed )
0478: ClipCursor( NULL );
0479: Pause( true );
0480: m_bMinimized = true;
0481: m_bMaximized = false;
0482: }
0483: else if( SIZE_MAXIMIZED == wParam )
0484: {
0485: if( m_bMinimized )
0486: Pause( false );
0487: m_bMinimized = false;
0488: m_bMaximized = true;
0489: HandlePossibleSizeChange();
0490: }
0491: else if( SIZE_RESTORED == wParam )
0492: {
0493: if( m_bMaximized )
0494: {
0495: m_bMaximized = false;
0496: HandlePossibleSizeChange();
0497: }
0498: else if( m_bMinimized)
0499: {
0500: Pause( false );
0501: m_bMinimized = false;
0502: HandlePossibleSizeChange();
0503: }
0504: else
0505: {
0506:
0507:
0508:
0509:
0510: }
0511: }
0512: break;
0513:
0514: case WM_EXITSIZEMOVE:
0515: Pause( false );
0516: HandlePossibleSizeChange();
0517: break;
0518:
0519: case WM_SETCURSOR:
0520:
0521: if( m_bActive && !m_bWindowed )
0522: {
0523: SetCursor( NULL );
0524: if( m_bShowCursorWhenFullscreen )
0525: m_pd3dDevice->ShowCursor( true );
0526: return true;
0527: }
0528: break;
0529:
0530: case WM_MOUSEMOVE:
0531: if( m_bActive && m_pd3dDevice != NULL )
0532: {
0533: POINT ptCursor;
0534: GetCursorPos( &ptCursor );
0535: if( !m_bWindowed )
0536: ScreenToClient( m_hWnd, &ptCursor );
0537: m_pd3dDevice->SetCursorPosition( ptCursor.x, ptCursor.y, 0 );
0538: }
0539: break;
0540:
0541: case WM_ENTERMENULOOP:
0542:
0543: Pause(true);
0544: break;
0545:
0546: case WM_EXITMENULOOP:
0547: Pause(false);
0548: break;
0549:
0550: case WM_NCHITTEST:
0551:
0552: if( !m_bWindowed )
0553: return HTCLIENT;
0554: break;
0555:
0556: case WM_POWERBROADCAST:
0557: switch( wParam )
0558: {
0559: #ifndef PBT_APMQUERYSUSPEND
0560: #define PBT_APMQUERYSUSPEND 0x0000
0561: #endif
0562: case PBT_APMQUERYSUSPEND:
0563:
0564:
0565:
0566: return true;
0567:
0568: #ifndef PBT_APMRESUMESUSPEND
0569: #define PBT_APMRESUMESUSPEND 0x0007
0570: #endif
0571: case PBT_APMRESUMESUSPEND:
0572:
0573:
0574:
0575: return true;
0576: }
0577: break;
0578:
0579: case WM_SYSCOMMAND:
0580:
0581: switch( wParam )
0582: {
0583: case SC_MOVE:
0584: case SC_SIZE:
0585: case SC_MAXIMIZE:
0586: case SC_KEYMENU:
0587: case SC_MONITORPOWER:
0588: if( false == m_bWindowed )
0589: return 1;
0590: break;
0591: }
0592: break;
0593:
0594: case WM_COMMAND:
0595: switch( LOWORD(wParam) )
0596: {
0597: case IDM_CHANGEDEVICE:
0598:
0599: Pause(true);
0600: UserSelectNewDevice();
0601: Pause(false);
0602: return 0;
0603:
0604: case IDM_TOGGLEFULLSCREEN:
0605:
0606: Pause( true );
0607: if( FAILED( ToggleFullscreen() ) )
0608: DisplayErrorMsg( D3DAPPERR_RESETFAILED, MSGERR_APPMUSTEXIT );
0609: Pause( false );
0610: return 0;
0611:
0612: case IDM_EXIT:
0613:
0614: SendMessage( hWnd, WM_CLOSE, 0, 0 );
0615: return 0;
0616: }
0617: break;
0618:
0619: case WM_CLOSE:
0620: Cleanup3DEnvironment();
0621: SAFE_RELEASE( m_pD3D );
0622: FinalCleanup();
0623: HMENU hMenu;
0624: hMenu = GetMenu(hWnd);
0625: if( hMenu != NULL )
0626: DestroyMenu( hMenu );
0627: DestroyWindow( hWnd );
0628: PostQuitMessage(0);
0629: m_hWnd = NULL;
0630: return 0;
0631: }
0632:
0633: return DefWindowProc( hWnd, uMsg, wParam, lParam );
0634: }
0635:
0636:
0637:
0638:
0639:
0640:
0641:
0642:
0643: HRESULT CD3DApplication::HandlePossibleSizeChange()
0644: {
0645: HRESULT hr = S_OK;
0646: RECT rcClientOld;
0647: rcClientOld = m_rcWindowClient;
0648:
0649: if( m_bIgnoreSizeChange )
0650: return S_OK;
0651:
0652:
0653: GetWindowRect( m_hWnd, &m_rcWindowBounds );
0654: GetClientRect( m_hWnd, &m_rcWindowClient );
0655:
0656: if( rcClientOld.right - rcClientOld.left !=
0657: m_rcWindowClient.right - m_rcWindowClient.left ||
0658: rcClientOld.bottom - rcClientOld.top !=
0659: m_rcWindowClient.bottom - m_rcWindowClient.top)
0660: {
0661:
0662:
0663: Pause( true );
0664:
0665: m_d3dpp.BackBufferWidth = m_rcWindowClient.right - m_rcWindowClient.left;
0666: m_d3dpp.BackBufferHeight = m_rcWindowClient.bottom - m_rcWindowClient.top;
0667:
0668: if( m_pd3dDevice != NULL )
0669: {
0670:
0671: if( FAILED( hr = Reset3DEnvironment() ) )
0672: {
0673: if( hr != D3DERR_OUTOFVIDEOMEMORY )
0674: hr = D3DAPPERR_RESETFAILED;
0675: DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
0676: }
0677: }
0678: Pause( false );
0679: }
0680: return hr;
0681: }
0682:
0683:
0684:
0685:
0686:
0687:
0688:
0689:
0690: HRESULT CD3DApplication::Initialize3DEnvironment()
0691: {
0692: HRESULT hr;
0693:
0694: D3DAdapterInfo* pAdapterInfo = m_d3dSettings.PAdapterInfo();
0695: D3DDeviceInfo* pDeviceInfo = m_d3dSettings.PDeviceInfo();
0696:
0697: m_bWindowed = m_d3dSettings.IsWindowed;
0698:
0699:
0700: AdjustWindowForChange();
0701:
0702:
0703: BuildPresentParamsFromSettings();
0704:
0705: if( pDeviceInfo->Caps.PrimitiveMiscCaps & D3DPMISCCAPS_NULLREFERENCE )
0706: {
0707:
0708: DisplayErrorMsg( D3DAPPERR_NULLREFDEVICE, 0 );
0709: }
0710:
0711: DWORD behaviorFlags;
0712: if (m_d3dSettings.GetVertexProcessingType() == SOFTWARE_VP)
0713: behaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
0714: else if (m_d3dSettings.GetVertexProcessingType() == MIXED_VP)
0715: behaviorFlags = D3DCREATE_MIXED_VERTEXPROCESSING;
0716: else if (m_d3dSettings.GetVertexProcessingType() == HARDWARE_VP)
0717: behaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
0718: else if (m_d3dSettings.GetVertexProcessingType() == PURE_HARDWARE_VP)
0719: behaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
0720: else
0721: behaviorFlags = 0;
0722:
0723:
0724: hr = m_pD3D->CreateDevice( m_d3dSettings.AdapterOrdinal(), pDeviceInfo->DevType,
0725: m_hWndFocus, behaviorFlags, &m_d3dpp,
0726: &m_pd3dDevice );
0727:
0728: if( SUCCEEDED(hr) )
0729: {
0730:
0731:
0732:
0733:
0734:
0735:
0736:
0737:
0738: if( m_bWindowed )
0739: {
0740: SetWindowPos( m_hWnd, HWND_NOTOPMOST,
0741: m_rcWindowBounds.left, m_rcWindowBounds.top,
0742: ( m_rcWindowBounds.right - m_rcWindowBounds.left ),
0743: ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ),
0744: SWP_SHOWWINDOW );
0745: }
0746:
0747:
0748: m_pd3dDevice->GetDeviceCaps( &m_d3dCaps );
0749: m_dwCreateFlags = behaviorFlags;
0750:
0751:
0752: if( pDeviceInfo->DevType == D3DDEVTYPE_REF )
0753: lstrcpy( m_strDeviceStats, TEXT("REF") );
0754: else if( pDeviceInfo->DevType == D3DDEVTYPE_HAL )
0755: lstrcpy( m_strDeviceStats, TEXT("HAL") );
0756: else if( pDeviceInfo->DevType == D3DDEVTYPE_SW )
0757: lstrcpy( m_strDeviceStats, TEXT("SW") );
0758:
0759: if( behaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING &&
0760: behaviorFlags & D3DCREATE_PUREDEVICE )
0761: {
0762: if( pDeviceInfo->DevType == D3DDEVTYPE_HAL )
0763: lstrcat( m_strDeviceStats, TEXT(" (pure hw vp)") );
0764: else
0765: lstrcat( m_strDeviceStats, TEXT(" (simulated pure hw vp)") );
0766: }
0767: else if( behaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING )
0768: {
0769: if( pDeviceInfo->DevType == D3DDEVTYPE_HAL )
0770: lstrcat( m_strDeviceStats, TEXT(" (hw vp)") );
0771: else
0772: lstrcat( m_strDeviceStats, TEXT(" (simulated hw vp)") );
0773: }
0774: else if( behaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING )
0775: {
0776: if( pDeviceInfo->DevType == D3DDEVTYPE_HAL )
0777: lstrcat( m_strDeviceStats, TEXT(" (mixed vp)") );
0778: else
0779: lstrcat( m_strDeviceStats, TEXT(" (simulated mixed vp)") );
0780: }
0781: else if( behaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING )
0782: {
0783: lstrcat( m_strDeviceStats, TEXT(" (sw vp)") );
0784: }
0785:
0786: if( pDeviceInfo->DevType == D3DDEVTYPE_HAL )
0787: {
0788:
0789:
0790:
0791: lstrcat( m_strDeviceStats, TEXT(": ") );
0792: const int cchDesc = sizeof(pAdapterInfo->AdapterIdentifier.Description);
0793: TCHAR szDescription[cchDesc];
0794: DXUtil_ConvertAnsiStringToGenericCch( szDescription,
0795: pAdapterInfo->AdapterIdentifier.Description, cchDesc );
0796: int maxAppend = sizeof(m_strDeviceStats) / sizeof(TCHAR) -
0797: lstrlen( m_strDeviceStats ) - 1;
0798: _tcsncat( m_strDeviceStats, szDescription, maxAppend );
0799: }
0800:
0801:
0802: LPDIRECT3DSURFACE9 pBackBuffer = NULL;
0803: m_pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
0804: pBackBuffer->GetDesc( &m_d3dsdBackBuffer );
0805: pBackBuffer->Release();
0806:
0807:
0808: if( m_bShowCursorWhenFullscreen && !m_bWindowed )
0809: {
0810: HCURSOR hCursor;
0811: #ifdef _WIN64
0812: hCursor = (HCURSOR)GetClassLongPtr( m_hWnd, GCLP_HCURSOR );
0813: #else
0814: hCursor = (HCURSOR)ULongToHandle( GetClassLong( m_hWnd, GCL_HCURSOR ) );
0815: #endif
0816: D3DUtil_SetDeviceCursor( m_pd3dDevice, hCursor, true );
0817: m_pd3dDevice->ShowCursor( true );
0818: }
0819:
0820:
0821: if( m_bClipCursorWhenFullscreen )
0822: {
0823: if (!m_bWindowed )
0824: {
0825: RECT rcWindow;
0826: GetWindowRect( m_hWnd, &rcWindow );
0827: ClipCursor( &rcWindow );
0828: }
0829: else
0830: {
0831: ClipCursor( NULL );
0832: }
0833: }
0834:
0835:
0836: hr = InitDeviceObjects();
0837: if( FAILED(hr) )
0838: {
0839: DeleteDeviceObjects();
0840: }
0841: else
0842: {
0843: m_bDeviceObjectsInited = true;
0844: hr = RestoreDeviceObjects();
0845: if( FAILED(hr) )
0846: {
0847: InvalidateDeviceObjects();
0848: }
0849: else
0850: {
0851: m_bDeviceObjectsRestored = true;
0852: return S_OK;
0853: }
0854: }
0855:
0856:
0857: Cleanup3DEnvironment();
0858: }
0859:
0860:
0861: if( hr != D3DAPPERR_MEDIANOTFOUND &&
0862: hr != HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) &&
0863: pDeviceInfo->DevType == D3DDEVTYPE_HAL )
0864: {
0865: if (FindBestWindowedMode(false, true))
0866: {
0867: m_bWindowed = true;
0868: AdjustWindowForChange();
0869:
0870: SetWindowPos( m_hWnd, HWND_NOTOPMOST,
0871: m_rcWindowBounds.left, m_rcWindowBounds.top,
0872: ( m_rcWindowBounds.right - m_rcWindowBounds.left ),
0873: ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ),
0874: SWP_SHOWWINDOW );
0875:
0876:
0877: DisplayErrorMsg( hr, MSGWARN_SWITCHEDTOREF );
0878:
0879: hr = Initialize3DEnvironment();
0880: }
0881: }
0882: return hr;
0883: }
0884:
0885:
0886:
0887:
0888:
0889:
0890:
0891:
0892: void CD3DApplication::BuildPresentParamsFromSettings()
0893: {
0894: m_d3dpp.Windowed = m_d3dSettings.IsWindowed;
0895: m_d3dpp.BackBufferCount = 1;
0896: m_d3dpp.MultiSampleType = m_d3dSettings.MultisampleType();
0897: m_d3dpp.MultiSampleQuality = m_d3dSettings.MultisampleQuality();
0898: m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
0899: m_d3dpp.EnableAutoDepthStencil = m_d3dEnumeration.AppUsesDepthBuffer;
0900: m_d3dpp.hDeviceWindow = m_hWnd;
0901: if( m_d3dEnumeration.AppUsesDepthBuffer )
0902: {
0903: m_d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
0904: m_d3dpp.AutoDepthStencilFormat = m_d3dSettings.DepthStencilBufferFormat();
0905: }
0906: else
0907: {
0908: m_d3dpp.Flags = 0;
0909: }
0910:
0911: if( m_bWindowed )
0912: {
0913: m_d3dpp.BackBufferWidth = m_rcWindowClient.right - m_rcWindowClient.left;
0914: m_d3dpp.BackBufferHeight = m_rcWindowClient.bottom - m_rcWindowClient.top;
0915: m_d3dpp.BackBufferFormat = m_d3dSettings.PDeviceCombo()->BackBufferFormat;
0916: m_d3dpp.FullScreen_RefreshRateInHz = 0;
0917: m_d3dpp.PresentationInterval = m_d3dSettings.PresentInterval();
0918: }
0919: else
0920: {
0921: m_d3dpp.BackBufferWidth = m_d3dSettings.DisplayMode().Width;
0922: m_d3dpp.BackBufferHeight = m_d3dSettings.DisplayMode().Height;
0923: m_d3dpp.BackBufferFormat = m_d3dSettings.PDeviceCombo()->BackBufferFormat;
0924: m_d3dpp.FullScreen_RefreshRateInHz = m_d3dSettings.Fullscreen_DisplayMode.RefreshRate;
0925: m_d3dpp.PresentationInterval = m_d3dSettings.PresentInterval();
0926: }
0927: }
0928:
0929:
0930:
0931:
0932:
0933:
0934:
0935:
0936: HRESULT CD3DApplication::Reset3DEnvironment()
0937: {
0938: HRESULT hr;
0939:
0940:
0941: if( m_bDeviceObjectsRestored )
0942: {
0943: m_bDeviceObjectsRestored = false;
0944: InvalidateDeviceObjects();
0945: }
0946:
0947: if( FAILED( hr = m_pd3dDevice->Reset( &m_d3dpp ) ) )
0948: return hr;
0949:
0950:
0951: LPDIRECT3DSURFACE9 pBackBuffer;
0952: m_pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
0953: pBackBuffer->GetDesc( &m_d3dsdBackBuffer );
0954: pBackBuffer->Release();
0955:
0956:
0957: if( m_bShowCursorWhenFullscreen && !m_bWindowed )
0958: {
0959: HCURSOR hCursor;
0960: #ifdef _WIN64
0961: hCursor = (HCURSOR)GetClassLongPtr( m_hWnd, GCLP_HCURSOR );
0962: #else
0963: hCursor = (HCURSOR)ULongToHandle( GetClassLong( m_hWnd, GCL_HCURSOR ) );
0964: #endif
0965: D3DUtil_SetDeviceCursor( m_pd3dDevice, hCursor, true );
0966: m_pd3dDevice->ShowCursor( true );
0967: }
0968:
0969:
0970: if( m_bClipCursorWhenFullscreen )
0971: {
0972: if (!m_bWindowed )
0973: {
0974: RECT rcWindow;
0975: GetWindowRect( m_hWnd, &rcWindow );
0976: ClipCursor( &rcWindow );
0977: }
0978: else
0979: {
0980: ClipCursor( NULL );
0981: }
0982: }
0983:
0984:
0985: hr = RestoreDeviceObjects();
0986: if( FAILED(hr) )
0987: {
0988: InvalidateDeviceObjects();
0989: return hr;
0990: }
0991: m_bDeviceObjectsRestored = true;
0992:
0993:
0994: if( false == m_bFrameMoving )
0995: {
0996: m_bSingleStep = true;
0997: DXUtil_Timer( TIMER_START );
0998: DXUtil_Timer( TIMER_STOP );
0999: }
1000:
1001: return S_OK;
1002: }
1003:
1004:
1005:
1006:
1007:
1008:
1009:
1010:
1011: HRESULT CD3DApplication::ToggleFullscreen()
1012: {
1013: HRESULT hr;
1014: int AdapterOrdinalOld = m_d3dSettings.AdapterOrdinal();
1015: D3DDEVTYPE DevTypeOld = m_d3dSettings.DevType();
1016:
1017: Pause( true );
1018: m_bIgnoreSizeChange = true;
1019:
1020:
1021: m_bWindowed = !m_bWindowed;
1022: m_d3dSettings.IsWindowed = m_bWindowed;
1023:
1024:
1025: AdjustWindowForChange();
1026:
1027:
1028:
1029: if (m_d3dSettings.AdapterOrdinal() == AdapterOrdinalOld &&
1030: m_d3dSettings.DevType() == DevTypeOld)
1031: {
1032:
1033: BuildPresentParamsFromSettings();
1034: hr = Reset3DEnvironment();
1035: }
1036: else
1037: {
1038: Cleanup3DEnvironment();
1039: hr = Initialize3DEnvironment();
1040: }
1041: if( FAILED( hr ) )
1042: {
1043: if( hr != D3DERR_OUTOFVIDEOMEMORY )
1044: hr = D3DAPPERR_RESETFAILED;
1045: m_bIgnoreSizeChange = false;
1046: if( !m_bWindowed )
1047: {
1048:
1049: m_bWindowed = !m_bWindowed;
1050: m_d3dSettings.IsWindowed = m_bWindowed;
1051: AdjustWindowForChange();
1052: SetWindowPos( m_hWnd, HWND_NOTOPMOST,
1053: m_rcWindowBounds.left, m_rcWindowBounds.top,
1054: ( m_rcWindowBounds.right - m_rcWindowBounds.left ),
1055: ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ),
1056: SWP_SHOWWINDOW );
1057: }
1058: return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
1059: }
1060:
1061: m_bIgnoreSizeChange = false;
1062:
1063:
1064:
1065:
1066:
1067:
1068:
1069:
1070:
1071: if( m_bWindowed )
1072: {
1073: SetWindowPos( m_hWnd, HWND_NOTOPMOST,
1074: m_rcWindowBounds.left, m_rcWindowBounds.top,
1075: ( m_rcWindowBounds.right - m_rcWindowBounds.left ),
1076: ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ),
1077: SWP_SHOWWINDOW );
1078: }
1079:
1080: Pause( false );
1081: return S_OK;
1082: }
1083:
1084:
1085:
1086:
1087:
1088:
1089:
1090:
1091:
1092: HRESULT CD3DApplication::ForceWindowed()
1093: {
1094: HRESULT hr;
1095:
1096: if( m_bWindowed )
1097: return S_OK;
1098:
1099: if( !FindBestWindowedMode(false, false) )
1100: {
1101: return E_FAIL;
1102: }
1103: m_bWindowed = true;
1104:
1105:
1106:
1107: Pause( true );
1108:
1109:
1110: Cleanup3DEnvironment();
1111:
1112:
1113: if( FAILED(hr = Initialize3DEnvironment() ) )
1114: return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
1115:
1116: Pause( false );
1117: return S_OK;
1118: }
1119:
1120:
1121:
1122:
1123:
1124:
1125:
1126:
1127:
1128:
1129:
1130: HRESULT CD3DApplication::AdjustWindowForChange()
1131: {
1132: if( m_bWindowed )
1133: {
1134:
1135: SetWindowLong( m_hWnd, GWL_STYLE, m_dwWindowStyle );
1136: if( m_hMenu != NULL )
1137: {
1138: SetMenu( m_hWnd, m_hMenu );
1139: m_hMenu = NULL;
1140: }
1141: }
1142: else
1143: {
1144:
1145: SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE );
1146: if( m_hMenu == NULL )
1147: {
1148: m_hMenu = GetMenu( m_hWnd );
1149: SetMenu( m_hWnd, NULL );
1150: }
1151: }
1152: return S_OK;
1153: }
1154:
1155:
1156:
1157:
1158:
1159:
1160:
1161:
1162:
1163: HRESULT CD3DApplication::UserSelectNewDevice()
1164: {
1165: HRESULT hr;
1166:
1167:
1168: if( m_bWindowed == false )
1169: {
1170: if( FAILED( ToggleFullscreen() ) )
1171: {
1172: DisplayErrorMsg( D3DAPPERR_RESETFAILED, MSGERR_APPMUSTEXIT );
1173: return E_FAIL;
1174: }
1175: }
1176:
1177: CD3DSettingsDialog settingsDialog( &m_d3dEnumeration, &m_d3dSettings);
1178: if( settingsDialog.ShowDialog( m_hWnd ) != IDOK )
1179: return S_OK;
1180: settingsDialog.GetFinalSettings( &m_d3dSettings );
1181:
1182: m_bWindowed = m_d3dSettings.IsWindowed;
1183:
1184:
1185: Cleanup3DEnvironment();
1186:
1187:
1188:
1189: if( FAILED( hr = Initialize3DEnvironment() ) )
1190: {
1191: if( hr != D3DERR_OUTOFVIDEOMEMORY )
1192: hr = D3DAPPERR_RESETFAILED;
1193: if( !m_bWindowed )
1194: {
1195:
1196: m_bWindowed = !m_bWindowed;
1197: m_d3dSettings.IsWindowed = m_bWindowed;
1198: AdjustWindowForChange();
1199: SetWindowPos( m_hWnd, HWND_NOTOPMOST,
1200: m_rcWindowBounds.left, m_rcWindowBounds.top,
1201: ( m_rcWindowBounds.right - m_rcWindowBounds.left ),
1202: ( m_rcWindowBounds.bottom - m_rcWindowBounds.top ),
1203: SWP_SHOWWINDOW );
1204: }
1205: return DisplayErrorMsg( hr, MSGERR_APPMUSTEXIT );
1206: }
1207:
1208:
1209: if( false == m_bFrameMoving )
1210: {
1211: m_bSingleStep = true;
1212: DXUtil_Timer( TIMER_START );
1213: DXUtil_Timer( TIMER_STOP );
1214: }
1215: return S_OK;
1216: }
1217:
1218:
1219:
1220:
1221:
1222:
1223:
1224:
1225: INT CD3DApplication::Run()
1226: {
1227:
1228: HACCEL hAccel = LoadAccelerators( NULL, MAKEINTRESOURCE(IDR_MAIN_ACCEL) );
1229:
1230:
1231: bool bGotMsg;
1232: MSG msg;
1233: msg.message = WM_NULL;
1234: PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
1235:
1236: while( WM_QUIT != msg.message )
1237: {
1238:
1239:
1240: if( m_bActive )
1241: bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );
1242: else
1243: bGotMsg = ( GetMessage( &msg, NULL, 0U, 0U ) != 0 );
1244:
1245: if( bGotMsg )
1246: {
1247:
1248: if( hAccel == NULL || m_hWnd == NULL ||
1249: 0 == TranslateAccelerator( m_hWnd, hAccel, &msg ) )
1250: {
1251: TranslateMessage( &msg );
1252: DispatchMessage( &msg );
1253: }
1254: }
1255: else
1256: {
1257: if( m_bDeviceLost )
1258: {
1259:
1260: Sleep( 100 );
1261: }
1262:
1263: if( m_bActive )
1264: {
1265: if( FAILED( Render3DEnvironment() ) )
1266: SendMessage( m_hWnd, WM_CLOSE, 0, 0 );
1267: }
1268: }
1269: }
1270: if( hAccel != NULL )
1271: DestroyAcceleratorTable( hAccel );
1272:
1273: return (INT)msg.wParam;
1274: }
1275:
1276:
1277:
1278:
1279:
1280:
1281:
1282:
1283: HRESULT CD3DApplication::Render3DEnvironment()
1284: {
1285: HRESULT hr;
1286:
1287: if( m_bDeviceLost )
1288: {
1289:
1290: if( FAILED( hr = m_pd3dDevice->TestCooperativeLevel() ) )
1291: {
1292:
1293: if( D3DERR_DEVICELOST == hr )
1294: return S_OK;
1295:
1296:
1297: if( D3DERR_DEVICENOTRESET == hr )
1298: {
1299:
1300:
1301: if( m_bWindowed )
1302: {
1303: D3DAdapterInfo* pAdapterInfo = m_d3dSettings.PAdapterInfo();
1304: m_pD3D->GetAdapterDisplayMode( pAdapterInfo->AdapterOrdinal, &m_d3dSettings.Windowed_DisplayMode );
1305: m_d3dpp.BackBufferFormat = m_d3dSettings.Windowed_DisplayMode.Format;
1306: }
1307:
1308: if( FAILED( hr = Reset3DEnvironment() ) )
1309: return hr;
1310: }
1311: return hr;
1312: }
1313: m_bDeviceLost = false;
1314: }
1315:
1316:
1317: FLOAT fAppTime = DXUtil_Timer( TIMER_GETAPPTIME );
1318: FLOAT fElapsedAppTime = DXUtil_Timer( TIMER_GETELAPSEDTIME );
1319: if( ( 0.0f == fElapsedAppTime ) && m_bFrameMoving )
1320: return S_OK;
1321:
1322:
1323: if( m_bFrameMoving || m_bSingleStep )
1324: {
1325:
1326: m_fTime = fAppTime;
1327: m_fElapsedTime = fElapsedAppTime;
1328:
1329:
1330: if( FAILED( hr = FrameMove() ) )
1331: return hr;
1332:
1333: m_bSingleStep = false;
1334: }
1335:
1336:
1337: if( FAILED( hr = Render() ) )
1338: return hr;
1339:
1340: UpdateStats();
1341:
1342:
1343: hr = m_pd3dDevice->Present( NULL, NULL, NULL, NULL );
1344: if( D3DERR_DEVICELOST == hr )
1345: m_bDeviceLost = true;
1346:
1347: return S_OK;
1348: }
1349:
1350:
1351:
1352:
1353:
1354:
1355:
1356:
1357: void CD3DApplication::UpdateStats()
1358: {
1359:
1360: static FLOAT fLastTime = 0.0f;
1361: static DWORD dwFrames = 0;
1362: FLOAT fTime = DXUtil_Timer( TIMER_GETABSOLUTETIME );
1363: ++dwFrames;
1364:
1365:
1366: if( fTime - fLastTime > 1.0f )
1367: {
1368: m_fFPS = dwFrames / (fTime - fLastTime);
1369: fLastTime = fTime;
1370: dwFrames = 0;
1371:
1372: TCHAR strFmt[100];
1373: D3DFORMAT fmtAdapter = m_d3dSettings.DisplayMode().Format;
1374: if( fmtAdapter == m_d3dsdBackBuffer.Format )
1375: {
1376: lstrcpyn( strFmt, D3DUtil_D3DFormatToString( fmtAdapter, false ), 100 );
1377: }
1378: else
1379: {
1380: _sntprintf( strFmt, 100, TEXT("backbuf %s, adapter %s"),
1381: D3DUtil_D3DFormatToString( m_d3dsdBackBuffer.Format, false ),
1382: D3DUtil_D3DFormatToString( fmtAdapter, false ) );
1383: }
1384: strFmt[99] = TEXT('\0');
1385:
1386: TCHAR strDepthFmt[100];
1387: if( m_d3dEnumeration.AppUsesDepthBuffer )
1388: {
1389: _sntprintf( strDepthFmt, 100, TEXT(" (%s)"),
1390: D3DUtil_D3DFormatToString( m_d3dSettings.DepthStencilBufferFormat(), false ) );
1391: strDepthFmt[99] = TEXT('\0');
1392: }
1393: else
1394: {
1395:
1396: strDepthFmt[0] = TEXT('\0');
1397: }
1398:
1399: TCHAR* pstrMultiSample;
1400: switch( m_d3dSettings.MultisampleType() )
1401: {
1402: case D3DMULTISAMPLE_NONMASKABLE: pstrMultiSample = TEXT(" (Nonmaskable Multisample)"); break;
1403: case D3DMULTISAMPLE_2_SAMPLES: pstrMultiSample = TEXT(" (2x Multisample)"); break;
1404: case D3DMULTISAMPLE_3_SAMPLES: pstrMultiSample = TEXT(" (3x Multisample)"); break;
1405: case D3DMULTISAMPLE_4_SAMPLES: pstrMultiSample = TEXT(" (4x Multisample)"); break;
1406: case D3DMULTISAMPLE_5_SAMPLES: pstrMultiSample = TEXT(" (5x Multisample)"); break;
1407: case D3DMULTISAMPLE_6_SAMPLES: pstrMultiSample = TEXT(" (6x Multisample)"); break;
1408: case D3DMULTISAMPLE_7_SAMPLES: pstrMultiSample = TEXT(" (7x Multisample)"); break;
1409: case D3DMULTISAMPLE_8_SAMPLES: pstrMultiSample = TEXT(" (8x Multisample)"); break;
1410: case D3DMULTISAMPLE_9_SAMPLES: pstrMultiSample = TEXT(" (9x Multisample)"); break;
1411: case D3DMULTISAMPLE_10_SAMPLES: pstrMultiSample = TEXT(" (10x Multisample)"); break;
1412: case D3DMULTISAMPLE_11_SAMPLES: pstrMultiSample = TEXT(" (11x Multisample)"); break;
1413: case D3DMULTISAMPLE_12_SAMPLES: pstrMultiSample = TEXT(" (12x Multisample)"); break;
1414: case D3DMULTISAMPLE_13_SAMPLES: pstrMultiSample = TEXT(" (13x Multisample)"); break;
1415: case D3DMULTISAMPLE_14_SAMPLES: pstrMultiSample = TEXT(" (14x Multisample)"); break;
1416: case D3DMULTISAMPLE_15_SAMPLES: pstrMultiSample = TEXT(" (15x Multisample)"); break;
1417: case D3DMULTISAMPLE_16_SAMPLES: pstrMultiSample = TEXT(" (16x Multisample)"); break;
1418: default: pstrMultiSample = TEXT(""); break;
1419: }
1420:
1421: const int cchMaxFrameStats = sizeof(m_strFrameStats) / sizeof(TCHAR);
1422: _sntprintf( m_strFrameStats, cchMaxFrameStats, _T("%.02f fps (%dx%d), %s%s%s"), m_fFPS,
1423: m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height,
1424: strFmt, strDepthFmt, pstrMultiSample );
1425: m_strFrameStats[cchMaxFrameStats - 1] = TEXT('\0');
1426: }
1427: }
1428:
1429:
1430:
1431:
1432:
1433:
1434:
1435:
1436: void CD3DApplication::Pause( bool bPause )
1437: {
1438: static DWORD dwAppPausedCount = 0;
1439:
1440: dwAppPausedCount += ( bPause ? +1 : -1 );
1441: m_bActive = ( dwAppPausedCount ? false : true );
1442:
1443:
1444: if( bPause && ( 1 == dwAppPausedCount ) )
1445: {
1446:
1447: if( m_bFrameMoving )
1448: DXUtil_Timer( TIMER_STOP );
1449: }
1450:
1451: if( 0 == dwAppPausedCount )
1452: {
1453:
1454: if( m_bFrameMoving )
1455: DXUtil_Timer( TIMER_START );
1456: }
1457: }
1458:
1459:
1460:
1461:
1462:
1463:
1464:
1465:
1466: void CD3DApplication::Cleanup3DEnvironment()
1467: {
1468: if( m_pd3dDevice != NULL )
1469: {
1470: if( m_bDeviceObjectsRestored )
1471: {
1472: m_bDeviceObjectsRestored = false;
1473: InvalidateDeviceObjects();
1474: }
1475: if( m_bDeviceObjectsInited )
1476: {
1477: m_bDeviceObjectsInited = false;
1478: DeleteDeviceObjects();
1479: }
1480:
1481: if( m_pd3dDevice->Release() > 0 )
1482: DisplayErrorMsg( D3DAPPERR_NONZEROREFCOUNT, MSGERR_APPMUSTEXIT );
1483: m_pd3dDevice = NULL;
1484: }
1485: }
1486:
1487:
1488:
1489:
1490:
1491:
1492:
1493:
1494: HRESULT CD3DApplication::DisplayErrorMsg( HRESULT hr, DWORD dwType )
1495: {
1496: static bool s_bFatalErrorReported = false;
1497: TCHAR strMsg[512];
1498:
1499:
1500:
1501: if( s_bFatalErrorReported )
1502: return hr;
1503:
1504: switch( hr )
1505: {
1506: case D3DAPPERR_NODIRECT3D:
1507: _tcscpy( strMsg, _T("Could not initialize Direct3D. You may\n")
1508: _T("want to check that the latest version of\n")
1509: _T("DirectX is correctly installed on your\n")
1510: _T("system. Also make sure that this program\n")
1511: _T("was compiled with header files that match\n")
1512: _T("the installed DirectX DLLs.") );
1513: break;
1514:
1515: case D3DAPPERR_NOCOMPATIBLEDEVICES:
1516: _tcscpy( strMsg, _T("Could not find any compatible Direct3D\n")
1517: _T("devices.") );
1518: break;
1519:
1520: case D3DAPPERR_NOWINDOWABLEDEVICES:
1521: _tcscpy( strMsg, _T("This sample cannot run in a desktop\n")
1522: _T("window with the current display settings.\n")
1523: _T("Please change your desktop settings to a\n")
1524: _T("16- or 32-bit display mode and re-run this\n")
1525: _T("sample.") );
1526: break;
1527:
1528: case D3DAPPERR_NOHARDWAREDEVICE:
1529: _tcscpy( strMsg, _T("No hardware-accelerated Direct3D devices\n")
1530: _T("were found.") );
1531: break;
1532:
1533: case D3DAPPERR_HALNOTCOMPATIBLE:
1534: _tcscpy( strMsg, _T("This sample requires functionality that is\n")
1535: _T("not available on your Direct3D hardware\n")
1536: _T("accelerator.") );
1537: break;
1538:
1539: case D3DAPPERR_NOWINDOWEDHAL:
1540: _tcscpy( strMsg, _T("Your Direct3D hardware accelerator cannot\n")
1541: _T("render into a window.\n")
1542: _T("Press F2 while the app is running to see a\n")
1543: _T("list of available devices and modes.") );
1544: break;
1545:
1546: case D3DAPPERR_NODESKTOPHAL:
1547: _tcscpy( strMsg, _T("Your Direct3D hardware accelerator cannot\n")
1548: _T("render into a window with the current\n")
1549: _T("desktop display settings.\n")
1550: _T("Press F2 while the app is running to see a\n")
1551: _T("list of available devices and modes.") );
1552: break;
1553:
1554: case D3DAPPERR_NOHALTHISMODE:
1555: _tcscpy( strMsg, _T("This sample requires functionality that is\n")
1556: _T("not available on your Direct3D hardware\n")
1557: _T("accelerator with the current desktop display\n")
1558: _T("settings.\n")
1559: _T("Press F2 while the app is running to see a\n")
1560: _T("list of available devices and modes.") );
1561: break;
1562:
1563: case D3DAPPERR_MEDIANOTFOUND:
1564: case HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ):
1565: _tcscpy( strMsg, _T("Could not load required media." ) );
1566: break;
1567:
1568: case D3DAPPERR_RESETFAILED:
1569: _tcscpy( strMsg, _T("Could not reset the Direct3D device." ) );
1570: break;
1571:
1572: case D3DAPPERR_NONZEROREFCOUNT:
1573: _tcscpy( strMsg, _T("A D3D object has a non-zero reference\n")
1574: _T("count (meaning things were not properly\n")
1575: _T("cleaned up).") );
1576: break;
1577:
1578: case D3DAPPERR_NULLREFDEVICE:
1579: _tcscpy( strMsg, _T("Warning: Nothing will be rendered.\n")
1580: _T("The reference rendering device was selected, but your\n")
1581: _T("computer only has a reduced-functionality reference device\n")
1582: _T("installed. Install the DirectX SDK to get the full\n")
1583: _T("reference device.\n") );
1584: break;
1585:
1586: case E_OUTOFMEMORY:
1587: _tcscpy( strMsg, _T("Not enough memory.") );
1588: break;
1589:
1590: case D3DERR_OUTOFVIDEOMEMORY:
1591: _tcscpy( strMsg, _T("Not enough video memory.") );
1592: break;
1593:
1594: default:
1595: _tcscpy( strMsg, _T("Generic application error. Enable\n")
1596: _T("debug output for detailed information.") );
1597: }
1598:
1599: if( MSGERR_APPMUSTEXIT == dwType )
1600: {
1601: s_bFatalErrorReported = true;
1602: _tcscat( strMsg, _T("\n\nThis sample will now exit.") );
1603: MessageBox( NULL, strMsg, m_strWindowTitle, MB_ICONERROR|MB_OK );
1604:
1605:
1606: if( m_hWnd )
1607: SendMessage( m_hWnd, WM_CLOSE, 0, 0 );
1608: }
1609: else
1610: {
1611: if( MSGWARN_SWITCHEDTOREF == dwType )
1612: _tcscat( strMsg, _T("\n\nSwitching to the reference rasterizer,\n")
1613: _T("a software device that implements the entire\n")
1614: _T("Direct3D feature set, but runs very slowly.") );
1615: MessageBox( NULL, strMsg, m_strWindowTitle, MB_ICONWARNING|MB_OK );
1616: }
1617:
1618: return hr;
1619: }
1620: