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

📄 d3dapplication.cpp

📁 java实现的简单的分形树。简单易学!是学习分形知识的很好的例子。其java语法简单
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// --------------------------------------------------------------------------
// Dingus project - a collection of subsystems for game/graphics applications
// --------------------------------------------------------------------------
#include "stdafx.h"

#include <windowsx.h>
#include "D3DApplication.h"
#include "DXUtil.h"
#include "D3DUtil.h"
#include "resource.h"
#include <regstr.h>

using namespace dingus;


//---------------------------------------------------------------------------
// global access to the app (needed for the global gWndProc)

static CD3DApplication* gD3DApp = NULL;

//---------------------------------------------------------------------------
// Static msg handler which passes messages to the application class.

LRESULT CALLBACK gWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	return gD3DApp->msgProc( hWnd, uMsg, wParam, lParam );
}


//---------------------------------------------------------------------------
// CD3DApplication
//---------------------------------------------------------------------------

CD3DApplication::CD3DApplication()
:	mD3D(NULL), mD3DDevice(NULL),
	mHWnd(NULL), mHWndFocus(NULL), mHMenu(NULL),
	mWindowed(true), mActive(false), mDeviceLost(false),
	mMinimized(false), mMaximized(false), mIgnoreSizeChange(false),
	mDeviceObjectsInited(false), mDeviceObjectsRestored(false),
	mCreateFlags(0),
	mFrameMoving(true), mSingleStep(false),
	mTime(0.0), mElapsedTime(0.0), mFPS(0.0f),
	mWindowTitle( _T("D3D9 Application")),
	mCreationWidth(400),
	mCreationHeight(300),
	mShowCursorWhenFullscreen(false), mStartFullscreen(false), mVSyncFullscreen(true),
	mSelectDeviceAtStartup(false),
	mDebugTimer(false),

	mSSInStartingPause(false),
	mSSCheckingPassword(false),
	mSSIsWin9x(false),
	mSSMouseMoveCount(0),
	mSSHwndParent(0), mSSPasswordDLL(0), mSSVerifyPasswordProc(0)
{
	gD3DApp 		  = this;
	
	mDeviceStats[0] = _T('\0');
	mFrameStats[0]	= _T('\0');
	mSSRegistryPath[0] = _T('\0');
	
	pause( true ); // pause until we're ready to render
	
	// When mClipCursorWhenFullscreen is true, the cursor is limited to
	// the device window when the app goes fullscreen.	This prevents users
	// from accidentally clicking outside the app window on a multimon system.
	// This flag is turned off by default for debug builds, since it makes 
	// multimon debugging difficult.
#if defined(_DEBUG) || defined(DEBUG)
	mClipCursorWhenFullscreen = false;
#else
	mClipCursorWhenFullscreen = true;
#endif
}



/**
 *  Static function used by D3DEnumeration
 */
bool CD3DApplication::checkDeviceHelper( const D3DCAPS9& caps, eVertexProcessing vertexProc, D3DFORMAT backBufferFormat )
{
	DWORD behavior;
	if( vertexProc == SOFTWARE_VP )
		behavior = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
	else if( vertexProc == MIXED_VP )
		behavior = D3DCREATE_MIXED_VERTEXPROCESSING;
	else if( vertexProc == HARDWARE_VP )
		behavior = D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else if( vertexProc == PURE_HARDWARE_VP )
		behavior = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
	else
		behavior = 0; // TODO: throw exception
	
	return SUCCEEDED( gD3DApp->checkDevice( caps, behavior, backBufferFormat ) );
}


