您的位置:首页 > 其它

【DX11习题学习一】第四章练习 Direct3D Foundations

2016-06-20 16:30 489 查看
本系列只针对书中每章节的编程练习题,不涉及书中的数学题,需要数学部分的解答请点击

对应原书 P137 4.7EXERCISES

1. Modify the previous exercise solution by disabling theALT-ENTER functionality to switch between full screen and windowed mode; use the IDXGIFactory::MakeWindowAssociation method and specify
theDXGI_MWA_NO_WINDOW_CHANGES flag so that DXGI does not monitor the message queue. Note that theIDXGIFactory::MakeWindowAssociation method needs to be called afterIDXGIFactory::CreateSwapChain is called.

//创建交换链
IDXGIDevice* dxgiDevice = 0;
HR(md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice));
IDXGIAdapter* dxgiAdapter = 0;
HR(dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter));
IDXGIFactory* dxgiFactory = 0;
HR(dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory));
//调用MakeWindowAssociation方法前交换链必须已经创建
HR(dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain));
//Qu.1
HR(dxgiFactory->MakeWindowAssociation(mhMainWnd, DXGI_MWA_NO_WINDOW_CHANGES));


2. Some systems have more than one adapter (video card), and the application may wish to let the user choose which one to use, instead of always using the default adapter. Use the IDXGIFactory::EnumAdapters method
to determine how many adapters are on your system.

题意:有些电脑会有数个显卡,调用EnumAdapters 方法来看看电脑有多少个显卡吧

3. For each adapter the system possesses, IDXGIFactory::EnumAdapters outputs a pointer to a filled out IDXGIAdapter interface. This interface can be used to query
information about the adapter. Use the IDXGIAdapter::CheckInterfaceSupport method to see if the adapters on your system support Direct3D 11.

题意:对于每张显卡,EnumAdapters 方法常被调用来获取该显卡的信息并放到 IDXGIAdapter中,请使用CheckInterfaceSupport 方法来查看该是否支持DX11

<span style="font-size:14px;">//第2问和第3问的解答, 变量i表示第i张显卡,</span><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:10px;">dxgiAdapter在创建交换链时声明</span></span><span style="font-size:14px;">

UINT i = 0;
//std::vector<IDXGIAdapter*> vAdapters;
while (dxgiFactory->EnumAdapters(i, &dxgiAdapter) != DXGI_ERROR_NOT_FOUND)
{
if (dxgiAdapter->CheckInterfaceSupport(__uuidof(ID3D10Device), 0) != S_OK)
MessageBox(0, L"Direct3D 11 not supported", L"Support check", MB_OK);
++i;
}</span>


4.An adapter has outputs associated with it (e.g., a monitor). You can use the IDXGIAdapter::EnumOutputs method to enumerate the outputs for a particular adapter. Use this method to determine the number of outputs
for the default adapter.

题意:对于每张显卡,可以对应多个输出设备(如:显示器),请调用EnumOutputs 来看看默认显卡对应多少个输出设备

UINT i = 0;
IDXGIOutput * pOutput;
std::vector<IDXGIOutput*> vOutputs;
while(pAdapter->EnumOutputs(i, &pOutput) != DXGI_ERROR_NOT_FOUND)
{
vOutputs.push_back(pOutput);
++i;
}
//可使用MessageBox显示信息vOutputs.size()


5. Each output has a list of supported display modes (DXGI_MODE_DESC) for a given pixel format. For each output (IDXGIOutput), show the width, height, and refresh rate of each display mode the
output supports for the DXGI_FORMAT_R8G8B8A8_UNORM format using theIDXGIOutput::GetDisplayModeList method.

题意:通过调用GetDisplayModeList 输出关于显卡的显示模式信息

以下代码摘自网上,也包含了前几问相应调用函数的用法

#include <Windows.h>
#include <iostream>
#include <DXGI.h>
#include <vector>

using namespace std;

int main()
{
// 参数定义
IDXGIFactory * pFactory;
IDXGIAdapter * pAdapter;
std::vector <IDXGIAdapter*> vAdapters;            // 显卡

// 显卡的数量
int iAdapterNum = 0;

// 创建一个DXGI工厂
HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory));

if (FAILED(hr))
return -1;

// 枚举适配器
while (pFactory->EnumAdapters(iAdapterNum, &pAdapter) != DXGI_ERROR_NOT_FOUND)
{
vAdapters.push_back(pAdapter);
++iAdapterNum;
}

// 信息输出
cout << "===============获取到" << iAdapterNum << "块显卡===============" << endl;
for (size_t i = 0; i<vAdapters.size(); i++)
{
// 获取信息
DXGI_ADAPTER_DESC adapterDesc;
vAdapters[i]->GetDesc(&adapterDesc);

// 输出显卡信息
cout << "系统视频内存:" << adapterDesc.DedicatedSystemMemory / 1024 / 1024 << "M" << endl;
cout << "专用视频内存:" << adapterDesc.DedicatedVideoMemory / 1024 / 1024 << "M" << endl;
cout << "共享系统内存:" << adapterDesc.SharedSystemMemory / 1024 / 1024 << "M" << endl;
cout << "设备描述:" << adapterDesc.Description << endl;
cout << "设备ID:" << adapterDesc.DeviceId << endl;
cout << "PCI ID修正版本:" << adapterDesc.Revision << endl;
cout << "子系统PIC ID:" << adapterDesc.SubSysId << endl;
cout << "厂商编号:" << adapterDesc.VendorId << endl;

// 输出设备
IDXGIOutput * pOutput;
std::vector<IDXGIOutput*> vOutputs;
// 输出设备数量
int iOutputNum = 0;
while (vAdapters[i]->EnumOutputs(iOutputNum, &pOutput) != DXGI_ERROR_NOT_FOUND)
{
vOutputs.push_back(pOutput);
iOutputNum++;
}

cout << "-----------------------------------------" << endl;
cout << "获取到" << iOutputNum << "个显示设备:" << endl;
cout << endl;

for (size_t n = 0; n<vOutputs.size(); n++)
{
// 获取显示设备信息
DXGI_OUTPUT_DESC outputDesc;
vOutputs
->GetDesc(&outputDesc);

// 获取设备支持
UINT uModeNum = 0;
DXGI_FORMAT format = DXGI_FORMAT_R8G8B8A8_UNORM;
UINT flags = DXGI_ENUM_MODES_INTERLACED;

vOutputs
->GetDisplayModeList(format, flags, &uModeNum, 0);
DXGI_MODE_DESC * pModeDescs = new DXGI_MODE_DESC[uModeNum];
vOutputs
->GetDisplayModeList(format, flags, &uModeNum, pModeDescs);

cout << "显示设备名称:" << outputDesc.DeviceName << endl;
cout << "显示设备当前分辨率:" << outputDesc.DesktopCoordinates.right - outputDesc.DesktopCoordinates.left << "*" << outputDesc.DesktopCoordinates.bottom - outputDesc.DesktopCoordinates.top << endl;
cout << endl;

// 所支持的分辨率信息
cout << "分辨率信息:" << endl;
for (UINT m = 0; m<uModeNum; m++)
{
cout << "== 分辨率:" << pModeDescs[m].Width << "*" << pModeDescs[m].Height << "     刷新率" << (pModeDescs[m].RefreshRate.Numerator) / (pModeDescs[m].RefreshRate.Denominator) << endl;
}
}
vOutputs.clear();

}
vAdapters.clear();

system("pause");
return 0;
}


6. Experiment with modifying the viewport settings to draw the scene into a subrectangle of the back buffer. 

题意:修改视口的参数设置,在后缓冲区绘制一个子矩形来显示场景

//设置视口参数
//ID3D11DeviceContext* md3dImmediateContext;
mScreenViewPort.TopLeftX = 100.0f;
mScreenViewPort.TopLeftY = 100.0f;
mScreenViewPort.Width = 500.0f;//static_cast<float>(mClientWidth);
mScreenViewPort.Height = 400.0f;//static_cast<float>(mClientHeight);
mScreenViewPort.MinDepth = 0.0f;
mScreenViewPort.MaxDepth = 1.0f;
//需要在OMSetRenderTargets方法调用成功后在调用RSSetViewports
md3dImmediateContext->RSSetViewports(1, &mScreenViewPort);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: