Android OpenGL详解一
概述
Android通过OpenGL包含了对高性能2D和3D图形的支持.尤其支持OpenGLES API.OpenGL是一个跨平台的图形API,提供了软件操作3D图形硬件的接口.OpenGLES是一个专用于嵌入式设备的OpenGL规格.从android1.0开始支持OpenGLES 1.0和1.1API规格.从Android2.2 (API Level 8)开始,框架支持OpenGLES 2.0 API规格.
注:Android框架所提供的API与J2MEJSR239 OpenGL ES API非常相似,但并不是完全相同.如果你熟悉J2MEJSR239规格,请注意不同的地方.
基础知识
Android的框架API和NDK都支持OpenGL.本主题面向Android框架接口.关于NDK的更多信息,请观NDK开发文档.
在Android框架中有两个基本的类使你可以通过OpenGLES API创建和操作图形系统:
GLSu易做图ceView和GLSu易做图ceView.Renderer.如果你的目标是在你的Android应用中使用OpenGL,了解如何在一个activity中实现这些类是首要目标.
GLSu易做图ceView
这个类是一个View,你可以用OpenGLAPI调用来绘制对象并管理它们.它与Su易做图ceView很相似.你可以创建一个GLSu易做图ceView的实例然后把你的绘制操作添加给它.然而,如果你想捕获触屏事件,你应扩展GLSu易做图ceView类来实现触屏事件易做图,就像在SDK的OpenGL例子ES1.0, ES 2.0和TouchRotateActivity中所示.
GLSu易做图ceView.Renderer
此接口定义了在一个OpenGL GLSu易做图ceView上作画所需的方法们.你必须提供另一个类来实现这个接口然后把它附加到你的GLSu易做图ceView实例上,使用GLSu易做图ceView.setRenderer().
GLSu易做图ceView.Renderer接口需要你实现以下方法们:
onSu易做图ceCreated():当创建GLSu易做图ceView时被调用,只调用一次.在这个方法中执行只发生一次的动作,比如设置OpenGL环境参数或初始化OpenGL图形对象.
onDrawFrame():系统在每次重绘GLSu易做图ceView时调用此方法.此方法是绘制图形对象的主要的执行点.
onSu易做图ceChanged():当GLSu易做图ceView几何体改变时系统调用此方法,比如GLSu易做图ceView的大小改变或设备屏幕的方向改变.使用此方法来响应GLSu易做图ceView容器的变化.
OpenGL包
一旦你使用GLSu易做图ceView和GLSu易做图ceView.Renderer为OpenGL建立起一个容器,你就可以开始用以下类来调用OpenGLAPIs:
OpenGLES 1.0/1.1 API 包
android.opengl- 这个包为OpenGLES 1.0/1.1 类提供了一个静态接口并且其性能好于javax.microedition.khronos包中的接口.
GLES10
GLES10Ext
GLES11
GLES10Ext
javax.microedition.khronos.opengles- 这个包提供了OpenGLES 1.0/1.1 的标准实现.
GL10
GL10Ext
GL11
GL11Ext
GL11ExtensionPack
OpenGLES 2.0 API 类
android.opengl.GLES20- 这个包提供了OpenGLES 2.0 的接口并且从Android2.2 (API Level 8)开始才能用.
如果你想正确创建支持OpenGL的应用,请看OpenGL ES 1.0或OpenGLES 2.0的指南.
声明OpenGL的需求
如果你的应用使用的OpenGL特性不能被所有的设备支持,你必须在AndroidManifest.xml文件中包含你的OpenGL的需求.下面是最常见的OpenGLmanifest声明:
OpenGLES 版本需求-如果你的应用只支持OpenGLES 2.0,你必须把以下设置添加到manifest中以声明这个需求:
[html] <span style="color:#000000;"><!--Tell the system this app requires OpenGL ES 2.0. -->
<uses-featureandroid:glEsVersionuses-featureandroid:glEsVersion="0x00020000" android:required="true"/>
</span>
<span style="color:#000000;"><!--Tell the system this app requires OpenGL ES 2.0. -->
<uses-featureandroid:glEsVersion="0x00020000" android:required="true"/>
</span>
添加这个声明使得Android市场阻止你的应用被安装到不支持OpenGLES 2.0的设备上.
纹理压缩需求-如果你的应用使用了纹理压缩格式,你必须在你的manifest文件中用<supports-gl-texture>来声明所用格式.
在你的manifest中声明纹理压缩格式需求使得使用不支持其中任何一种压缩格式的设备的用户看不到你的应用.
为绘制对象映射坐标系
在Android设备中显示图形的一个基本问题是它们的屏幕的尺寸和形状可能不同.OpenGL假设一个正方形的,一致的坐标系统,并且,默认情况下,也乐于把这些坐标画到你的非正方形屏幕上,就像在正方形上一样.
图 1.默认OpenGL坐标系统(left)映射到典型的Android设备屏幕(right).
上面的插图,左图演示了一个OpenGL帧的一致的坐标系,以及如何映射到像右图这样的横向屏幕上.要解决这个问题,你可以设置OpenGL投影模式和相机视进行坐标变换使得你的图形对象在任何地方都具有正确的比例.
为了应用投影和视口,你要创建一个投影矩阵和一个视口矩阵然后把它们应用到OpenGL呈现管线中.投影矩阵重新计算你的图形的坐标于是它们可以正确地映射到Android设备屏幕上.视口矩追创建一个变换以从指定的眼睛位置呈现对象.
OpenGLES 1.0中的投影和视口 www.zzzyk.com
在ES1.0 API中,你通过创建每个矩追并把它们添加到OpenGL环境中来应用投影和视口.
投影矩阵-使用设备屏幕的几何体创建一个投影矩阵是为了重新计算对象坐标以使它们能按照正确的比例画出.下面的示例代码演示了如何实现GLSu易做图ceView.Renderer的onSu易做图ceChanged()方法来基于屏幕的纵横比创建一个投影矩阵然后把它应用到OpenGL呈现环境中.
[java] public void onSu易做图ceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
// make adjustments for screen ratio
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION); // set matrix to projection mode
gl.glLoadIdentity(); // reset the matrix to its default state
gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // apply the projection matrix
}
public void onSu易做图ceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
// make adjustments for screen ratio
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION); // set matrix to projection mode
gl.glLoadIdentity(); // reset the matrix to its default state
gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // apply the projection matrix
}
视口变换矩阵-一旦你使用投影矩阵调整了坐标系统,你必须同时应用一个视口矩阵.下面的示例代码演示了如何实现GLSu易做图ceView.Renderer的onDrawFrame()方法来应用视图模型并且使用GLU.gluLookAt()来指定眼睛位置创建一个视口变换.
[java] public void onDrawFrame(GL10 gl) {
...
// Set GL_MODELVIEW transformation mode
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity(); // reset the matrix to its default state
// When using GL_MODELVIEW, you must set the camera view
GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
...
}
public void onDrawFrame(GL10 gl) {
...
// Set GL_MODELVIEW transformation mode
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity(); // reset the matrix to its default state
&
补充:移动开发 , Android ,