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

📄 d3dapplication.cpp

📁 java实现的简单的分形树。简单易学!是学习分形知识的很好的例子。其java语法简单
💻 CPP
📖 第 1 页 / 共 4 页
字号:

void CD3DApplication::close()
{
	// Unflag screensaver running if in full on mode
	if( mSSMode == SM_FULL ) {
		BOOL bUnused;
		SystemParametersInfo( SPI_SCREENSAVERRUNNING, FALSE, &bUnused, 0 );
	}

	cleanup3DEnvironment();
	safeRelease( mD3D );
	shutdown();

	// Unload the password DLL (if we loaded it)
	if( mSSPasswordDLL != NULL ) {
		FreeLibrary( mSSPasswordDLL );
		mSSPasswordDLL = NULL;
	}
}

void CD3DApplication::doClose()
{
	PostMessage( mHWnd, WM_CLOSE, 0, 0 );
}

/** Reset the device if the client area size has changed. */
HRESULT CD3DApplication::handlePossibleSizeChange()
{
	HRESULT hr = S_OK;
	RECT clientOld;
	clientOld = mWindowClient;
	
	if( mIgnoreSizeChange )
		return S_OK;
	
	// update window properties
	GetWindowRect( mHWnd, &mWindowBounds );
	GetClientRect( mHWnd, &mWindowClient );
	
	if( clientOld.right - clientOld.left != mWindowClient.right - mWindowClient.left ||
		clientOld.bottom - clientOld.top != mWindowClient.bottom - mWindowClient.top )
	{
		// A new window size will require a new backbuffer
		// size, so the 3D structures must be changed accordingly.
		pause( true );
		
		mPresentParams.BackBufferWidth  = mWindowClient.right - mWindowClient.left;
		mPresentParams.BackBufferHeight = mWindowClient.bottom - mWindowClient.top;
		
		if( mD3DDevice != NULL ) {
			// Reset the 3D environment
			if( FAILED( hr = reset3DEnvironment() ) ) {
				if( hr != D3DERR_OUTOFVIDEOMEMORY )
					hr = (HRESULT)RESETFAILED;
				displayErrorMsg( hr, APPMUSTEXIT );
			}
		}
		pause( false );
	}
	return hr;
}



HRESULT CD3DApplication::initialize3DEnvironment()
{
	HRESULT hr;

	mSSMouseMoveCount = 0;
	
	const SD3DAdapterInfo& adInfo = mSettings.getAdapterInfo();
	const SD3DDeviceInfo& devInfo = mSettings.getDeviceInfo();
	
	mWindowed = (mSettings.mMode == CD3DSettings::WINDOWED);
	
	// Prepare window for possible windowed/fullscreen change
	adjustWindowForChange();
	
	// Set up the presentation parameters
	bool okparams = buildPresentParamsFromSettings();
	if( !okparams )
		return CANTTOGGLEFULLSCREEN;
	
	if( devInfo.caps.PrimitiveMiscCaps & D3DPMISCCAPS_NULLREFERENCE ) {
		// Warn user about null ref device that can't render anything
		displayErrorMsg( (HRESULT)NULLREFDEVICE, NONE );
	}
	
	DWORD behaviorFlags;
	if( mSettings.getVertexProcessing() == SOFTWARE_VP )
		behaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
	else if( mSettings.getVertexProcessing() == MIXED_VP )
		behaviorFlags = D3DCREATE_MIXED_VERTEXPROCESSING;
	else if( mSettings.getVertexProcessing() == HARDWARE_VP )
		behaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else if( mSettings.getVertexProcessing() == PURE_HARDWARE_VP )
		behaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
	else
		behaviorFlags = 0; // TODO: throw exception
	
	// Araz:
	behaviorFlags |= D3DCREATE_FPU_PRESERVE;
	behaviorFlags |= D3DCREATE_MULTITHREADED;
	
	// create the device
	hr = mD3D->CreateDevice(
		mSettings.getAdapterOrdinal(), devInfo.deviceType,
		mHWndFocus, behaviorFlags, &mPresentParams,
		&mD3DDevice );
	
	if( SUCCEEDED(hr) ) {
		// When moving from fullscreen to windowed mode, it is important to
		// adjust the window size after recreating the device rather than
		// beforehand to ensure that you get the window size you want.	For
		// example, when switching from 640x480 fullscreen to windowed with
		// a 1000x600 window on a 1024x768 desktop, it is impossible to set
		// the window size to 1000x600 until after the display mode has
		// changed to 1024x768, because windows cannot be larger than the
		// desktop.
		if( mWindowed ) {
			SetWindowPos( mHWnd, HWND_NOTOPMOST,
				mWindowBounds.left, mWindowBounds.top,
				( mWindowBounds.right - mWindowBounds.left ),
				( mWindowBounds.bottom - mWindowBounds.top ),
				SWP_SHOWWINDOW );
		}
		
		// Store device Caps
		mD3DDevice->GetDeviceCaps( &mD3DCaps );
		mCreateFlags = behaviorFlags;
		
		// Store device description
		if( devInfo.deviceType == D3DDEVTYPE_REF )
			lstrcpy( mDeviceStats, TEXT("REF") );
		else if( devInfo.deviceType == D3DDEVTYPE_HAL )
			lstrcpy( mDeviceStats, TEXT("HAL") );
		else if( devInfo.deviceType == D3DDEVTYPE_SW )
			lstrcpy( mDeviceStats, TEXT("SW") );
		
		if( behaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING && behaviorFlags & D3DCREATE_PUREDEVICE ) {
			if( devInfo.deviceType == D3DDEVTYPE_HAL )
				lstrcat( mDeviceStats, TEXT(" (pure hw vp)") );
			else
				lstrcat( mDeviceStats, TEXT(" (simulated pure hw vp)") );
		} else if( behaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING ) {
			if( devInfo.deviceType == D3DDEVTYPE_HAL )
				lstrcat( mDeviceStats, TEXT(" (hw vp)") );
			else
				lstrcat( mDeviceStats, TEXT(" (simulated hw vp)") );
		} else if( behaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING ) {
			if( devInfo.deviceType == D3DDEVTYPE_HAL )
				lstrcat( mDeviceStats, TEXT(" (mixed vp)") );
			else
				lstrcat( mDeviceStats, TEXT(" (simulated mixed vp)") );
		} else if( behaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING ) {
			lstrcat( mDeviceStats, TEXT(" (sw vp)") );
		}
		
		if( devInfo.deviceType == D3DDEVTYPE_HAL ) {
			// Be sure not to overflow mDeviceStats when appending the adapter 
			// description, since it can be long.  Note that the adapter description
			// is initially CHAR and must be converted to TCHAR.
			lstrcat( mDeviceStats, TEXT(": ") );
			const int cchDesc = sizeof(adInfo.adapterID.Description);
			TCHAR szDescription[cchDesc];
			dingus::convertAnsiStringToGenericCch( szDescription, 
				adInfo.adapterID.Description, cchDesc );
			int maxAppend = sizeof(mDeviceStats) / sizeof(TCHAR) -
				lstrlen( mDeviceStats ) - 1;
			_tcsncat( mDeviceStats, szDescription, maxAppend );
		}
		
		// Store render target surface desc
		IDirect3DSurface9* backBuffer = NULL;
		mD3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer );
		backBuffer->GetDesc( &mBackBuffer );
		backBuffer->Release();
		
		// Set up the fullscreen cursor
		if( mShowCursorWhenFullscreen && !mWindowed ) {
			HCURSOR hCursor;
#ifdef _WIN64
			hCursor = (HCURSOR)GetClassLongPtr( mHWnd, GCLP_HCURSOR );
#else
			hCursor = (HCURSOR)ULongToHandle( GetClassLong( mHWnd, GCL_HCURSOR ) );
#endif
			dingus::setDeviceCursor( *mD3DDevice, hCursor );
			mD3DDevice->ShowCursor( true );
		}
		
		// Confine cursor to fullscreen window
		if( mClipCursorWhenFullscreen ) {
			if( !mWindowed ) {
				RECT rcWindow;
				GetWindowRect( mHWnd, &rcWindow );
				ClipCursor( &rcWindow );
			} else {
				ClipCursor( NULL );
			}
		}
		
		mSSMouseMoveCount = 0; // make sure all changes don't count as mouse moves

		// Initialize the app's device-dependent objects
		hr = createDeviceObjects();
		if( FAILED(hr) ) {
			deleteDeviceObjects();
		} else {
			mDeviceObjectsInited = true;
			hr = activateDeviceObjects();
			if( FAILED(hr) ) {
				passivateDeviceObjects();
			} else {
				mDeviceObjectsRestored = true;
				return S_OK;
			}
		}
		
		// Cleanup before we try again
		cleanup3DEnvironment();
	}
	
	// If that failed, fall back to the reference rasterizer
	if( hr != MEDIANOTFOUND && 
		hr != HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) && 
		devInfo.deviceType == D3DDEVTYPE_HAL )
	{
		if( findBestWindowedMode( false, true ) ) {
			mWindowed = true;
			adjustWindowForChange();
			// Make sure main window isn't topmost, so error message is visible
			SetWindowPos( mHWnd, HWND_NOTOPMOST,
				mWindowBounds.left, mWindowBounds.top,
				( mWindowBounds.right - mWindowBounds.left ),
				( mWindowBounds.bottom - mWindowBounds.top ),
				SWP_SHOWWINDOW );
			
			// Let the user know we are switching from HAL to the reference rasterizer
			displayErrorMsg( hr, SWITCHEDTOREF );
			
			hr = initialize3DEnvironment();
			
			mSSMouseMoveCount = 0; // make sure all changes don't count as mouse moves
		}
	}
	return hr;
}


bool CD3DApplication::buildPresentParamsFromSettings()
{
	if( &mSettings.getDeviceCombo() == NULL )
		return false;

	mPresentParams.Windowed				= (mSettings.mMode == CD3DSettings::WINDOWED);
	mPresentParams.BackBufferCount		= 1;
	mPresentParams.MultiSampleType		= mSettings.getMultiSampleType();
	mPresentParams.MultiSampleQuality	= mSettings.getMultiSampleQuality();
	mPresentParams.SwapEffect			= D3DSWAPEFFECT_DISCARD;
	mPresentParams.EnableAutoDepthStencil = mEnumeration.mUsesDepthBuffer;
	mPresentParams.hDeviceWindow		= mHWnd;
	if( mEnumeration.mUsesDepthBuffer ) {
		//mPresentParams.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
		mPresentParams.Flags = 0;
		mPresentParams.AutoDepthStencilFormat = mSettings.getDepthStencilFormat();
	} else {
		mPresentParams.Flags = 0;
	}
	
	if( mWindowed ) {
		mPresentParams.BackBufferWidth  = mWindowClient.right - mWindowClient.left;
		mPresentParams.BackBufferHeight = mWindowClient.bottom - mWindowClient.top;
		mPresentParams.BackBufferFormat = mSettings.getDeviceCombo().backBufferFormat;
		mPresentParams.FullScreen_RefreshRateInHz = 0;
		mPresentParams.PresentationInterval = mSettings.getPresentInterval();
	} else {
		mPresentParams.BackBufferWidth  = mSettings.getDisplayMode().Width;
		mPresentParams.BackBufferHeight = mSettings.getDisplayMode().Height;
		mPresentParams.BackBufferFormat = mSettings.getDeviceCombo().backBufferFormat;
		mPresentParams.FullScreen_RefreshRateInHz = mSettings.getDisplayMode().RefreshRate;
		mPresentParams.PresentationInterval = mSettings.getPresentInterval();
	}
	return true;
}


HRESULT CD3DApplication::reset3DEnvironment()
{
	HRESULT hr;
	
	// Release all vidmem objects
	if( mDeviceObjectsRestored ) {
		mDeviceObjectsRestored = false;
		passivateDeviceObjects();
	}
	// Reset the device
	if( FAILED( hr = mD3DDevice->Reset( &mPresentParams ) ) )
		return hr;
	
	// Store render target surface desc
	IDirect3DSurface9* backBuffer;
	mD3DDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &backBuffer );
	backBuffer->GetDesc( &mBackBuffer );
	backBuffer->Release();
	
	// Set up the fullscreen cursor
	if( mShowCursorWhenFullscreen && !mWindowed ) {
		HCURSOR hCursor;
#ifdef _WIN64
		hCursor = (HCURSOR)GetClassLongPtr( mHWnd, GCLP_HCURSOR );
#else
		hCursor = (HCURSOR)ULongToHandle( GetClassLong( mHWnd, GCL_HCURSOR ) );
#endif
		dingus::setDeviceCursor( *mD3DDevice, hCursor );
		mD3DDevice->ShowCursor( true );
	}
	
	// Confine cursor to fullscreen window
	if( mClipCursorWhenFullscreen ) {
		if( !mWindowed ) {
			RECT rcWindow;
			GetWindowRect( mHWnd, &rcWindow );
			ClipCursor( &rcWindow );
		} else {
			ClipCursor( NULL );
		}
	}
	
	// Initialize the app's device-dependent objects
	hr = activateDeviceObjects();
	if( FAILED(hr) ) {
		passivateDeviceObjects();
		return hr;
	}
	mDeviceObjectsRestored = true;
	
	// If the app is paused, trigger the rendering of the current frame
	if( !mFrameMoving ) {
		mSingleStep = true;
		dingus::timer( TIMER_START );
		dingus::timer( TIMER_STOP );
	}
	
	return S_OK;
}


