在Android下初始化Native OpenGL ES

来源:互联网 发布:降龙软件优点 编辑:程序博客网 时间:2024/05/03 14:52

在上一篇文章中,介绍了在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的代码

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);}@Overridepublic void onSurfaceCreated(GL10 arg0,javax.microedition.khronos.egl.EGLConfig arg1) {// TODO Auto-generated method stubLibraryClass.init();}}

结论

使用GLSurfaceView可以省却大量进行EGL初始化的冗余代码,简化了在native层进行渲染的过程。


参考文献:

https://software.intel.com/en-us/articles/setting-up-native-opengl-es-on-android-platforms

0 0
原创粉丝点击