目录
一.什么是矩阵
二.什么是投影
1.正交投影
2.透视投影
?三.观察的方位
四、使用变换矩阵
一.什么是矩阵
????????在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合?[1]??,最早来自于方程组的系数及常数所构成的方阵。这一概念由19世纪英国数学家凯利首先提出。
???????????????????????????????????????????????????????????????????????????????????????????????????????????????? -----百度百科
点这里了解矩阵
二.什么是投影
Android OpenGLES的世界中,投影有两种,一种是正交投影,另外一种是透视投影。
1.正交投影
正交投影也可以称之为平行投影,想象下一束平行光正对照在一个物体上形成的阴影。正交投影,物体呈现出来的大小不会随着其距离视点的远近而发生变化。
在Android OpenGLES程序中,我们可以使用以下方法来设置正交投影:
Matrix.orthoM (float[] m, //接收正交投影的变换矩阵
int mOffset, //变换矩阵的起始位置(偏移量)
float left, //相对观察点近面的左边距
float right, //相对观察点近面的右边距
float bottom, //相对观察点近面的下边距
float top, //相对观察点近面的上边距
float near, //相对观察点近面距离
float far) //相对观察点远面距离
正交投影如下图:
2.透视投影
透视投影也可以称之为中心投影,可以理解为光源就是一个点(如灯泡、手电筒等),这个时候离光源远物体投影则小,离光源越近则投影越大。
在Android OpenGLES程序中,我们可以使用以下方法来设置透视投影:
Matrix.frustumM (float[] m, //接收透视投影的变换矩阵
int mOffset, //变换矩阵的起始位置(偏移量)
float left, //相对观察点近面的左边距
float right, //相对观察点近面的右边距
float bottom, //相对观察点近面的下边距
float top, //相对观察点近面的上边距
float near, //相对观察点近面距离
float far) //相对观察点远面距离
透视投影如下图:
?三.观察的方位
以上讲的是物体在不同方位不同光源情况下不同的呈现,但是结合生活实际想一想,如果观察的位置和角度不同,我们观测到的物体差别也是很大的。
相机位置:相机的位置是比较好理解的,就是相机在3D空间里面的坐标点。 相机观察方向:相机的观察方向,表示的是相机镜头的朝向,你可以朝前拍、朝后拍、也可以朝左朝右,或者其他的方向。 相机UP方向:相机的UP方向,可以理解为相机顶端指向的方向。比如你把相机斜着拿着,拍出来的照片就是斜着的,你倒着拿着,拍出来的就是倒着的。 ?
Matrix.setLookAtM (float[] rm, //接收相机变换矩阵
int rmOffset, //变换矩阵的起始位置(偏移量)
float eyeX,float eyeY, float eyeZ, //观察点位置
float centerX,float centerY,float centerZ, //被观物体中心参考位置
float upX,float upY,float upZ) //up向量在xyz上的分量,即观察的方向(正在看还是横着看,抬头还是低头)
四、使用变换矩阵
实际上相机设置和投影设置并不是真正的设置,而是通过设置参数,得到一个使用相机后顶点坐标的变换矩阵,和投影下的顶点坐标变换矩阵,我们还需要把矩阵传入给顶点着色器,在顶点着色器中用传入的矩阵乘以坐标的向量,得到实际展示的坐标向量。注意,是矩阵乘以坐标向量,不是坐标向量乘以矩阵,矩阵乘法是不满足交换律的。 而通过上面的相机设置和投影设置,我们得到的是两个矩阵,为了方便,我们需要将相机矩阵和投影矩阵相乘,得到一个实际的变换矩阵,再传给顶点着色器。矩阵相乘。
Matrix.multiplyMM (float[] result, //接收相乘结果
int resultOffset, //接收矩阵的起始位置(偏移量)
float[] lhs, //左矩阵
int lhsOffset, //左矩阵的起始位置(偏移量)
float[] rhs, //右矩阵
int rhsOffset) //右矩阵的起始位置(偏移量)
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//计算宽高比
float ratio=(float)width/height;
//设置透视投影
Matrix.frustumM(mProjectMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
//设置相机位置
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 7.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
//计算变换矩阵
Matrix.multiplyMM(mMVPMatrix,0,mProjectMatrix,0,mViewMatrix,0);
}
注:openGl新手,欢迎大佬批评指正。
|