⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enumeration.cs

📁 《3d游戏编程入门经典》中范例小游戏。使用C#+DirectX开发。
💻 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 + -