2008年8月18日星期一

OpenGL Transformation

Modelview(Modeling and Viewing) Transformation:

“First of all, telling about the order of matrices in a matrix product is senseless as long as nothing was said about using either column or row vectors. OpenGL uses column vectors, while D3D uses row vectors.” 这是必须先明确的,OpenGL中 v_new = M * v_old, where M is 4*4, and v_new , v_old is 4*1.

仔细阅读红宝书第三章(http://www.glprogramming.com/red/chapter03.html)里面介绍了可以从两个角度来看待矩阵变换次序。

首先,OpenGL中维护一个C is current modelview matrix. All viewing and modeling transformations are represented as 4*4 matrices, 用M表示。之后无论是直接用glMultMatrix*() or transformation command(glT/R/S) 其实就是将变换矩阵M后乘当前的C矩阵得到C*M,
然后在v' = C*M*v.

利用红宝书中的例子:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixf(N); /* apply transformation N */
glMultMatrixf(M); /* apply transformation M */
glMultMatrixf(L); /* apply transformation L */
glBegin(GL_POINTS);
glVertex3f(v); /* draw transformed vertex v */
glEnd();
先将C设置I, C' = CNML, v' = C'v = INMLv.
这个理解一般没有异议,解决了code顺序与矩阵乘法次序概念上问题。
也就是说如果你都写好了code,叫我将矩阵写出来当然没有问题;反过来,你给出里NML,让我将code写出来,这也好办。
但是,从用户/写代码的人来看,当我需要将一个object/vertex怎么变怎么变,又不知道具体的矩阵M,我怎么做呢?

关键要理解glTranslate*, and glRotate*的次序,红宝书中那先旋转还是先平移的例子要好好看。

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixf(T); /* translation */
glMultMatrixf(R); /* rotation */
draw_the_object();

1. "fixed coordinate system - in which matrix multiplications affect the position, orientation, and scaling of your model - you have to think of the multiplications as occurring in the opposite order from how they appear in the code. "
从一个固定的全局的,可以理解为世界坐标来看的话,代码从后往前考虑,NMLv是L, M, N依次作用于v。这个"your model"为什么呢?书中的意思是从固定的这坐标系来看待时候,不要考虑你的物体坐标,反正我就是影响你这个物体的每一个点在我这个固定坐标里面的位置。
上面例子从固定的世界坐标来看的话,物体先被绕着固定世界坐标系的原点旋转,再沿着世界坐标系来平移,根本不用考虑什么物体坐标系。

2. “Another way to view matrix multiplications is to forget about a grand, fixed coordinate system in which your model is transformed and instead imagine that a local coordinate system is tied to the object you're drawing. All operations occur relative to this changing coordinate system. With this approach, the matrix multiplications now appear in the natural order in the code. (Regardless of which analogy you're using, the code is the same, but how you think about it differs.) ”
物体的局部坐标系来看,有一个物体本身的坐标系跟物体本身绑定在一起,所有变换都会作用于这个物体的坐标系(同时由于物体是对于这个自己的坐标系来说的,所以物体跟着自己局部坐标系也被变换了)。
于是上面的例子中,物体的坐标系先被平移了,然后物体的坐标系绕着自己的原点来旋转。整个过程当中,世界坐标依然没有变,而且物体一直跟着自己的物体坐标系变化。 对于想树形结构的物体,如机械人,太阳系,红宝书的建议是从局部坐标来看。

========
上面的问题弄清楚就看为什么人家常说要先做scale, then rotate, translate last呢?
v' = T*R*S*v
从全局的角度来看(也就是从后往前看),先做scale的话,scale之后的3个轴还是与scale之前的方向一样,虽然长度变了,但这不影响下面的Rotation变换。
从局部物体角度来看(也就是从前往后看),物体本身的坐标先做旋转,物体也跟着旋转了,之后的缩放,物体的坐标系会被缩放,连带物体也一样。

========


注意:
glRotate*(angle, xAxis, yAxis, zAxis), 其中轴(xAxis, yAxis, zAxis)是通过original的unit vector。


http://csc.csudh.edu/jhan/Fall2006/csc461/CourseNotes/CSC461-Lecture16.ppt
http://www.juniata.edu/faculty/rhodes/graphics/opengltrans.htm
http://www.cs.unm.edu/~angel/CS433/LECTURES/CS433_13.pdf 上面三个链接其内容几乎一样的,看这个就可以了。

http://pages.cs.wisc.edu/~psilord/docs/local_axis.html 难懂
http://www.songho.ca/opengl/gl_transform.html OpenGL Transformation. 从math上介绍geometry pipline上的变换矩阵,很好.

没有评论:

发表评论