⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d3dapplication.cpp

📁 java实现的简单的分形树。简单易学!是学习分形知识的很好的例子。其java语法简单
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			displayErrorMsg( RESETFAILED, APPMUSTEXIT );
			return E_FAIL;
		}
	}
	
	bool dlgok = justShowSettingsDialog();
	if( !dlgok )
		return S_OK;
	
	// Release all scene objects that will be re-created for the new device
	cleanup3DEnvironment();
	
	// Inform the display class of the change. It will internally
	// re-create valid surfaces, a d3ddevice, etc.
	if( FAILED( hr = initialize3DEnvironment() ) ) {
		if( hr != D3DERR_OUTOFVIDEOMEMORY )
			hr = RESETFAILED;
		if( !mWindowed ) {
			// Restore window type to windowed mode
			mWindowed = !mWindowed;
			mSettings.mMode = mWindowed ? (CD3DSettings::WINDOWED) : (CD3DSettings::FULLSCREEN);
			adjustWindowForChange();
			SetWindowPos( mHWnd, HWND_NOTOPMOST,
				mWindowBounds.left, mWindowBounds.top,
				( mWindowBounds.right - mWindowBounds.left ),
				( mWindowBounds.bottom - mWindowBounds.top ),
				SWP_SHOWWINDOW );
		}
		return displayErrorMsg( hr, APPMUSTEXIT );
	}
	
	// If the app is paused, trigger the rendering of the current frame
	if( false == mFrameMoving ) {
		mSingleStep = true;
		dingus::timer( TIMER_START );
		dingus::timer( TIMER_STOP );
	}
	return S_OK;
}

bool CD3DApplication::justShowSettingsDialog()
{
	CD3DSettingsDialog settingsDialog( mEnumeration, mSettings );
	if( settingsDialog.showDialog( mHInstance, mHWnd, *this ) != IDOK )
		return false;
	settingsDialog.getFinalSettings( mSettings );
	mWindowed = (mSettings.mMode == CD3DSettings::WINDOWED);
	return true;
}


int CD3DApplication::run()
{
	// First manage screensaver running modes
	if( mSSMode == SM_CONFIG || mSSMode == SM_PASSCHANGE )
		return 0; // done already

	//
	// some stuff for screensavers

	// Figure out if we're on Win9x
	OSVERSIONINFO osvi; 
	osvi.dwOSVersionInfoSize = sizeof(osvi);
	GetVersionEx( &osvi );
	mSSIsWin9x = (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);

	// If we're in full mode, and on 9x, then need to load the password DLL
	if( mSSMode == SM_FULL && mSSIsWin9x ) {
		// Only do this if the password is set - check registry:
		HKEY hKey; 
		if( RegCreateKeyEx( HKEY_CURRENT_USER, REGSTR_PATH_SCREENSAVE, 0, NULL, 0, KEY_READ, NULL, &hKey, NULL ) == ERROR_SUCCESS ) { 
			DWORD dwVal;
			DWORD dwSize = sizeof(dwVal); 
			if ( (RegQueryValueEx( hKey, REGSTR_VALUE_USESCRPASSWORD, NULL, NULL,
				(BYTE*)&dwVal, &dwSize ) == ERROR_SUCCESS) && dwVal ) 
			{ 
				mSSPasswordDLL = LoadLibrary( TEXT("PASSWORD.CPL") );
				if( mSSPasswordDLL )
					mSSVerifyPasswordProc = (SSVERIFYPASSWORDPROC)GetProcAddress( mSSPasswordDLL, "VerifyScreenSavePwd" );
				RegCloseKey( hKey );
			}
		}
	}

	// Flag as screensaver running if in full on mode
	if( mSSMode == SM_FULL ) {
		bool bUnused;
		SystemParametersInfo( SPI_SCREENSAVERRUNNING, TRUE, &bUnused, 0 );
	}
	

	//
	// message pump

	// Load keyboard accelerators
	HACCEL hAccel = LoadAccelerators( NULL, MAKEINTRESOURCE(IDR_MAIN_ACCEL) );
	
	// Now we're ready to recieve and process Windows messages.
	bool gotMsg;
	MSG  msg;
	msg.message = WM_NULL;
	PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );
	
	while( WM_QUIT != msg.message ) {
		// Use PeekMessage() if the app is active, so we can use idle time to
		// render the scene. Else, use GetMessage() to avoid eating CPU time.
		if( mActive )
			gotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );
		else
			gotMsg = ( GetMessage( &msg, NULL, 0U, 0U ) != 0 );
		
		if( gotMsg ) {
			// Translate and dispatch the message
			if( hAccel == NULL || mHWnd == NULL ||  0 == TranslateAccelerator( mHWnd, hAccel, &msg ) ) {
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
		} else {
			if( mDeviceLost ) {
				// Yield some CPU time to other processes
				Sleep( 100 ); // 100 milliseconds
			}
			// render a frame during idle time (no messages are waiting)
			if( mActive ) {
				// some sleep if in screensaver mode
				if( mSSMode == SM_FULL || mSSMode == SM_PREVIEW )
					Sleep( 2 );
				if( FAILED( render3DEnvironment() ) )
					SendMessage( mHWnd, WM_CLOSE, 0, 0 );
			}
		}
	}
	if( hAccel != NULL )
		DestroyAcceleratorTable( hAccel );
	
	return (INT)msg.wParam;
}


/** Draws the scene. */
HRESULT CD3DApplication::render3DEnvironment()
{
	HRESULT hr;

	if( mDeviceLost ) {
		// Test the cooperative level to see if it's okay to render
		if( FAILED( hr = mD3DDevice->TestCooperativeLevel() ) ) {
			// If the device was lost, do not render until we get it back
			if( D3DERR_DEVICELOST == hr )
				return S_OK;
			
			// Check if the device needs to be reset.
			if( D3DERR_DEVICENOTRESET == hr ) {
				// If we are windowed, read the desktop mode and use the same
				// format for the back buffer
				if( mWindowed ) {
					const SD3DAdapterInfo& adInfo = mSettings.getAdapterInfo();
					mD3D->GetAdapterDisplayMode( adInfo.adapterOrdinal, &mSettings.getDisplayMode() );
					mPresentParams.BackBufferFormat = mSettings.getDisplayMode().Format;
				}
				
				if( FAILED( hr = reset3DEnvironment() ) )
					return hr;
			}
			return hr;
		}
		mDeviceLost = false;
	}
	
	// Timer
	// For debugging - so we get reproducable behaviour
	if( mDebugTimer ) {
		mElapsedTime = 1.0f / 60.0f; // emulate 60FPS
		mTime += mElapsedTime;
	} else {
		double appTime		= dingus::timer( TIMER_GETAPPTIME );
		double elapsedTime	= dingus::timer( TIMER_GETELAPSEDTIME );
		mTime		 = appTime;
		mElapsedTime = elapsedTime;
	}
	
	// perform
	if( FAILED( hr = performOneTime() ) )
		return hr;

	mSingleStep = false;
	
	updateStats();
	
	// Show the frame on the primary surface.
	hr = mD3DDevice->Present( NULL, NULL, NULL, NULL );
	if( D3DERR_DEVICELOST == hr )
		mDeviceLost = true;
	
	return S_OK;
}



void CD3DApplication::updateStats()
{
	// Keep track of the frame count
	static double lastTime = 0.0f;
	static int frameCount  = 0;
	double time = dingus::timer( TIMER_GETABSOLUTETIME );
	++frameCount;
	
	// Update the scene stats once per second
	if( time - lastTime > 1.0 ) {
		mFPS = (float)(frameCount / (time - lastTime));
		lastTime = time;
		frameCount = 0;
		
		TCHAR strFmt[100];
		D3DFORMAT fmtAdapter = mSettings.getDisplayMode().Format;
		if( fmtAdapter == mBackBuffer.Format ) {
			lstrcpyn( strFmt, dingus::convertD3DFormatToString( fmtAdapter ), 100 );
		} else {
			_sntprintf( strFmt, 100, TEXT("backbuf %s, adapter %s"), 
				dingus::convertD3DFormatToString( mBackBuffer.Format ), 
				dingus::convertD3DFormatToString( fmtAdapter ) );
		}
		strFmt[99] = TEXT('\0');
		
		TCHAR strDepthFmt[100];
		if( mEnumeration.mUsesDepthBuffer ) {
			_sntprintf( strDepthFmt, 100, TEXT(" (%s)"), 
				dingus::convertD3DFormatToString( mSettings.getDepthStencilFormat() ) );
			strDepthFmt[99] = TEXT('\0');
		} else {
			// No depth buffer
			strDepthFmt[0] = TEXT('\0');
		}
		
		TCHAR* pstrMultiSample;
		switch( mSettings.getMultiSampleType() ) {
		case D3DMULTISAMPLE_NONMASKABLE:  pstrMultiSample = TEXT(" (Nonmaskable Multisample)"); break;
		case D3DMULTISAMPLE_2_SAMPLES:	pstrMultiSample = TEXT(" (2x Multisample)"); break;
		case D3DMULTISAMPLE_3_SAMPLES:	pstrMultiSample = TEXT(" (3x Multisample)"); break;
		case D3DMULTISAMPLE_4_SAMPLES:	pstrMultiSample = TEXT(" (4x Multisample)"); break;
		case D3DMULTISAMPLE_5_SAMPLES:	pstrMultiSample = TEXT(" (5x Multisample)"); break;
		case D3DMULTISAMPLE_6_SAMPLES:	pstrMultiSample = TEXT(" (6x Multisample)"); break;
		case D3DMULTISAMPLE_7_SAMPLES:	pstrMultiSample = TEXT(" (7x Multisample)"); break;
		case D3DMULTISAMPLE_8_SAMPLES:	pstrMultiSample = TEXT(" (8x Multisample)"); break;
		case D3DMULTISAMPLE_9_SAMPLES:	pstrMultiSample = TEXT(" (9x Multisample)"); break;
		case D3DMULTISAMPLE_10_SAMPLES: pstrMultiSample = TEXT(" (10x Multisample)"); break;
		case D3DMULTISAMPLE_11_SAMPLES: pstrMultiSample = TEXT(" (11x Multisample)"); break;
		case D3DMULTISAMPLE_12_SAMPLES: pstrMultiSample = TEXT(" (12x Multisample)"); break;
		case D3DMULTISAMPLE_13_SAMPLES: pstrMultiSample = TEXT(" (13x Multisample)"); break;
		case D3DMULTISAMPLE_14_SAMPLES: pstrMultiSample = TEXT(" (14x Multisample)"); break;
		case D3DMULTISAMPLE_15_SAMPLES: pstrMultiSample = TEXT(" (15x Multisample)"); break;
		case D3DMULTISAMPLE_16_SAMPLES: pstrMultiSample = TEXT(" (16x Multisample)"); break;
		default:						pstrMultiSample = TEXT(""); break;
		}
		
		const int cchMaxFrameStats = sizeof(mFrameStats) / sizeof(TCHAR);
		_sntprintf( mFrameStats, cchMaxFrameStats, _T("%.02f fps (%dx%d), %s%s%s"), mFPS,
			mBackBuffer.Width, mBackBuffer.Height,
			strFmt, strDepthFmt, pstrMultiSample );
		mFrameStats[cchMaxFrameStats - 1] = TEXT('\0');
	}
}

/** Called in to toggle the pause state of the app. */
void CD3DApplication::pause( bool pause )
{
	static DWORD pausedCount = 0;
	
	pausedCount += (pause ? +1 : -1);
	mActive = (pausedCount ? false : true);
	
	// Handle the first pause request (of many, nestable pause requests)
	if( pause && ( 1 == pausedCount ) ) {
		// Stop the scene from animating
		if( mFrameMoving )
			dingus::timer( TIMER_STOP );
	}
	
	if( 0 == pausedCount ) {
		// Restart the timers
		if( mFrameMoving )
			dingus::timer( TIMER_START );
	}
}


/** Cleanup scene objects. */
void CD3DApplication::cleanup3DEnvironment()
{
	if( mD3DDevice != NULL ) {
		if( mDeviceObjectsRestored ) {
			mDeviceObjectsRestored = false;
			passivateDeviceObjects();
		}
		if( mDeviceObjectsInited ) {
			mDeviceObjectsInited = false;
			deleteDeviceObjects();
		}
		
		if( mD3DDevice->Release() > 0 )
			displayErrorMsg( NONZEROREFCOUNT, APPMUSTEXIT );
		mD3DDevice = NULL;
	}
}



void CD3DApplication::ssChangePassword()
{
	// Load the password change DLL
	HINSTANCE mpr = LoadLibrary( TEXT("MPR.DLL") );
	if( mpr != NULL ) {
		// Grab the password change function from it
		typedef DWORD (PASCAL *PWCHGPROC)( LPCSTR, HWND, DWORD, LPVOID );
		PWCHGPROC pwd = (PWCHGPROC)GetProcAddress( mpr, "PwdChangePasswordA" );
		// Do the password change
		if ( pwd != NULL )
			pwd( "SCRSAVE", mSSHwndParent, 0, NULL );
		// Free the library
		FreeLibrary( mpr );
	}
}



/** Displays error messages in a message box. */
HRESULT CD3DApplication::displayErrorMsg( HRESULT hr, eAppMsg type )
{
	static bool fatalErrorReported = false;
	TCHAR strMsg[512];
	
	// If a fatal error message has already been reported, the app
	// is already shutting down, so don't show more error messages.
	if( fatalErrorReported )
		return hr;
	
	switch( hr ) {
	case CANTTOGGLEFULLSCREEN:
		_tcscpy( strMsg,
			_T("Could not toggle fullscreen mode.\n")
			_T("Your Direct3D device or desktop settings\n")
			_T("might not support required video mode.\n")
			_T("Try increasing desktop bit depth.\n") );
		break;

	case NODIRECT3D:
		_tcscpy( strMsg,
			_T("Could not initialize Direct3D. You may\n")
			_T("want to check that the latest version of\n")
			_T("DirectX is correctly installed on your\n")
			_T("system.  Also make sure that this program\n")
			_T("was compiled with header files that match\n")
			_T("the installed DirectX DLLs.") );
		break;
		
	case NOCOMPATIBLEDEVICES:
		_tcscpy( strMsg,
			_T("Could not find any compatible Direct3D\n")
			_T("devices.") );
		break;
		
	case NOWINDOWABLEDEVICES:
		_tcscpy( strMsg,
			_T("This program cannot run in a desktop\n")
			_T("window with the current display settings.\n")
			_T("Please change your desktop settings to a\n")
			_T("16- or 32-bit display mode and re-run this\n")
			_T("program.") );
		break;
		
	case NOHARDWAREDEVICE:
		_tcscpy( strMsg,
			_T("No hardware-accelerated Direct3D devices\n")
			_T("were found.") );
		break;
		
	case HALNOTCOMPATIBLE:
		_tcscpy( strMsg,
			_T("This program requires functionality that is\n")
			_T("not available on your Direct3D hardware\n")
			_T("accelerator.") );
		break;
		
	case NOWINDOWEDHAL:
		_tcscpy( strMsg,
			_T("Your Direct3D hardware accelerator cannot\n")
			_T("render into a window.\n")
			_T("Press F2 while the app is running to see a\n")
			_T("list of available devices and modes.") );
		break;
		
	case NODESKTOPHAL:
		_tcscpy( strMsg,
			_T("Your Direct3D hardware accelerator cannot\n")
			_T("render into a window with the current\n")
			_T("desktop display settings.\n")
			_T("Press F2 while the app is running to see a\n")
			_T("list of available devices and modes.") );
		break;
		
	case NOHALTHISMODE:
		_tcscpy( strMsg,
			_T("This program requires functionality that is\n")
			_T("not available on your Direct3D hardware\n")
			_T("accelerator with the current desktop display\n")
			_T("settings.\n")
			_T("Press F2 while the app is running to see a\n")
			_T("list of available devices and modes.") );
		break;
		
	case MEDIANOTFOUND:
	case HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ):
		_tcscpy( strMsg, _T("Could not load required media." ) );
		break;
		
	case RESETFAILED:
		_tcscpy( strMsg, _T("Could not reset the Direct3D device." ) );
		break;
		
	case NONZEROREFCOUNT:
		_tcscpy( strMsg,
			_T("A D3D object has a non-zero reference\n")
			_T("count (meaning things were not properly\n")
			_T("cleaned up).") );
		break;
		
	case NULLREFDEVICE:
		_tcscpy( strMsg,
			_T("Warning: Nothing will be rendered.\n")
			_T("The reference rendering device was selected, but your\n")
			_T("computer only has a reduced-functionality reference device\n")
			_T("installed.  Install the DirectX SDK to get the full\n")
			_T("reference device.\n") );
		break;
		
	case E_OUTOFMEMORY:
		_tcscpy( strMsg, _T("Not enough memory.") );
		break;
		
	case D3DERR_OUTOFVIDEOMEMORY:
		_tcscpy( strMsg, _T("Not enough video memory.") );
		break;
		
	default:
		_tcscpy( strMsg,
			_T("Generic application error. Enable\n")
			_T("debug output for detailed information.") );
	}
	
	if( APPMUSTEXIT == type ) {
		fatalErrorReported = true;
		_tcscat( strMsg, _T("\n\nThis program will now exit.") );
		MessageBox( NULL, strMsg, mWindowTitle, MB_ICONERROR|MB_OK );
		
		// Close the window, which shuts down the app
		if( mHWnd )
			SendMessage( mHWnd, WM_CLOSE, 0, 0 );
	} else {
		if( SWITCHEDTOREF == type )
			_tcscat( strMsg,
			_T("\n\nSwitching to the reference rasterizer,\n")
			_T("a software device that implements the entire\n")
			_T("Direct3D feature set, but runs very slowly.") );
		MessageBox( NULL, strMsg, mWindowTitle, MB_ICONWARNING|MB_OK );
	}
	
	return hr;
}


// --------------------------------------------------------------------------

static INT_PTR CALLBACK gScreenSettingsDlgProcStub( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	// TBD
	//return gD3DApp->ssScreenSettingsDlgProc( hwnd, msg, wParam, lParam );
}

void CD3DApplication::ssScreenSettingsDlg( HWND hwndParent )
{
	// TBD
	//LPCTSTR pstrTemplate = MAKEINTRESOURCE( IDD_SINGLEMONITORSETTINGS );
	//DialogBox(mInstance, pstrTemplate, hwndParent, screenSettingsDlgProcStub );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -