这个例子使用native部分来实现opengl es而不是java部分。
Java部分与例子2相似。
MainActivity.java
public class MainActivity extends Activity { GLSurfaceView mGLView; static { System.loadLibrary("myegl_jni"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // (NEW) this.mGLView = new MyGLSurfaceView(this); setContentView(this.mGLView); } }
public class MyGLSurfaceView extends GLSurfaceView { GLSurfaceView.Renderer mRenderer; private boolean goNative; /** * TODO Put here a description of what this constructor does. * * @param context * @param goNative */ public MyGLSurfaceView(Context context) { super(context); // TODO Auto-generated constructor stub. mRenderer = new MyRenderer(); // Set the Renderer for drawing on the GLSurfaceView setRenderer(mRenderer); } }
public class MyRenderer implements GLSurfaceView.Renderer { private static final String TAG = "agl"; private native String nativeGetHelloString(); private native void nativeDrawFrame(); private native void nativeSurfaceChanged(int width, int height); private native void nativeSurfaceCreated(); @Override public void onDrawFrame(GL10 gl) { nativeDrawFrame(); Log.d(TAG, "onDrawFrame " + nativeGetHelloString()); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { nativeSurfaceChanged(width,height); Log.d(TAG, "onSurfaceChanged"); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { nativeSurfaceCreated(); Log.d(TAG, "onSurfaceCreate"); } }
#include <jni.h> #include <string.h> #include <android/log.h> #include <GLES/gl.h> #include <GLES/gl.h> #include <GLES/glext.h> #include <stdio.h> #include <stdlib.h> #include <math.h> extern "C" { #define LOG_TAG "libgl2jni" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) void printGLString(char* name, GLenum s); void init(); void resize(int width, int height); void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); void renderFrame(); GLfloat rtri; //三角形的旋转变量 GLfloat rquad; //四边形的旋转变量 const GLfloat PI = 3.1415f; GLfloat gVertices[] = { 0.0f, 1.0f, 0.0f, -1.0f,-1.0f, 1.0f, 1.0f,-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,-1.0f, 1.0f, 1.0f,-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f,-1.0f, -1.0f, -1.0f,-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f,-1.0f,-1.0f, -1.0f,-1.0f, 1.0f }; GLfloat gColors[] = { 1.0f,0.0f,0.0f, 1.0f, 0.0f,1.0f,0.0f, 1.0f, 0.0f,0.0f,1.0f, 1.0f, 1.0f,0.0f,0.0f, 1.0f, 0.0f,0.0f,1.0f, 1.0f, 0.0f,1.0f,0.0f, 1.0f, 1.0f,0.0f,0.0f, 1.0f, 0.0f,1.0f,0.0f, 1.0f, 0.0f,0.0f,1.0f, 1.0f, 1.0f,0.0f,0.0f, 1.0f, 0.0f,0.0f,1.0f, 1.0f, 0.0f,1.0f,0.0f, 1.0f }; } //end of extern "C"
#include "com_example_nativeegl_MyRenderer.h" extern "C" { void printGLString(char* name, GLenum s) { char *v = (char *) glGetString(s); LOGI("GL %s = %s", name, v); } /* * Class: com_example_nativeegl_MyRenderer * Method: nativeGetHelloString * Signature: ()Ljava/lang/String; */ jstring nativeGetHelloString(JNIEnv *env, jobject obj) { return env->NewStringUTF((char*)" This is calling from JNI suckers!"); } /* * Class: com_example_nativeegl_MyRenderer * Method: nativeDrawFrame * Signature: ()V */ void nativeDrawFrame(JNIEnv *env, jobject obj) { renderFrame(); } /* * Class: com_example_nativeegl_MyRenderer * Method: nativeSurfaceChanged * Signature: (II)V */ void nativeSurfaceChanged(JNIEnv *env, jobject obj, jint width, jint height){ resize(width, height); } void init() { LOGD("init the renderer"); glShadeModel(GL_SMOOTH); glClearColor(0.0f,0.0f, 0.0f, 0.0f); glClearDepthf(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); } void resize(int width, int height) { LOGD("resize the renderer"); glViewport(0,0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // GLfloat ratio = (GLfloat)width/(GLfloat)height; gluPerspective(45.0f, (GLfloat)width/(GLfloat)height, 0.1f, 100.0f); //glOrthof(-2.0f, 2.0f, -2.0f, 2.0f, -2.0f, 2.0f); glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵 glLoadIdentity(); // 重置模型观察矩阵 } void gluPerspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar) { GLfloat top = zNear * ((GLfloat) tan(fovy * PI / 360.0)); GLfloat bottom = -top; GLfloat left = bottom * aspect; GLfloat right = top * aspect; glFrustumf(left, right, bottom, top, zNear, zFar); } void renderFrame() { LOGD("renderFrame the renderer"); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存 glLoadIdentity(); // 重置模型观察矩阵 glTranslatef(0.0f,0.0f, -6.0f); // 移入屏幕 6.0 glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转金字塔 glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_FLOAT, 0, gColors); glVertexPointer(3, GL_FLOAT, 0, gVertices); glDrawArrays(GL_TRIANGLES, 0, 12); rtri += 0.2f; // 增加三角形的旋转变量 //LOGI("xxxxx"); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glFlush(); } /* * Class: com_example_nativeegl_MyRenderer * Method: nativeSurfaceCreated * Signature: ()V */ void nativeSurfaceCreated(JNIEnv *env, jobject obj) { init(); } //----------------------------JNI part:Native register------------------------------------------------------ static JNINativeMethod gMethods[] = { //{"native method name from Java","(arguments type)return type", "(void*)local_native_name" {"nativeGetHelloString", "()Ljava/lang/String;", (void *)nativeGetHelloString}, {"nativeDrawFrame", "()V", (void *)nativeDrawFrame}, {"nativeSurfaceChanged", "(II)V", (void *)nativeSurfaceChanged}, {"nativeSurfaceCreated", "()V", (void *)nativeSurfaceCreated}, }; static const char* className="com/example/nativeegldynamicjni/MyRenderer"; static int registerNativeMethods(JNIEnv *env) { jclass clazz; clazz = env->FindClass(className); if (clazz == NULL) { LOGD("failed to load the class %s", className); return JNI_FALSE; } if (env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])) < 0) { return JNI_FALSE; } return JNI_TRUE; } //end of registerNativeMethods jint JNI_OnLoad(JavaVM* vm, void* reserved) { JNIEnv* env = NULL; jint result = -1; if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { LOGE("ERROR: GetEnv failed\n"); goto bail; } if (registerNativeMethods(env) < 0) { LOGE("ERROR: jnitest native registration failed\n"); goto bail; } result = JNI_VERSION_1_4; bail: return result; } } //end of extern "C"
#Description:makefile of Helloworld LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS := -Wall LOCAL_MODULE := myegl_jni LOCAL_C_INCLUDES :=$(LOCAL_PATH)/include LOCAL_CPP_EXTENSION := .cpp LOCAL_LDLIBS += -llog -lGLESv1_CM LOCAL_SRC_FILES := com_example_nativeegl_MyRenderer.cpp include $(BUILD_SHARED_LIBRARY)