/** Called when user toggles between fullscreen mode and windowed mode. */
HRESULT CD3DApplication::toggleFullscreen()
{
	HRESULT hr;
	int adOrdinalOld = mSettings.getAdapterOrdinal();
	D3DDEVTYPE devTypeOld = mSettings.getDevType();
	
	pause( true );
	mIgnoreSizeChange = true;
	
	// Toggle the windowed state
	mWindowed = !mWindowed;
	mSettings.mMode = (mSettings.mMode==CD3DSettings::WINDOWED) ? (CD3DSettings::FULLSCREEN) : (CD3DSettings::WINDOWED);
	
	// Prepare window for windowed/fullscreen change
	adjustWindowForChange();
	
	// If adapterOrdinal and deviceType are the same, we can just do a Reset().
	// If they've changed, we need to do a complete device teardown/rebuild.
	if( mSettings.getAdapterOrdinal() == adOrdinalOld && mSettings.getDevType() == devTypeOld ) {
		// Reset the 3D device
		bool okparams = buildPresentParamsFromSettings();
		if( okparams )
			hr = reset3DEnvironment();
		else
			hr = CANTTOGGLEFULLSCREEN;
	} else {
		cleanup3DEnvironment();
		hr = initialize3DEnvironment();
	}
	
	if( FAILED( hr ) ) {
		if( hr != D3DERR_OUTOFVIDEOMEMORY )
			hr = RESETFAILED;
		mIgnoreSizeChange = false;
		if( !mWindowed ) {
			// Restore window type to windowed mode
			mWindowed = !mWindowed;
			mSettings.mMode = CD3DSettings::WINDOWED;
			adjustWindowForChange();
			SetWindowPos( mHWnd, HWND_NOTOPMOST,
				mWindowBounds.left, mWindowBounds.top,
				( mWindowBounds.right - mWindowBounds.left ),
				( mWindowBounds.bottom - mWindowBounds.top ),
				SWP_SHOWWINDOW );
		}
		return displayErrorMsg( hr, APPMUSTEXIT );
	}
	
	mIgnoreSizeChange = false;
	
	// When moving from fullscreen to windowed mode, it is important to
	// adjust the window size after resetting the device rather than
	// beforehand to ensure that you get the window size you want.	For
	// example, when switching from 640x480 fullscreen to windowed with
	// a 1000x600 window on a 1024x768 desktop, it is impossible to set
	// the window size to 1000x600 until after the display mode has
	// changed to 1024x768, because windows cannot be larger than the
	// desktop.
	if( mWindowed ) {
		SetWindowPos( mHWnd, HWND_NOTOPMOST,
			mWindowBounds.left, mWindowBounds.top,
			( mWindowBounds.right - mWindowBounds.left ),
			( mWindowBounds.bottom - mWindowBounds.top ),
			SWP_SHOWWINDOW );
	}
	
	pause( false );
	return S_OK;
}


/** Switch to a windowed mode, even if that means picking a new device and/or adapter. */
HRESULT CD3DApplication::forceWindowed()
{
	HRESULT hr;
	
	if( mWindowed )
		return S_OK;
	
	if( !findBestWindowedMode( false, false ) )
		return E_FAIL;

	mWindowed = true;
	
	// Now destroy the current 3D device objects, then reinitialize
	
	pause( true );
	
	// Release all scene objects that will be re-created for the new device
	cleanup3DEnvironment();
	
	// create the new device
	if( FAILED(hr = initialize3DEnvironment() ) )
		return displayErrorMsg( hr, APPMUSTEXIT );
	
	pause( false );
	return S_OK;
}


/**
 *  Prepare the window for a possible change between windowed mode and fullscreen
 *  mode. This function is virtual and thus can be overridden to provide
 *  different behavior, such as switching to an entirely different window for
 *  fullscreen mode (as in the MFC sample apps).
 */
HRESULT CD3DApplication::adjustWindowForChange()
{
	if( mWindowed ) {
		// Set windowed-mode style
		SetWindowLong( mHWnd, GWL_STYLE, mWindowStyle );
		if( mHMenu != NULL ) {
			SetMenu( mHWnd, mHMenu );
			mHMenu = NULL;
		}
	} else {
		// Set fullscreen-mode style
		SetWindowLong( mHWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE );
		if( mHMenu == NULL ) {
			mHMenu = GetMenu( mHWnd );
			SetMenu( mHWnd, NULL );
		}
	}
	return S_OK;
}


/**
 *  Displays a dialog so the user can select a new adapter, device, or
 *  display mode, and then recreates the 3D environment if needed
 */
HRESULT CD3DApplication::userSelectNewDevice()
{
	HRESULT hr;
	
	// Can't display dialogs in fullscreen mode
	if( mWindowed == false ) {
		if( FAILED( toggleFullscreen() ) ) {

⌨️ 快捷键说明

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