sinawear

导航

OPENGL和DX的不同.

因为我熟悉的是DX,所以,大多只标出OPENGL.

 

OPENGL:
1)用角度。

2)纹理坐标向上。

3)Z轴正方向,向屏幕外。右手坐标系.

4)矩阵变化是累积制的.

5)三角形正面(逆时针)

 

关于Opengl和Dx的矩阵问题

 

我们知道信息是, 1)左乘(Dx采取),右乘(Opengl采取)2)矩阵的乘法就是行乘列,不变的,矩阵不满足交换律。3)最终矩阵数据似乎应该有某种意义上的相等. 因为平移后旋转和旋转后平移效果是不同的.

左乘: object * matrix;
右乘: matrix * object;

首先,Opengl是基于c的。
运算基于函数,而对于矩阵的运算又是基于栈的。
如果,将Opengl的矩阵从栈中抽出。
即:
由于OpenGL的栈结构,后入栈的先乘。

OPENGL左乘:
proj * view * world * obj;

DX右乘:
obj * world * view * proj;

1)object * 行主序矩阵;
2)列主序矩阵 * object;

行主序(Dx采取),列主序(Opengl采取)
比如矩阵:
v0(0,1,2,3)
v1(4,5,6,7)
v2(8,9,10,11)
v3(12,13,14,15)

a)行主序矩阵为:
|0 1 2 3|
|4 5 6 7|
|8 9 10 11|
|12 13 14 15|

b)列主序矩阵为:

|0 4 8 12|
|1 5 9 13|
|2 6 10 14|
|3 7 11 15|

假设object行主序为:

|a b c d|
|e f g h|
|i j k l|
|m n o p|

按照1,则为:
a*0+b*4+c*8+d*12 a*1+b*5+c*9+d*13 a*2+b*6+c*10+d*14 a*3+b*7+c*11+d*15
即:4b+8c+12d a+5b+9c+13d 2a+6b+10c+14d 3a+7b+11c+15d
.....(后面,我就不写了。这里,只取一行)

计算列主序的:

|0 4 8 12|
|1 5 9 13|
|2 6 10 14|
|3 7 11 15|
*
a e i m
b f j n
c g k o
d h l p

按照2,则为:

= 0*a+4*b+8*c+12*d 0*e+4*f+8*g+12*h 0*i+4*j+8*k+12*l 0*m+4*n+8*o+12*p
即:4b+8c+12d 4f+8g+12h 4j+8k+12l 4n+8o+12p
=1*a+5*b+9*c+13*d 1*e+5*f+6*g+7*h 1*i+5*j+9*k+13*l 1*m+5*n+9*o+13*p
即:a+5b+9c+13d e+5f+6g+7h i+5j+9k+13l m+5n+9o+13p

....

 

发现是最终结果是转置的.

而我们知道:行主序 = 转置列主序;

根据上面结果我们知道:行主序(mat1) *行主序(mat2) = 转置(列主序(mat2) * 列主序(mat1)) :定理A

即DX计算的矩阵一列的变换最终结构和opengl,仍为行主序,列主序问题(即,只需轻轻一转置);

 

翻开维基查看到矩阵有该性质: \left( A B \right) ^\mathrm{T} = B^\mathrm{T} A^\mathrm{T}

http://zh.wikipedia.org/wiki/%E8%BD%89%E7%BD%AE

 

这就是为什么DX,相关矩阵运算移植到OPENGL要这样写:

即满足左乘和右乘式子,和定理A:

左乘: object * matrix;
右乘: matrix * object;

D3DXMATRIX RotaZ10, RotaY20, RotaX30, Trans0, MatZ120, Mat3;

D3DXMatrixTranslation(&Trans0, 1, 2, 3);
D3DXMatrixRotationY(&RotaY20, D3DXToRadian(20));
D3DXMatrixRotationZ(&RotaZ10, D3DXToRadian(10));
D3DXMatrixRotationX(&RotaX30, D3DXToRadian(30));
D3DXMatrixRotationZ(&MatZ120, D3DXToRadian(120));

Mat3 =  Trans0 * RotaZ10 * RotaY20 * RotaX30 * MatZ120 ;

移植到OPENGL:

glLoadIdentity(); //

glTranslatef(1,2,3);

glRotatef(10, 0,0,1);

glRotatef(20, 0,1,0);

glRotatef(30, 1,0,0);

glRotatef(120, 0,0,1);

 

 

OPENGL右手坐标系,Z轴问题和显示:

opengl的正Z轴向外, 那么我们像往屏幕内移动,该怎么办呢, 将z值设小, 不,不,不.

glLoadIdentity();
glTranslatef(0,-0.5f,walk_on_z);

这里的walk_on_z值仍然是越大,越往屏幕内移动.

因为投影矩阵定义的关系吧.

 

posted on 2012-12-22 22:45  sinawear  阅读(2847)  评论(0编辑  收藏  举报