📄 d3dapp.cs
字号:
/// <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 + -