http://www.d3dcoder.net/Data/Book4/d3d11Win10.htm
Direct3D 11 书中案例(Windows10和Visual Studio 2015)
最近,我收到一些关于在Visual Studio2015中编译Direct3D 11书中案例时的问题邮件,这篇文章将解释必要的步骤。先来了解一下为什么会出现问题。
从Windows8开始,DirectX不再是一个需要单独安装的SDK,相反,DirectX随操作系统一起发布,并通过Windows Update进行更新。此外,D3DX库已经被弃用,并且没有随Windows一起提供,XNA数学库现在名为DirectX Math。同样的,从Visual Studio 2015开始,dxerr.lib与Visual Studio 2015不再兼容。因此,我们构建和运行Direct3D 11案例的策略可以总结如下:
1、找到案例中使用的D3DX功能的替代方案,这比听起来更容易:因为DirectX团队已经开源了许多的D3DX功能。
2、切换到使用DirectX Math--这非常简单,因为库几乎是相同的,我们只需要考虑将DirectX Math中的所有东西放进DirectX命名空间。
3、找到dxerr.lib的替代方案或者不再使用它的功能。我们使用到这个库是为了我们的错误追踪代码:
#define HR(x) \
{ \
HRESULT hr = (x); \
if(FAILED(hr)) \
{ \
DXTrace(__FILEW__, (DWORD)__LINE__, hr, L#x, true); \
} \
}
注意,另一种方法是安装旧的June 2010 DirectX SDK来得到D3DX和XNA Math,但是它需要解决一些引入的额外的冲突,并且那个SDK已经是6年前本书撰写时的了,所以我们应该采取不需要下载旧SDK的方法。
下载
DX11书中使用的Effects框架,一个开源版本,并且兼容DirectX Windows 8及以上的Effects框架可以在这里找到:
https://github.com/Microsoft/FX11
下载源码,打开Effects11_2015解决方案文件并用Visual Studio2015在debug和release模式下重新构建。把debug库改名为Effects11d.lib,把release库改名为Effects11.lib。复制d3dx11effect.h, Effects11d.lib 和 Effects11.lib文件到书中的公共目录(覆盖旧的)
接下来,我们需要一个加载纹理的替代方案,同样的,D3DX中加载纹理的代码已经开源:
https://github.com/Microsoft/DirectXTex
拉取DDSTextureLoader,把DDSTextureLoader.h/.cpp拖进书中的公共目录,并添加进你的工程,我们将使用这个代码加载硬盘上的纹理。
最后,我们需要dxerr.lib的替代方案,这个博客总结了我们为什么需要这么做的详细原因https://blogs.msdn.microsoft.com/chuckw/2012/04/24/wheres-dxerr-lib/。简单来说,前面的链接(我看了下现在是在https://walbourn.github.io/wheres-dxerr-lib/)有一个到dxerr_nov2015.zip的链接,其中包含两个文件dxerr.h和dxerr.cpp,我们可以将其放入书中的公共目录以获得dxerr.lib的功能,将这两个文件放入你的工程。
读者可能还记得,D3DX也有一些有用的基于网格的代码,幸运的是,DirectX团队也发布了这段代码。这里是博客文章和一个链接的存储库:
https://blogs.msdn.microsoft.com/chuckw/2014/06/27/directxmesh/
https://github.com/Microsoft/DirectXMesh
对于那些感兴趣的人,您可以在Chuck Walbourn的博客:https://blogs.msdn.microsoft.com/chuckw/上阅读关于DirectX的历史变化
项目更改:
在C/C++属性页 > 通用, 加载书中的公共目录到“Additional Include Directories”列表
在链接器属性页 > 通用, 加载书中的公共目录到“Additional Library Directories”列表.
代码更改:
在本节中,我们将描述构建和运行“BlendDemo”所需的更改。
删除所有#include
删除对dxerr.lib库的依赖,添加dxerr.h/.cpp到工程并更改#include
在d3dUtil.h中添加#include "DDSTextureLoader.h"。
把所有的#include
所有DirectX数学类型(XMVECTOR、XMFLOAT4X4、XMMatrixTranspose等)都需要以“DirectX::”作为前缀,因为它们现在位于DirectX命名空间中。
所有对XMCOLOR的引用都需要用DirectX::PackedVector作为前缀,因为XMCOLOR位于DirectX::PackedVector命名空间中。
删除对D3DX11INLINE的所有引用。你可以删除它或者用内联替换。
从d3dUtil.h中删除helper函数d3dHelper::CreateTexture2DArraySRV。您可以使用texassemble工具(https://directxtex.codeplex.com/wikipage?title=Texassemble&referringTitle=Texconv)离线创建一个纹理数组,这是首选的过程。
在d3dUtil.h中,用__FILEW__替换DXTrace调用中的__FILE__,这样我们就可以得到一个宽字符串。
在d3dUtil.h中,像这样重写extractfrustumplane(这个改变是为将输入矩阵转换成XMFLOAT4X4,这样我们就可以使用重载括号运算符来获取元素):
void ExtractFrustumPlanes(XMFLOAT4 planes[6], CXMMATRIX T)
{
XMFLOAT4X4 M;
XMStoreFloat4x4(&M, T);
//
// Left
//
planes[0].x = M(0,3) + M(0,0);
planes[0].y = M(1,3) + M(1,0);
planes[0].z = M(2,3) + M(2,0);
planes[0].w = M(3,3) + M(3,0);
//
// Right
//
planes[1].x = M(0,3) - M(0,0);
planes[1].y = M(1,3) - M(1,0);
planes[1].z = M(2,3) - M(2,0);
planes[1].w = M(3,3) - M(3,0);
//
// Bottom
//
planes[2].x = M(0,3) + M(0,1);
planes[2].y = M(1,3) + M(1,1);
planes[2].z = M(2,3) + M(2,1);
planes[2].w = M(3,3) + M(3,1);
//
// Top
//
planes[3].x = M(0,3) - M(0,1);
planes[3].y = M(1,3) - M(1,1);
planes[3].z = M(2,3) - M(2,1);
planes[3].w = M(3,3) - M(3,1);
//
// Near
//
planes[4].x = M(0,2);
planes[4].y = M(1,2);
planes[4].z = M(2,2);
planes[4].w = M(3,2);
//
// Far
//
planes[5].x = M(0,3) - M(0,2);
planes[5].y = M(1,3) - M(1,2);
planes[5].z = M(2,3) - M(2,2);
planes[5].w = M(3,3) - M(3,2);
// Normalize the plane equations.
for(int i = 0; i < 6; ++i)
{
XMVECTOR v = XMPlaneNormalize(XMLoadFloat4(&planes[i]));
XMStoreFloat4(&planes[i], v);
}
}
使用DirectX::createddstextureomfile替换D3DX11CreateShaderResourceViewFromFile进行纹理加载。例如,在“Blend Demo”中我们替换:
HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice,
L"Textures/grass.dds", 0, 0, &mGrassMapSRV, 0 ));
HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice,
L"Textures/water2.dds", 0, 0, &mWavesMapSRV, 0 ));
HR(D3DX11CreateShaderResourceViewFromFile(md3dDevice,
L"Textures/WireFence.dds", 0, 0, &mBoxMapSRV, 0 ));
为
ID3D11Resource* texResource = nullptr;
HR(DirectX::CreateDDSTextureFromFile(md3dDevice,
L"Textures/grass.dds", &texResource, &mGrassMapSRV));
ReleaseCOM(texResource); // view saves reference
HR(DirectX::CreateDDSTextureFromFile(md3dDevice,
L"Textures/water2.dds", &texResource, &mWavesMapSRV));
ReleaseCOM(texResource); // view saves reference
HR(DirectX::CreateDDSTextureFromFile(md3dDevice,
L"Textures/WireFence.dds", &texResource, &mBoxMapSRV));
ReleaseCOM(texResource); // view saves reference
此时,“Blend Demo”应该已经构建并运行了。