在Android下初始化Native OpenGL ES
2015-10-24 14:14
459 查看
在上一篇文章中,介绍了在Android Native层初始化EGL及OpenGL ES的方法,其中,大量代码花费在EGL的初始化上面,非常的麻烦。在本文中,将展示利用GLSurfaceView来代替我们手动初始化EGL的过程。
用GLSurfaceView替换默认View
在创建一个新工程后,我们需要用GLSurfaceView来作为当前的activity view。GLSurfaceView中封装了EGL的相关功能,其中有两个重要的接口:setEGLContextClientVersion和setRenderer。
setEGLContextClientVersion用来设置OpenGL ES的版本,这里使用OpenGL ES 2.0.
实际的渲染工作是通过继承自GLSurfaceView.Renderer基类的实例来完成的,渲染实例通过setRenderer进行指定。
下面是Activity的代码
在AndroidManifest.xml中需要指明使用了OpenGL ES 2.0的特性:
onSurfaceCreated中进行一些初始化的工作,onSurfaceChanged中当窗口参数发生变化时进行一些更新操作,onDrawFrame是真正进行绘制的地方。这里可以直接利用Java层的OpenGL ES接口进行绘制,但本文着重要介绍的是如何在native层进行绘制,因此,我们在后面再详细介绍这三个方法的具体内容。
这里我们可以看到,三个jni接口函数分别封装了三个内部函数与GLSurfaceView.Renderer中的三个抽象方法对应。
jni代码的编译方法见之前的文章,这里就不再赘述了。
剩下的工作就是在Java层加载编译出来的jni动态库文件,并在相应的位置调用相应的接口:
用GLSurfaceView替换默认View
在创建一个新工程后,我们需要用GLSurfaceView来作为当前的activity view。GLSurfaceView中封装了EGL的相关功能,其中有两个重要的接口:setEGLContextClientVersion和setRenderer。setEGLContextClientVersion用来设置OpenGL ES的版本,这里使用OpenGL ES 2.0.
实际的渲染工作是通过继承自GLSurfaceView.Renderer基类的实例来完成的,渲染实例通过setRenderer进行指定。
下面是Activity的代码
public class DemoActivity extends Activity { private GLSurfaceView view; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); view = new GLSurfaceView(this); view.setEGLContextClientVersion(2); view.setRenderer(new ApplicationRender()); setContentView(view); } }
在AndroidManifest.xml中需要指明使用了OpenGL ES 2.0的特性:
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
GLSurfaceView.Renderer
GLSurfaceView.Renderer中有3个其子类必须实现的虚方法:onSurfaceCreated、onSurfaceChanged和onDrawFrame。onSurfaceCreated中进行一些初始化的工作,onSurfaceChanged中当窗口参数发生变化时进行一些更新操作,onDrawFrame是真正进行绘制的地方。这里可以直接利用Java层的OpenGL ES接口进行绘制,但本文着重要介绍的是如何在native层进行绘制,因此,我们在后面再详细介绍这三个方法的具体内容。
Native渲染
JNI层的完整代码如下#include <jni.h> #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> void InitializeOpenGL() { glClearColor(1.0f, 1.0f, 0.0f, 1.0f); } void resizeViewport(int newWidth, int newHeight) { glViewport(0, 0, newWidth, newHeight); } void renderFrame() { glClear(GL_COLOR_BUFFER_BIT); } JNIEXPORT void JNICALL Java_com_example_demo_LibraryClass_init(JNIEnv* env, jobject thiz) { InitializeOpenGL(); } JNIEXPORT void JNICALL Java_com_example_demo_LibraryClass_resize(JNIEnv* env, jobject thiz, jint width, jint height) { resizeViewport(width, height); } JNIEXPORT void JNICALL Java_com_example_demo_LibraryClass_render(JNIEnv* env, jobject thiz) { renderFrame(); } </gles2></gles2></jni>
这里我们可以看到,三个jni接口函数分别封装了三个内部函数与GLSurfaceView.Renderer中的三个抽象方法对应。
jni代码的编译方法见之前的文章,这里就不再赘述了。
剩下的工作就是在Java层加载编译出来的jni动态库文件,并在相应的位置调用相应的接口:
public class LibraryClass { static { System.loadLibrary("demo"); } public static native void init(); public static native void resize(int width, int height); public static native void render(); }
public class ApplicationRender implements GLSurfaceView.Renderer { public void onDrawFrame(GL10 gl) { LibraryClass.render(); } public void onSurfaceChanged(GL10 gl, int width, int height) { LibraryClass.resize(width, height); } @Override public void onSurfaceCreated(GL10 arg0, javax.microedition.khronos.egl.EGLConfig arg1) { // TODO Auto-generated method stub LibraryClass.init(); } }
结论
使用GLSurfaceView可以省却大量进行EGL初始化的冗余代码,简化了在native层进行渲染的过程。参考文献:
https://software.intel.com/en-us/articles/setting-up-native-opengl-es-on-android-platforms相关文章推荐
- Android&iOS安装包更新笔记
- android图片特效
- Android开发重启adb的批处理
- Android屏幕适配全攻略(最权威的官方适配指导)
- Android应用程序线程的消息循环模型
- .gradle 文件简单介绍
- Android docs4.3API
- Android编码规范02
- Android XUtils的使用
- android ListView几个比较特别的属性
- Android自定义view之弹出式dialog
- Android消息机制深入了解
- android下的三种动画
- Android 百度地图路径规划
- Android 弹软键盘时listview的变化控制
- Android属性动画完全解析(二)
- android----Timer和TimerTask的使用
- android-----用代码安装apk文件
- Android 百度地图定位
- Android编码规范01