?? d3dapp.cs
字號:
//-----------------------------------------------------------------------------
// File: D3DApp.cs
//
// Desc: Application class for the Direct3D samples framework library.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Direct3D = Microsoft.DirectX.Direct3D;
/// <summary>
/// The base class for all the graphics (D3D) samples, it derives from windows forms
/// </summary>
public class GraphicsSample : System.Windows.Forms.Form
{
#region Menu Information
// The menu items that *all* samples will need
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;
protected System.Windows.Forms.MenuItem mnuExit;
#endregion
// The window we will render too
private System.Windows.Forms.Control ourRenderTarget;
// Should we use the default windows
protected bool isUsingMenus = true;
// We need to keep track of our enumeration settings
protected D3DEnumeration enumerationSettings = new D3DEnumeration();
protected D3DSettings graphicsSettings = new D3DSettings();
private bool isMaximized = false; // Are we maximized?
private bool isHandlingSizeChanges = true; // Are we handling size changes?
private bool isClosing = false; // Are we closing?
private bool isChangingFormStyle = false; // Are we changing the forms style?
private bool isWindowActive = true; // Are we waiting for got focus?
private float lastTime = 0.0f; // The last time
private int frames = 0; // Number of frames since our last update
private int appPausedCount = 0; // How many times has the app been paused (and when can it resume)?
// Internal variables for the state of the app
protected bool windowed;
protected bool active;
protected bool ready;
protected bool hasFocus;
protected bool isMultiThreaded = false;
// 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 Device device; // The 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 CreateFlags behavior; // Indicate sw or hw vertex processing
protected BehaviorFlags BehaviorFlags { get { return new BehaviorFlags(behavior); } }
protected System.Windows.Forms.Control RenderTarget { get { return ourRenderTarget; } set { ourRenderTarget = value; } }
// 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
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
private System.Drawing.Size storedSize;
private System.ComponentModel.IContainer components;
private System.Windows.Forms.Timer updateTimer;
private System.Drawing.Point storedLocation;
// Overridable functions for the 3D scene created by the app
protected virtual bool ConfirmDevice(Caps caps, VertexProcessingType vertexProcessingType,
Format adapterFormat, Format backBufferFormat) { return true; }
protected virtual void OneTimeSceneInitialization() { /* Do Nothing */ }
protected virtual void InitializeDeviceObjects() { /* 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 */ }
/// <summary>
/// Constructor
/// </summary>
public GraphicsSample()
{
device = null;
active = false;
ready = false;
hasFocus = false;
behavior = 0;
ourRenderTarget = this;
frameMoving = true;
singleStep = false;
framePerSecond = 0.0f;
deviceStats = null;
frameStats = null;
this.Text = "D3D9 Sample";
this.ClientSize = new System.Drawing.Size(400,300);
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();
}
/// <summary>
/// Picks the best graphics device, and initializes it
/// </summary>
/// <returns>true if a good device was found, false otherwise</returns>
public bool CreateGraphicsSample()
{
enumerationSettings.ConfirmDeviceCallback = new D3DEnumeration.ConfirmDeviceCallbackType(this.ConfirmDevice);
enumerationSettings.Enumerate();
if (ourRenderTarget.Cursor == null)
{
// Set up a default cursor
ourRenderTarget.Cursor = System.Windows.Forms.Cursors.Default;
}
// 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;
try
{
ChooseInitialSettings();
// Initialize the application timer
DXUtil.Timer(DirectXTimer.Start);
// Initialize the app's custom scene stuff
OneTimeSceneInitialization();
// Initialize the 3D environment for the app
InitializeEnvironment();
}
catch (SampleException d3de)
{
HandleSampleException(d3de, ApplicationMessage.ApplicationMustExit);
return false;
}
catch
{
HandleSampleException(new SampleException(), ApplicationMessage.ApplicationMustExit);
return false;
}
// The app is ready to go
ready = true;
return true;
}
/// <summary>
/// Sets up graphicsSettings with best available windowed mode, subject to
/// the doesRequireHardware and doesRequireReference constraints.
/// </summary>
/// <param name="doesRequireHardware">Does the device require hardware support</param>
/// <param name="doesRequireReference">Does the device require the ref device</param>
/// <returns>true if a mode is found, false otherwise</returns>
public bool FindBestWindowedMode(bool doesRequireHardware, bool doesRequireReference)
{
// Get display mode of primary adapter (which is assumed to be where the window
// will appear)
DisplayMode primaryDesktopDisplayMode = Manager.Adapters[0].CurrentDisplayMode;
GraphicsAdapterInfo bestAdapterInfo = null;
GraphicsDeviceInfo bestDeviceInfo = null;
DeviceCombo bestDeviceCombo = null;
foreach (GraphicsAdapterInfo adapterInfo in enumerationSettings.AdapterInfoList)
{
foreach (GraphicsDeviceInfo deviceInfo in adapterInfo.DeviceInfoList)
{
if (doesRequireHardware && deviceInfo.DevType != DeviceType.Hardware)
continue;
if (doesRequireReference && deviceInfo.DevType != DeviceType.Reference)
continue;
foreach (DeviceCombo deviceCombo in deviceInfo.DeviceComboList)
{
bool adapterMatchesBackBuffer = (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 && adapterMatchesBackBuffer)
{
bestAdapterInfo = adapterInfo;
bestDeviceInfo = deviceInfo;
bestDeviceCombo = deviceCombo;
if (deviceInfo.DevType == DeviceType.Hardware && adapterMatchesBackBuffer)
{
// 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.WindowedAdapterInfo = bestAdapterInfo;
graphicsSettings.WindowedDeviceInfo = bestDeviceInfo;
graphicsSettings.WindowedDeviceCombo = bestDeviceCombo;
graphicsSettings.IsWindowed = true;
graphicsSettings.WindowedDisplayMode = primaryDesktopDisplayMode;
graphicsSettings.WindowedWidth = ourRenderTarget.ClientRectangle.Right - ourRenderTarget.ClientRectangle.Left;
graphicsSettings.WindowedHeight = ourRenderTarget.ClientRectangle.Bottom - ourRenderTarget.ClientRectangle.Top;
if (enumerationSettings.AppUsesDepthBuffer)
graphicsSettings.WindowedDepthStencilBufferFormat = (DepthFormat)bestDeviceCombo.DepthStencilFormatList[0];
graphicsSettings.WindowedMultisampleType = (MultiSampleType)bestDeviceCombo.MultiSampleTypeList[0];
graphicsSettings.WindowedMultisampleQuality = 0;
graphicsSettings.WindowedVertexProcessingType = (VertexProcessingType)bestDeviceCombo.VertexProcessingTypeList[0];
graphicsSettings.WindowedPresentInterval = (PresentInterval)bestDeviceCombo.PresentIntervalList[0];
return true;
}
/// <summary>
/// Sets up graphicsSettings with best available fullscreen mode, subject to
/// the doesRequireHardware and doesRequireReference constraints.
/// </summary>
/// <param name="doesRequireHardware">Does the device require hardware support</param>
/// <param name="doesRequireReference">Does the device require the ref device</param>
/// <returns>true if a mode is found, false otherwise</returns>
public bool FindBestFullscreenMode(bool doesRequireHardware, bool doesRequireReference)
{
// 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;
GraphicsAdapterInfo bestAdapterInfo = null;
GraphicsDeviceInfo bestDeviceInfo = null;
DeviceCombo bestDeviceCombo = null;
foreach (GraphicsAdapterInfo adapterInfo in enumerationSettings.AdapterInfoList)
{
adapterDesktopDisplayMode = Manager.Adapters[adapterInfo.AdapterOrdinal].CurrentDisplayMode;
foreach (GraphicsDeviceInfo deviceInfo in adapterInfo.DeviceInfoList)
{
if (doesRequireHardware && deviceInfo.DevType != DeviceType.Hardware)
continue;
if (doesRequireReference && deviceInfo.DevType != DeviceType.Reference)
continue;
foreach (DeviceCombo deviceCombo in deviceInfo.DeviceComboList)
{
bool adapterMatchesBackBuffer = (deviceCombo.BackBufferFormat == deviceCombo.AdapterFormat);
bool adapterMatchesDesktop = (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 && adapterMatchesDesktop ||
bestDeviceCombo.DevType == DeviceType.Hardware && adapterMatchesDesktop && adapterMatchesBackBuffer)
{
bestAdapterDesktopDisplayMode = adapterDesktopDisplayMode;
bestAdapterInfo = adapterInfo;
bestDeviceInfo = deviceInfo;
bestDeviceCombo = deviceCombo;
if (deviceInfo.DevType == DeviceType.Hardware && adapterMatchesDesktop && adapterMatchesBackBuffer)
{
// 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.FullscreenAdapterInfo = bestAdapterInfo;
graphicsSettings.FullscreenDeviceInfo = bestDeviceInfo;
graphicsSettings.FullscreenDeviceCombo = bestDeviceCombo;
graphicsSettings.IsWindowed = false;
graphicsSettings.FullscreenDisplayMode = bestDisplayMode;
if (enumerationSettings.AppUsesDepthBuffer)
graphicsSettings.FullscreenDepthStencilBufferFormat = (DepthFormat)bestDeviceCombo.DepthStencilFormatList[0];
graphicsSettings.FullscreenMultisampleType = (MultiSampleType)bestDeviceCombo.MultiSampleTypeList[0];
graphicsSettings.FullscreenMultisampleQuality = 0;
graphicsSettings.FullscreenVertexProcessingType = (VertexProcessingType)bestDeviceCombo.VertexProcessingTypeList[0];
graphicsSettings.FullscreenPresentInterval = PresentInterval.Default;
return true;
}
/// <summary>
/// Choose the initial settings for the application
/// </summary>
/// <returns>true if the settings were initialized</returns>
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;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -