在OpenGL ES中,对模型的变换主要有移动、伸缩和旋转三种,分别对应方法glTranslatef、glScalef和glRotatef三个方法。
glTranslatef方法用于模型的平移,接受三个参数,分别对应X、Y和Z轴上的移动值,正数表示向该轴的正方向移动,负数表示向该轴的负方向移动。在刚开始分析OpenGLDemo样例的时候我们已经看到样例中执行了以下语句:
gl.glTranslatef(0, 0, -3.5f);
该方法将模型向Z轴的负方向移动了3.5个单位,之所以做这样的移动是因为模型建立的时候是在坐标原点建立的,而观察点也是在坐标原点。为了让观察点和模型之间有一定距离,比如3.5个单位的距离,需要移动模型3.5个单位或者是移动观察点3.5个单位。如果是移动观察点的话则需要调用上一节讨论的GLUtils.gluLookAt方法将观察点设置在{0,0,3.5}的位置上。移动模型的话则使用glTranslatef将模型设置在{0,0,-3.5}的位置上。在这里两者是等效的。上一节的简化样例中以上两种方法都同时调用了,使观察点和模型之间的距离变成了7.0个单位。
glScalef方法用于伸缩模型,它可以改变模型的大小,甚至改变模型的比例。这个方法接受三个参数,分别对应在X轴、Y轴和Z轴上的伸缩系数,表示在X轴、Y轴和Z轴上伸缩变化的大小。如果参数为1则表示不进行伸缩,如果参数小于1则缩小,如果参数大于1则放大。如以下方法将模型在X、Y和Z轴上都放大到2倍
gl.glScalef(2.0f,2.0f,2.0f);
使用glScalef的时候需要注意模型的比例,如果三个参数不相同的话会改变模型的比例,有时可能会造成开发人员不希望的效果。比如对一个立方体执行以下操作会将它变成一个长方体。
gl.glScalef(2.0f,1.0f,1.0f);
同样,开发人员可以对OpenGLDemo样例进行修改,使该样例中的立方体变成一个不断伸长的长方体。具体实现方法请参考让观察点飞离模型的方法。
glRotatef方法对模型进行旋转,在之前的内容中也对该方法有讲解。这个方法接受四个参数,第一个参数是需要旋转的角度,后面三个参数用于指定围着X,Y,Z三个轴的旋转系数。将三个轴的旋转系数乘于旋转角度都可以获得在不同的轴需要旋转的角度。样例中的以下代码让立方体绕X轴和Y轴转动_angle所记录的角度,因为第四个参数为0,则模型不会绕着Z轴转动。
gl.glRotatef(_angle, 1.0f, 1.0f, 0.0f);
因为在X轴和Y轴上的转动系数相同,所以立方体绕X轴转动的情况和绕Y轴转动的情况相同,用户看到的是立方体向右下方向旋转。
在执行glRotatef方法的时候需要注意该方法是让模型绕坐标原点转动,并不是绕模型自身的原点转动。当模型在坐标原点的时候,坐标原点和模型自身的原点重合,两者没有差另。不过,当模型不在坐标原点的时候,绕坐标原点转动和绕模型自身原点转动的效果是完全不同的。
比如有一个立方体在Z轴上,坐标为{0,0,10},执行glRotatef方法让这个立方体绕Y轴转动90度会让这个立方体移动到X轴上,坐标可能是{10,0,0},而不是让立方体在原来的位置自转90度。
进一步的建议是开发人员在执行多次模型变换的时候需要考虑变换执行的顺序,比如,先平移然后再旋转的结果和先旋转再平移的结果可能完全不同。