在x_jun 的DX11 入门教程里面留了一些作业,本篇文章是第一篇文章的课后作业
原文链接 :DirectX11 With Windows SDK--01 DirectX11初始化
尝试修改项目代码,让窗口内的显示变红
这个问题比较简单 我们找到 DrawScene() 函数把static float blue[4] = { 0.0f, 0.0f, 1.0f, 1.0f };
这个代码段改为static float red[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
即可,记得修改参数某些电脑可能有多于一个的显示适配器(显卡)。首先要通过
CreateDXGIFactory
创建IDXGIFactory
,然后使用IDXGIFactory::EnumAdapters
来枚举显示适配器。尝试通过这种方式查看你的电脑有多少个显示适配器(IDXGIAdapter)
,并察看它们的信息。
这个问题首先我在D3DApp::InitDirect3D()
函数的最后,按照问题的提示 添加了如下代码// 先创建Factory 和 adapter ComPtr<IDXGIFactory> Factory = nullptr; ComPtr<IDXGIAdapter> adapter = nullptr; // 根据函数的要求添加参数 CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void**>(Factory.GetAddressOf())); // 枚举显示适配器 可以修改一下 数字 枚举 Factory->EnumAdapters(0, adapter.GetAddressOf()); // 通过 GetDesc函数去获取 adapter的描述,需要填充一个 DXGI_ADAPTER_DESC DXGI_ADAPTER_DESC apDesc; adapter->GetDesc(&apDesc); // 输出 Description // 把WCHAR 类型转为char 需要添加 #include <comdef.h>头文件 _bstr_t b(apDesc.Description); const char* s = b; // 这个是格式化输出 可以在输出中打印字符 要是用这个先要添加 最下面的宏 OUTINFO_1_PARAM("IDXGIAdapter----DEBUG----%s\n", s); // OUTINFO 系列的宏定义 (百度的) //输出调试信息--在DebugView软件里面看调试信息 #define OUTINFO_0_PARAM(fmt) {CHAR sOut[256];CHAR sfmt[50];sprintf_s(sfmt,"%s%s","INFO--",fmt);sprintf_s(sOut,(sfmt));OutputDebugStringA(sOut);} #define OUTINFO_1_PARAM(fmt,var) {CHAR sOut[256];CHAR sfmt[50];sprintf_s(sfmt,"%s%s","INFO--",fmt);sprintf_s(sOut,(sfmt),var);OutputDebugStringA(sOut);} #define OUTINFO_2_PARAM(fmt,var1,var2) {CHAR sOut[256];CHAR sfmt[50];sprintf_s(sfmt,"%s%s","INFO--",fmt);sprintf_s(sOut,(sfmt),var1,var2);OutputDebugStringA(sOut);} #define OUTINFO_3_PARAM(fmt,var1,var2,var3) {CHAR sOut[256];CHAR sfmt[50];sprintf_s(sfmt,"%s%s","INFO--",fmt);sprintf_s(sOut,(sfmt),var1,var2,var3);OutputDebugStringA(sOut);}
运行程序我们就能到看详细信息了 如图所示:
一个显示适配器可能关联了多个输出设备
(IDXGIOutput)
,你可以使用IDXGIAdapter::EnumOutputs
方法来枚举出特定的输出,尝试观察它们的信息
紧跟着在上一个问题的代码后面添加ComPtr<IDXGIOutput> output = nullptr; // 尝试修改函数中的数字 观察控制台输出 adapter->EnumOutputs(0, output.GetAddressOf()); DXGI_OUTPUT_DESC outDesc; output->GetDesc(&outDesc); _bstr_t out(outDesc.DeviceName); const char* o = out; OUTINFO_1_PARAM("IDXGIOutput---DEBUG----- %s\n", o);
我的输出如下
对于给定的像素格式,一个输出设备可以支持许多种显示模式
(DXGI_MODE_DESC)
,通过它可以看到全屏宽度、高度、刷新率。尝试使用IDXGIOutput::GetDisplayModeList
方法观察所有支持的模式(传递DXGI_FORMAT_R8G8B8A8_UNORM
格式进去)。
在下面添加代码UINT num = 0; DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM; UINT flags = DXGI_ENUM_MODES_INTERLACED; output->GetDisplayModeList(format, flags, &num, 0); DXGI_MODE_DESC* pDescs = new DXGI_MODE_DESC[num]; output->GetDisplayModeList(format, flags, &num, pDescs); OUTINFO_1_PARAM("dasda-%d\n",pDescs->Width);
通过debug 断点调试我们可以发现如图
默认情况下的窗口程序是可以通过ALT+ENTER来进入/退出全屏的。此外,我们可以通过
IDXGISwapChain
来动态设置窗口全屏属性,找到对应的方法并尝试一下。m_pSwapChain->SetFullscreenState(true, nullptr);
现在尝试指定显示适配器来创建D3D设备。通过
CreateDXGIFactory
函数来创建IDXGIFactory
,通常它会包含接口IDXGIFactory1
,但有可能它也会包含接口IDXGIFactory2。在没有创建D3D设备的情况下,这种方式就可以帮助我们了解是否可以创建出Direct3D 11.1的设备。为了能够指定显示适配器来创建D3D11设备,我们需要将D3D_DRIVER_TYPE
强行设置为D3D_DRIVER_TYPE_UNKNOWN
,否则在创建设备的时候会得到如下报错信息:DX ERROR: D3D11CreateDevice: When creating a device from an existing adapter (i.e. pAdapter is non-NULL), DriverType must be D3D_DRIVER_TYPE_UNKNOWN. [ INITIALIZATION ERROR #3146141: ]
找到InitDirect3D()
函数在遍历驱动类型数组的for循环上面添加
```cpp ComPtr<IDXGIAdapter> dxgiAdapter = nullptr; ComPtr<IDXGIFactory> dxgiFactory = nullptr; CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void**>(dxgiFactory.GetAddressOf())); dxgiFactory->EnumAdapters(0, dxgiAdapter.GetAddressOf()); //修改D3D11CreateDevice() 函数 将第一个参数设置为 dxgiAdapter.Get() ```