2016-10-26 49 views
0

我已经阅读了多篇有关前/后乘法,列/行专业版,DirectX与OpenGL的文章和文章,而且我可能会比开头更困惑。OpenGL vs DirectX,本地还是全球?

所以,让我们说我们写在OpenGL的指令(伪):

旋转(...) 翻译(...)

据我了解,OpenGL的将尽诉” = R * T * v,有效地转换矢量的本地坐标帧。

但在DirectX中,如果我们做的转换(伪)以相同的顺序,

旋转(...) 翻译(...)

结果会不一样,对?由于DirectX预乘,结果将是v'= v * R * T,因此使用全局坐标转换矢量。

所以,当我说OpenGL是后乘法,DirectX是预乘法就像说OpenGL在本地坐标中移动,而DirectX在全局坐标中移动时,我是否正确?

谢谢。

+2

没有'旋转()'或'翻译()'在OpenGL或DirectX的方法。那你指的是什么?旧的OpenGL矩阵堆栈函数'glRotatef()'等不计数。 –

+1

这就是为什么我提到伪代码的原因,因为我想比较2个库,而没有语法方式。 –

+0

但是,如果两个库都不支持这种语法,那么使用这种伪代码就毫无意义。更具体地说,OpenGL没有任何集成数学,并且DirectX的数学库已经被自己提取到一个库中。 –

回答

0

在OpenGL中没有预乘的事情。

为什么你认为OpenGL的反转乘法是,它存储在列优先布局矩阵的原因:

a c 
b d 

的换位矩阵相乘的数学规则是:

A^T * B^T = (B*A)^T 

所以如果你想计算v' = v * R * T(所有行 - 主矩阵),你将不得不写

(v')^T = v * R * T 

或在您的伪代码:

translate(...) rotate(...) translate(...) 

或者你可以存储你的旋转和平移矩阵列主了。

1

你最好打赌是读Matrices, Handedness, Pre and Post Multiplication, Row vs Column Major, and Notations

  • OpenGL代码通常使用右手坐标系,列主矩阵,列向量和后乘法。

  • Direct3D代码通常使用左手坐标系,行主矩阵,行向量和预乘法。

的XNA Game Studio的数学库(因此Monogame,团结等)使用右手坐标系,行为主的矩阵,行向量和预乘法。

DirectXMath库使用行主矩阵,行向量和前乘法,但留给你选择使用左手或右手坐标系统。现在更老的是deprecated D3DXMath

在任一系统中,你还在做同样的物体坐标 - >世界坐标 - >眼睛坐标 - >剪辑坐标转换。

所以用OpenGL GLM你可以这样做:

using namespace glm; 

mat4 myTranslationMatrix = translate(10.0f, 0.0f, 0.0f); 

mat4 myRotationMatrix = rotate(90.f, vec3(0, 1, 0)); 

mat4 myScaleMatrix = scale(2.0f, 2.0f, 2.0f); 

mat4 myModelMatrix = myTranslationMatrix * myRotationMatrix * myScaleMatrix; 
vec4 myTransformedVector = myModelMatrix * myOriginalVector; 

在DirectXMath你会怎么做:

using namespace DirectX; 

XMMATRIX myTranslationMatrix = XMMatrixTranslation(10.0f, 0.0f, 0.0f); 

XMMATRIX myRotationMatrix = XMMatrixRotationY(XMConvertToRadians(90.f)); 

XMMATRIX myScaleMatrix = XMMatrixScaling(2.0f, 2.0f, 2.0f) 

XMMATRIX myModelMatrix = myScaleMatrix * myRotationMatrix * myTranslationMatrix; 
XMVECTOR myTransformedVector = XMVector4Transform(myOriginalVector, myModelMatrix); 

,你会得到相同的变换结果。

如果你是新的DirectXMath,那么你应该看看在DirectX Tool KitSimpleMath包装里面隐藏一些与C++构造函数和运营商严格的SIMD友好对齐要求。由于SimpleMath基于XNA Game Studio C#数学设计,因此它假定右手视图坐标,但如果需要,您可以轻松地将其与“原生”DirectXMath混合使用以使用左手视图坐标。

大多数这些决定是任意的,但确实有合理的设计推理。 OpenGL的数学库试图匹配正常的后乘法数学约定,这导致他们采用列主矩阵。在Direct3D的早期阶段,团队认为连接顺序的颠倒是令人困惑的,所以他们翻转了所有的约定。多年以后,XNA Game Studio团队认为传统的Direct3D串联顺序很直观,但是“向前”是负向z令人困惑,所以他们转向右手坐标。因此,许多更现代的Direct3D样本都使用右手视图系统,但您仍然可以看到Direct3D样本的左手和右手视图设置组合。因此,在这一点上,我们确实拥有“OpenGL风格”,“经典Direct3D风格“和”现代Direct3D风格“。

请注意,当使用固定功能硬件完成某些事情时,这些约定真的很重要,但对可编程着色器流水线而言,重要的是您是一致的。实际上,HLSL着色器默认预期矩阵为列主要形式,所以您经常会看到DirectXMath矩阵在复制到常量缓冲区时进行转置。