DirectX11编程2 龙书第四章练习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012632851/article/details/82288041

环境:VS2017  语言:C++

 

根据上一次的博文,龙书第四章后面有一些练习题,这边正好做一下。

 

先附上工程链接:https://github.com/anguangzhihen/Dx11

1.程序最好运行在Win32上;

2.如果Common下的脚本没有找到,请到工程/属性中添加包含目录;

3.所有的练习都在其中,全局搜索“练习”关键字就能找到,想要运行打开注释即可。

   

有任何的错误,请大佬们指正。

   

扫描二维码关注公众号,回复: 3415632 查看本文章

1.让Alt+Enter方式切换全屏/窗口无效。

答:

// 练习4.1,在CreateSwapChain函数调用后添加
HR(dxgiFactory->MakeWindowAssociation(mhMainWnd, DXGI_MWA_NO_WINDOW_CHANGES));

 

MakeWindowAssociation第二个参数可以填写三种值:

1)DXGI_MWA_NO_WINDOW_CHANGES,禁用全屏/窗口转换;

2)DXGI_MWA_NO_ALT_ENTER,禁用Alt+Enter的屏幕切换;

3)DXGI_MWA_NO_PRINT_SCREEN,禁用Print Screen键。

 

2.打印所有显卡的数量。

答:

// 练习4.2
UINT i = 0;
IDXGIAdapter* adapter = 0;
std::vector<IDXGIAdapter*> adapters;
while (dxgiFactory->EnumAdapters(i, &adapter) != DXGI_ERROR_NOT_FOUND)
{
	DXGI_ADAPTER_DESC desc;
	if (SUCCEEDED(adapter->GetDesc(&desc)))
	{
		std::wostringstream outs;
		outs << mMainWndCaption << L"显卡" << i << " " << desc.Description << L":" << L"\n";
		OutputDebugString(outs.str().c_str());
	}
		

	adapters.push_back(adapter);
	i++;
}
std::wostringstream outs;
outs << mMainWndCaption << L"显卡数量:" << adapters.size()<< L"\n" ;
OutputDebugString(outs.str().c_str());

效果:

 

关于Microsoft Basic Render Driver是在没有安装显卡驱动的情况下,使用基本通用驱动来运行GPU。

 

代码实际练习下来,连打Log都不会了,要不要这么难……

 

3.检查当前显卡是否支持dx11

答:

// 练习4.3,CheckInterfaceSupport方法只能用于检测dx10和vista以上系统,如果需要检测则直接创建接口,创建成功则支持(例如 ID3D11Device::CreateBlendState)
for (size_t i = 0; i < adapters.size(); i++)
{
	auto adapter = adapters[i];
	LARGE_INTEGER ver;
	if (adapter->CheckInterfaceSupport(__uuidof(ID3D10Device), &ver) == S_OK)
	{
		std::wostringstream outs;
		outs << mMainWndCaption << L"显卡" << i << L"支持Dx10\n";
		OutputDebugString(outs.str().c_str());
	}
	else
	{
		std::wostringstream outs;
		outs << mMainWndCaption << L"显卡" << i << L"不支持Dx10\n";
		OutputDebugString(outs.str().c_str());
	}

	// 使用CreateBlendState函数判断是否支持dx11
	ID3D11Device* device;
	HRESULT hr = D3D11CreateDevice(
		adapter,	// 使用指定的显卡
		D3D_DRIVER_TYPE_UNKNOWN,
		0,
		createDeviceFlags,
		0, 0,
		D3D11_SDK_VERSION,	// 我们使用Dx11的SDK
		&device,0,0);

	if (FAILED(hr))
	{
		MessageBox(0, L"Direct3D Reature Level 11 unsupported.", 0, 0);
		continue;
	}

	ID3D11BlendState* m_BlendState;
	D3D11_BLEND_DESC blendDesc = { 0 };
	blendDesc.RenderTarget[0].BlendEnable = TRUE;
	blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; // Color_Fsrc
	blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; // Color_Fdst
	blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; // Color_Operation
	blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; // Alpha_Fsrc
	blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; // Alpha_Fdst
	blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; // Alpha_Operation
	blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

	if (FAILED(device->CreateBlendState(&blendDesc, &m_BlendState)))
	{
		std::wostringstream outs;
		outs << mMainWndCaption << L"显卡" << i << L"不支持Dx11\n";
		OutputDebugString(outs.str().c_str());
	}
	else
	{
		std::wostringstream outs;
		outs << mMainWndCaption << L"显卡" << i << L"支持Dx11\n";
		OutputDebugString(outs.str().c_str());
	}
	ReleaseCOM(m_BlendState);
	ReleaseCOM(device);
}

书上说让我们用CheckInterfaceSupport,但是一查发现不支持dx11,google了一下,发现该方法只能用于dx10,真正有需要的话请用后面的方法吧。

 

4.输出默认显卡使用的显示器数量。

答:

// 练习4.4
auto adapterDef = adapters[0];
IDXGIOutput* output;
std::vector<IDXGIOutput*> outputs;

UINT index = 0;
while (adapterDef->EnumOutputs(index, &output) != DXGI_ERROR_NOT_FOUND)
{
	outputs.push_back(output);
	index++;
}

std::wostringstream outs1;
outs1 << mMainWndCaption << L"显示器数量:" << outputs.size() << L"\n";
OutputDebugString(outs1.str().c_str());

 

跟获取Adapter差不多,这类方法调用已经很熟练了。

 

每次打Log也蛮烦的,这边还是定义两个宏好了:

#define Log2(x, y){ std::wostringstream outs; outs << x << y << L"\n"; OutputDebugString(outs.str().c_str()); }
#define Log3(x, y, z){ std::wostringstream outs; outs << x << y << z << L"\n"; OutputDebugString(outs.str().c_str()); }

 

效果:

5.打印当前显示器所支持的分辨率和刷新率

// 练习4.5
for (size_t i = 0; i < outputs.size(); i++)
{
	UINT num = 0;
	IDXGIOutput* out = outputs[i];
	out->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &num, 0);

	DXGI_MODE_DESC* pDescs = new DXGI_MODE_DESC[num];
	out->GetDisplayModeList(DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_ENUM_MODES_INTERLACED, &num, pDescs);

	for (size_t i = 0; i < num; i++)
	{
		auto desc = pDescs[i];

		std::wostringstream outs;
		outs << "width:" << desc.Width << " height:" << desc.Height << " Rate:" << desc.RefreshRate.Numerator << "/" << desc.RefreshRate.Denominator  << L"\n"; 
		OutputDebugString(outs.str().c_str());
	}
}

效果:

 

6.尝试使用不同的Viewport参数显示游戏。

尝试下来没有发什么不同,看别的博主说需要填充其他东西才能看的出来,到时候再补一张图片吧。

猜你喜欢

转载自blog.csdn.net/u012632851/article/details/82288041