C++11 DirectX 数学 : XMVECTORF32 as base structure initialization

标签 c++ math c++11 initialization directx

我正在用 C++11/VC11 编写另一个游戏引擎,目前使用 DirectX/Direct3D11 作为渲染后端。为了从公共(public)接口(interface)(以及以后可能实现的 OpenGL 后端)中隐藏 DirectX 类型,我自己开发了一个线性代数库,但它暂时仍然在内部使用 DirectX Math。 DirectX Math 或多或少是一堆围绕 C++ SIMD 内在函数(__m128 等)的类型定义。 为了保持较低的间接级别并使内容尽可能“原子”和内联,我更喜欢直接从 DirectX 数学类型继承(在本例中为 XMVECTORF32)——即我不想将其用作成员变量:

struct vector4 : private DirectX::XMVECTORF32

MSDN 给出了以下正确初始化 XMVECTORF32 结构的示例:

XMVECTOR data;
XMVECTORF32 floatingVector = { 0.f, 0.f, 0.1f, 1.f };
data = floatingVector;

但是,编译器无法理解我尝试将 XMVECTORF32 初始化为基本结构。

struct vector4 : private DirectX::XMVECTORF32 // not XMFLOAT4 due to possible conversation overhead
{
    friend class matrix44;

    inline vector4(scalar v0, scalar v1, scalar v2, scalar v3)
        :   DirectX::XMVECTORF32{v0, v1, v2, v3} // ERROR: ';' expected
    {
    }
};

我错过了什么吗?如何正确执行我打算做的基础初始化?是否有一些新的 C++11 初始化糖可以帮助我?

------------ 编辑 ------------

出于某些原因,我没有看到明显的东西。检查 XMVECTORF32 的定义后,很明显我可以访问底层 union float 组“f”,因此初始化看起来像这样。

struct vector4 : private DirectX::XMVECTORF32
{
    friend struct matrix44;

    inline vector4(scalar v0, scalar v1, scalar v2, scalar v3)
    {
        f[0] = v0;
        f[1] = v1;
        f[2] = v2;
        f[3] = v3;
    }
};

没有转换,没有 union ,没有 c 数组。通过内联,性能应该接近最佳。

------------ 编辑 2 ----------

XMVECTORF32 不适用于存储数据。因此 vector 必须继承自 XMFLOAT4。否则,这会产生不可重现的访问冲突异常,尤其是在启用优化的情况下。这是更多背景:http://www.asawicki.info/news_1429_xna_math_and_access_violation.html

我的最终代码如下所示:

struct vector4 : private DirectX::XMFLOAT4
{
    friend struct matrix44;

    inline vector4(scalar v0, scalar v1, scalar v2, scalar v3)
        :   DirectX::XMFLOAT4(v0, v1, v2, v3)
    {
    }

    inline scalar& v0() { return x; }
    inline scalar& v1() { return y; }
    inline scalar& v2() { return z; }
    inline scalar& v3() { return w; }
};

必须使用 XMLoadFloat4 之前的 SIMD 计算将 vector 数据加载到 XMVECTOR 中 - 没有办法绕过它。将 XMVECTOR 想象成寄存器 - 而不是内存位置。

最佳答案

只要 DirectX::XMVECTORF32 是一个聚合类,您的代码在 C++11 中就没问题(请参阅演示其用法的 live example)。

但是,您使用的编译器支持统一初始化(如 this Q&A on StackOverflow 所阐明),并且在 C++03 中您无法初始化一个基本聚合类,就像您将复制初始化一个变量一样。

因此,您必须在初始化列表中显式初始化基类的成员,或者在 vector4 构造函数的主体中调用类似 SetVector() 的方法.

关于C++11 DirectX 数学 : XMVECTORF32 as base structure initialization,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15311568/

相关文章:

mysql - MySQL 中的递归数学

java - 完美数程序java

javascript - 带有 Math.min() 的函数返回第一个元素

c++ - 这是冲突吗?关于 C++ 汽车

c++ - 检索类内初始化成员的默认值

c++ - 是否有任何自动递归类型推理或现代方法来做到这一点

具有未使用变量的 C++ 异常

java - 语义 - 将已实现的接口(interface)传递给方法

c++ - 使用指向派生类的指针作为模板参数时出错

c++ - 谁负责释放由 std::move 移动的资源?