OpenGLES Android篇零基础系列(四):透视投影(PerspectiveProjection)与正射投影(OrthographicProjection)

前言

 OpenGLES Android篇零基础系统前面已经写了三篇了,因为OpenGL里面的水着实是深,所以里面好多的概念都没有去查资料,如果一碰到不会的就去查,就感觉没有连贯性。所以就只能是先一笔带过,然后再慢慢研究。

正文

前面我们已经了解到,OpenGL其实是把物体从世界坐标系通过各种复杂的转变,计算等变成屏幕坐标系,显示在视口中。即:把三维物体转变为二维图像。而转变的方式有透视、正射,

首先我们看下何谓视景体
视景体:就是一个可以观看投影物体的可视区域,由近平面,远平面,左,上,右,下各面组成。
只有在可视区域内才可见,区域外会被裁剪。

透视投影

假设有一个视点E(Xp,Yp,Zp),以及世界坐标系中任意一点X(Xa,Ya,Za),还有置于E与X之间的一个视平面P(或近平面)。然后以X为起点,向视点E做射线,与视平面相交于点S。点S即为我们看到的点。下面我偷个图一看就明白了:
这里写图片描述

这种投影就与我们现实生活中用肉眼看东西时很接近了,很逼真。
用一个有照相机的图如下 :
这里写图片描述

在OpenGLES2.x中我们这样用PerspectiveProjection透视投影:

//定义一个16x16的透视矩阵
private final float[] mProjMatrix = new float[16];
//视图矩阵
private final float[] mVMatrix= new float[16];
//透视矩阵与视图矩阵变换后的总矩阵
private final float[] mMVPMatrix= new float[16];
/**
*横竖屏切换时调用
*
**/
public void onSurfaceChanged(GL10 gl, int width, int height) {
 float ratio = (float) width / height;
        // this projection matrix is applied to object coordinates
        // in the onDrawFrame() method
        //创建一个透视视景体
        //注意:near,far都必须大于0,且二者不能相等,
        Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}


 public void onDrawFrame(GL10 gl) {
  Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1f, 0f);
        // Calculate the projection and view transformation
        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
 }

如上,当我们拿到顶点的变化总矩阵后,就可以为GLSL中的MVPMatrix索引赋值,那样最终得到的gl_Position就能正确在屏幕上展示:

 /**
     * 顶点着色器的语句
     */
    private final String mVertexShader =
            "attribute vec4 position;\n" +
                    "uniform mat4 uMVPMatrix;" +
                    "void main(){\n" +
                    "gl_Position = uMVPMatrix * position ;\n" +
                    "};\n"

正射投影

正射投影又称正交投影,其视景体为长方体,投影物体的大小不会随视点与远平面之间的距离而变化,
这也是与透视投影最大的区别。见下图:
这里写图片描述

突然来任务了,来不及往下写,思绪也被打乱了,只能把任务完成,然后再续

原创文章 80 获赞 34 访问量 17万+

猜你喜欢

转载自blog.csdn.net/u011153817/article/details/52044722