一、概念

在OpenGl ES中,将一个3D模型显示到2D屏幕中有以下四个过程。

 1. 视角(Viewing)变换 2. 模型(Modeling)变换 3. 投影(Projection)变换 4. 视窗(Viewport)变换

视角(Viewing)变换

相当于你拿着一台照相机移动,从不同的位置来观察一个人,比如下图


模型(Modeling)变换

此时相机不动,人做移动,比如下图


根据相对运动,可以看到视角(Viewing)变换和模型(Modeling)变换的效果是一样的。

投影(Projection)变换

此时相机可以调整远近距离,人不动,这样观察到的也会不一样,比如下图


视窗(Viewport)变换

按下快门之后,需要把像素按照比例转化后显示到屏幕上,这就是视窗(Viewport)变换,对应的就是

        // Surface改变的的时候调用        @Override        public void onSurfaceChanged(GL10 gl, int width, int height) {            // 设置窗口大小            gl.glViewport(0, 0, width  , height);        }

二、视角(Viewing)变换和 模型(Modeling)变换操作

前面说了,这两者产生的效果是一样的,具体的有以下三种变换

 - Translate    平移变换 - Rotate       旋转变换 - Scale        缩放变换

平移变换

在平移变换之前,需调用以下代码才能进行变换

     //设置为单位矩阵     gl.glLoadIdentity();

以上一篇绘制的三角形为例子,没移动前

调用glTranslatef(float x, float y, float z)方法进行平移

向右移动0.6f个x坐标

    //向右移动0.6f个x坐标    gl.glTranslatef(0.6f, 0f, 0f);

效果


旋转变换

调用glRotatef(float angle, float x, float y, float z)传入4个参数,角度和x、y、z坐标。此时一定要注意旋转的角度,角度为正表示逆时针。

PS:我发现可以用安培定则 来判断旋转方向,大拇指正对向量方向,卷曲手握着向量,手指弯曲的方向即为要旋转的方向。

    //以(1f,0f,0f)空间向量旋转60度    gl.glRotatef(60, 1f, 0f, 0f);

    //以(1f,0f,0f)空间向量旋转180度    gl.glRotatef(180, 1f, 0f, 0f);


缩放变换

调用glScalef(float x, float y, float z)进行缩放,三个参数为缩放比例,
缩放之前的坐标乘以缩放比例即可

比如:

    //缩小为原来0.1倍    gl.glScalef(0.1f,0.1f, 0.1f);

效果:


组合变换

组合变换要注意顺序,比如平移和缩放变换组合起来,先平移后缩放和先缩放后平移的效果是不一样的。因为每次变换所依赖的是当前矩阵

先缩放再平移

            //缩小为原来0.1倍             gl.glScalef(0.1f,0.1f, 0.1f);             //向右移动0.6f个x坐标             gl.glTranslatef(0.6f, 0f, 0f);

效果:


先平移再缩放

             //向右移动0.6f个x坐标             gl.glTranslatef(0.6f, 0f, 0f);             //缩小为原来0.1倍             gl.glScalef(0.1f,0.1f, 0.1f);

效果:


重置矩阵

如果想重置矩阵为没有任何变换之前,调用glLoadIdentity()

比如下面一段代码就将矩阵重置到之前的矩阵

             //向右移动0.6f个x坐标             gl.glTranslatef(0.6f, 0f, 0f);             //缩小为原来0.1倍             gl.glScalef(0.1f,0.1f, 0.1f);             //重置矩阵             gl.glLoadIdentity();

效果图:


保存、恢复矩阵

调用glPushMatrix保存当前矩阵,调用glPopMatrix恢复当前矩阵。
比如先保存矩阵,再重置矩阵,最后恢复矩阵,那么矩阵没改变。

            //向右移动0.6f个x坐标             gl.glTranslatef(0.6f, 0f, 0f);             //缩小为原来0.1倍             gl.glScalef(0.1f,0.1f, 0.1f);             //保存当前矩阵             gl.glPushMatrix();                       //重置矩阵             gl.glLoadIdentity();                         //恢复矩阵             gl.glPopMatrix();

效果图


三、投影(Projection)变换操作

前面说了,投影(Projection)变换相当于相机调整远近距离,人不动。

投影变换会定义一个视锥(viewing volume),视锥有两个作用

 - 物体如何投影到屏幕(透视投影或者正侧投影) - 裁剪场景的区域大小

OpenGL ES可以使用两种不同的投影变换:透视投影(Perspective Projection)和正侧投影(Orthographic Projection)。


透视投影(Perspective Projection)

透视投影 ,就像我们眼睛看一个物体,近大远小。 如下图

从照相机(View Point)望去,由left、top、bottom、right四条线组成的面(也就是near面)和最远处的面(也就是far面)组成了一个椎体,这个椎体叫View volumn。

裁剪就是把Viewing Volume之外的都裁剪掉,这样可以提高绘图性能。
定义透视投影的方法如下,传入6个参数

public void glFrustumf(float left,float right,float bottom,float top,float near,float far)

也可以用GLU.gluPerspective(fovy, aspect, zNear, zFar)方法,fovy是竖直方向也就是Y方向的夹角,aspect是near面的宽高比,即top的长度除以left长度。

后续会有例子来讲如何用这个。


正侧投影(Orthographic Projection)

透视投影 ,View Volumn椎体不变,一直是一个长方体,无论距离怎么改变,投影都不变。

定义正侧投影的方法如下,传入6个参数

public void glOrthof(float left, float right,float bottom,float top,float near,float far)


四、视窗(Viewport)变换操作

就是上面写的

按下快门之后,需要把像素按照比例转化后显示到屏幕上,这就是视窗(Viewport)变换,分两步

 - 设置窗口的位置和大小————glViewport(int x, int y, int width, int height) - 设置观察的位置和角度————GLU.gluLookAt(gl, eyeX, eyeY, eyeZ,  centerX, centerY, centerZ,  upX, upY, upZ)

设置窗口的位置和大小

这个之前讲过,没什么好说的

            // Surface改变的的时候调用        @Override        public void onSurfaceChanged(GL10 gl, int width, int height) {            // 设置窗口大小            gl.glViewport(0, 0, width  , height);        }

设置观察的位置和角度

GLU.gluLookAt(gl, eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ)

 - eye理解为照相机或者你的眼睛,默认位置在原点(0,0,0) - center是观察物体的坐标,从eye到center的向量就是观察的方向 - up默认为Y轴正方向,可以理解为眼睛到头顶的方向,比如改成(0,-1,0)那就是倒立着观察了

比如一个物体,默认gluLookAt坐标

        @Override        public void onDrawFrame(GL10 gl) {         ......        GLU.gluLookAt(gl, 0f, 0f, 0f,  0f, 0f, -1f,  0f, 1f, 0f);        ......

效果如下:

我改为GLU.gluLookAt(gl, 0f, 0f, 0f, 0f, 0f, -1f, 1f, 0f, 0f);

即侧着头看,效果如下


五、结束

图形的变换就介绍到这,下一篇讲解如何给图形添加颜色。

更多相关文章

  1. Android(安卓)UI之ImageView
  2. 调用手机的摄像头,并且返回照片显示在程序界面上.
  3. Android中由IP地址查询经纬度坐标的实例
  4. 图解Android(安卓)View的scrollTo(),scrollBy(),getScrollX(), g
  5. Android中Matrix的pre post set方法理解(来源:Linux社区 作者:zjmd
  6. Android图像处理——ColorMatrix
  7. 创建自定义视图在Android矩阵效果画布教程
  8. android gif 图片显示问题
  9. 细数Android原生工程接入EasyAR-SurfaceTracking遇到的坑

随机推荐

  1. Android Studio 1.0正式稳定版下载地址
  2. Android(安卓)Monkey测试
  3. Android的一些开源库
  4. [android]-记录日志到sd卡
  5. Android反射机制详解
  6. android代码实现ScaleAnimation动画(附原
  7. android 文档民间翻译版本
  8. Android prototype Q&A video and transc
  9. Android 简单购物车
  10. 38 Android actionbar 简单使用