📄 enumeration.cs
字号:
/// Enumeration.cs
/// This class will hold the enumeration methods
using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
namespace Blockers
{
#region Helper objects
/// <summary>
/// Hold information about each adapter
/// </summary>
internal struct GraphicsInfo
{
public bool canUse;
public AdapterDetails info;
public int adapterOrdinal;
public Caps deviceCaps;
public bool canRenderWindow;
public DisplayMode[] supportedModes;
public CreateFlags[] vertexProcessing;
public uint currentMode;
}
/// <summary>
/// Will be used to sort display modes
/// </summary>
internal class DisplayModeComparer : System.Collections.IComparer
{
#region IComparer Members
/// <summary>
/// Compare two display modes
/// </summary>
public int Compare(object x, object y)
{
DisplayMode dm1 = (DisplayMode)x;
DisplayMode dm2 = (DisplayMode)y;
// Sort by format first
if (dm1.Format != dm2.Format)
{
switch(dm1.Format)
{
case Format.X8R8G8B8:
switch(dm2.Format)
{
case Format.A8R8G8B8:
return +1;
case Format.R5G6B5:
return +1;
case Format.X1R5G5B5:
return +1;
case Format.A1R5G5B5:
return +1;
}
break;
case Format.A8R8G8B8:
switch( dm2.Format )
{
case Format.X8R8G8B8:
return -1;
case Format.R5G6B5:
return +1;
case Format.X1R5G5B5:
return +1;
case Format.A1R5G5B5:
return +1;
}
break;
case Format.R5G6B5:
switch( dm2.Format )
{
case Format.A8R8G8B8:
return -1;
case Format.X8R8G8B8:
return -1;
case Format.X1R5G5B5:
return +1;
case Format.A1R5G5B5:
return +1;
}
break;
case Format.X1R5G5B5:
switch( dm2.Format )
{
case Format.A8R8G8B8:
return -1;
case Format.X8R8G8B8:
return -1;
case Format.R5G6B5:
return -1;
case Format.A1R5G5B5:
return +1;
}
break;
case Format.A1R5G5B5:
switch( dm2.Format )
{
case Format.A8R8G8B8:
return -1;
case Format.X8R8G8B8:
return -1;
case Format.R5G6B5:
return -1;
case Format.X1R5G5B5:
return -1;
}
break;
}
}
// if the formats are the same, sort by width/height
if (dm1.Width < dm2.Width) return -1;
if (dm1.Width > dm2.Width) return +1;
if (dm1.Height < dm2.Height) return -1;
if (dm1.Height > dm2.Height) return +1;
// All else fails, they must be equal
return 0;
}
#endregion
}
#endregion
/// <summary>
/// Will hold the list of devices that are supported for our
/// application
/// </summary>
public class DeviceList
{
#region Constant Data
private const int MinimumWidth = 800;
private const int MinimumHeight = 600;
#endregion
#region Instance Data
private GraphicsInfo[] adapters = null;
private int indexAdapter = 0;
#endregion
#region Class Methods
/// <summary>
/// Builds the list of devices supported.
/// </summary>
/// <returns>true if devices were found; false otherwise</returns>
public bool Build()
{
uint numberAdapters = 0;
// How many adapters do we have?
adapters = new GraphicsInfo[Manager.Adapters.Count];
int i = 0;
// Go through each adapter in the system
foreach(AdapterInformation ai in Manager.Adapters)
{
// Store information for this adapter
adapters[i].adapterOrdinal = ai.Adapter;
adapters[i].info = ai.Information;
adapters[i].canUse = false;
// Store any display modes and formats
uint numberModes = 0;
uint numberFormats = 0;
DisplayMode[] modes = new DisplayMode[100];
Format[] formats = new Format[20];
// Make sure the current display format is in the list
formats[numberFormats++] = ai.CurrentDisplayMode.Format;
// Now add each other format
foreach(DisplayMode dm in ai.SupportedDisplayModes)
{
// Filter out any resolution modes that are too small for our use
// We will use a constant value here for easily changing it.
if ((dm.Width < MinimumWidth) || (dm.Height < MinimumHeight))
continue;
// Ok, this mode is good enough, filter out any refresh rate duplicates
uint checkmode;
for (checkmode = 0; checkmode < numberModes; checkmode++)
{
if ((modes[checkmode].Width == dm.Width) &&
(modes[checkmode].Height == dm.Height) &&
(modes[checkmode].Format == dm.Format))
break;
}
// If this is a new mode, add it to the list of modes we are storing
if (checkmode == numberModes)
{
modes[numberModes] = dm;
modes[numberModes].RefreshRate = 0; // We don't care about refresh
numberModes++;
}
// Now check to see if this format is new
uint checkformat;
for(checkformat = 0; checkformat < numberFormats; checkformat++)
{
if (dm.Format == formats[checkformat])
break;
}
// Is the format new?
if (checkformat == numberFormats)
{
// Add it to the list
formats[checkformat++] = dm.Format;
}
}
// Get an array of just the modes we will be using
DisplayMode[] realModes = new DisplayMode[numberModes];
Array.Copy(modes, 0, realModes, 0, numberModes);
modes = realModes;
// Sort the modes
Array.Sort(modes, new DisplayModeComparer());
try
{
adapters[i].deviceCaps = Manager.GetDeviceCaps(ai.Adapter, DeviceType.Hardware);
adapters[i].canRenderWindow = false;
adapters[i].currentMode = 0;
// We can check the device for our formats now
bool[] canUseFormat = new bool[numberFormats];
CreateFlags[] vert = new CreateFlags[numberFormats];
for(int j = 0; j < numberFormats; j++)
{
// By default, say no
canUseFormat[j] = false;
if (!Manager.CheckDeviceType(ai.Adapter, DeviceType.Hardware, formats[j],
formats[j], false))
continue;
// Ok, can the device do hardware?
if (adapters[i].deviceCaps.DeviceCaps.SupportsHardwareTransformAndLight)
{
vert[j] = CreateFlags.HardwareVertexProcessing;
// Can this device also do pure devices?
if (adapters[i].deviceCaps.DeviceCaps.SupportsPureDevice)
{
// Yes, use a pure hardware device
vert[j] |= CreateFlags.PureDevice;
}
canUseFormat[j] = true;
}
// If not, set the software flag
if (!canUseFormat[j])
{
vert[j] = CreateFlags.SoftwareVertexProcessing;
canUseFormat[j] = true;
}
}
// Add all of the enumerated display modes with formats
// that can be used to the devices list of valid modes
DisplayMode[] testModes = new DisplayMode[numberModes];
CreateFlags[] testVerts = new CreateFlags[numberModes];
uint adapterNumModes = 0;
for (int j = 0; j < numberModes; j++)
{
for(int testFormat = 0; testFormat < numberFormats; testFormat++)
{
if (canUseFormat[testFormat])
{
// This is a valid device, store information
testModes[adapterNumModes] = modes[j];
testVerts[adapterNumModes] = vert[testFormat];
adapterNumModes++;
}
}
}
// Perfect, now store the modes
adapters[i].supportedModes = new DisplayMode[adapterNumModes];
adapters[i].vertexProcessing = new CreateFlags[adapterNumModes];
Array.Copy(testModes, 0, adapters[i].supportedModes, 0, adapterNumModes);
Array.Copy(testVerts, 0, adapters[i].vertexProcessing, 0, adapterNumModes);
// Now pick a default mode, choose the minimum supported if possible, also
// you should prefer a 16bit mode over 32bit
for(uint j = 0; j < adapters[i].supportedModes.Length; j++)
{
if ((adapters[i].supportedModes[j].Width == MinimumWidth) &&
(adapters[i].supportedModes[j].Height == MinimumHeight))
{
adapters[i].currentMode = j;
// If this is a 16bit mode, we're golden
if ((adapters[i].supportedModes[j].Format == Format.R5G6B5) ||
(adapters[i].supportedModes[j].Format == Format.X1R5G5B5) ||
(adapters[i].supportedModes[j].Format == Format.A1R5G5B5))
{
break;
}
}
}
// Check to see if the device is compatible with the desktop display mode
// which we stored before.
if ((canUseFormat[0]) &&
(Manager.CheckDeviceType(ai.Adapter, DeviceType.Hardware, ai.CurrentDisplayMode.Format,
ai.CurrentDisplayMode.Format, true)))
{
adapters[i].canRenderWindow = true;
}
// This device is valid if modes were found
if (adapterNumModes > 0)
{
adapters[i].canUse = true;
numberAdapters++;
}
i++;
}
catch
{
adapters[i].canUse = false;
}
}
if (numberAdapters == 0)
{
// no adapters were found that will work for our application
System.Diagnostics.Debugger.Log(0, GameEngine.GameName, "No valid adapters found on system.");
return false;
}
// Can the device render windowed?
for(int j = 0; j < numberAdapters; j++)
{
if (adapters[j].canRenderWindow)
{
return true;
}
}
// no adapters were found that will work for our application
System.Diagnostics.Debugger.Log(0, GameEngine.GameName, "All devices found only support full screen.");
return false;
}
#endregion
#region Properties
/// <summary>
/// The index of the adapter
/// </summary>
public int AdapterIndex
{
get { return indexAdapter; }
}
/// <summary>
/// Retreive the adapter information
/// </summary>
internal GraphicsInfo[] AdapterInfo
{
get { return adapters; }
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -