using System; using System.Configuration; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; using Microsoft.Samples.DirectX.UtilityToolkit; public class GameEngine : IDeviceCreation { ///程序入口。初始化所有部分并進入一個消息處理循環。用空閑時間顯示場景 static int Main() { using(Framework sampleFramework = new Framework()) { return sampleFramework.ExitCode; } } } |
![]() 圖1:添加引用對話框 |
Microsoft.DirectX.Direct3D.Device device = null; |
private Device device = null; |
/// 設備初始化的時候調用。這段代碼檢查設備最小的性能, /// 如果沒有通過檢查,就返回false public bool IsDeviceAclearcase/" target="_blank" >cceptable(Caps caps, Format adapterFormat, Format backBufferFormat, bool windowed) { if (!Manager.CheckDeviceFormat(caps.AdapterOrdinal, caps.DeviceType, adapterFormat, Usage.QueryPostPixelShaderBlending, ResourceType.Textures, backBufferFormat)) return false; if (caps.MaxActiveLights == 0) return false; return true; } /// 在建立某個設備之前,這個回調函數會被立即調用,以允許應用程序修改設備的 /// 設置信息。它提供的設置參數包含了框架組件為新設備挑選的設置, 并且應用程序 /// 可以直接對這個結構進行任何需要的修改。請注意,示例框架沒有糾正無效的 /// 設備設置信息,因此必須小心地返回有效的設備設置,否則建立設備就會失敗。 public void ModifyDeviceSettings(DeviceSettings settings, Caps caps) { // 這個應用程序沒有使用任何get方法,它被設計成在一個純設備上工作。 // 因此如果受到支持并且使用HWVP,就建立一個純設備。 if ( (caps.DeviceCaps.SupportsPureDevice) && ((settings.BehaviorFlags & CreateFlags.HardwareVertexProcessing) != 0 ) ) settings.BehaviorFlags |= CreateFlags.PureDevice; } |
請注意 后臺緩沖區是實際要顯示的數據(象素)在發送給顯卡處理并輸出到屏幕之前所存儲的地方。后臺緩沖區的格式決定了可以顯示多少種色彩。大多數格式遵循特定的命名習慣--每個字符跟著一個數字,例如A8R8G8B8。字符所指定的構成部分擁有與其后面的數字相同數量的位(bit)。在A8R8G8B8中,該格式可以包含32位色彩信息,alpha、red、green和blue各用8位。最常見的構成是: A Alpha R Red G Green B Blue X Unused |
請注意 窗體模式是我們運行的大多數應用程序的顯示方式。其中大多數應用程序帶有邊框和控制菜單,右上角帶有最小化、最大化和關閉按鈕。在全屏模式下,應用程序覆蓋了整個屏幕,并且在大多數情況下沒有邊框。如果全屏模式使用了另外的屏幕大?。惝斍笆褂玫淖烂妫?,你可以改變桌面的分辨率。 |
private Framework sampleFramework = null; // 示例的框架組件 /// 建立該類的一個新的實例 public GameEngine(Framework f) { // 存儲框架組件 sampleFramework = f; } |
// 查找系統中的每個適配器 for each(AdapterInformation ai in Manager.Adapters) { EnumAdapterInformation adapterInfo = new EnumAdapterInformation(); // 存儲一些信息 adapterInfo.AdapterOrdinal = (uint)ai.Adapter; // 序號 adapterInfo.AdapterInformation = ai.Information; // 信息 // 獲取這個適配器上的所有顯示模式 // 建立一個所有顯示適配器格式的臨時列表 adapterFormatList.Clear(); // 現在檢測支持哪種格式 for(int i = 0; i < allowedFormats.Length; i++) { // 檢查這種格式的每一種可支持的顯示模式 for each(DisplayMode dm in ai.SupportedDisplayModes[allowedFormats[i]]) { if ( (dm.Width < minimumWidth) || (dm.Height < minimumHeight) || (dm.Width > maximumWidth) || (dm.Height > maximumHeight) || (dm.RefreshRate < minimumRefresh) || (dm.RefreshRate > maximumRefresh) ) { continue; // 這種格式是無效的 } // 添加到列表中 adapterInfo.displayModeList.Add(dm); // 如果先前并不存在就把它添加到格式列表中 if (!adapterFormatList.Contains(dm.Format)) { adapterFormatList.Add(dm.Format); } } } // 獲取適配器顯示模式 DisplayMode currentAdapterMode = ai.CurrentDisplayMode; // 檢查這種格式是否在列表中 if (!adapterFormatList.Contains(currentAdapterMode.Format)) { adapterFormatList.Add(currentAdapterMode.Format); } // 對顯示模式列表進行排序 adapterInfo.displayModeList.Sort(sorter); // 獲取這個適配器上每個設備的信息 EnumerateDevices(adapterInfo, adapterFormatList); // 如果適配器上至少有一個設備,并且它是兼容的,就把它添加到列表中 if (adapterInfo.deviceInfoList.Count > 0) { adapterInformationList.Add(adapterInfo); } } |
請注意 這是一種通過把設備創建為適配器組的方式在"不同的"設備之間共享資源的方法。這種方法受到了少許限制。你可以查閱DirectX文檔了解更多的信息。 |
請注意 示例框架選擇的最小尺寸為640x480并不意味著在全屏模式下它就會選擇最小的尺寸。在全屏模式下,示例框架選擇最好的可用尺寸,它一般是當前桌面的大?。ㄍǔ2皇?40x480的)。 |
public class DisplayModeSorter : IComparer { /// 比較兩種顯示模式 public int Compare(object x, object y) { DisplayMode d1 = (DisplayMode)x; DisplayMode d2 = (DisplayMode)y; if (d1.Width > d2.Width) return +1; if (d1.Width < d2.Width) return -1; if (d1.Height > d2.Height) return +1; if (d1.Height < d2.Height) return -1; if (d1.Format > d2.Format) return +1; if (d1.Format < d2.Format) return -1; if (d1.RefreshRate > d2.RefreshRate) return +1; if (d1.RefreshRate < d2.RefreshRate) return -1; // 它們一定相同,所以返回0 return 0; } } |
private static void EnumerateDevices(EnumAdapterInformation adapterInfo, ArrayList adapterFormatList) { // 在查找設備類型的時候忽略任何異常 DirectXException.IgnoreExceptions(); // 列舉每個Direct3D設備類型 for(uint i = 0; i < deviceTypeArray.Length; i++) { // 建立一個新設備信息對象 EnumDeviceInformation deviceInfo = new EnumDeviceInformation(); // 存儲該類型 deviceInfo.DeviceType = deviceTypeArray[i]; // 試圖獲取其性能 deviceInfo.Caps = Manager.GetDeviceCaps((int)adapterInfo.AdapterOrdinal, deviceInfo.DeviceType); // 獲取該設備上每個設備組合的信息 EnumerateDeviceCombos( adapterInfo, deviceInfo, adapterFormatList); // 我們有設備組合嗎? if (deviceInfo.deviceSettingsList.Count > 0) { // 有,把它添加到列表中 adapterInfo.deviceInfoList.Add(deviceInfo); } } // 打開異常處理開關 DirectXException.EnableExceptions(); } |
private static void EnumerateDeviceCombos(EnumAdapterInformation adapterInfo, EnumDeviceInformation deviceInfo, ArrayList adapterFormatList) { // 查找這種設備支持哪種適配器格式 for each(Format adapterFormat in adapterFormatList) { for(int i = 0; i < backbufferFormatsArray.Length; i++) { bool windowed = false; do { if ((!windowed) && (adapterInfo.displayModeList.Count == 0)) continue; if (!Manager.CheckDeviceType((int)adapterInfo.AdapterOrdinal, deviceInfo.DeviceType, adapterFormat, backbufferFormatsArray[i], windowed)) continue; // 不支持的 // 我們需要加速象素陰影混合嗎? if (isPostPixelShaderBlendingRequired) { if (!Manager.CheckDeviceFormat( (int)adapterInfo.AdapterOrdinal, deviceInfo.DeviceType, adapterFormat, Usage.QueryPostPixelShaderBlending, ResourceType.Textures, backbufferFormatsArray[i])) continue; // 不支持的 } // 如果提供了某個應用程序回調函數,就要確保這個設備受到該應用程序的支持 if (deviceCreationInterface != null) { if (!deviceCreationInterface.IsDeviceAcceptable(deviceInfo.Caps, adapterFormat, backbufferFormatsArray[i],windowed)) continue; // 應用程序不喜歡這個設備 } EnumDeviceSettingsCombo deviceCombo = new EnumDeviceSettingsCombo(); // 存儲信息 deviceCombo.AdapterOrdinal = adapterInfo.AdapterOrdinal; deviceCombo.DeviceType = deviceInfo.DeviceType; deviceCombo.AdapterFormat = adapterFormat; deviceCombo.BackBufferFormat = backbufferFormatsArray[i]; deviceCombo.IsWindowed = windowed; BuildDepthStencilFormatList(deviceCombo); BuildMultiSampleTypeList(deviceCombo); if (deviceCombo.multiSampleTypeList.Count == 0) { continue; } BuildConflictList(deviceCombo); BuildPresentIntervalList(deviceInfo, deviceCombo); deviceCombo.adapterInformation = adapterInfo; deviceCombo.deviceInformation = deviceInfo; // 把組合添加到設備列表中 deviceInfo.deviceSettingsList.Add(deviceCombo); windowed = !windowed; } while (windowed); } } } |
原文轉自:http://www.anti-gravitydesign.com