一、概念
- 视图变换:设置相机位置和方向
- 模型变换:设置模型位置和方向
- 投影变换:透视投影和正投影。透视投影:近大远小;正投影:直接映射。
- 视口变换:设置如何映射到窗口屏幕
二、内容
2.1 模型变换
- glTranslate:平移
- glRotate:渲染
- glScale:缩放
2.2 视图变换:
gluLookAt(观察点位置,瞄准参考点,朝上方向);
2.3 透视投影:
创建视景体:
- glFrustum(左,右,底,高,近,远)无需特殊对称
- gluPerspective(上下角度,宽高比,近,远)对称于x,y轴
2.4正投影:
glOrtho(左,右,底,高,近,远)
2.5 视口变换:
glViewport(x,y,width,height)
三、矩阵堆栈
每一次对矩阵执行的操作时,实际操作的都是最顶部的那个矩阵。
- glPushMatrix:复制最顶部矩阵压入堆栈中;
- glPopMatrix:抛弃销毁堆栈顶部的矩阵
介于glPushMatrix和glPopMatrix之间的矩阵运算相对是独立的,相互不影响。
四、逆变换
屏幕坐标转换为三维空间坐标
gluUnproject(winX,winY,winZ,modelMatrix[16],projMatrix[16],viewPort[4],*objX,*objY,*objZ)
| objX | | 2(winX - view[0]) / view[2] - 1 |
| objY | = INV(PM) | 2(winY - view[1]) / view[3] - 1 |
| objZ | | 2(winZ) - 1|
| W | | 1|
五、OpenGL ES 2.0 中的矩阵
http://blog.youkuaiyun.com/kesalin/article/details/7168967
矩阵运算规则:
1) 若矩阵 A 和 B 不是互逆矩阵,则不满足乘法交换律,即 A × B 不等于 B × A;
2) M × N 阶的矩阵只能和 N × O 阶的矩阵相乘,即 N 的阶数相等,结果为 M × O 阶的矩阵;
3) 矩阵 A × B 的运算过程是 A 的每一行依次乘以 B 的每一列作为结果矩阵中的一行;
4) 矩阵 A 的逆矩阵 B 满足 A × B = B × A = 单位矩阵。
5) 单位矩阵是对角线上的值为1,其余均为 0 的矩阵。单位矩阵不影响坐标变换(你可以将下面的3D变换矩阵换成单位矩阵来思考下)。
3D空间的物体投影到2D平面上时,就需要使用到齐次坐标,因此我们需要使用 4 × 4 的 Matrix 来表示变换。在编程语言中,这样的 Matrix 可用大小为 16 的一维数组或4 × 4 的二维数组来表示。由于矩阵乘法不满足乘法交换律,用数组表示 Matrix 又分为两种形式:行主序和列主序,它们在本质上是等价的,只不过是一个是右乘(行主序,矩阵放右边)和一个是左乘(列主序,矩阵放左边)。OpenGL 使用列主序矩阵,即列矩阵,因此我们总是倒过来算的(左乘矩阵,变换效果是按从右向左的顺序进行): 投影矩阵 × 视图矩阵 × 模型矩阵 × 3D位置。
4× 4列矩阵的数组表示:数字表示数组下标对应的行列位置:
那么
平移矩阵可表示为:
平移矩阵 × 列矩阵(a, b, c, 1) = 列矩阵(a + x, b + y, c + z, 1)。
缩放矩阵可表示为:
缩放矩阵 × 列矩阵(a, b, c, 1) = 列矩阵(a × sx, b × sy, c × sz, 1)。
绕 X 轴旋转的旋转矩阵可表示为:
绕 X 轴旋转的旋转矩阵 × 列矩阵(a, b, c, 1) = 列矩阵(a, b × cos(θ) - c × sin(θ), b × -sin(θ) + c × cos(θ), 1)。
绕 Y 轴旋转的旋转矩阵可表示为:
绕 Y 轴旋转的旋转矩阵 × 列矩阵(a, b, c, 1) = 列矩阵(a × cos(θ) - c × sin(θ), b , a × -sin(θ) + c × cos(θ), 1)。
绕 Z 轴旋转的旋转矩阵可表示为:
绕 Z 轴旋转的旋转矩阵 × 列矩阵(a, b, c, 1) = 列矩阵(a × cos(θ) - b × sin(θ), a × -sin(θ) + b × cos(θ), c, 1)。