【问题标题】:DirectX 11 EffectsDirectX 11 效果
【发布时间】:2014-08-03 13:46:40
【问题描述】:

我正在尝试学习 DirectX 11,并且正在使用适用于 Windows 7 的 Visual Studio 2013 编写一个小型应用程序。我正在关注“使用 DirectX 11 进行 3D 游戏编程简介”一书,到目前为止一切正常。我刚刚阅读了本书中展示 BoxApp 示例的部分,我只是在编写代码,试图在我的应用中实现类似的东西,以便更好地了解正在发生的事情。

我遇到了示例代码中使用的以下已弃用库函数的问题:

D3DX11CompileFromFile(....);
D3DX11CreateEffectFromMemory(...);

首先只是想看看我是否理解为什么这些不再可用,我对为什么这些函数不再存在的理解是 Windows 8 已弃用 D3DX 头文件和库。最初它们是提供的帮助程序库Dx9 的 DirectX SDK,然后由操作系统为 Dx10 提供,然后在 Dx11.1(2) 中被弃用?

现在我的主要问题是如何在没有弃用 D3DX 标头的情况下编译着色器和效果?我只是对解决这个问题的正确方法有点困惑。

在我看来有两种选择:

  1. 下载帮助程序库 Effects11,它将提供与以前类似的功能。
  2. 使用 D3DCompiler 库并手动编译效果。

就像我说的那样,我不太确定哪个是最好的选择(或者即使有更好的替代选择)。我的理解是 Effects11 的引入更多是为了支持需要移植到 Dx11 的旧 Dx10。由于我没有任何要移植的 Dx10 代码,因此我对这种支持并不太在意,我对 Windows 8 中的 Metro 应用程序支持也不太在意(我认为这对他们来说是正确的术语?)但是如果 D3DCompiler path 也意味着对 Metro 应用程序的支持,那么我想这是可取的。

无论如何,我们将不胜感激任何建议或见解。提前致谢。

【问题讨论】:

    标签: c++ visual-studio-2013 directx-11 direct3d11 d3dx


    【解决方案1】:

    好吧,回顾一下 Direct3DX 实用程序库 (D3DX) 的历史可能会有所帮助。它最初作为 DirectX 7 SDK 的一部分作为静态库提供,您可以直接链接到应用程序中。它涵盖了许多与现在相同的功能,但值得注意的是它不支持效果,因为直到 Direct3D 8 才引入着色器。

    这一切都运行良好,直到有一天微软认为静态库是一个很大的安全漏洞。这可能是因为在 GDI+ 中发现了一些令人讨厌的错误,导致许多使用 GDI+ 的应用程序容易受到与畸形图像相关的攻击。尽管 GDI+ 是作为 DLL 发布的,但每个使用它的应用程序都会在自己的安装目录中安装自己的副本。这意味着微软不能简单地使用 Windows 更新修补 GDI+ DLL,每个使用它的应用程序都必须创建自己的补丁并将其分发给用户。

    因此,Microsoft 决定向开发人员提供二进制代码以包含在他们的应用程序中是一个错误。 Microsoft 提供的任何二进制代码都必须通过 Windows Update 进行更新。这意味着不再有共享库以及对如何重新分发和安装 DLL 的新限制。这就是重新分发 D3DX DLL 时需要使用 DirectX 运行时安装程序的原因。 (这也是为什么 Visual Studio 具有涉及清单及其可再分发 DLL 的所有复杂要求的原因。)

    但问题在于,它导致 Microsoft 每次更改 D3DX DLL 时都必须创建一个新版本,这几乎是每次他们发布 SDK 的新版本时。每个新的 DLL 都不向后兼容旧的 DLL,因此它有了一个新名称。如果您查看system32 目录,您可能会发现几十个不同的D3DX DLL。

    (显然 D3DX 中只有一个安全漏洞被披露过,CVE-2006-4183。据我所知,这只是在 SDK 的后续版本中修复,没有发布补丁来修复旧版本 D3DX DLL 中的错误.)

    最终,Microsoft 决定停止发布新版本的 DirectX SDK,并将其作为 Windows SDK 的一部分。除了 D3DX 之外的所有东西,所以就微软而言,它几乎已经死了。无需维护、无需改进、无需更换。

    然后有一天微软决定从本质上开源 D3DX 库,因为我不知道。所以我们几乎回到了我们开始的地方,应用程序将库直接链接到它们的可执行文件中。除了现在它是开源的,而不是二进制文件,所以任何与安全相关的错误都不是微软的问题。

    所以你基本上有四个选择:

    • 使用上一版 DirectX SDK(2010 年 6 月)中的 D3DX DLL
    • 使用开源的 Effect11 库
    • 编写自己的代码
    • 使用某种第三方中间件

    第一个选项意味着您可能需要将 DirectX redist 与您的安装程序捆绑在一起。让它在新版本的 Visual Studio 中工作也是一个相当复杂的过程。第二种选择意味着您最终要负责让它发挥作用。第三种选择也是如此,它可能需要做更多的工作。第四个选项可能不存在。所以我认为作为一个新的 Direct3D 程序员,现在最好使用开源库。

    另一种选择是使用已经建立的游戏引擎,例如 Unreal 或 Unity,但我假设您已经排除了这种可能性。

    【讨论】:

    • 感谢您提供详细的历史记录,我一直有兴趣了解此类内容。是的,我打折了其他引擎,我基本上是在业余时间尝试学习 DirectX,以便在我工作的地方更新一些图形库,再加上我一直感兴趣但没有时间的东西学习。所以从你所说的最新版本的 DirectX 现在不再支持 D3DX,所以从我可以看到创建着色器的“新”方法是使用 HLSL 编译器 API 编译 .hlsl 文件并在运行时链接或链接到预编译的着色器?
    • 另外只是补充一点,我很可能会查看您提供的解决方案之一(感谢那些他们几乎确认了我所期望的选项),因为这似乎是最简单的前进的道路,我只是想了解 D3DX 有效地消失了,DirectX 程序员的实际期望是什么 :)
    • 没有一种创建着色器的新方法。您总是不能使用效果并直接调用编译器。所改变的只是微软如何分发实现效果的最新版本的代码。旧的 Direct3D 11 D3DX DLL 效果代码仍然适用于当前版本的 DirectX。开源的 Effect11 代码仍然适用于当前版本的 DirectX。微软希望你做的是编写一个只能在 Windows 8 上运行的 Windows 应用商店应用程序,所以不要太看重微软似乎期望的东西。
    • 啊,我明白了。好的,这是有道理的。感谢您提供信息。
    • 除了担心 D3DX 的安全驱动服务之外,静态库还存在编译器和 CRT 特定的问题。如果您使用 VC 版本 A 构建了一个库,并尝试将其与 VC 版本 B 一起使用,那么就会发生不好的事情。 DLL 有一个更正式的 ABI,所以这不是一个问题。
    【解决方案2】:

    “Effects 11”运行时的最新版本在 CodePlex

    此时使用 Effects 11 有两个主要问题:

    (1) 构建使用“效果 11”所需的着色器(或真正的着色器加元数据)所需的 fx_5_0 HLSL 配置文件已弃用。它目前在最新的公共 D3DCompiler (#47) 中“按原样”工作,尽管在其他 5_0 配置文件中工作的一些较新的“DirectX 11.1”和“DirectX 11.2”时代构造无法使用“fx_5_0”进行编译。官方已弃用它,预计将在未来的 HLSL 编译器版本中删除。

    (2) “Effects 11”要求您在运行时有可用的 D3DCompile API。这是 Windows 8.0 和 Windows Phone 8.0 上的 Windows 应用商店应用程序的问题,因为您只能使用 D3DCompile 进行开发。对于适用于 Windows 8.1 和 Windows Phone 8.1 的 Windows 应用商店应用,D3DCompile #47 可用于应用商店部署的应用。这意味着理论上您可以为此使用“Effects 11”,但不鼓励这样做。

    “Effects 11”CodePlex 讨论区实际上解决了您的一些问题:

    Is Effects 11 deprecated?

    How do I avoid using fx_5_0?

    “Effects 11”运行时作为学习 HLSL 的工具仍然非常有用,我已经使用它发布了一些旧的 DirectX SDK samplestutorials 以用于教育价值。

    至于你应该投资学习它还是长期使用它,这完全取决于你。

    对于只想使用 Direct3D 11 进行编码的初学者,您可以使用 DirectX Tool Kit 的 BasicEffect,它有一堆“普通”着色器,可以处理所有常量和其他问题,而无需使用“Effects 11”一点也不。如果你想玩一些你可以在这里做的事情,你也可以尝试使用Visual Studio Shader Designer (DGSL) 系统(DirectX Tool Kit 也支持),虽然这实际上更像是一个“玩具”解决方案,但可以有用。在任何情况下,您都可以在这些经验的基础上学习编写自己的“效果”系统。

    【讨论】:

    • 对于迟到的回复表示歉意,因为我刚刚遇到这个问题,但感谢您的回复。非常详细,很好地解释了一切。我认为作为初学者,我可能会按照您的建议进行操作,并查看工具包的基本效果。再次感谢:)
    猜你喜欢
    • 2012-08-30
    • 1970-01-01
    • 2016-04-06
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多