www.pudn.com > IntroductionTo3DGameEngineDesign.rar > oldD3DApp.cs


//----------------------------------------------------------------------------- 
// File: D3DApp.cs 
// 
// Desc: Application class for the Direct3D samples framework library. 
// 
// Copyright (c) 2001-2002 Microsoft Corporation. All rights reserved. 
//----------------------------------------------------------------------------- 
using System; 
using Microsoft.DirectX; 
using Microsoft.DirectX.Direct3D; 
using Direct3D=Microsoft.DirectX.Direct3D; 
 
#region Enums for D3D Applications 
public enum AppMsgType  
{  
	None,  
	ErrorAppMustExit,  
	WarnSwitchToRef 
}; 
 
#endregion 
 
public class GraphicsException : System.Exception 
{ 
	private ErrorCode resultCode = ErrorCode.Generic; 
	public enum ErrorCode 
	{ 
		Generic, 
		NoDirect3D, 
		NoWindow, 
		NoCompatibleDevices, 
		NoWindowableDevices, 
		NoHardwareDevice, 
		HalNotCompatible, 
		NoWindowedHal, 
		NoDesktopHal, 
		NoHalThisMode, 
		MediaNotFound, 
		ResizeFailed, 
		NullRefDevice, 
	} 
	public GraphicsException(){} 
	public GraphicsException(ErrorCode code) 
	{ 
		resultCode = code; 
	} 
	public override string Message {  
		get  
		{  
			string strMsg = null; 
 
			switch( resultCode ) 
			{ 
				case ErrorCode.NoDirect3D: 
					strMsg = "Could not initialize Direct3D. You may\n"; 
					strMsg += "want to check that the latest version of\n"; 
					strMsg += "DirectX is correctly installed on your\n"; 
					strMsg += "system.  Also make sure that this program\n"; 
					strMsg += "was compiled with header files that match\n"; 
					strMsg += "the installed DirectX DLLs."; 
					break; 
 
				case ErrorCode.NoCompatibleDevices: 
					strMsg = "Could not find any compatible Direct3D\ndevices."; 
					break; 
 
				case ErrorCode.NoWindowableDevices: 
					strMsg = "This sample cannot run in a desktop\n"; 
					strMsg += "window with the current display settings.\n"; 
					strMsg += "Please change your desktop settings to a\n"; 
					strMsg += "16- or 32-bit display mode and re-run this\n"; 
					strMsg += "sample."; 
					break; 
 
				case ErrorCode.NoHardwareDevice: 
					strMsg = "No hariare-accelerated Direct3D devices\n"; 
					strMsg += "were found."; 
					break; 
 
				case ErrorCode.HalNotCompatible: 
					strMsg = "This sample requires functionality that is\n"; 
					strMsg += "not available on your Direct3D hariare\n"; 
					strMsg += "accelerator."; 
					break; 
 
				case ErrorCode.NoWindowedHal: 
					strMsg = "Your Direct3D hariare accelerator cannot\n"; 
					strMsg += "render into a window.\n"; 
					strMsg += "Press F2 while the app is running to see a\n"; 
					strMsg += "list of available devices and modes."; 
					break; 
 
				case ErrorCode.NoDesktopHal: 
					strMsg = "Your Direct3D hariare accelerator cannot\n"; 
					strMsg += "render into a window with the current\n"; 
					strMsg += "desktop display settings.\n"; 
					strMsg += "Press F2 while the app is running to see a\n"; 
					strMsg += "list of available devices and modes."; 
					break; 
 
				case ErrorCode.NoHalThisMode: 
					strMsg = "This sample requires functionality that is\n"; 
					strMsg += "not available on your Direct3D hariare\n"; 
					strMsg += "accelerator with the current desktop display\n"; 
					strMsg += "settings.\n"; 
					strMsg += "Press F2 while the app is running to see a\n"; 
					strMsg += "list of available devices and modes."; 
					break; 
 
				case ErrorCode.MediaNotFound: 
					strMsg = "Could not load required media."; 
					break; 
 
				case ErrorCode.ResizeFailed: 
					strMsg = "Could not reset the Direct3D device."; 
					break; 
 
				case ErrorCode.NullRefDevice: 
					strMsg = "Warning: Nothing will be rendered.\n"; 
					strMsg += "The reference rendering device was selected, but your\n"; 
					strMsg += "computer only has a reduced-functionality reference device\n"; 
					strMsg += "installed.  Install the DirectX SDK to get the full\n"; 
					strMsg += "reference device.\n"; 
					break; 
 
				case (ErrorCode)Direct3D.ErrorCode.OutOfVidMemory: 
					strMsg = "Not enough video memory."; 
					break; 
 
				default: 
					strMsg = "Generic application error. Enable\n"; 
					strMsg += "debug output for detailed information."; 
					break; 
 
			} 
			return strMsg; 
		}  
	} 
} 
public class GraphicsSample : System.Windows.Forms.Form, IDisposable 
{ 
	// Menu information 
	protected System.Windows.Forms.MainMenu mnuMain; 
	protected System.Windows.Forms.MenuItem mnuFile; 
	private System.Windows.Forms.MenuItem mnuGo; 
	private System.Windows.Forms.MenuItem mnuSingle; 
	private System.Windows.Forms.MenuItem mnuBreak1; 
	private System.Windows.Forms.MenuItem mnuChange; 
	private System.Windows.Forms.MenuItem mnuBreak2; 
	private System.Windows.Forms.MenuItem mnuExit; 
 
	//----------------------------------------------------------------------------- 
	// Global access to the app (needed for the global WndProc()) 
	//----------------------------------------------------------------------------- 
	public static GraphicsSample ourSample = null; 
	public bool m_bTerminate = false; 
 
	protected D3DEnumeration enumerationSettings = new D3DEnumeration(); 
	protected D3DSettings graphicsSettings = new D3DSettings(); 
	private bool isDisposed = false; 
 
	private float lastTime = 0.0f; 
	private uint frames  = 0; 
	private uint appPausedCount = 0; 
 
	// Internal variables for the state of the app 
	protected bool windowed; 
	protected bool active; 
	protected bool ready; 
	protected bool hasFocus; 
 
	// Internal variables used for timing 
	protected bool frameMoving; 
	protected bool singleStep; 
	// Main objects used for creating and rendering the 3D scene 
	protected PresentParameters presentParams = new PresentParameters();         // Parameters for CreateDevice/Reset 
	protected D3D graphicsObject;              // The main D3D object 
	protected Device device;        // The D3D rendering device 
	protected RenderStates renderState; 
	protected SamplerStates sampleState; 
	protected TextureStates textureStates; 
	private Caps graphicsCaps;           // Caps for the device 
	protected Caps Caps { get { return graphicsCaps; } } 
	private SurfaceDescription backBufferDesc;   // Surface desc of the backbuffer 
	public SurfaceDescription backBuffer { get { return backBufferDesc; } } 
	private CreateFlags behavior;     // Indicate sw or hw vertex processing 
	protected BehaviorFlags BehaviorFlags { get { return new BehaviorFlags(behavior); } } 
	protected System.Drawing.Rectangle windowBoundsRect;    // Saved window bounds for mode switches 
	protected System.Drawing.Rectangle clientRect;    // Saved client area size for mode switches 
 
	// Variables for timing 
	protected float appTime;             // Current time in seconds 
	protected float elapsedTime;      // Time elapsed since last frame 
	protected float framePerSecond;              // Instanteous frame rate 
	protected string deviceStats;// String to hold D3D device stats 
	protected string frameStats; // String to hold frame stats 
 
	private bool deviceLost = false; 
 
	// Overridable variables for the app 
	protected string windowTitle;    // Title for the app's window 
	private int minDepthBits;    // Minimum number of bits needed in depth buffer 
	protected int MinDepthBits { get { return minDepthBits; } set { minDepthBits = value;  enumerationSettings.AppMinDepthBits = value;} } 
	private int minStencilBits;  // Minimum number of bits needed in stencil buffer 
	protected int MinStencilBits { get { return minStencilBits; } set { minStencilBits = value;  enumerationSettings.AppMinStencilBits = value;} } 
	protected bool showCursorWhenFullscreen; // Whether to show cursor when fullscreen 
	protected bool clipCursorWhenFullscreen; // Whether to limit cursor pos when fullscreen 
	protected bool startFullscreen; // Whether to start up the app in fullscreen mode 
 
	// Overridable functions for the 3D scene created by the app 
	protected virtual bool ConfirmDevice(Caps caps, VertexProcessingType vertexProcessingType, Format fmt) { return true; } 
	protected virtual void OneTimeSceneInit()                         { /* Do Nothing */ } 
	protected virtual void InitDeviceObjects()                        { /* Do Nothing */ } 
	protected virtual void RestoreDeviceObjects(System.Object sender, System.EventArgs e)                     { /* Do Nothing */ } 
	protected virtual void FrameMove()                                { /* Do Nothing */ } 
	protected virtual void Render()                                   { /* Do Nothing */ } 
	protected virtual void InvalidateDeviceObjects(System.Object sender, System.EventArgs e)                  { /* Do Nothing */ } 
	protected virtual void DeleteDeviceObjects(System.Object sender, System.EventArgs e)                      { /* Do Nothing */ } 
	protected virtual void FinalCleanup()                       { /* Do Nothing */ } 
 
 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: GraphicsSample() 
	// Desc: Constructor 
	//----------------------------------------------------------------------------- 
	public GraphicsSample() 
	{ 
		ourSample = this; 
 
		graphicsObject              = null; 
		device        = null; 
		active           = false; 
		ready            = false; 
		hasFocus		= false; 
		behavior     = 0; 
 
		frameMoving      = true; 
		singleStep       = false; 
		framePerSecond              = 0.0f; 
		deviceStats = null; 
		frameStats  = null; 
 
		this.Text    = "D3D9 Sample"; 
		this.ClientSize = new System.Drawing.Size(800,600); 
		this.KeyPreview = true; 
 
		minDepthBits    = 16; 
		minStencilBits  = 0; 
		showCursorWhenFullscreen = false; 
		startFullscreen = false; 
 
		// When clipCursorWhenFullscreen 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 (DEBUG) 
			clipCursorWhenFullscreen = false; 
		#else 
			clipCursorWhenFullscreen = true; 
		#endif 
		InitializeComponent(); 
	} 
 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: CreateD3DApp() 
	// Desc: 
	//----------------------------------------------------------------------------- 
	public bool CreateD3DApp() 
	{ 
		// Create the Direct3D object 
		graphicsObject = new D3D(); 
		if( graphicsObject == null ) 
		{ 
			DisplayErrorMsg( new GraphicsException(GraphicsException.ErrorCode.NoDirect3D), AppMsgType.ErrorAppMustExit ); 
			return false; 
		} 
 
		enumerationSettings.D3D = graphicsObject; 
		enumerationSettings.ConfirmDeviceCallback = new D3DEnumeration.ConfirmDeviceCallbackType(this.ConfirmDevice); 
		enumerationSettings.Enumerate(); 
 
		if (this.Cursor == null) 
		{ 
			// Set up a default cursor 
			this.Cursor = System.Windows.Forms.Cursors.Default; 
		} 
		// Unless a substitute hWnd has been specified, create a window to 
		// render into 
		this.Menu = mnuMain; 
 
		// Save window properties 
		windowBoundsRect = new System.Drawing.Rectangle(this.Location, this.Size); 
		clientRect = this.ClientRectangle; 
 
		ChooseInitialD3DSettings(); 
 
		// Initialize the application timer 
		DXUtil.Timer( TIMER.START ); 
 
		try 
		{ 
			// Initialize the 3D environment for the app 
			Initialize3DEnvironment(); 
			// Initialize the app's custom scene stuff 
			OneTimeSceneInit(); 
		} 
		catch (GraphicsException d3de) 
		{ 
			DisplayErrorMsg( d3de, AppMsgType.ErrorAppMustExit ); 
			return false; 
		} 
		catch 
		{ 
			return false; 
		} 
 
		// The app is ready to go 
		ready = true; 
 
		return true; 
	} 
 
 
 
	// Sets up graphicsSettings with best available windowed mode, subject to  
	// the bRequireHAL and bRequireREF constraints.  Returns false if no such 
	// mode can be found. 
	public bool FindBestWindowedMode(bool bRequireHAL, bool bRequireREF) 
	{ 
		// Get display mode of primary adapter (which is assumed to be where the window  
		// will appear) 
		DisplayMode primaryDesktopDisplayMode = graphicsObject.Adapters[0].DisplayMode; 
 
		D3DAdapterInfo bestAdapterInfo = null; 
		D3DDeviceInfo bestDeviceInfo = null; 
		D3DDeviceCombo bestDeviceCombo = null; 
 
		foreach (D3DAdapterInfo adapterInfo in enumerationSettings.AdapterInfoList) 
		{ 
			foreach (D3DDeviceInfo deviceInfo in adapterInfo.DeviceInfoList) 
			{ 
				if (bRequireHAL && deviceInfo.DevType != DeviceType.Hardware) 
					continue; 
				if (bRequireREF && deviceInfo.DevType != DeviceType.Reference) 
					continue; 
				foreach (D3DDeviceCombo deviceCombo in deviceInfo.DeviceComboList) 
				{ 
					bool bAdapterMatchesBB = (deviceCombo.BackBufferFormat == deviceCombo.AdapterFormat); 
					if (!deviceCombo.IsWindowed) 
						continue; 
					if (deviceCombo.AdapterFormat != primaryDesktopDisplayMode.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 == null ||  
						bestDeviceCombo.DevType != DeviceType.Hardware && deviceInfo.DevType == DeviceType.Hardware || 
						deviceCombo.DevType == DeviceType.Hardware && bAdapterMatchesBB ) 
					{ 
						bestAdapterInfo = adapterInfo; 
						bestDeviceInfo = deviceInfo; 
						bestDeviceCombo = deviceCombo; 
						if (deviceInfo.DevType == DeviceType.Hardware && bAdapterMatchesBB) 
						{ 
							// This windowed device combo looks great -- take it 
							goto EndWindowedDeviceComboSearch; 
						} 
						// Otherwise keep looking for a better windowed device combo 
					} 
				} 
			} 
		} 
	EndWindowedDeviceComboSearch: 
		if (bestDeviceCombo == null ) 
			return false; 
 
		graphicsSettings.Windowed_AdapterInfo = bestAdapterInfo; 
		graphicsSettings.Windowed_DeviceInfo = bestDeviceInfo; 
		graphicsSettings.Windowed_DeviceCombo = bestDeviceCombo; 
		graphicsSettings.IsWindowed = true; 
		graphicsSettings.Windowed_DisplayMode = primaryDesktopDisplayMode; 
		graphicsSettings.Windowed_Width = clientRect.Right - clientRect.Left; 
		graphicsSettings.Windowed_Height = clientRect.Bottom - clientRect.Top; 
		if (enumerationSettings.AppUsesDepthBuffer) 
			graphicsSettings.Windowed_DepthStencilBufferFormat = (Format)bestDeviceCombo.DepthStencilFormatList[0]; 
		graphicsSettings.Windowed_MultisampleType = (MultiSampleType)bestDeviceCombo.MultiSampleTypeList[0]; 
		graphicsSettings.Windowed_MultisampleQuality = 0; 
		graphicsSettings.Windowed_VertexProcessingType = (VertexProcessingType)bestDeviceCombo.VertexProcessingTypeList[0]; 
		graphicsSettings.Windowed_PresentInterval = (PresentInterval)bestDeviceCombo.PresentIntervalList[0]; 
		return true; 
	} 
 
 
 
 
	// Sets up graphicsSettings with best available fullscreen mode, subject to  
	// the bRequireHAL and bRequireREF constraints.  Returns false if no such 
	// mode can be found. 
	public bool FindBestFullscreenMode(bool bRequireHAL, bool bRequireREF) 
	{ 
		// 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 
		DisplayMode adapterDesktopDisplayMode = new DisplayMode(); 
		DisplayMode bestAdapterDesktopDisplayMode = new DisplayMode(); 
		DisplayMode bestDisplayMode = new DisplayMode(); 
		bestAdapterDesktopDisplayMode.Width = 0; 
		bestAdapterDesktopDisplayMode.Height = 0; 
		bestAdapterDesktopDisplayMode.Format = 0; 
		bestAdapterDesktopDisplayMode.RefreshRate = 0; 
 
		D3DAdapterInfo bestAdapterInfo = null; 
		D3DDeviceInfo bestDeviceInfo = null; 
		D3DDeviceCombo bestDeviceCombo = null; 
 
		foreach (D3DAdapterInfo adapterInfo in enumerationSettings.AdapterInfoList) 
		{ 
			adapterDesktopDisplayMode = graphicsObject.Adapters[adapterInfo.AdapterOrdinal].DisplayMode; 
			foreach (D3DDeviceInfo deviceInfo in adapterInfo.DeviceInfoList) 
			{ 
				if (bRequireHAL && deviceInfo.DevType != DeviceType.Hardware) 
					continue; 
				if (bRequireREF && deviceInfo.DevType != DeviceType.Reference) 
					continue; 
				foreach (D3DDeviceCombo deviceCombo in deviceInfo.DeviceComboList) 
				{ 
					bool bAdapterMatchesBB = (deviceCombo.BackBufferFormat == deviceCombo.AdapterFormat); 
					bool bAdapterMatchesDesktop = (deviceCombo.AdapterFormat == adapterDesktopDisplayMode.Format); 
					if (deviceCombo.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 == null || 
						bestDeviceCombo.DevType != DeviceType.Hardware && deviceInfo.DevType == DeviceType.Hardware || 
						bestDeviceCombo.DevType == DeviceType.Hardware && bestDeviceCombo.AdapterFormat != adapterDesktopDisplayMode.Format && bAdapterMatchesDesktop || 
						bestDeviceCombo.DevType == DeviceType.Hardware && bAdapterMatchesDesktop && bAdapterMatchesBB ) 
					{ 
						bestAdapterDesktopDisplayMode = adapterDesktopDisplayMode; 
						bestAdapterInfo = adapterInfo; 
						bestDeviceInfo = deviceInfo; 
						bestDeviceCombo = deviceCombo; 
						if (deviceInfo.DevType == DeviceType.Hardware && bAdapterMatchesDesktop && bAdapterMatchesBB) 
 
						{ 
							// This fullscreen device combo looks great -- take it 
							goto EndFullscreenDeviceComboSearch; 
						} 
						// Otherwise keep looking for a better fullscreen device combo 
					} 
				} 
			} 
		} 
	EndFullscreenDeviceComboSearch: 
		if (bestDeviceCombo == null) 
			return false; 
 
		// Need to find a display mode on the best adapter that uses pBestDeviceCombo->AdapterFormat 
		// and is as close to bestAdapterDesktopDisplayMode's res as possible 
		bestDisplayMode.Width = 0; 
		bestDisplayMode.Height = 0; 
		bestDisplayMode.Format = 0; 
		bestDisplayMode.RefreshRate = 0; 
		foreach( DisplayMode displayMode in bestAdapterInfo.DisplayModeList ) 
		{ 
			if( displayMode.Format != bestDeviceCombo.AdapterFormat ) 
				continue; 
			if( displayMode.Width == bestAdapterDesktopDisplayMode.Width && 
				displayMode.Height == bestAdapterDesktopDisplayMode.Height &&  
				displayMode.RefreshRate == bestAdapterDesktopDisplayMode.RefreshRate ) 
			{ 
				// found a perfect match, so stop 
				bestDisplayMode = displayMode; 
				break; 
			} 
			else if( displayMode.Width == bestAdapterDesktopDisplayMode.Width && 
				displayMode.Height == bestAdapterDesktopDisplayMode.Height &&  
				displayMode.RefreshRate > bestDisplayMode.RefreshRate ) 
			{ 
				// refresh rate doesn't match, but width/height match, so keep this 
				// and keep looking 
				bestDisplayMode = displayMode; 
			} 
			else if( bestDisplayMode.Width == bestAdapterDesktopDisplayMode.Width ) 
			{ 
				// width matches, so keep this and keep looking 
				bestDisplayMode = displayMode; 
			} 
			else if( bestDisplayMode.Width == 0 ) 
			{ 
				// we don't have anything better yet, so keep this and keep looking 
				bestDisplayMode = displayMode; 
			} 
		} 
		graphicsSettings.Fullscreen_AdapterInfo = bestAdapterInfo; 
		graphicsSettings.Fullscreen_DeviceInfo = bestDeviceInfo; 
		graphicsSettings.Fullscreen_DeviceCombo = bestDeviceCombo; 
		graphicsSettings.IsWindowed = false; 
		graphicsSettings.Fullscreen_DisplayMode = bestDisplayMode; 
		if (enumerationSettings.AppUsesDepthBuffer) 
			graphicsSettings.Fullscreen_DepthStencilBufferFormat = (Format)bestDeviceCombo.DepthStencilFormatList[0]; 
		graphicsSettings.Fullscreen_MultisampleType = (MultiSampleType)bestDeviceCombo.MultiSampleTypeList[0]; 
		graphicsSettings.Fullscreen_MultisampleQuality = 0; 
		graphicsSettings.Fullscreen_VertexProcessingType = (VertexProcessingType)bestDeviceCombo.VertexProcessingTypeList[0]; 
		graphicsSettings.Fullscreen_PresentInterval = (PresentInterval)bestDeviceCombo.PresentIntervalList[0]; 
		return true; 
	} 
 
  
 
 
	public bool ChooseInitialD3DSettings() 
	{ 
		bool bFoundFullscreen = FindBestFullscreenMode(false, false); 
		bool bFoundWindowed = FindBestWindowedMode(false, false); 
		if (startFullscreen && bFoundFullscreen) 
			graphicsSettings.IsWindowed = false; 
		return (bFoundFullscreen || bFoundWindowed); 
	} 
	/* 
//				case WindowMessage.SETCURSOR: 
//					// Turn off Windows cursor in fullscreen mode 
//					if( active && ready && !windowed ) 
//					{ 
//						SetCursor( null ); 
//						if( showCursorWhenFullscreen ) 
//							device.ShowCursor( true ); 
//						return true; // prevent Windows from setting cursor to window class cursor 
//					} 
//					break; 
// 
//				case WindowMessage.MOUSEMOVE: 
//					if( active && ready && device != null ) 
//					{ 
//						Point ptCursor; 
//						GetCursorPos( &ptCursor ); 
//						if( !windowed ) 
//							ScreenToClient( m_hWnd, &ptCursor ); 
//						device.SetCursorPosition( ptCursor.x, ptCursor.y, 0L ); 
//					} 
//					break; 
	*/ 
	public void BuildPresentParamsFromSettings() 
	{ 
		presentParams.Windowed               = graphicsSettings.IsWindowed; 
		presentParams.BackBufferCount        = 1; 
		presentParams.MultiSample        = graphicsSettings.MultisampleType; 
		presentParams.MultiSampleQuality     = graphicsSettings.MultisampleQuality; 
		presentParams.SwapEffect             = SwapEffect.Discard; 
		presentParams.EnableAutoDepthStencil = enumerationSettings.AppUsesDepthBuffer; 
		presentParams.AutoDepthStencilFormat = graphicsSettings.DepthStencilBufferFormat; 
		presentParams.DeviceWindowHandle          = this.Handle; 
		presentParams.Flags                  = 0; 
		if( windowed ) 
		{ 
			presentParams.BackBufferWidth  = clientRect.Right - clientRect.Left; 
			presentParams.BackBufferHeight = clientRect.Bottom - clientRect.Top; 
			presentParams.BackBufferFormat = graphicsSettings.DeviceCombo.BackBufferFormat; 
			presentParams.FullScreenRefreshRateInHz = 0; 
			presentParams.PresentationInterval = PresentInterval.Immediate; 
		} 
		else 
		{ 
			presentParams.BackBufferWidth  = graphicsSettings.DisplayMode.Width; 
			presentParams.BackBufferHeight = graphicsSettings.DisplayMode.Height; 
			presentParams.BackBufferFormat = graphicsSettings.DeviceCombo.BackBufferFormat; 
			presentParams.FullScreenRefreshRateInHz = graphicsSettings.DisplayMode.RefreshRate; 
			presentParams.PresentationInterval = graphicsSettings.PresentInterval; 
		} 
	} 
 
 
	//----------------------------------------------------------------------------- 
	// Name: Initialize3DEnvironment() 
	// Desc: 
	//----------------------------------------------------------------------------- 
	public void Initialize3DEnvironment() 
	{ 
		D3DAdapterInfo adapterInfo = graphicsSettings.AdapterInfo; 
		D3DDeviceInfo deviceInfo = graphicsSettings.DeviceInfo; 
 
		windowed = graphicsSettings.IsWindowed; 
 
		// Prepare window for possible windowed/fullscreen change 
		AdjustWindowForChange(); 
 
		// Set up the presentation parameters 
		BuildPresentParamsFromSettings(); 
 
		if (deviceInfo.Caps.PrimitiveMiscCaps.NullReference ) 
		{ 
			// Warn user about null ref device that can't render anything 
			DisplayErrorMsg( new GraphicsException(GraphicsException.ErrorCode.NullRefDevice), AppMsgType.None ); 
		} 
 
		CreateFlags createFlags = new CreateFlags(); 
		if (graphicsSettings.VertexProcessingType == VertexProcessingType.Software) 
			createFlags = CreateFlags.SoftwareVertexProcessing; 
		else if (graphicsSettings.VertexProcessingType == VertexProcessingType.Mixed) 
			createFlags = CreateFlags.MixedVertexProcessing; 
		else if (graphicsSettings.VertexProcessingType == VertexProcessingType.Hardware) 
			createFlags = CreateFlags.HardwareVertexProcessing; 
		else if (graphicsSettings.VertexProcessingType == VertexProcessingType.PureHardware) 
		{ 
			createFlags = CreateFlags.HardwareVertexProcessing | CreateFlags.PureDevice; 
		} 
		/* 
		else 
			// TODO: throw exception 
		*/ 
		createFlags |= CreateFlags.MultiThreaded; 
 
		// Create the device 
		device = new Device(graphicsObject, graphicsSettings.AdapterOrdinal, graphicsSettings.DevType,  
			this, createFlags, presentParams); 
 
		if( device != null ) 
		{ 
			// Cache our local objects 
			renderState = device.RenderState; 
			sampleState = device.SamplerState; 
			textureStates = device.TextureState; 
			// 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( windowed ) 
			{ 
				// Make sure main window isn't topmost, so error message is visible 
				this.Location = new System.Drawing.Point(windowBoundsRect.Left, windowBoundsRect.Top); 
				this.Size = new System.Drawing.Size(( windowBoundsRect.Right - windowBoundsRect.Left ), ( windowBoundsRect.Bottom - windowBoundsRect.Top)); 
			} 
 
			// Store device Caps 
			graphicsCaps = device.DeviceCaps; 
			behavior = createFlags; 
 
			// Store device description 
			if( deviceInfo.DevType == DeviceType.Reference ) 
				deviceStats = "REF"; 
			else if( deviceInfo.DevType == DeviceType.Hardware ) 
				deviceStats = "HAL"; 
			else if( deviceInfo.DevType == DeviceType.Software ) 
				deviceStats = "SW"; 
 
			BehaviorFlags behaviorFlags = new BehaviorFlags(createFlags); 
			if( (behaviorFlags.HardwareVertexProcessing) &&  
				(behaviorFlags.PureDevice) ) 
			{ 
				if( deviceInfo.DevType == DeviceType.Hardware ) 
					deviceStats += " (pure hw vp)"; 
				else 
					deviceStats += " (simulated pure hw vp)"; 
			} 
			else if( (behaviorFlags.HardwareVertexProcessing) ) 
			{ 
				if( deviceInfo.DevType == DeviceType.Hardware ) 
					deviceStats  += " (hw vp)"; 
				else 
					deviceStats += " (simulated hw vp)"; 
			} 
			else if( behaviorFlags.MixedVertexProcessing) 
			{ 
				if( deviceInfo.DevType == DeviceType.Hardware ) 
					deviceStats += " (mixed vp)"; 
				else 
					deviceStats += " (simulated mixed vp)"; 
			} 
			else if( behaviorFlags.SoftwareVertexProcessing ) 
			{ 
				deviceStats += " (sw vp)"; 
			} 
 
			if( deviceInfo.DevType == DeviceType.Hardware ) 
			{ 
				deviceStats += ": "; 
				deviceStats += adapterInfo.AdapterIdentifier.Description; 
			} 
 
			// Store render target surface desc 
			Surface BackBuffer = device.GetBackBuffer(0,0, BackBufferType.Mono); 
			backBufferDesc = BackBuffer.Description; 
			BackBuffer.Dispose(); 
			BackBuffer = null; 
 
			// Set up the fullscreen cursor 
			if( showCursorWhenFullscreen && !windowed ) 
			{ 
				System.Windows.Forms.Cursor ourCursor = this.Cursor; 
				device.SetCursor(ourCursor.Handle, true); 
				device.ShowCursor(true); 
			} 
 
			// Confine cursor to fullscreen window 
			if( clipCursorWhenFullscreen ) 
			{ 
				if (!windowed ) 
				{ 
					System.Drawing.Rectangle rcWindow = this.ClientRectangle; 
				} 
			} 
 
			// Setup the event handlers for our device 
			device.DeviceLost += new System.EventHandler(this.InvalidateDeviceObjects); 
			device.DeviceReset += new System.EventHandler(this.RestoreDeviceObjects); 
			device.Disposing += new System.EventHandler(this.DeleteDeviceObjects); 
 
 
			// Initialize the app's device-dependent objects 
			try 
			{ 
				InitDeviceObjects(); 
				RestoreDeviceObjects(null, null); 
				active = true; 
				return; 
			} 
			catch 
			{ 
				// Cleanup before we try again 
				InvalidateDeviceObjects(null, null); 
				DeleteDeviceObjects(null, null); 
				device.Dispose(); 
				device = null; 
				if (this.Disposing) 
					return; 
			} 
		} 
 
		// If that failed, fall back to the reference rasterizer 
		if( deviceInfo.DevType == DeviceType.Hardware ) 
		{ 
			if (FindBestWindowedMode(false, true)) 
			{ 
				windowed = true; 
				// Make sure main window isn't topmost, so error message is visible 
				this.Location = new System.Drawing.Point(windowBoundsRect.Left, windowBoundsRect.Top); 
				this.Size = new System.Drawing.Size(( windowBoundsRect.Right - windowBoundsRect.Left ), ( windowBoundsRect.Bottom - windowBoundsRect.Top)); 
				AdjustWindowForChange(); 
 
				// Let the user know we are switching from HAL to the reference rasterizer 
				DisplayErrorMsg( null, AppMsgType.WarnSwitchToRef); 
 
				Initialize3DEnvironment(); 
			} 
		} 
	} 
 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: DisplayErrorMsg() 
	// Desc: Displays error messages in a message box 
	//----------------------------------------------------------------------------- 
	public void DisplayErrorMsg( GraphicsException e, AppMsgType Type ) 
	{ 
		string strMsg = null; 
		if (e != null) 
			strMsg = e.Message; 
 
		if (windowTitle == null) 
			windowTitle = ""; 
 
		if( AppMsgType.ErrorAppMustExit == Type ) 
		{ 
			strMsg  += "\n\nThis sample will now exit."; 
			System.Windows.Forms.MessageBox.Show(strMsg, windowTitle,  
				System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); 
 
			// Close the window, which shuts down the app 
			if( this.IsHandleCreated ) 
				this.Dispose( ); 
		} 
		else 
		{ 
			if( AppMsgType.WarnSwitchToRef == Type ) 
				strMsg = "\n\nSwitching to the reference rasterizer,\n"; 
				strMsg += "a software device that implements the entire\n"; 
				strMsg += "Direct3D feature set, but runs very slowly."; 
 
			System.Windows.Forms.MessageBox.Show(strMsg, windowTitle,  
				System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information); 
		} 
	} 
 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: Resize3DEnvironment 
	// Desc: Resizes the environment 
	//----------------------------------------------------------------------------- 
	public void Resize3DEnvironment() 
	{ 
		if (presentParams.Windowed) 
		{ 
			// Store the new width/height 
			backBufferDesc.Width = this.ClientSize.Width; 
			backBufferDesc.Height = this.ClientSize.Height; 
		} 
		else 
		{ 
			// Store the new width/height 
			backBufferDesc.Width = presentParams.BackBufferWidth; 
			backBufferDesc.Height = presentParams.BackBufferHeight; 
		} 
 
		// Reset the device 
		device.Reset(presentParams); 
 
		this.ClientSize = new System.Drawing.Size(presentParams.BackBufferWidth, presentParams.BackBufferHeight); 
		// Store render target surface desc 
		Surface BackBuffer = device.GetBackBuffer(0,0, BackBufferType.Mono); 
		backBufferDesc = BackBuffer.Description; 
		BackBuffer.Dispose(); 
		BackBuffer = null; 
 
 
 
		// Set up the fullscreen cursor 
		if( showCursorWhenFullscreen && !windowed ) 
		{ 
			System.Windows.Forms.Cursor ourCursor = this.Cursor; 
			device.SetCursor(ourCursor.Handle, true); 
			device.ShowCursor(true); 
		} 
 
		// Confine cursor to fullscreen window 
		if( clipCursorWhenFullscreen ) 
		{ 
			if (!windowed ) 
			{ 
				System.Drawing.Rectangle rcWindow = this.ClientRectangle; 
			} 
		} 
 
		// If the app is paused, trigger the rendering of the current frame 
		if( false == frameMoving ) 
		{ 
			singleStep = true; 
			DXUtil.Timer( TIMER.START ); 
			DXUtil.Timer( TIMER.STOP ); 
		} 
	} 
 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: ToggleFullScreen() 
	// Desc: Called when user toggles between fullscreen mode and windowed mode 
	//----------------------------------------------------------------------------- 
	public void ToggleFullscreen() 
	{ 
		int AdapterOrdinalOld = graphicsSettings.AdapterOrdinal; 
		DeviceType DevTypeOld = graphicsSettings.DevType; 
 
		ready = false; 
 
		// Toggle the windowed state 
		windowed = !windowed; 
		graphicsSettings.IsWindowed = windowed; 
 
		// Prepare window for windowed/fullscreen change 
		AdjustWindowForChange(); 
 
		// If AdapterOrdinal and DevType are the same, we can just do a Reset(). 
		// If they've changed, we need to do a complete device teardown/rebuild. 
		if (graphicsSettings.AdapterOrdinal == AdapterOrdinalOld && 
			graphicsSettings.DevType == DevTypeOld) 
		{ 
			// Resize the 3D device 
			try 
			{ 
				BuildPresentParamsFromSettings(); 
				Resize3DEnvironment(); 
			} 
			catch  
			{ 
				if( windowed ) 
					ForceWindowed(); 
				else 
					 throw new Exception(); 
			} 
		} 
		else 
		{ 
			device.Dispose(); 
			device = null; 
			Initialize3DEnvironment(); 
		} 
 
		// 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( windowed ) 
		{ 
			this.Location = new System.Drawing.Point(windowBoundsRect.Left, windowBoundsRect.Top); 
			this.Size = new System.Drawing.Size(( windowBoundsRect.Right - windowBoundsRect.Left ), ( windowBoundsRect.Bottom - windowBoundsRect.Top)); 
		} 
 
		ready = true; 
	} 
 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: ForceWindowed() 
	// Desc: Switch to a windowed mode, even if that means picking a new device 
	//       and/or adapter 
	//----------------------------------------------------------------------------- 
	public void ForceWindowed() 
	{ 
		if( windowed ) 
			return; 
 
		if( !FindBestWindowedMode(false, false) ) 
		{ 
			return; 
		} 
		windowed = true; 
 
		// Now destroy the current 3D device objects, then reinitialize 
 
		ready = false; 
 
		// Release display objects, so a new device can be created 
		device.Dispose(); 
		device = null; 
 
		// Create the new device 
		try 
		{ 
			Initialize3DEnvironment(); 
		} 
		catch (GraphicsException e) 
		{ 
			DisplayErrorMsg( e,AppMsgType.ErrorAppMustExit ); 
		} 
		catch 
		{ 
			DisplayErrorMsg( new GraphicsException(),AppMsgType.ErrorAppMustExit ); 
		} 
		ready = true; 
	} 
 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: AdjustWindowForChange() 
	// Desc: Prepare the window for a possible change between windowed mode and 
	//       fullscreen mode.   
	//----------------------------------------------------------------------------- 
	public void AdjustWindowForChange() 
	{ 
		if( windowed ) 
		{ 
			// Set windowed-mode style 
		} 
		else 
		{ 
			// Set fullscreen-mode style 
		} 
	} 
 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: IdleTime() 
	// Desc: This function is called anytime our thread has nothing else to do 
	// (ie, no messages to process, etc) 
	//----------------------------------------------------------------------------- 
	public void IdleTime(object sender, EventArgs e) 
	{ 
		// Render a frame during idle time (no messages are waiting) 
		if( active && ready ) 
		{ 
			try  
			{ 
				if (deviceLost) 
				{ 
					// Yield some CPU time to other processes 
					System.Threading.Thread.Sleep(100); // 100 milliseconds 
				} 
				if ( m_bTerminate ) 					 
					this.Exit(null, null); 
 
				// Render a frame during idle time 
				if (active) 
				{ 
					Render3DEnvironment(); 
				} 
			} 
			catch (DirectXException d3de) 
			{ 
				System.Diagnostics.Debug.WriteLine(d3de.ErrorString); 
			} 
			catch (GraphicsException e2) 
			{ 
				DisplayErrorMsg( e2,AppMsgType.ErrorAppMustExit ); 
			} 
			catch ( Exception e3 ) 
			{ 
				System.Diagnostics.Debug.WriteLine(e3.Message); 
			} 
			catch 
			{ 
				DisplayErrorMsg( new GraphicsException(),AppMsgType.ErrorAppMustExit ); 
			} 
/*			catch  
			{ 
				this.Dispose(); 
			} 
			*/ 
		} 
	} 
 
	//----------------------------------------------------------------------------- 
	// Name: Run() 
	// Desc: Run the D3D Application 
	//----------------------------------------------------------------------------- 
	public void Run() 
	{ 
		// Now we're ready to recieve and process Windows messages. 
		System.Windows.Forms.Application.Run(this); 
		if (!isDisposed) 
			this.Dispose(); 
	} 
 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: Render3DEnvironment() 
	// Desc: Draws the scene. 
	//----------------------------------------------------------------------------- 
	public void Render3DEnvironment() 
	{ 
		if (deviceLost) 
		{ 
			// Test the cooperative level to see if it's okay to render 
			int result; 
			device.TestCooperativeLevel(out result); 
			if (result != 0) 
			{ 
				// If the device was lost, do not render until we get it back 
				if (result == (int)ErrorCode.DeviceLost) 
					return; 
 
				// Check if the device needs to be resized. 
				if( (int)ErrorCode.DeviceNotReset == result ) 
				{ 
					// If we are windowed, read the desktop mode and use the same format for 
					// the back buffer 
					if( windowed ) 
					{ 
						D3DAdapterInfo adapterInfo = graphicsSettings.AdapterInfo; 
						graphicsSettings.Windowed_DisplayMode = graphicsObject.Adapters[adapterInfo.AdapterOrdinal].DisplayMode; 
						presentParams.BackBufferFormat = graphicsSettings.Windowed_DisplayMode.Format; 
					} 
 
					Resize3DEnvironment(); 
				} 
			} 
			deviceLost = false; 
		} 
 
		// Get the app's time, in seconds. Skip rendering if no time elapsed 
		float fAppTime        = DXUtil.Timer( TIMER.GETAPPTIME ); 
		float fElapsedAppTime = DXUtil.Timer( TIMER.GETELAPSEDTIME ); 
		if( ( 0.0f == fElapsedAppTime ) && frameMoving ) 
			return; 
 
		// FrameMove (animate) the scene 
		if( frameMoving || singleStep ) 
		{ 
			// Store the time for the app 
			appTime        = fAppTime; 
			elapsedTime = fElapsedAppTime; 
 
			// Frame move the scene 
			FrameMove(); 
 
			singleStep = false; 
		} 
 
		// Render the scene as normal 
		Render(); 
 
		UpdateStats(); 
 
		try 
		{ 
			// Show the frame on the primary surface. 
			device.Present(); 
		} 
		catch (DirectXException de) 
		{ 
			if (de.ErrorCode == (int) ErrorCode.DeviceLost) 
				deviceLost = true; 
		} 
	} 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: UpdateStats() 
	// Desc:  
	//----------------------------------------------------------------------------- 
	public void UpdateStats() 
	{ 
		// Keep track of the frame count 
		float time = DXUtil.Timer( TIMER.GETABSOLUTETIME ); 
		++frames; 
 
		// Update the scene stats once per second 
		if( time - lastTime > 1.0f ) 
		{ 
			framePerSecond    = frames / (time - lastTime); 
			lastTime = time; 
			frames  = 0; 
 
			string strFmt; 
			DisplayMode mode = graphicsObject.Adapters[graphicsSettings.AdapterOrdinal].DisplayMode; 
			if (mode.Format == backBufferDesc.Format) 
			{ 
				strFmt = mode.Format.ToString(); 
			} 
			else 
			{ 
				strFmt = String.Format("backbuf {0}, adapter {1}",  
					backBufferDesc.Format.ToString(), mode.Format.ToString()); 
			} 
 
			string strDepthFmt; 
			if( enumerationSettings.AppUsesDepthBuffer ) 
			{ 
				strDepthFmt = String.Format( " ({0})",  
					graphicsSettings.DepthStencilBufferFormat.ToString()); 
			} 
			else 
			{ 
				// No depth buffer 
				strDepthFmt = ""; 
			} 
 
			string strMultiSample; 
			switch( graphicsSettings.MultisampleType ) 
			{ 
				case Direct3D.MultiSampleType.OneSample: strMultiSample = " (1x Multisample)"; break; 
				case Direct3D.MultiSampleType.TwoSamples: strMultiSample = " (2x Multisample)"; break; 
				case Direct3D.MultiSampleType.ThreeSamples: strMultiSample = " (3x Multisample)"; break; 
				case Direct3D.MultiSampleType.FourSamples: strMultiSample = " (4x Multisample)"; break; 
				case Direct3D.MultiSampleType.FiveSamples: strMultiSample = " (5x Multisample)"; break; 
				case Direct3D.MultiSampleType.SixSamples: strMultiSample = " (6x Multisample)"; break; 
				case Direct3D.MultiSampleType.SevenSamples: strMultiSample = " (7x Multisample)"; break; 
				case Direct3D.MultiSampleType.EightSamples: strMultiSample = " (8x Multisample)"; break; 
				case Direct3D.MultiSampleType.NineSamples: strMultiSample = " (9x Multisample)"; break; 
				case Direct3D.MultiSampleType.TenSamples: strMultiSample = " (10x Multisample)"; break; 
				case Direct3D.MultiSampleType.ElevenSamples: strMultiSample = " (11x Multisample)"; break; 
				case Direct3D.MultiSampleType.TwelveSamples: strMultiSample = " (12x Multisample)"; break; 
				case Direct3D.MultiSampleType.ThirteenSamples: strMultiSample = " (13x Multisample)"; break; 
				case Direct3D.MultiSampleType.FourteenSamples: strMultiSample = " (14x Multisample)"; break; 
				case Direct3D.MultiSampleType.FifteenSamples: strMultiSample = " (15x Multisample)"; break; 
				case Direct3D.MultiSampleType.SixteenSamples: strMultiSample = " (16x Multisample)"; break; 
				default: strMultiSample = ""; break; 
			} 
			frameStats = String.Format("{0} fps ({1}x{2}), {3}{4}{5}", framePerSecond.ToString("f2"), 
				backBufferDesc.Width, backBufferDesc.Height, strFmt, strDepthFmt, strMultiSample); 
		} 
	} 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: Pause() 
	// Desc: Called in to toggle the pause state of the app. 
	//----------------------------------------------------------------------------- 
	public void Pause( bool bPause ) 
	{ 
 
		appPausedCount  += (uint)( bPause ? +1 : -1 ); 
		ready = ( (appPausedCount > 0) ? false : true ); 
 
		// Handle the first pause request (of many, nestable pause requests) 
		if( bPause && ( 1 == appPausedCount ) ) 
		{ 
			// Stop the scene from animating 
			if( frameMoving ) 
				DXUtil.Timer( TIMER.STOP ); 
		} 
 
		if( 0 == appPausedCount ) 
		{ 
			// Restart the timers 
			if( frameMoving ) 
				DXUtil.Timer( TIMER.START ); 
		} 
	} 
 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: Cleanup3DEnvironment() 
	// Desc: Cleanup scene objects 
	//----------------------------------------------------------------------------- 
	public void Cleanup3DEnvironment() 
	{ 
		active = false; 
		ready  = false; 
 
		if( device != null ) 
		{ 
			device.Dispose(); 
			device = null; 
			graphicsObject       = null; 
		} 
 
		FinalCleanup(); 
	} 
	#region Menu EventHandlers 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: UserSelectNewDevice() 
	// Desc: Displays a dialog so the user can select a new adapter, device, or 
	//       display mode, and then recreates the 3D environment if needed 
	//----------------------------------------------------------------------------- 
	public void UserSelectNewDevice(object sender, EventArgs e) 
	{ 
		// Prompt the user to select a new device or mode 
		if( active && ready ) 
		{ 
			Pause(true); 
 
			DoSelectNewDevice(); 
 
			Pause(false); 
		} 
	} 
	private void DoSelectNewDevice() 
	{ 
		// Can't display dialogs in fullscreen mode 
		if( windowed == false ) 
		{ 
			try 
			{ 
				ToggleFullscreen(); 
			} 
			catch 
			{ 
				DisplayErrorMsg( new GraphicsException(GraphicsException.ErrorCode.ResizeFailed), AppMsgType.ErrorAppMustExit); 
				return; 
			} 
		} 
 
		// Make sure the main form is in the background 
		this.SendToBack(); 
		D3DSettingsForm settingsForm = new D3DSettingsForm(enumerationSettings, graphicsSettings); 
		System.Windows.Forms.DialogResult result = settingsForm.ShowDialog(null); 
		if( result != System.Windows.Forms.DialogResult.OK) 
		{ 
			return; 
		} 
		graphicsSettings = settingsForm.settings; 
 
		windowed = graphicsSettings.IsWindowed; 
 
		// Release display objects, so a new device can be created 
		device.Dispose(); 
		device = null; 
 
		// Inform the display class of the change. It will internally 
		// re-create valid surfaces, a d3ddevice, etc. 
		try 
		{ 
			Initialize3DEnvironment(); 
		} 
		catch(GraphicsException d3de) 
		{ 
			DisplayErrorMsg( d3de, AppMsgType.ErrorAppMustExit ); 
		} 
		catch (DirectXException de) 
		{ 
			DisplayErrorMsg( new GraphicsException((GraphicsException.ErrorCode)de.ErrorCode), AppMsgType.ErrorAppMustExit ); 
		} 
 
		// If the app is paused, trigger the rendering of the current frame 
		if( false == frameMoving ) 
		{ 
			singleStep = true; 
			DXUtil.Timer( TIMER.START ); 
			DXUtil.Timer( TIMER.STOP ); 
		} 
	} 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: ToggleStart() 
	// Desc: Will start (or stop) simulation 
	//----------------------------------------------------------------------------- 
	private void ToggleStart(object sender, EventArgs e) 
	{ 
		//Toggle frame movement 
		frameMoving = !frameMoving; 
		DXUtil.Timer( frameMoving ? TIMER.START : TIMER.STOP); 
	} 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: SingleStep() 
	// Desc: Will single step the simulation 
	//----------------------------------------------------------------------------- 
	private void SingleStep(object sender, EventArgs e) 
	{ 
		// Single-step frame movement 
		if( false == frameMoving ) 
			DXUtil.Timer( TIMER.ADVANCE ); 
		else 
			DXUtil.Timer( TIMER.STOP ); 
		frameMoving = false; 
		singleStep  = true; 
	} 
 
 
 
