写在前面:我也是OpenGL的初学者,本篇是作为一个学习笔记来写的。
首先学习一下关于OpenGL中的重要概念:矩阵
你做了一个物体想放在空间某一个坐标上,需要一个World矩阵吧?然后你需要一个摄像机来拍摄这个物体,让这个物体可见,对吧?那不就需要:
1、View矩阵,决定摄像机在哪里,朝哪里看。
2、Projection矩阵,摄像机的视角、焦距、近平面、远平面。
3、最后把物体的每个Pixel的xyz坐标 分别 乘以 World,View,Projection矩阵。就是在屏幕上的坐标。
这些也是我今天刚学到的(逃
由此可见,在OpenGL中我们大部分操作都和这些矩阵有关系。那么我们是如何操作这些矩阵的呢?
Matrix.frustumM方法,他有8个参数(我的天呐,居然要传这么多参数
ps:这是一个用于创建投影矩阵的方法
//这里节选自Matrix.frustumM
final float r_width = 1.0f / (right - left);
final float r_height = 1.0f / (top - bottom);
final float r_depth = 1.0f / (near - far);
final float x = 2.0f * (near * r_width);
final float y = 2.0f * (near * r_height);
final float A = (right + left) * r_width;
final float B = (top + bottom) * r_height;
final float C = (far + near) * r_depth;
final float D = 2.0f * (far * near * r_depth);
m[offset + 0] = x;
m[offset + 5] = y;
m[offset + 8] = A;
m[offset + 9] = B;
m[offset + 10] = C;
m[offset + 14] = D;
m[offset + 11] = -1.0f;
m[offset + 1] = 0.0f;
m[offset + 2] = 0.0f;
m[offset + 3] = 0.0f;
m[offset + 4] = 0.0f;
m[offset + 6] = 0.0f;
m[offset + 7] = 0.0f;
m[offset + 12] = 0.0f;
m[offset + 13] = 0.0f;
m[offset + 15] = 0.0f;
第一个参数 m 就是我们要传入的矩阵,一般是一个float[16]的数组,这个矩阵也就是我们的投影矩阵
第二个参数 offset 翻译过来叫偏移量,但是我尝试对这个偏移量进行修改的时候都报错了,所以这里我都直接传入0(从源码中看就更好理解为什么会报错了,坑啊)
left、right、bottom、top这四个参数是投影面的大小,但是不同于我们一般的view,这里的参数表示的是比例,并不是绝对值。
可以看到我们传入进去的right、left等值,并没有被直接使用,而是以1.0f作为基准,将我们传入的数字换成了比例。
(这个地方我也不知道怎么解释,毕竟我也个初学者,只能将它理解为比例模式,如果有更好的解释方式,也请留言告诉我)
另外两个参数near和far,一个表示近点,一个表示远点。。。这两个点的概念也不太好理解。按照我的理解是,通过frustumM方法设置好投影(projection)矩阵后,它的近点和远点就规定了后面Matrix.setLookAtM方法设定的摄像机位置,摄像头的z坐标不能小于近点,也不能大于远点。否则就会导致图像消失。
Matrix.setLookAtM方法,它有11个参数!!!(丧心病狂
ps:这是一个用于创建摄像头矩阵的方法
public static void setLookAtM(float[] rm, int rmOffset,
float eyeX, float eyeY, float eyeZ,
float centerX, float centerY, float centerZ, float upX, float upY,
float upZ) {
//省略。。。
}
第一个参数 rm 是一个float[16]的矩阵,也就是我们的摄像头矩阵
第二个参数 rmOffset 偏移量。。。暂时没发现有什么卵用
随后的eyeX、eyeY、eyeZ表示眼睛(摄像头)的位置,刚刚我们说了,在frustum方法里已经规定了摄像头的坐标范围,必须在远点和近点之间,否则就会看不到东西。一般来说eyeX、eyeY传入0就可以了,这样表示摄像头处于居中位置,然后可以在远点和近点之间调整eyeZ。由于近大远小的透视原理,eyeY越接近近点,我们看到的图像就越大,反之则越小。
centerX、centerY、centerZ表示目标位置。我们的眼睛(摄像头)位置确定了,但是我们的眼睛(摄像头)朝哪看呢?,是不是需要一个方向?这个centerX、Y、Z就是这个意思,它决定了我们的眼睛(摄像头)朝哪个方向看。一般来说我们会选择朝着画面的中心去看(摄像头对准目标中心)。这时我们就只需要给这三个参数全部配0就可以了。
upX、upY、upZ就表示我们的摄像头的姿势。类似于我们用手机拍照,我可以横着拍,竖着拍对吧。这是因为我们调整了手机的方向,从而导致拍摄到的画面也发生了旋转。所以当我们将upX轴设置为1的时候,就类似我们用手机横着拍照。这时得到的画面方向是与X轴平行的。而设置upY为1的时候,就表示画面是方向是与Y轴平行的。假设你设置了upZ为1,那你就拍不到任何画面了,因为摄像头的姿势已经偏离了拍摄目标,所以就什么也看不到了。