学习OPENGL ES的过程中,总是对一个概念很模糊:顶点坐标最终怎么反射到具体的屏幕上去的?
代码中也经常看到设置UNIT_SIZE,定义其为单位长度,更有的设置一个宏ONE来作为顶点坐标
例1:
final float UNIT_SIZE=0.2f
float vertices[]=new float[]{
-4*UNIT_SIZE,0,0, //第一个顶点
0, -4*UNIT_SIZE,0,//第二个顶点
4*UNIT_SIZE,00 //第三个顶点
}
那么这些坐标设置怎么反馈到最终的屏幕上,坐标的单位是多少?
理解这个有点麻烦,书上和网上能完全讲明白的不多,也许是认为这个太容易了,不屑讲吧。
暂时记住以下几点:
1、setLookAtM设置摄像机位置,frustumM设置透视投影,都可以看成是单位比例,而不是实际的位置。
摄像机位置就是视点,根据frustumM的设置,形成一个视景体模型:
视点--------近平面-------远平面
所以理解这三个的位置关系很重要。
2、近平面的位置在哪里?
根据视点的位置坐标,减去frustumM中的near,就是近平面的位置。
3、视口的位置在哪里?
根据glViewport(x,y,width,height)来设置视口,这个视口可以认为就是手机屏幕。相当于在近平面中抠出一块显示到手机屏幕上。
这样就很清楚了,视口的位置与近平面一致,只是近平面比视口的范围大。
4、顶点坐标反映物体的具体位置。视景体建立后,讲顶点坐标扔进去,就可以看到怎么裁剪了。
5、单位的问题,我认为FLOAT下,单位为1.0f。INT的时候,单位为0x10000。
建议所有的运算都用FLOAT吧。
6、世界坐标系的原点在屏幕的中心吗?
经常可以看到有人这么说,而且还有人说是屏幕左上,这些说法都不准确的。屏幕左上是android体系下的坐标原点。
世界坐标系的原点也不一定在屏幕中心。两者没啥关系,主要看视口的设置,而视口又是和近平面的设置一致。
本来想画图说明的,不过太麻烦了,就这样吧。
补充:
1、视口与近平面的关系:
视口可以看成近平面的映射,所以两者要保持相同比例。所以理解为裁剪不合适。
2、视口的设置:glViewport是设置真实屏幕上的显示区域,将设置的区域与近平面进行映射。所以其设置值是真实屏幕坐标数据,一般来说就是480,720之类的值。
3、这样来看,屏幕上的坐标与空间矩阵的坐标的对应转换就很清晰了:
设置投影(视景体):
void frustumM(float[] m, int offset,float left, float right, float bottom, float top,float near, float far)
设置视口:
void glViewport(int x,int y,int width,int height);
left+right映射到width-x上,bottom+top映射到height-y上。