OpenGL ES2 学习教程1——Android入口

本教程适用于学习opengles,采用c++语言。基于Android平台。

创建工程

可以使用android-studio,eclipse去创建一个工程,这里我使用命令行(Android的环境配置略)。

# create android project mkdir GlesTutorial cd GlesTutorial android create project --target android-19 --name GlesTutorial --path ./ --package com.richard.glestutorial --activity AppActivity  # jni port mkdir jni # core c++ code mkdir core

在项目的根目录下创建一个jni目录,用来放jni相关的文件,core为我们以后主要使用的编程目录,将只存放c++代码。

这里run没问题就继续。

创建SurfaceView

我们不再使用sdk中的api去创建view,而是利用opengl-es来创建我们的view。android里可以用到GLSurfaceView,这是给Opengl专用的。

在AppActivity中采用我们自己的view,并将一些生命周期状态发送给我们自己的View:

package com.richard.glestutorial;  import android.app.Activity; import android.os.Bundle;  public class AppActivity extends Activity {     protected AppSurfaceView mView;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         mView = new AppSurfaceView(getApplication());         setContentView(mView);     }      @Override     protected void onPause() {         super.onPause();         mView.onPause();     }      @Override     protected void onResume() {         super.onResume();         mView.onResume();     }      @Override     protected void onDestroy() {         super.onDestroy();     } }

创建AppSurfaceView.java 继承GLSurfaceView:

package com.richard.glestutorial;  import android.content.Context; import android.opengl.GLSurfaceView;  public class AppSurfaceView extends GLSurfaceView {      protected GLRenderer mRender;      public AppSurfaceView(Context context) {         super(context);         setEGLContextClientVersion(2); // set OpenGLES version                  mRender = new GLRenderer();    // SurfaceView 需要设置一个渲染对象,待会自己实现一个SurfaceView.Renderer         setRenderer(mRender);     }      @Override     public void onPause() {         super.onPause();         mRender.handleOnPause();     }      @Override     public void onResume() {         super.onResume();         mRender.handleOnResume();     } }

GLRendder.java:

package com.richard.glestutorial;  import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10;  import android.opengl.GLSurfaceView.Renderer; import android.util.Log;  public class GLRenderer implements Renderer {      static {         System.loadLibrary("gltutorial");  // 一起来就加载c++库文件,待会来指定这个库     }      @Override     public void onSurfaceCreated(GL10 gl, EGLConfig config) {         GLRenderer.nativeInit();     }      @Override     public void onSurfaceChanged(GL10 gl, int width, int height) {         GLRenderer.nativeOnReSize(width, height);     }      @Override     public void onDrawFrame(GL10 gl) {         GLRenderer.nativeUpdate();     }      public void handleOnPause() {         GLRenderer.nativeOnPause();     }      public void handleOnResume() {         Log.v("GLES Tutorial", "nativeOnResume");         GLRenderer.nativeOnResume();     }          // ------------------------------------------------------------     // Native Method      private static native void nativeInit();      private static native void nativeOnReSize(int width, int height);      private static native void nativeUpdate();      private static native void nativeOnPause();      private static native void nativeOnResume(); }

这里设置了GLRenderer中声明了5个native方法,分别为:初始化;重绘制时设置view大小;每帧更新;暂停(退出前台);继续(回到前台)。将这些必备的状态通知给C++。以便我们进行绘制。

编写库

好了,接下来先编写Android.mk,用以生成libgltutorial.so这个库。在jni目录下新建Android.mk:

LOCAL_PATH:= $(call my-dir)  include $(CLEAR_VARS)  LOCAL_MODULE    := gltutorial  LOCAL_LDLIBS    := -llog -lGLESv2 LOCAL_CFLAGS    := -Werror LOCAL_CPPFLAGS  := -std=c++11  include $(BUILD_SHARED_LIBRARY)

LOCAL_MODULE 指定了这个库的名字并添加了log库,opengl-es2这两个库给c++使用。LOCAL_CFLAGS是c/c++编译选项,Werror是警告也作为错误信息在编译时给出。BUILD_SHARED_LIBRARY是指定编译为动态库。

native实现

库是有了,还没有添加内容,这里要将GLRenderer中的native的实现以及我们自己定义的C++代码全部作为库。

先实现native方法:在bin下找到java源码build后的位置classes,运行javah生成native头文件: com_richard_glestutorial_GLRenderer.h

cd bin/classes javah -classpath ~/dev/android/android-sdk-macosx/platforms/android-19/android.jar:. com.richard.glestutorial.GLRenderer mv com_richard_glestutorial_GLRenderer.h ../../jni/

编写实现代码:com_richard_glestutorial_GLRenderer.cpp:这里为了以后使用方便,新建一个Director在根目录的core/中。

#include "com_richard_glestutorial_GLRenderer.h" #include "../core/Director.h"  JNIEXPORT void JNICALL Java_com_richard_glestutorial_GLRenderer_nativeInit   (JNIEnv *env, jclass thiz) {     Director::getInstance(); }  JNIEXPORT void JNICALL Java_com_richard_glestutorial_GLRenderer_nativeOnReSize   (JNIEnv *env, jclass thiz, jint width, jint height) {      Director::getInstance()->setFrameSize(width, height); }  JNIEXPORT void JNICALL Java_com_richard_glestutorial_GLRenderer_nativeUpdate   (JNIEnv *env, jclass thiz) {     Director::getInstance()->mainLoop(); }  JNIEXPORT void JNICALL Java_com_richard_glestutorial_GLRenderer_nativeOnPause   (JNIEnv *env, jclass thiz) {     Director::getInstance()->onEnterBackground(); }  JNIEXPORT void JNICALL Java_com_richard_glestutorial_GLRenderer_nativeOnResume   (JNIEnv *env, jclass thiz) {     Director::getInstance()->onEnterForeground(); }

Director的定义如下:

Director.h:

#ifndef _DRECTOR_H__ #define _DRECTOR_H__  class Director { public:     static Director* getInstance();      void init();      void setFrameSize(float width, float height);      void mainLoop();      void onEnterForeground();      void onEnterBackground();  private:     Director();     ~Director();      float _fFrameWidth;     float _fFrameHeight; }; 

其实现可以添加一些log。可以用于查看。

最后要在Android.mk中指定所有的c++代码:

LOCAL_SRC_FILES :=  com_richard_glestutorial_GLRenderer.cpp  ../core/Director.cpp                  LOCAL_C_INCLUDES :=  $(LOCAL_PATH)

Run

最后运行,我们就可以看到一个空白的view的界面。以后我们就可以在上面写界面了。

ndk-build # 编译库 ant debug # ant打包 adb install -r bin/GlesTutorial-debug.apk  # adb install adb logcat | grep GLES  # 查看log

所有项目代码看里面的lesson1的tag。读者可以clone代码后,使用git checkout lesson1。github也提供了在线查看:点Branch:master那个绿色按钮可以看到tags,然后去切换。

脚本宝典为你提供优质服务
脚本宝典 » OpenGL ES2 学习教程1——Android入口

发表评论

提供最优质的资源集合

立即查看 了解详情