您的位置:首页 > 移动开发 > Android开发

在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的代码

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: