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

📄 d3dapp.cs

📁 《.NET游戏编程入门经典-c#篇》
💻 CS
📖 第 1 页 / 共 4 页
字号:




	/// <summary>
	/// Switch to a windowed mode, even if that means picking a new device and/or adapter
	/// </summary>
	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 {
			InitializeEnvironment();
		}
		catch (SampleException e) {
			HandleSampleException(e,ApplicationMessage.ApplicationMustExit);
		}
		catch {
			HandleSampleException(new SampleException(),ApplicationMessage.ApplicationMustExit);
		}
		ready = true;
	}




	/// <summary>
	/// Called when our sample has nothing else to do, and it's time to render
	/// </summary>
	private void FullRender() {
		// Render a frame during idle time (no messages are waiting)
		if (active && ready) {
			try {
				if ((deviceLost) || (System.Windows.Forms.Form.ActiveForm != this)) {
					// Yield some CPU time to other processes
					System.Threading.Thread.Sleep(100); // 100 milliseconds
				}
				// Render a frame during idle time
				if (active) {
					Render3DEnvironment();
				}
			}
			catch (Exception ee) {
				System.Windows.Forms.MessageBox.Show("An exception has occurred.  This sample must exit.\r\n\r\n" + ee.ToString(), "Exception", 
					System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
				this.Close();
			}
		}
	}




	/// <summary>
	/// Run the simulation
	/// </summary>
	public void Run() {
		// Now we're ready to recieve and process Windows messages.
		System.Windows.Forms.Control mainWindow = this;

		// If the render target is a form and *not* this form, use that form instead,
		// otherwise, use the main form.
		if ((ourRenderTarget is System.Windows.Forms.Form) && (ourRenderTarget != this))
			mainWindow = ourRenderTarget;

		mainWindow.Show();
		while (mainWindow.Created) {
			FullRender();
			System.Windows.Forms.Application.DoEvents();
		}
	}




	/// <summary>
	/// Draws the scene 
	/// </summary>
	public void Render3DEnvironment() {
		if (deviceLost) {
			try {
				// Test the cooperative level to see if it's okay to render
				device.TestCooperativeLevel();
			}
			catch (DeviceLostException) {
				// If the device was lost, do not render until we get it back
				isHandlingSizeChanges = false;
				isWindowActive = false;
				return;
			}
			catch (DeviceNotResetException) {
				// Check if the device needs to be resized.

				// If we are windowed, read the desktop mode and use the same format for
				// the back buffer
				if (windowed) {
					GraphicsAdapterInfo adapterInfo = graphicsSettings.AdapterInfo;
					graphicsSettings.WindowedDisplayMode = Manager.Adapters[adapterInfo.AdapterOrdinal].CurrentDisplayMode;
					presentParams.BackBufferFormat = graphicsSettings.WindowedDisplayMode.Format;
				}

				// Reset the device and resize it
				device.Reset(device.PresentationParameters);
				EnvironmentResized(device, new System.ComponentModel.CancelEventArgs());
			}
			deviceLost = false;
		}

		// Get the app's time, in seconds. Skip rendering if no time elapsed
		float fAppTime        = DXUtil.Timer(DirectXTimer.GetApplicationTime);
		float fElapsedAppTime = DXUtil.Timer(DirectXTimer.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(DeviceLostException) {
			deviceLost = true;
		}
	}




	/// <summary>
	/// Update the various statistics the simulation keeps track of
	/// </summary>
	public void UpdateStats() {
		// Keep track of the frame count
		float time = DXUtil.Timer(DirectXTimer.GetAbsoluteTime);
		++frames;

		// Update the scene stats once per second
		if (time - lastTime > 1.0f) {
			framePerSecond    = frames / (time - lastTime);
			lastTime = time;
			frames  = 0;

			string strFmt;
			Format fmtAdapter = graphicsSettings.DisplayMode.Format;
			if (fmtAdapter == device.PresentationParameters.BackBufferFormat) {
				strFmt = fmtAdapter.ToString();
			}
			else {
				strFmt = String.Format("backbuf {0}, adapter {1}", 
					device.PresentationParameters.BackBufferFormat.ToString(), fmtAdapter.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.NonMaskable: strMultiSample = " (NonMaskable 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 = string.Empty; break;
			}
			frameStats = String.Format("{0} fps ({1}x{2}), {3}{4}{5}", framePerSecond.ToString("f2"),
				device.PresentationParameters.BackBufferWidth, device.PresentationParameters.BackBufferHeight, 
				strFmt, strDepthFmt, strMultiSample);
		}
	}




	/// <summary>
	/// Called in to toggle the pause state of the app.
	/// </summary>
	/// <param name="pause">true if the simulation should pause</param>
	public void Pause(bool pause) {
		appPausedCount  += (int)(pause ? +1 : -1);
		ready = ((appPausedCount > 0) ? false : true);

		// Handle the first pause request (of many, nestable pause requests)
		if (pause && (1 == appPausedCount)) {
			// Stop the scene from animating
			if (frameMoving)
				DXUtil.Timer(DirectXTimer.Stop);
		}

		if (0 == appPausedCount) {
			// Restart the timers
			if (frameMoving)
				DXUtil.Timer(DirectXTimer.Start);
		}
	}




	/// <summary>
	/// Set our variables to not active and not ready
	/// </summary>
	public void CleanupEnvironment() {
		active = false;
		ready  = false;
		if (device != null)
			device.Dispose();

		device = null;
	}
	#region Menu EventHandlers




	/// <summary>
	/// Prepares the simulation for a new device being selected
	/// </summary>
	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);
		}
	}




	/// <summary>
	/// Displays a dialog so the user can select a new adapter, device, or
	/// display mode, and then recreates the 3D environment if needed
	/// </summary>
	private void DoSelectNewDevice() {
		isHandlingSizeChanges = false;
		// Can't display dialogs in fullscreen mode
		if (windowed == false) {
			try {
				ToggleFullscreen();
				isHandlingSizeChanges = false;
			}
			catch {
				HandleSampleException(new ResetFailedException(), ApplicationMessage.ApplicationMustExit);
				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) {
			isHandlingSizeChanges = true;
			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 {
			InitializeEnvironment();
		}
		catch(SampleException d3de) {
			HandleSampleException(d3de, ApplicationMessage.ApplicationMustExit);
		}
		catch {
			HandleSampleException(new SampleException(), ApplicationMessage.ApplicationMustExit);
		}

		// 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);
		}
		isHandlingSizeChanges = true;
	}




	/// <summary>
	/// Will start (or stop) simulation
	/// </summary>
	private void ToggleStart(object sender, EventArgs e) {
		//Toggle frame movement
		frameMoving = !frameMoving;
		DXUtil.Timer(frameMoving ? DirectXTimer.Start : DirectXTimer.Stop);
	}




	/// <summary>
	/// Will single step the simulation
	/// </summary>
	private void SingleStep(object sender, EventArgs e) {
		// Single-step frame movement
		if (false == frameMoving)
			DXUtil.Timer(DirectXTimer.Advance);
		else
			DXUtil.Timer(DirectXTimer.Stop);
		frameMoving = false;
		singleStep  = true;
	}




	/// <summary>
	/// Will end the simulation
	/// </summary>
	private void ExitSample(object sender, EventArgs e) {
		this.Close();
	}
	#endregion




	#region WinForms Overrides
	/// <summary>
	/// Clean up any resources
	/// </summary>
	protected override void Dispose(bool disposing) {
		CleanupEnvironment();
		mnuMain.Dispose();

⌨️ 快捷键说明

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