在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实现为GridView添加边框效果
  2. Android(安卓)中使用HttpUrlConnection实现get请求服务器
  3. Android屏幕截图实现 (adbd部分)
  4. 在 Android(安卓)应用中使用数据库
  5. Android实现TextView字符串波浪式跳动
  6. 使用本地仓库实现最新版ReactNative集成Android
  7. Android(安卓)AES加密算法及其实现
  8. ViewPager实现QQ主界面,ViewFlipper实现某些新闻应用,自动播放,很
  9. 浅谈Java中Collections.sort对List排序的两种方法

随机推荐

  1. android调整checkbox的大小
  2. Android(安卓)input 输入系统学习
  3. Android(安卓)WebView获取上一个链接的路
  4. android画图-解锁界面
  5. Android——TabWidget
  6. Android(安卓)如何加载大图片
  7. Android(安卓)ViewHolder 优化 ListView
  8. Android倒计时器——CountDownTimer
  9. 关于LinearLayout布局中,子控件平分宽度
  10. Android开发遇到的问题