📄 d3dapp.cs
字号:
// 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 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;
// 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( TIMER.START );
DXUtil.Timer( TIMER.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;
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)
{
// Resize the 3D device
try
{
BuildPresentParamsFromSettings();
device.Reset(presentParams);
EnvironmentResized(device, null);
}
catch
{
if( windowed )
ForceWindowed();
else
throw new Exception();
}
}
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 )
{
// We were maximized, restore that state
if (isMaximized)
{
this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
}
this.ClientSize = storedSize;
this.SendToBack();
this.BringToFront();
}
isHandlingSizeChanges = true;
ready = true;
}
/// <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()
{
if ( m_bTerminate )
this.Close();
// 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
}
// 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.
this.Show();
while (this.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
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, null);
}
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(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( 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 = Manager.Adapters[graphicsSettings.AdapterOrdinal].CurrentDisplayMode;
if (mode.Format == device.PresentationParameters.BackBufferFormat)
{
strFmt = mode.Format.ToString();
}
else
{
strFmt = String.Format("backbuf {0}, adapter {1}",
device.PresentationParameters.BackBufferFormat.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.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 ) )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -