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

📄 d3dapp.cs

📁 《.NET游戏编程入门经典-c#篇》
💻 CS
📖 第 1 页 / 共 4 页
字号:
	public bool ChooseInitialSettings() {
		bool foundFullscreenMode = FindBestFullscreenMode(false, false);
		bool foundWindowedMode = FindBestWindowedMode(false, false);
		if (startFullscreen && foundFullscreenMode)
			graphicsSettings.IsWindowed = false;

		if (!foundFullscreenMode && !foundWindowedMode)
			throw new NoCompatibleDevicesException();

		return (foundFullscreenMode || foundWindowedMode);
	}




	/// <summary>
	/// Build presentation parameters from the current settings
	/// </summary>
	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.PresentFlag = PresentFlag.None;

		if (windowed) {
			presentParams.BackBufferWidth  = ourRenderTarget.ClientRectangle.Right - ourRenderTarget.ClientRectangle.Left;
			presentParams.BackBufferHeight = ourRenderTarget.ClientRectangle.Bottom - ourRenderTarget.ClientRectangle.Top;
			presentParams.BackBufferFormat = graphicsSettings.DeviceCombo.BackBufferFormat;
			presentParams.FullScreenRefreshRateInHz = 0;
			presentParams.PresentationInterval = PresentInterval.Immediate;
			presentParams.DeviceWindow = ourRenderTarget;
		}
		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;
			presentParams.DeviceWindow = this;
		}
	}




	/// <summary>
	/// Initialize the graphics environment
	/// </summary>
	public void InitializeEnvironment() {
		GraphicsAdapterInfo adapterInfo = graphicsSettings.AdapterInfo;
		GraphicsDeviceInfo deviceInfo = graphicsSettings.DeviceInfo;

		windowed = graphicsSettings.IsWindowed;

		// Set up the presentation parameters
		BuildPresentParamsFromSettings();

		if (deviceInfo.Caps.PrimitiveMiscCaps.IsNullReference) {
			// Warn user about null ref device that can't render anything
			HandleSampleException(new NullReferenceDeviceException(), ApplicationMessage.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; 
		}
		else
			throw new ApplicationException();
#if (DX9)
#else
		// Make sure to allow multithreaded apps if we need them
		presentParams.ForceNoMultiThreadedFlag = !isMultiThreaded;
#endif
		try {
			// Create the device
			device = new Device(graphicsSettings.AdapterOrdinal, graphicsSettings.DevType, 
				windowed ? ourRenderTarget : this , createFlags, presentParams);

			// 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
				System.Drawing.Size currentClientSize = this.ClientSize;
				this.Size = this.ClientSize;
				this.SendToBack();
				this.BringToFront();
				this.ClientSize = currentClientSize;
			}

			// Store device Caps
			graphicsCaps = device.DeviceCaps;
			behavior = createFlags;

			System.Text.StringBuilder sb = new System.Text.StringBuilder();

			// Store device description
			if (deviceInfo.DevType == DeviceType.Reference)
				sb.Append("REF");
			else if (deviceInfo.DevType == DeviceType.Hardware)
				sb.Append("HAL");
			else if (deviceInfo.DevType == DeviceType.Software)
				sb.Append("SW");

			BehaviorFlags behaviorFlags = new BehaviorFlags(createFlags);
			if ((behaviorFlags.HardwareVertexProcessing) && 
				(behaviorFlags.PureDevice)) {
				if (deviceInfo.DevType == DeviceType.Hardware)
					sb.Append(" (pure hw vp)");
				else
					sb.Append(" (simulated pure hw vp)");
			}
			else if (behaviorFlags.HardwareVertexProcessing) {
				if (deviceInfo.DevType == DeviceType.Hardware)
					sb.Append(" (hw vp)");
				else
					sb.Append(" (simulated hw vp)");
			}
			else if (behaviorFlags.MixedVertexProcessing) {
				if (deviceInfo.DevType == DeviceType.Hardware)
					sb.Append(" (mixed vp)");
				else
					sb.Append(" (simulated mixed vp)");
			}
			else if (behaviorFlags.SoftwareVertexProcessing) {
				sb.Append(" (sw vp)");
			}

			if (deviceInfo.DevType == DeviceType.Hardware) {
				sb.Append(": ");
				sb.Append(adapterInfo.AdapterDetails.Description);
			}

			// Set device stats string
			deviceStats = sb.ToString();

			// Set up the fullscreen cursor
			if (showCursorWhenFullscreen && !windowed) {
				System.Windows.Forms.Cursor ourCursor = this.Cursor;
				device.SetCursor(ourCursor, 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);
			device.DeviceResizing += new System.ComponentModel.CancelEventHandler(this.EnvironmentResized);

			// Initialize the app's device-dependent objects
			try {
				InitializeDeviceObjects();
				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;
			}
		}
		catch {
			// 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
					System.Drawing.Size currentClientSize = this.ClientSize;
					this.Size = this.ClientSize;
					this.SendToBack();
					this.BringToFront();
					this.ClientSize = currentClientSize;

					// Let the user know we are switching from HAL to the reference rasterizer
					HandleSampleException(null, ApplicationMessage.WarnSwitchToRef);

					InitializeEnvironment();
				}
			}
		}
	}




	/// <summary>
	/// Displays sample exceptions to the user
	/// </summary>
	/// <param name="e">The exception that was thrown</param>
	/// <param name="Type">Extra information on how to handle the exception</param>
	public void HandleSampleException(SampleException e, ApplicationMessage Type) {
		// Build a message to display to the user
		string strMsg = string.Empty;
		if (e != null)
			strMsg = e.Message;

		if (ApplicationMessage.ApplicationMustExit == Type) {
			strMsg  += "\n\nThis sample will now exit.";
			System.Windows.Forms.MessageBox.Show(strMsg, this.Text, 
				System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);

			// Close the window, which shuts down the app
			if (this.IsHandleCreated)
				this.Close();
		}
		else {
			if (ApplicationMessage.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, this.Text, 
				System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
		}
	}




	/// <summary>
	/// Fired when our environment was resized
	/// </summary>
	/// <param name="sender">the device that's resizing our environment</param>
	/// <param name="e">Set the cancel member to true to turn off automatic device reset</param>
	public void EnvironmentResized(object sender, System.ComponentModel.CancelEventArgs e) {
		// Check to see if we're closing or changing the form style
		if ((isClosing) || (isChangingFormStyle)) {
			// We are, cancel our reset, and exit
			e.Cancel = true;
			return;
		}

		// Check to see if we're minimizing and our rendering object
		// is not the form, if so, cancel the resize
		if ((ourRenderTarget != this) && (this.WindowState == System.Windows.Forms.FormWindowState.Minimized))
			e.Cancel = true;

		if (!isWindowActive) 
			e.Cancel = true;

		// Set up the fullscreen cursor
		if (showCursorWhenFullscreen && !windowed) {
			System.Windows.Forms.Cursor ourCursor = this.Cursor;
			device.SetCursor(ourCursor, true);
			device.ShowCursor(true);
		}

		// If the app is paused, trigger the rendering of the current frame
		if (false == frameMoving) {
			singleStep = true;
			DXUtil.Timer(DirectXTimer.Start);
			DXUtil.Timer(DirectXTimer.Stop);
		}
	}




	/// <summary>
	/// Called when user toggles between fullscreen mode and windowed mode
	/// </summary>
	public void ToggleFullscreen() {
		int AdapterOrdinalOld = graphicsSettings.AdapterOrdinal;
		DeviceType DevTypeOld = graphicsSettings.DevType;

		isHandlingSizeChanges = false;
		isChangingFormStyle = true;
		ready = false;

		// Toggle the windowed state
		windowed = !windowed;

		// Save our maximized settings..
		if (!windowed && isMaximized)
			this.WindowState = System.Windows.Forms.FormWindowState.Normal;

		graphicsSettings.IsWindowed = windowed;

		// 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) {
			BuildPresentParamsFromSettings();
			// Resize the 3D device
		RETRY:
			try {
				device.Reset(presentParams);
			}
			catch {
				if (windowed)
					ForceWindowed();
				else {
					// Sit in a loop until the device passes Reset()
					try {
						device.TestCooperativeLevel();
					}
					catch(DeviceNotResetException) {
						// Device still needs to be Reset. Try again.
						// Yield some CPU time to other processes
						System.Threading.Thread.Sleep(100); // 100 milliseconds
						goto RETRY;
					}
				}
			}
			EnvironmentResized(device, new System.ComponentModel.CancelEventArgs());
		}
		else {
			device.Dispose();
			device = null;
			InitializeEnvironment();
		}

		// 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) {
			// if our render target is the main window and we haven't said 
			// ignore the menus, add our menu
			if ((ourRenderTarget == this) && (isUsingMenus))
				this.Menu = mnuMain;
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;
			isChangingFormStyle = false;

			// We were maximized, restore that state
			if (isMaximized) {
				this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
			}
			this.SendToBack();
			this.BringToFront();
			this.ClientSize = storedSize;
			this.Location = storedLocation;
		}
		else {
			if (this.Menu != null)
				this.Menu = null;

			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
			isChangingFormStyle = false;
		}
		isHandlingSizeChanges = true;
		ready = true;
	}

⌨️ 快捷键说明

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