以下均转自Android游戏编程入门经典,转载请标明出处
OpenGL ES使用视口将投影到近裁剪面的点的坐标变换为帧缓冲区的像素坐标。通过下面方法可以使用帧缓冲区的一部分或者全部:
GL10.glViewport(int x, int y, int width, int height)
x和y坐标表示帧缓冲区中视口的左下角,width和height表示视口的大小,单位是像素。通常,将x和y设置为0,width和height设置为屏幕的分辨率,也就是全屏模式。当然也可以操作OpenGL ES,使得该方法只使用帧缓冲区的一部分,它会自动把渲染输出进行缩放以适应这部分区域。
注意:虽然看起来是该方法设置了渲染用的2D坐标系统,但实际上并不是这样。它只是定义了OpenGL ES使用的部分用来输出最终图像的帧缓冲区。2D坐标系统是通过投影和模型-视图矩阵定义的。
OpenGL ES会记录3个矩阵:投影矩阵、模型-视图矩阵和纹理矩阵。在使用矩阵之前,必须告诉OpenGL ES要操作哪个矩阵。
GL10.glMatrixMode(int mode)
参数mode可以是GL10.GL_PROJECTION、GL10.GL_MODELVIEW或者GL10.GL_TEXTURE。
OpenGL ES提供一种方法可以把活动矩阵设置成一个正交投影矩阵:
GL10.glOrthof(int left, int right, int bottom, int top, int near, int far)
可以利用你的空间想象力,想像平行投影的视锥具有盒子形状。glOrthof()的参数可以解释为指定了视锥盒子的其中两个角。
由于需要进行2D图像处理,因此必须指明角点(左,底,前)和(右,顶,后),这样可以工作在一种像素坐标系统下,如下将建立一个480 * 320的2D坐标系统:
gl.glOrthof(0, 480, 0, 320, 1, -1);
虽然视锥非常薄,但在2D模式下,这样是没有问题的。坐标系统的可视范围是从(0, 0, 1)到(480, 320, -1)。在这个盒状区域里的任何点在屏幕上都是可见的。这些点投影到盒状区域的正面,也就是近裁剪面。不论这些投影的尺寸多大,它们都将被拉伸到视口上。
为了能够完全可靠地使用视锥,需要给他的Z轴分配一些缓冲区,不能将near和far参数都设置为0。
下面的代码使用黑色进行清屏,设置视口使其延伸到整个帧缓冲区,设置投影矩阵。通过这些设置,该坐标系统的坐标原点设定在屏幕左下角,y轴指向上。
gl.glClearColor(0, 0, 0, 1);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glViewport(0, 0, glGraphics.getWidth(), glGraphics.getHeight());
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, 320, 0, 480, 1, -1);
其实,OpenGL ES提供的大多数操作活动矩阵的方法并不是直接设置活动矩阵。实际上的做法是,这些方法根据它们携带的参数构造一个临时的矩阵,并用这个矩阵与当前的矩阵相乘。glOrthof()方法也不例外。因此,如果每一帧中都调用glOrthof(),那么每次调用投影矩阵都会与其自身相乘,这是相当糟糕的情况。为了避免这种情况,在与投影矩阵相乘前需要确保在合适的地方有一个干净的单位矩阵。一个矩阵与单位矩阵相乘,该矩阵保持不变。这正是调用glLoadIdentity()的目的。
需要注意的是,坐标系统由(0, 0, 1)变为(320, 480, -1)--这是竖屏模式渲染。