HRESULT CD3DApplication::create( HINSTANCE hInstance, bool screenSaverMode )
{
	HRESULT hr;

	// if we're screensaver - set low priority and parse cmd line
	if( screenSaverMode ) {
		SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_IDLE );
		mSSMode = ssParseCmdLine( GetCommandLine() );
		// force windowed in preview mode
		if( mSSMode == SM_PREVIEW )
			mStartFullscreen = false;
	} else {
		mSSMode = SM_NONE;
		mSSHwndParent = NULL;
	}
	
	mHInstance = hInstance;
	
	//
	// setup d3d object, enumerate possible options, etc.

	// create the Direct3D object
	mD3D = Direct3DCreate9( D3D_SDK_VERSION );
	if( mD3D == NULL )
		return displayErrorMsg( (HRESULT)NODIRECT3D, APPMUSTEXIT );
	
	// Build a list of Direct3D adapters, modes and devices. The
	// checkDevice() callback is used to confirm that only devices that
	// meet the app's requirements are considered.
	mEnumeration.setDirect3D( *mD3D );
	mEnumeration.mConfirmDeviceCallback = checkDeviceHelper;

	if( FAILED( hr = mEnumeration.enumerate() ) ) {
		safeRelease( mD3D );
		return displayErrorMsg( hr, APPMUSTEXIT );
	}

	if( FAILED( hr = chooseInitialD3DSettings() ) ) {
		safeRelease( mD3D );
		return displayErrorMsg( hr, APPMUSTEXIT );
	}
	
	//
	// manage screensaver running modes

	switch( mSSMode ) {
	case SM_CONFIG:
		ssDoConfig();
		safeRelease( mD3D );
		return S_OK;
		break;
	case SM_PASSCHANGE:
		ssChangePassword();
		safeRelease( mD3D );
		return S_OK;
		break;
	}

	
	// force no dialog at startup if we're screensaver
	if( mSSMode != SM_NONE )
		mSelectDeviceAtStartup = false;

	if( mSelectDeviceAtStartup ) {
		bool ok = justShowSettingsDialog();
		if( !ok ) {
			safeRelease( mD3D );
			if( mHWnd )
				SendMessage( mHWnd, WM_CLOSE, 0, 0 );
			return E_FAIL;
		}
	}

	//
	// create main window

	// Unless a substitute hWnd has been specified, create a window to
	// render into, OR
	// do the needed thing if we're screensaver
	if( mSSMode==SM_NONE && mHWnd == NULL ||
		(mSSMode==SM_PREVIEW || mSSMode==SM_TEST || mSSMode==SM_FULL) )
	{
		// Register the windows class
		WNDCLASS wndClass = { 0, gWndProc, 0, 0, hInstance,
			LoadIcon( hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON) ),
			LoadCursor( NULL, IDC_ARROW ),
			(HBRUSH)GetStockObject(WHITE_BRUSH),
			NULL, _T("D3D Window")
		};
		// TBD - need this?
		//if( screenSaverMode )
		//	wndClass.style = CS_VREDRAW | CS_HREDRAW;
		RegisterClass( &wndClass );
		
		// Set the window's initial style and size
		RECT rc;
		if( mSSMode==SM_PREVIEW ) {
			GetClientRect( mSSHwndParent, &rc );
			mWindowStyle = WS_VISIBLE | WS_CHILD;
			AdjustWindowRect( &rc, mWindowStyle, false );
			// create the render window
			mHWnd = CreateWindow( _T("D3D Window"), mWindowTitle, mWindowStyle,
				CW_USEDEFAULT, CW_USEDEFAULT,
				(rc.right-rc.left), (rc.bottom-rc.top), mSSHwndParent,
				NULL, hInstance, 0 );
		} else {
			mWindowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | 
				WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE;
			SetRect( &rc, 0, 0, mCreationWidth, mCreationHeight );
			AdjustWindowRect( &rc, mWindowStyle, true );
			// create the render window
			mHWnd = CreateWindow( _T("D3D Window"), mWindowTitle, mWindowStyle,
				CW_USEDEFAULT, CW_USEDEFAULT,
				(rc.right-rc.left), (rc.bottom-rc.top), NULL,
				LoadMenu( hInstance, MAKEINTRESOURCE(IDR_MENU) ),
				hInstance, 0 );
		}
	}
	
	// The focus window can be a specified to be a different window than the
	// device window. If not, use the device window as the focus window.
	if( mHWndFocus == NULL )
		mHWndFocus = mHWnd;
	
	// Save window properties
	mWindowStyle = GetWindowLong( mHWnd, GWL_STYLE );
	GetWindowRect( mHWnd, &mWindowBounds );
	GetClientRect( mHWnd, &mWindowClient );

	// In screensaver preview mode, "pause" (enter a limited message loop)
	// briefly before proceeding, so the display control panel knows to
	// update itself.
	if( mSSMode == SM_PREVIEW ) {
		mSSInStartingPause = true;
		// Post a message to mark the end of the initial group of window messages
		PostMessage( mHWnd, WM_USER, 0, 0 );
		MSG msg;
		while( mSSInStartingPause ) {
			if( !GetMessage( &msg, mHWnd, 0, 0 ) ) {
				PostQuitMessage(0);
				break;
			}
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
	}

	// read SS settings
	if( mSSMode != SM_NONE )
		ssReadSettings();
	
	
	// Initialize the application timer
	dingus::timer( TIMER_START );
	
	// Initialize the app
	if( FAILED( hr = initialize() ) ) {
		safeRelease( mD3D );
		return displayErrorMsg( hr, APPMUSTEXIT );
	}
	
	// Initialize the 3D environment for the app
	if( FAILED( hr = initialize3DEnvironment() ) ) {
		safeRelease( mD3D );
		return displayErrorMsg( hr, APPMUSTEXIT );
	}
	
	// The app is ready to go
	pause( false );
	
	return S_OK;
}



