DirectX11编程2 红龙书第四章练习

环境:VS2017  语言:C++

 

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

 

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

1.这边的程序都是以win64运行的;

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

3.如果没有找到libs,请到工程/属性/链接器添加附加库目录“../Common/libs”

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

   

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

   

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参数显示游戏。

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

 

运行Skull Demo的效果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
DirectX 11 》是一本介绍DirectX 11图形编程的中文版教材。它详细解释了DirectX 11的基本概念、架构和功能,并提供了一系列示例和实践项目,旨在帮助读者深入理解和掌握DirectX 11的应用。 这本首先介绍了DirectX 11的基本概念和发展历史,包括DirectX图形API的前身及其版本间的演化过程。然后,中详细讲解了DirectX 11的基本架构和图形编程模型,涵盖了像素着色器、顶点着色器、几何着色器和计算着色器等关键概念。 中还重点介绍了DirectX 11的高级图形编程技术,包括着色器模型、纹理映射、多边形剔除和深度测试等,这些技术在真实场景的图形渲染中起到重要作用。此外,还介绍了DirectX 11中的阴影、反射、抗锯齿和HDR等高级效果的实现原理和应用方式。 《DirectX 11 》不仅仅注重理论知识的传授,还通过实际案例和项目来巩固读者的学习成果。中提供了许多示例代码和练习题,读者可以亲自动手实践,并通过编程实践来理解DirectX 11的各项功能和应用。 总体而言,这本为想要学习和掌握DirectX 11图形编程的读者提供了基础知识和实践经验。它结构清晰、内容详尽,既适合初学者入门,也适合有一定基础的读者进一步提高自己的图形编程水平。无论是对于游戏开发者、图形设计师还是计算机图形学爱好者来说,这本都是一本值得阅读的学习资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值