1 平移
glTranslatef(x,y,z); 其中,x,y,z分别表示在X、Y、Z轴上平移的量
2 旋转
与平移类似,OpenGL也为我们提供了一个高级函数用于旋转物体:
glRotatef(Angle,x,y,z);
这个函数将生成并应用一个将坐标系以向量(x,y,z)为轴,旋转angle个角度的矩阵。
3 缩放
缩放变换其实是将坐标系的x、y、z轴按不同的缩放因子展宽,从而实现缩放效果。函数
glScalef(x,y,z);
把坐标系的X、Y、Z轴分别缩放x、y、z倍。
4 变换的叠加性质
使用变换时,我们应该注意的是,变换是叠加在上次变换的基础上的。也就是说,变换的效果会累积。每次调用变换函数时,会生成一个新的函数来乘以当前的模型视图矩阵,随后,新的矩阵将成为当前的模型变换矩阵,在下次执行变换时,会被新的矩阵相乘,因此作用效果将不断累积。
我们可以调用glLoadIdentity();函数将当前模型视图变换矩阵重置到初始状态,再进行新的绘制。如:
void RenderScene()
{
glMatrixMode(GL_MODELVIEW);
//沿Y轴向上平移10个单位
glTranslatef(0,10,0);
//画第一个球体
DrawSphere(5);
//加载单位矩阵
glLoadIdentity();
//沿X轴向上平移10个单位
glTranslatef(10,0,0);
//画第二个球体
DrawSphere(5);
}
5 矩阵堆栈
如果每次变换前都把当前矩阵恢复到单位矩阵,也比较麻烦。更多时候,我们希望保存当前矩阵,执行一些变换之后,把当前矩阵恢复到上次保存时的状态。
OpenGL为我们提供了一个“矩阵堆栈”满足我们的这种要求。我们可以把当前矩阵压入堆栈中,然后执行一些变换,再弹出刚才压入的矩阵,从而把当前矩阵恢复到上次变换之前的状态。我们调用
glPushMatrix();
把当前矩阵压入矩阵堆栈,调用
glPopMatrix();
弹出矩阵。我们还可以分别调用
glGet(GL_MAX_MODELVIEW_STACK_DEPTH);
glGet(GL_MAX_PROJECTION_STACK_DEPTH);
来获取模型视图矩阵堆栈和投影矩阵堆栈的最大堆栈深度。一般情况下(在Windows平台上),模型视图的最大堆栈深度是32,而投影堆栈的最大深度是2。
使用矩阵堆栈上例中的程序可以改写为:
void RenderScene()
{
glMatrixMode(GL_MODELVIEW);
//推入矩阵堆栈
glPushMatrix();
//沿Y轴向上平移10个单位
glTranslatef(0,10,0);
//画第一个球体
DrawSphere(5);
//恢复到上次保存时的状态
glPopMatrix();
//沿X轴向左平移10个单位
glTranslatef(10,0,0);
//画第二个球体
DrawSphere(5);
}
6.投影矩阵
设置投影矩阵往往在OpenGL绘图和模型视图变换之前。一般情况下,我们调用
glMatrixMode(GL_PROJECTION);
将当前矩阵设置为投影矩阵。再调用
glOrtho 或 gluPerspective 来创建平行或透视投影。创建完后,再调用
glMatrixMode(GL_MODELVIEW);
将当前变换矩阵设置为模型视图变换矩阵。
7. 定义和使用自己的变换
除了使用OpenGL为我们提供的几个高级变换函数之外,我们还可以自己创建一个矩阵,并使用当前矩阵乘以该矩阵来进行特殊的变换。你可以创建一个4×4的二维数组用于描述一个矩阵。如:
Float M[4][4];
其中M[j,i]表示矩阵M的第j行,第i列的数据。
你也可以创建一个一维数组:
Float M[16];
无论是2维数组还是一维数组,都是按照列优先的顺序保存的。
如图所示
|
矩阵定义完后,调用
glLoadMatrix(M);
可以用矩阵M替换当前矩阵,调用
glMultMatrix(M);
用当前矩阵乘以矩阵M。
要说明的是,使用glLoadMatrix或glMultMatrix的速度没有OpenGL的高级变换函数快。所以如果不是高级变换函数完成不了的变换,就不要使用glLoadMatrix或者glMultMatrix。