/**
 *  Sets up mSettings with best available windowed mode, subject to the
 *  requireHAL and requireREF constraints. Returns false if no such mode
 *  can be found.
 */
bool CD3DApplication::findBestWindowedMode( bool requireHAL, bool requireREF )
{
	// Get display mode of primary adapter (which is assumed to be where the
	// window will appear)
	D3DDISPLAYMODE primaryDesktopDM;
	mD3D->GetAdapterDisplayMode( 0, &primaryDesktopDM );
	
	const SD3DAdapterInfo* bestAdapterInfo = NULL;
	const SD3DDeviceInfo* bestDeviceInfo = NULL;
	const SD3DDeviceCombo* bestDeviceCombo = NULL;
	
	for( int iai = 0; iai < mEnumeration.mAdapterInfos.size(); ++iai ) {
		const SD3DAdapterInfo* adInfo = mEnumeration.mAdapterInfos[iai];
		for( int idi = 0; idi < adInfo->deviceInfos.size(); ++idi ) {
			const SD3DDeviceInfo* devInfo = adInfo->deviceInfos[idi];
			if( requireHAL && devInfo->deviceType != D3DDEVTYPE_HAL )
				continue;
			if( requireREF && devInfo->deviceType != D3DDEVTYPE_REF )
				continue;
			for( int idc = 0; idc < devInfo->deviceCombos.size(); ++idc ) {
				const SD3DDeviceCombo* devCombo = devInfo->deviceCombos[idc];
				bool matchesBB = (devCombo->backBufferFormat == devCombo->adapterFormat);
				if( !devCombo->isWindowed )
					continue;
				if( devCombo->adapterFormat != primaryDesktopDM.Format )
					continue;
				// If we haven't found a compatible DeviceCombo yet, or if
				// this set is better (because it's a HAL, and/or because
				// formats match better), save it
				if( !bestDeviceCombo || 
					bestDeviceCombo->deviceType != D3DDEVTYPE_HAL && devCombo->deviceType == D3DDEVTYPE_HAL ||
					devCombo->deviceType == D3DDEVTYPE_HAL && matchesBB )
				{
					bestAdapterInfo = adInfo;
					bestDeviceInfo = devInfo;
					bestDeviceCombo = devCombo;
					if( devCombo->deviceType == D3DDEVTYPE_HAL && matchesBB ) {
						// This windowed device combo looks great -- take it
						goto _endComboSearch;
					}
					// Otherwise keep looking for better combo
				}
			}
		}
	}

_endComboSearch:
	CD3DSettings::SSettings& settings = mSettings.mSettings[CD3DSettings::WINDOWED];
	if( bestDeviceCombo == NULL ) {
		settings.adapterInfo = NULL;
		settings.deviceInfo = NULL;
		settings.deviceCombo = NULL;
		return false;
	}
	
	mSettings.mMode = CD3DSettings::WINDOWED;
	settings.adapterInfo = bestAdapterInfo;
	settings.deviceInfo = bestDeviceInfo;
	settings.deviceCombo = bestDeviceCombo;
	settings.displayMode = primaryDesktopDM;
	mSettings.mWindowedWidth = mWindowClient.right - mWindowClient.left;
	mSettings.mWindowedHeight = mWindowClient.bottom - mWindowClient.top;
	if( mEnumeration.mUsesDepthBuffer )
		settings.depthStencilFormat = (D3DFORMAT)bestDeviceCombo->depthStencilFormats[0];
	settings.multisampleType = (D3DMULTISAMPLE_TYPE)bestDeviceCombo->multiSampleTypes[0];
	settings.multisampleQuality = 0;
	settings.vertexProcessing = (eVertexProcessing)bestDeviceCombo->vertexProcessings[0];
	settings.presentInterval = bestDeviceCombo->presentIntervals[0];
	return true;
}


