What
openGL中的矩阵是一组提供了接口的二维数组,用来表示图形的变换
空间中点的坐标由一维数组(vector)表示,用矩阵表示点将要进行的变换,相乘后即得到变换后的坐标
从笛卡尔坐标(Cartesian Coordinates)到齐次坐标(Homogeneous Coordinates)
点的坐标可以用一个三维vector表示,进行rotate和scale变换时乘对应的矩阵(3 * 3)即可完成变换。但对translate变换,乘一个3 * 3的矩阵并不能直接完成,因此为了将所有变换的实现都统一到矩阵的乘法,在进行变换时将点的坐标扩展到四维,对应的矩阵也用4 * 4实现,因此openGL中用到的矩阵是4 * 4的
How
openGL中将3D坐标投影到2D屏幕坐标的步骤:
- model-view transform
- projection transform
- apply
- viewport transform
以下分别进行说明
Model-View Transform
model指要绘制的物体,view指观察者的位置
这一阶段包括
- 物体在场景中的平移、旋转、缩放
- 将场景放在观察者面前
因为观察者和物体是相对的,观察者的移动相当于物体往相反方向移动,因此两者可以统一为model-view transform
相关函数
- glTranslate(x, y, z)
- glRotate(rad, vx, vy, vz)
- glScale(x, y, z)
- gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz)
Projection Transform
在model-view transform中完成了建模后,就需要开始将模型投影到观察者眼中
投影变换(projection transform)分为两种,透视投影(perspective projection)和正交投影(orthographic projection)
Perspective projection
透视投影即近小远大的观察方式
这一步首先要继续对场景进行裁剪(clip),通过上、下、左、右、近平面、远平面将能显示的部分裁剪成平截椎体(frustum)
相关函数
- gluPerspective(fovy, aspect, zNear, zFar)
Orthographic Projection
正交投影即远近一样大的观察方式
同样进行裁剪
相关函数
- glOrtho(left, right, bottom, top, near, far)
Apply
openGL根据前面的变换得到的矩阵进行计算
Viewport Transform
Apply结束后就得到了2D的投影视图,我们可以根据需要把它放置到当前窗口(window)的指定位置
相关函数
- glViewport(x, y, width, height)
Programing
代码参考 projection.c
Perspective projection:
glLookAt()先指定观察者的位置、视线的方向、视线的上方,然后glPerspective()/glOrtho()进行剪切,留下可见的部分
需要注意,__glTranslate()/glRotate()等函数在对物体变换的同时也会对坐标系进行变换__。例如,先glTranslate(1, 0, 0)再glRotate(angle, 0, 1, 0),最终物体不是绕着(0, 0, 0)->(0, 1, 0)的轴旋转,而是绕着平移后的坐标轴的原点(1, 0, 0)->(1, 1, 0)的轴旋转,坐标轴改变后同样会影响之后的gluLookAt()等函数的设置,因此一般最后再进行平移旋转
1 | glMatrixMode(GL_PROJECTION); |
参考资料
《OpenGL编程指南》第5章