在android中使用OpenGL ES需要三个步骤:

1. 创建GLSurfaceView组件,使用Activity来显示GLSurfaceView组建。

2. 为GLSurfaceView组建创建GLSurfaceView.Renderer实例,实现GLSurfaceView.Renderer类时需要实现该接口里的三个方法:

  • abstract void onDrawFrame(GL10 gl):Called to draw the current frame.

  • abstract void onSurfaceChanged(GL10 gl, int width, int height):Called when the surface changed size.

  • abstract void onSurfaceCreated(GL10 gl, EGLConfig config):Called when the surface is created or recreated.

3. 调用GLSurfaceView组建的setRenderer (GLSurfaceView.Renderer renderer) 方法指定Renderer对象,该对象将会完成GLSurfaceView里3D图形的绘制。

然后来看一个Demo,首先是主Activity:

packagecom.example.androidgldemo;importandroid.opengl.GLSurfaceView;importandroid.os.Bundle;importandroid.app.Activity;importandroid.view.Menu;publicclassAndroidGLDemoextendsActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);GLSurfaceViewglView=newGLSurfaceView(this);AndroidGLDemoRendererrenderer=newAndroidGLDemoRenderer();glView.setRenderer(renderer);setContentView(glView);}@OverridepublicbooleanonCreateOptionsMenu(Menumenu){//Inflatethemenu;thisaddsitemstotheactionbarifitispresent.getMenuInflater().inflate(R.menu.activity_main,menu);returntrue;}}

然后是Renderer的实现:

packagecom.example.androidgldemo;importjava.nio.ByteBuffer;importjava.nio.ByteOrder;importjava.nio.FloatBuffer;importjava.nio.IntBuffer;importjavax.microedition.khronos.egl.EGLConfig;importjavax.microedition.khronos.opengles.GL10;importandroid.opengl.GLSurfaceView.Renderer;publicclassAndroidGLDemoRendererimplementsRenderer{float[]mTriangleData=newfloat[]{0.1f,0.6f,0.0f,-0.3f,0.0f,0.0f,0.3f,0.1f,0.0f};int[]mTriangleColor=newint[]{65535,0,0,0,0,65535,0,0,0,0,65535,0,};float[]mRectData=newfloat[]{0.4f,0.4f,0.0f,0.4f,-0.4f,0.0f,-0.4f,0.4f,0.0f,-0.4f,-0.4f,0.0f};int[]mRectColor=newint[]{0,65535,0,0,0,0,65535,0,65535,0,0,0,65535,65535,0,0,};FloatBuffermTriangleDataBuffer;IntBuffermTriangleColorBuffer;FloatBuffermRectDataBuffer;IntBuffermRectColorBuffer;publicAndroidGLDemoRenderer(){mTriangleDataBuffer=bufferUtil(mTriangleData);mTriangleColorBuffer=bufferUtil(mTriangleColor);mRectDataBuffer=bufferUtil(mRectData);mRectColorBuffer=bufferUtil(mRectColor);}@OverridepublicvoidonDrawFrame(GL10gl){gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);gl.glEnableClientState(GL10.GL_COLOR_ARRAY);gl.glMatrixMode(GL10.GL_MODELVIEW);gl.glLoadIdentity();gl.glTranslatef(-0.6f,0.0f,-1.5f);gl.glVertexPointer(3,GL10.GL_FLOAT,0,mTriangleDataBuffer);gl.glColorPointer(4,GL10.GL_FIXED,0,mTriangleColorBuffer);gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);gl.glLoadIdentity();gl.glTranslatef(0.6f,0.8f,-1.5f);gl.glVertexPointer(3,GL10.GL_FLOAT,0,mRectDataBuffer);gl.glColorPointer(4,GL10.GL_FIXED,0,mRectColorBuffer);gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);gl.glFinish();gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);}@OverridepublicvoidonSurfaceChanged(GL10gl,intwidth,intheight){gl.glViewport(0,0,width,height);gl.glMatrixMode(GL10.GL_PROJECTION);gl.glLoadIdentity();floatratio=(float)width/height;gl.glFrustumf(-ratio,ratio,-1,1,1,10);}@OverridepublicvoidonSurfaceCreated(GL10gl,EGLConfigconfig){gl.glDisable(GL10.GL_DITHER);gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);gl.glClearColor(0,0,0,0);gl.glShadeModel(GL10.GL_SMOOTH);gl.glEnable(GL10.GL_DEPTH_TEST);gl.glDepthFunc(GL10.GL_LEQUAL);}publicIntBufferbufferUtil(int[]arr){IntBufferbuffer;ByteBufferqbb=ByteBuffer.allocateDirect(arr.length*4);qbb.order(ByteOrder.nativeOrder());buffer=qbb.asIntBuffer();buffer.put(arr);buffer.position(0);returnbuffer;}publicFloatBufferbufferUtil(float[]arr){FloatBufferbuffer;ByteBufferqbb=ByteBuffer.allocateDirect(arr.length*4);qbb.order(ByteOrder.nativeOrder());buffer=qbb.asFloatBuffer();buffer.put(arr);buffer.position(0);returnbuffer;}}

注意构造函数中那些Buffer的创建方式。在这个地方,不能直接使用FloatBuffer/IntBuffer 的wrap() method。直接用这个method创建出来的buffer会导致JE:

02-2623:12:08.945:E/OpenGLES(2750):Applicationcom.example.androidgldemo(SDKtarget17)calledaGL11PointermethodwithanindirectBuffer.02-2623:12:08.968:W/dalvikvm(2750):threadid=11:threadexitingwithuncaughtexception(group=0x40d57930)02-2623:12:08.984:E/AndroidRuntime(2750):FATALEXCEPTION:GLThread1693802-2623:12:08.984:E/AndroidRuntime(2750):java.lang.IllegalArgumentException:MustuseanativeorderdirectBuffer02-2623:12:08.984:E/AndroidRuntime(2750):atcom.google.android.gles_jni.GLImpl.glVertexPointerBounds(NativeMethod)02-2623:12:08.984:E/AndroidRuntime(2750):atcom.google.android.gles_jni.GLImpl.glVertexPointer(GLImpl.java:1122)02-2623:12:08.984:E/AndroidRuntime(2750):atcom.example.androidgldemo.AndroidGLDemoRenderer.onDrawFrame(AndroidGLDemoRenderer.java:63)02-2623:12:08.984:E/AndroidRuntime(2750):atandroid.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)02-2623:12:08.984:E/AndroidRuntime(2750):atandroid.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)


更多相关文章

  1. Android 中文设置成粗体的方法
  2. Bitmap和Drawable相互转换方法
  3. android onSaveInstanceState方法 横坚屏切换
  4. Android Studio 编译提示 aapt.exe finished with non-zero exit
  5. android中处理json最佳方法
  6. [置顶] 彻底解决Android 应用方法数不能超过65K的问题
  7. Android JNI编程内存问题定位方法

随机推荐

  1. Mysql表,列,库增删改查问题小结
  2. MySQL的几种安装方式及配置问题小结
  3. Linux操作系统操作MySQL常用命令小结
  4. 阿里云ECS centos6.8下安装配置MySql5.7
  5. MySql版本问题sql_mode=only_full_group_
  6. Mysql误操作后利用binlog2sql快速回滚的
  7. Windows下mysql5.7.18安装配置教程
  8. mysql中格式化数字详解
  9. Mysql事务操作失败如何解决
  10. mysql报错:Deadlock found when trying to