📄 d3dapp.cs
字号:
}
}
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)bestDeviceCombo.PresentIntervalList[0];
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;
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;
}
}
//-----------------------------------------------------------------------------
// Name: InitializeEnvironment()
// Desc: Initialize the graphics environment
//-----------------------------------------------------------------------------
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 | CreateFlags.PureDevice;
}
else
throw new ApplicationException();
createFlags |= CreateFlags.MultiThreaded;
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.ClientSize = currentClientSize;
this.SendToBack();
this.BringToFront();
}
// Store device Caps
graphicsCaps = device.DeviceCaps;
behavior = createFlags;
// Store device description
if( deviceInfo.DevType == DeviceType.Reference )
deviceStats = "REF";
else if( deviceInfo.DevType == DeviceType.Hardware )
deviceStats = "HAL";
else if( deviceInfo.DevType == DeviceType.Software )
deviceStats = "SW";
BehaviorFlags behaviorFlags = new BehaviorFlags(createFlags);
if( (behaviorFlags.HardwareVertexProcessing) &&
(behaviorFlags.PureDevice) )
{
if( deviceInfo.DevType == DeviceType.Hardware )
deviceStats += " (pure hw vp)";
else
deviceStats += " (simulated pure hw vp)";
}
else if( (behaviorFlags.HardwareVertexProcessing) )
{
if( deviceInfo.DevType == DeviceType.Hardware )
deviceStats += " (hw vp)";
else
deviceStats += " (simulated hw vp)";
}
else if( behaviorFlags.MixedVertexProcessing)
{
if( deviceInfo.DevType == DeviceType.Hardware )
deviceStats += " (mixed vp)";
else
deviceStats += " (simulated mixed vp)";
}
else if( behaviorFlags.SoftwareVertexProcessing )
{
deviceStats += " (sw vp)";
}
if( deviceInfo.DevType == DeviceType.Hardware )
{
deviceStats += ": ";
deviceStats += adapterInfo.AdapterDetails.Description;
}
// 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.ClientSize = currentClientSize;
this.SendToBack();
this.BringToFront();
// 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 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -