(1)世界坐标系
OpenGL为右手坐标系 D3D为左手坐标系
(2)投影平面
D3D投影平面为z=1.0,OpenGL为z=-1.0;为了便于理解,可将其定义为视景体近裁截面
(3)CVV
OpenGL中z的范围:[-1.0, 1.0] D3D为:[0.0, 1.0]
(4)shader
shader开始是以汇编的形式出现,在推出一段时间后,就出现如下几种类C的高级语言(注:这些高级语言会被编译成显卡识别的汇编代码)
OpenGL的shader语言为GLSL D3D为HLSL
CG是nVidia公司的shader语言 可以同时在OpenGL和D3D上跑
ASHLI(Advanced Shading Language Interface)是ATI公司的shader语言
(5)顶点颜色顺序
OpenGL为:RGBA格式 D3D为:BGRA格式
(6)视口坐标系
OpenGL的原点为左下角像素的中心 x轴向右 y轴向上
D3D9的原点为左上角像素的左上角 D3D10+的原点为左上角像素的中心 x轴向右 y轴向下
-----------------------节选自《跨越opengl和d3d的鸿沟(一):开篇》 -----------------------
初学者经常说,OpenGL用右手坐标系,而D3D用左手;裁剪空间里OpenGL的z是[-1, 1],而D3D是[0, 1];不可调和。
实际上,直接把左手的顶点和矩阵给OpenGL也是没有问题的。毕竟如果在VS里执行的都是mul(v, matrix),得到的会是同样的结果。可能会造成麻烦的反而是viewport的z。
假设一个经过clip之后的顶点坐标为(x, y, z, w),那么在OpenGL上,该顶点经过viewport变换的z是(z/w + 1) / 2,而在D3D上则是z/w而已。
这对于depth test不影响,但depth buffer里的值就不同了。所以需要对project matrix做一些调整,
才能让他们写到depth buffer中的数值相同。具体来说,如果要让OpenGL流水线接受D3D的project matrix,就需要乘上
1 & 0 & 0 & 0
0 & 1 & 0 & 0
0 & 0 & 2 & 0
0 & 0 & -1 & 1
相当于把project space的顶点z都作了z = z * 2 – 1的操作,所以经过viewport变换就一致了。
D3D到OpenGL的矩阵也可以依此类推。所以,在坐标系上,很容易就能使两者接受同样的输入,同时也没有增加runtime开销。
本篇讲的都是可以在不改变API的情况下,通过输入数据来消除OpenGL和D3D之区别。
-----
可参考: