Android视图框架对于创建复杂布局非常方便。然而,这种便利是以性能为代价的。当性能至关重要的时候,Android提供了几种更强大的图形处理能力,当然难度也是随之上升了。在本节中,我将介绍:
(1)SurfaceView使用标准的Canvas对象并与单独的渲染进程结合,得到更好的性能;
(2)新得RenderScript框架可以被用于创建独立结构的图形渲染;
(3)OpenGL可用于一些严格的图形工作和游戏。
3、OpenGL可用于一些严格的图形工作和游戏
Android为使用OpenGL ES 1.0和OpenGL ES 2.0标准的硬件渲染图形提供了完全支持。OpenGL API可以通过Java框架和本地开发套件(NDK)来进行调用。Java框架提供了一个简单已用的API,但是却有一个小的性能损失。对于全加速图形支持,以及移植现有代码,NDK提供了最佳的解决方案。不过,这超出了本书的范围。
这里我只做一个java框架的API,初步了解OpenGL。创建OpenGL需要两个类:GLSurfaceView和GLSurface.Render。GLSurfaceView类和SurfaceView类相似,并且可以结合OpenGL渲染图形和Android标准视图框架。这个类提供了单独的渲染线程,可以独立于UI线程生成图形。此外,GLSurfaceView提供了一些调试工具,可以来帮助在渲染代码中追踪错误。
注意:OpenGL,需要一部android设备,模拟器是不可用的。
效果如下图:
一个不停旋转的三角形,当手触摸屏幕的时候,背景颜色会随着手触碰的位置不通而变化。
这里分为三部:
3.1 声明GLSurface.Render方法
public class ExampleRender implements GLSurfaceView.Renderer { private float[] mVertics={-2.0f, -2.0f, 0, 2.0f, -2.0f, 0, 0.0f, 2.0f, 0}; private FloatBuffer mVertexBuffer; private float mRed; private float mGreen; private float mBlue; private float mAngle; private long mLastFrameTime = 0; /********************************************************** * 更新onDrawFrame方法,基于color字段设置视图的颜色并绘制三角形。 */ @Override public void onDrawFrame(GL10 gl) { // TODO Auto-generated method stub gl.glClearColor(mRed, mGreen, mBlue, 1.0f); gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); upDateAngle(); gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -7.0f); gl.glRotatef(mAngle, 0.0f, 0.0f, 1.0f); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glColor4f(255f, 255f, 255f, 0.0f); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); } /*********************************************************** * 更新onSurfaceChanged方法来设置映射矩阵。OpenGL假定了一个方形的 * 显示,所以你需要改变图形的长度比来匹配屏幕。 */ @Override public void onSurfaceChanged(GL10 gl, int width, int height) { // TODO Auto-generated method stub gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); float ratio = (float)width/height; GLU.gluPerspective(gl, 45.0f, ratio, 0.1f, 100.0f); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); } /*********************************************************** * 初始化方法中的顶点 */ @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(mVertics.length*4); vertexByteBuffer.order(ByteOrder.nativeOrder()); mVertexBuffer = vertexByteBuffer.asFloatBuffer(); mVertexBuffer.put(mVertics); mVertexBuffer.position(0); } private void upDateAngle(){ long now = System.currentTimeMillis(); if(mLastFrameTime != 0){ mAngle += 10*(now - mLastFrameTime)/1000.0; } mLastFrameTime = now; } public void setColor(float red, float green, float blue){ this.mRed = red; this.mGreen = green; this.mBlue = blue; } }
这里重载了GLSurfaceView的创建,更改,和onDrawFrame方法,并添加了,更新角度和设置颜色的方法,方便我们使用。
3.2 继承GLSurfaceView方法,setRender为3.1中的ExampleRender
public class ExampleGLSurfaceView extends GLSurfaceView { public ExampleRender mRender; public ExampleGLSurfaceView(Context context) { super(context); // TODO Auto-generated constructor stub mRender = new ExampleRender(); setRenderer(mRender); } /*************************************************** * 重写onTouchEvent */ @Override public boolean onTouchEvent(MotionEvent event){ switch (event.getAction()){ case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: final float x = event.getX()/getWidth(); final float y = event.getY()/getHeight(); queueEvent(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub mRender.setColor(x, y, 0.5f); } }); return true; } return super.onTouchEvent(event); } }
这里重写了onTouchEvent方法,实现了手触碰,颜色变化的功能。
3.3 在主界面上显示当前做的View
public class MainActivity extends Activity { private ExampleGLSurfaceView mGLView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLView = new ExampleGLSurfaceView(this); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(mGLView); }
这里是使用了java的框架的API,也只是实现了一个小的功能,OpenGL的功能非常的强大,大家可以参考http://blog.csdn.net/mapdigit/article/details/7526556目录列表来学习。