	//----------------------------------------------------------------------------- 
	// Name: Exit() 
	// Desc: Will end the simulation 
	//----------------------------------------------------------------------------- 
	private void Exit(object sender, EventArgs e) 
	{ 
		this.Dispose(); 
	} 
	#endregion 
	#region WinForms Overrides 
	protected override void OnLoad(System.EventArgs e) 
	{ 
		// Show the window and set focus to it 
		this.Show(); 
		this.Select(); 
		while(Created) 
		{ 
			IdleTime(null, null); 
			System.Windows.Forms.Application.DoEvents(); 
		} 
	} 
 
	protected override void Dispose(bool disposing) 
	{ 
		isDisposed = true; 
		Cleanup3DEnvironment(); 
		base.Dispose(disposing); 
		mnuMain.Dispose(); 
	} 
 
	protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e) 
	{ 
/* 
		// Check for our shortcut keys (Space) 
		if (e.KeyChar == ' ') 
		{ 
			mnuSingle.PerformClick(); 
			e.Handled = true; 
		} 
 
		// Check for our shortcut keys (Return to start or stop) 
		if (e.KeyChar == '\r') 
		{ 
			mnuGo.PerformClick(); 
			e.Handled = true; 
 
		} 
*/ 
		// Check for our shortcut keys (Escape to quit) 
		if ((byte)e.KeyChar == (byte)(int)System.Windows.Forms.Keys.Escape) 
		{ 
			mnuExit.PerformClick(); 
			e.Handled = true; 
		} 
 
	} 
 
	protected override void OnLostFocus(System.EventArgs e) 
	{ 
		hasFocus = false; 
		base.OnLostFocus(e); 
	} 
 
	protected override void OnGotFocus(System.EventArgs e) 
	{ 
		hasFocus = true; 
		base.OnGotFocus(e); 
	} 
	protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e) 
	{ 
		char tstr = (char)(e.KeyValue); 
		if ( GameEngine.Console.IsVisible && e.KeyData == System.Windows.Forms.Keys.Return ) 
		{ 
			GameEngine.Console.ProcessEntry(); 
		} 
		if ( e.KeyData == System.Windows.Forms.Keys.F12 ) 
		{ 
			GameEngine.Console.ToggleState(); 
		} 
		else if ( GameEngine.Console.IsVisible &&  
			(e.KeyData == System.Windows.Forms.Keys.Space || 
			( e.KeyData >= System.Windows.Forms.Keys.A && 
			e.KeyData <= System.Windows.Forms.Keys.Z ) || 
			( e.KeyData >= System.Windows.Forms.Keys.D0 && 
			e.KeyData <= System.Windows.Forms.Keys.D9 )  
			) ) 
		{ 
			GameEngine.Console.AddCharacterToEntryLine( tstr ); 
		} 
		else if ( GameEngine.Console.IsVisible && e.KeyData == System.Windows.Forms.Keys.OemPeriod ) 
		{ 
			GameEngine.Console.AddCharacterToEntryLine( '.' ); 
		} 
		else if ( GameEngine.Console.IsVisible && e.KeyData == System.Windows.Forms.Keys.OemMinus ) 
		{ 
			GameEngine.Console.AddCharacterToEntryLine( '-' ); 
		} 
		else if ( GameEngine.Console.IsVisible && e.KeyData == System.Windows.Forms.Keys.Back ) 
		{ 
			GameEngine.Console.Backspace(); 
		} 
		if ( (e.Alt) && (e.KeyCode == System.Windows.Forms.Keys.Return)) 
		{ 
			// Toggle the fullscreen/window mode 
			if( active && ready ) 
			{ 
				Pause( true ); 
 
				try 
				{ 
					ToggleFullscreen(); 
					Pause( false );                         
					return; 
				} 
				catch 
				{ 
					DisplayErrorMsg( new GraphicsException(GraphicsException.ErrorCode.ResizeFailed), AppMsgType.ErrorAppMustExit); 
				} 
				finally 
				{ 
					e.Handled = true; 
				} 
			} 
		} 
		// Allow the control to handle the keystroke now 
//		base.OnKeyDown(e); 
	} 
 
	private void InitializeComponent() 
	{ 
		//  
		// GraphicsSample 
		//  
		this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); 
		this.MinimumSize = new System.Drawing.Size(100, 100); 
		#region MenuCreation/etc 
		this.mnuMain = new System.Windows.Forms.MainMenu(); 
		this.mnuFile = new System.Windows.Forms.MenuItem(); 
		this.mnuGo = new System.Windows.Forms.MenuItem(); 
		this.mnuSingle = new System.Windows.Forms.MenuItem(); 
		this.mnuBreak1 = new System.Windows.Forms.MenuItem(); 
		this.mnuChange = new System.Windows.Forms.MenuItem(); 
		this.mnuBreak2 = new System.Windows.Forms.MenuItem(); 
		this.mnuExit = new System.Windows.Forms.MenuItem(); 
		//  
		// mainMenu1 
		//  
		this.mnuMain.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { 
																				this.mnuFile}); 
		//  
		// mnuFile 
		//  
		this.mnuFile.Index = 0; 
		this.mnuFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { 
																				this.mnuGo, 
																				this.mnuSingle, 
																				this.mnuBreak1, 
																				this.mnuChange, 
																				this.mnuBreak2, 
																				this.mnuExit}); 
		this.mnuFile.Text = "&File"; 
		//  
		// mnuGo 
		//  
		this.mnuGo.Index = 0; 
		this.mnuGo.Text = "&Go/stop\tEnter"; 
		this.mnuGo.Click += new System.EventHandler(this.ToggleStart); 
		//  
		// mnuSingle 
		//  
		this.mnuSingle.Index = 1; 
		this.mnuSingle.Text = "&Single step\tSpace"; 
		this.mnuSingle.Click += new System.EventHandler(this.SingleStep); 
		//  
		// mnuBreak1 
		//  
		this.mnuBreak1.Index = 2; 
		this.mnuBreak1.Text = "-"; 
		//  
		// mnuChange 
		//  
		this.mnuChange.Index = 3; 
		this.mnuChange.Shortcut = System.Windows.Forms.Shortcut.F2; 
		this.mnuChange.ShowShortcut = true; 
		this.mnuChange.Text = "&Change Device..."; 
		this.mnuChange.Click += new System.EventHandler(this.UserSelectNewDevice); 
		//  
		// mnuBreak2 
		//  
		this.mnuBreak2.Index = 4; 
		this.mnuBreak2.Text = "-"; 
		//  
		// mnuExit 
		//  
		this.mnuExit.Index = 5; 
		this.mnuExit.Text = "E&xit\tESC"; 
		this.mnuExit.Click += new System.EventHandler(this.Exit); 
		#endregion 
	} 
 
	protected override void OnMenuStart(System.EventArgs e) 
	{ 
		Pause(true); // Pause the simulation while the menu starts 
	} 
 
	protected override void OnMenuComplete(System.EventArgs e) 
	{ 
		Pause(false); // Unpause the simulation  
	} 
 
	protected override void OnSizeChanged(System.EventArgs e) 
	{ 
		this.OnResize(null); 
	} 
	protected override void OnResize(System.EventArgs e) 
	{ 
		if (!ready) 
			return; 
 
		active = !( this.WindowState == System.Windows.Forms.FormWindowState.Minimized || this.Visible == false ); 
 
		if( active && windowed ) 
		{ 
			System.Drawing.Rectangle rcClientOld; 
			rcClientOld = clientRect; 
 
			// Update window properties 
			windowBoundsRect = new System.Drawing.Rectangle(this.Location, this.Size); 
			clientRect = this.ClientRectangle; 
 
			if( rcClientOld.Right - rcClientOld.Right != 
				clientRect.Right - clientRect.Left || 
				rcClientOld.Bottom - rcClientOld.Top != 
				clientRect.Bottom - clientRect.Top) 
			{ 
				// A new window size will require a new backbuffer 
				// size, so the 3D structures must be changed accordingly. 
				ready = false; 
 
				presentParams.BackBufferWidth  = clientRect.Right - clientRect.Left; 
				presentParams.BackBufferHeight = clientRect.Bottom - clientRect.Top; 
 
				// Resize the 3D environment 
				try 
				{ 
					Resize3DEnvironment(); 
				} 
				catch  
				{ 
					DisplayErrorMsg( new GraphicsException(GraphicsException.ErrorCode.ResizeFailed), AppMsgType.ErrorAppMustExit); 
				} 
 
				ready = true; 
			} 
		} 
	} 
	#endregion 
 
}