C++ 为什么要将左手和右手矩阵的入口点分开,而不是用右手标记或转换函数?

C++ 为什么要将左手和右手矩阵的入口点分开,而不是用右手标记或转换函数?,c++,math,graphics,directx,directx-11,C++,Math,Graphics,Directx,Directx 11,矩阵计算API包含用于生成左手矩阵和右手矩阵的单独函数(例如XMMatrixLookAtLHvs.XMMatrixLootAtRH以及XMMatrixPerspectiveLHvs.XMMatrixPerspectiveLH) 我并不完全理解这两个坐标系之间的完全区别(特别是当它们应用于传统的DirectX和OpenGL时),但是为什么API的结构是这样的,而不是组合入口点并提供,一个enum表示惯用手,或者一个额外的通用函数,用于将用于右手系统的矩阵转换为左手系统的矩阵(或者反之亦然)?只是两

矩阵计算API包含用于生成左手矩阵和右手矩阵的单独函数(例如
XMMatrixLookAtLH
vs.
XMMatrixLootAtRH
以及
XMMatrixPerspectiveLH
vs.
XMMatrixPerspectiveLH

我并不完全理解这两个坐标系之间的完全区别(特别是当它们应用于传统的DirectX和OpenGL时),但是为什么API的结构是这样的,而不是组合入口点并提供,一个
enum
表示惯用手,或者一个额外的通用函数,用于将用于右手系统的矩阵转换为左手系统的矩阵(或者反之亦然)?只是两种操作都需要快速(即,您可以提供这些选项,但它们对于任何实际目的来说都太慢,因此不值得支持),还是这些矩阵函数有一些基本要求,要求LH和RH变化完全是独立的端点


<> > >编辑:以澄清:虽然我确实理解了为什么API设计决定被解释的答案,但我的主要好奇是,在考虑数学和实现时,参数化或事实转换函数是否可以正确或有效地实现。(即,如果两个部分不能真正共享代码,则效率低下).

设计API时,这是基于观点的。在引擎中,计算矩阵所花费的时间可以忽略不计。他们可以使用一组标志来驱动,而不是名称和代码重复,而不会产生任何真正的重大问题

<代码> DirectXMath <代码>现在也相当古老,不是C++的一个好例子,它对它所做的足够好,但是大多数项目会重写其数学库。

对于现代GPU和着色器,方便性是一种纯粹的时尚选择,只要您的管道保持一致,或者在需要时执行从建模工具到渲染引擎的转换。值得注意的是,除了方便性之外,您通常还必须处理Y或Z向上的约定


理解灵巧性最简单的方法是用手指组成一个框架(拇指是X,食指是Y,中间是Z)。如果你用双手组成框架,并尝试对齐两个手指,区别很明显,第三个轴是颠倒的。仅此而已:)

这是基于观点设计API的。在引擎中,计算基于方便性的有效差分矩阵所花费的时间可以忽略不计。他们可以使用一组标志来驱动,而不是名称和代码重复,而不会出现任何真正的重大问题

<代码> DirectXMath <代码>现在也相当古老,不是C++的一个好例子,它对它所做的足够好,但是大多数项目会重写其数学库。

对于现代GPU和着色器,只要管道保持一致,或者在需要时执行从建模工具到渲染引擎的转换,方便性就是一种纯粹的时尚选择。值得注意的是,除了方便之外,您还经常需要处理Y或Z向上的约定

理解灵巧的简单方法是用手指形成一个框架(拇指是X,食指是Y,中间是Z)。如果你用双手做这件事,并试着让两个手指对齐,那么区别是显而易见的,第三个轴是反向的。仅此而已:)

该项目历史悠久。我早在2008年就开始研究它,当时Xbox360的“xboxmath”专注于VMX128,没有SSE/SSE2优化。从那时起,当我从xboxmath迁移到xnamath,然后再从xnamath迁移到DirectXMath时,我尝试维护对现有客户机的支持,其中包括作为两个不同函数的“LH”和“RH”,大部分初始API表面积都被保留了下来

这种设计有一个实际的原因:一个应用程序只能使用其中一个,而不能同时使用两个。对一个参数进行潜在的运行时检查以选择固定的和已知的内容并没有多大用处

另一个实际原因是最小化代码中的分支。大多数DirectXMath函数都是避免所有分支的直线代码,而是使用元素选择。这最初是因为Xbox 360是一款速度极快的顺序处理器,但没有特别先进的分支预测器

通常,查看坐标系的选择取决于历史的舒适度:OpenGL长期以来一直首选列主视图、右手查看系统。DirectX历来使用行主视图、左手视图坐标。XNA游戏工作室选择去行主要,右手观看坐标

使用现代可编程GPU管道,实际上不需要使用其中一种,只要您保持一致:DirectX API可以支持LH或RH。大多数DirectX示例,包括使用左手查看坐标编写的任何内容。大多数Windows应用商店示例和基于.NET的系统通常遵循XNA Game Studio惯例

正因为如此,DirectXMath支持行主矩阵,让开发人员使用右手和左手。DirectXMath的包装器对于来自C#的XNA Game Studio数学库的人来说是自然的,因此它假设是右手的

>响应@ GalPO1N:“DrimxxMaX现在也相当古老,不是C++的好例子,它对它所做的足够好,但是大多数项目会重写其数学库。”

XBOxMyTM的传统是使用C可调用函数,因为在Xbox 360的早期,仍有很多开发者喜欢C++而不喜欢C++。随着C++编译器的成熟和开发者的品味的变化,这一点变得越来越不重要了。在从XNAMath到DirectXMath的转换中

inline XMMATRIX XM_CALLCONV XMMatrixPerspectiveFov(float FovAngleY, float AspectRatio, float NearZ, float FarZ, bool rhcoords )
{
    if (rhcoords)
    {
        return XMMatrixPerspectiveFovRH(FovAngleY, AspectRatio, NearZ, FarZ);
    }
    else
    {
        return XMMatrixPerspectiveFovLH(FovAngleY, AspectRatio, NearZ, FarZ);
    }
}