/**
 *  Sets up mSettings with best available fullscreen mode, subject to the
 *  requireHAL and requireREF constraints. Returns false if no such
 *  mode can be found.
 */
bool CD3DApplication::findBestFullscreenMode( bool requireHAL, bool requireREF )
{
	// For fullscreen, default to first HAL DeviceCombo that supports the
	// current desktop display mode, or any display mode if HAL is not
	// compatible with the desktop mode, or non-HAL if no HAL is available
	D3DDISPLAYMODE adapterDesktopDM;
	D3DDISPLAYMODE bestAdapterDesktopDM;
	D3DDISPLAYMODE bestDM;
	bestAdapterDesktopDM.Width = 0;
	bestAdapterDesktopDM.Height = 0;
	bestAdapterDesktopDM.Format = D3DFMT_UNKNOWN;
	bestAdapterDesktopDM.RefreshRate = 0;
	
	const SD3DAdapterInfo* bestAdapterInfo = NULL;
	const SD3DDeviceInfo* bestDeviceInfo = NULL;
	const SD3DDeviceCombo* bestDeviceCombo = NULL;
	
	for( int iai = 0; iai < mEnumeration.mAdapterInfos.size(); ++iai ) {
		const SD3DAdapterInfo* adInfo = mEnumeration.mAdapterInfos[iai];
		mD3D->GetAdapterDisplayMode( adInfo->adapterOrdinal, &adapterDesktopDM );
		for( int idi = 0; idi < adInfo->deviceInfos.size(); ++idi ) {
			const SD3DDeviceInfo* devInfo = adInfo->deviceInfos[idi];
			if( requireHAL && devInfo->deviceType != D3DDEVTYPE_HAL )
				continue;
			if( requireREF && devInfo->deviceType != D3DDEVTYPE_REF )
				continue;
			for( int idc = 0; idc < devInfo->deviceCombos.size(); ++idc ) {
				const SD3DDeviceCombo* devCombo = devInfo->deviceCombos[idc];
				bool matchesBB = (devCombo->backBufferFormat == devCombo->adapterFormat);
				bool matchesDesktop = (devCombo->adapterFormat == adapterDesktopDM.Format);
				if( devCombo->isWindowed )
					continue;
				// If we haven't found a compatible set yet, or if this set
				// is better (because it's a HAL, and/or because formats match
				// better), save it
				if( !bestDeviceCombo ||
					bestDeviceCombo->deviceType != D3DDEVTYPE_HAL && devInfo->deviceType == D3DDEVTYPE_HAL ||
					devCombo->deviceType == D3DDEVTYPE_HAL && bestDeviceCombo->adapterFormat != adapterDesktopDM.Format && matchesDesktop ||
					devCombo->deviceType == D3DDEVTYPE_HAL && matchesDesktop && matchesBB )
				{
					bestAdapterDesktopDM = adapterDesktopDM;
					bestAdapterInfo = adInfo;
					bestDeviceInfo = devInfo;
					bestDeviceCombo = devCombo;
					if( devInfo->deviceType == D3DDEVTYPE_HAL && matchesDesktop && matchesBB )
					{
						// This fullscreen device combo looks great -- take it
						goto _endComboSearch;
					}
					// Otherwise keep looking for a better combo
				}
			}
		}
	}
_endComboSearch:
	CD3DSettings::SSettings& settings = mSettings.mSettings[CD3DSettings::FULLSCREEN];
	if( bestDeviceCombo == NULL ) {
		settings.adapterInfo = NULL;
		settings.deviceInfo = NULL;
		settings.deviceCombo = NULL;
		return false;
	}
	
	// Need to find a display mode on the best adapter that uses
	// bestDeviceCombo->adapterFormat and is as close to bestAdapterDesktopDM's
	// res as possible
	bestDM.Width = 0;
	bestDM.Height = 0;
	bestDM.Format = D3DFMT_UNKNOWN;
	bestDM.RefreshRate = 0;
	for( int idm = 0; idm < bestAdapterInfo->displayModes.size(); ++idm ) {
		const D3DDISPLAYMODE& pdm = bestAdapterInfo->displayModes[idm];
		if( pdm.Format != bestDeviceCombo->adapterFormat )
			continue;
		if( pdm.Width == bestAdapterDesktopDM.Width &&
			pdm.Height == bestAdapterDesktopDM.Height && 
			pdm.RefreshRate == bestAdapterDesktopDM.RefreshRate )
		{
			// found a perfect match, so stop
			bestDM = pdm;
			break;
		} else if( pdm.Width == bestAdapterDesktopDM.Width &&
			pdm.Height == bestAdapterDesktopDM.Height && 
			pdm.RefreshRate > bestDM.RefreshRate )
		{
			// refresh rate doesn't match, but width/height match, so keep this
			// and keep looking
			bestDM = pdm;
		} else if( pdm.Width == bestAdapterDesktopDM.Width ) {
			// width matches, so keep this and keep looking
			bestDM = pdm;
		} else if( bestDM.Width == 0 ) {
			// we don't have anything better yet, so keep this and keep looking
			bestDM = pdm;
		}
	}
	
	mSettings.mMode = CD3DSettings::FULLSCREEN;

	settings.adapterInfo = bestAdapterInfo;
	settings.deviceInfo = bestDeviceInfo;
	settings.deviceCombo = bestDeviceCombo;
	settings.displayMode = bestDM;
	if( mEnumeration.mUsesDepthBuffer )
		settings.depthStencilFormat = (D3DFORMAT)bestDeviceCombo->depthStencilFormats[0];
	settings.multisampleType = (D3DMULTISAMPLE_TYPE)bestDeviceCombo->multiSampleTypes[0];
	settings.multisampleQuality = 0;
	settings.vertexProcessing = (eVertexProcessing)bestDeviceCombo->vertexProcessings[0];
	settings.presentInterval = mVSyncFullscreen ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;

	return true;
}


HRESULT CD3DApplication::chooseInitialD3DSettings()
{
	bool foundFullscreen = findBestFullscreenMode( false, false );
	bool foundWindowed = findBestWindowedMode( false, false );
	
	if( (mStartFullscreen || !foundWindowed || mSSMode==SM_FULL) && foundFullscreen )
		mSettings.mMode = CD3DSettings::FULLSCREEN;

	if( !foundFullscreen && (!foundWindowed || mSSMode==SM_FULL) )
		return (HRESULT)NOCOMPATIBLEDEVICES;
	
	return S_OK;
}

void CD3DApplication::ssReadSettings()
{
	// TBD

⌨️ 快捷键说明

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