您的位置:首页 > 移动开发 > Android开发

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

2016-07-27 16:16 686 查看

前言

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"


正射投影

正射投影又称正交投影,其视景体为长方体,投影物体的大小不会随视点与远平面之间的距离而变化,

这也是与透视投影最大的区别。见下图:



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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: