[Android NDK]Android JNI开发例子 ---3 在JNI中实现openGL功能

来源:互联网 发布:raysource mac版 编辑:程序博客网 时间:2024/06/01 14:01

这个例子使用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);    }}

MyGLSurfaceView.java

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);    }}


Renderer.java

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");    }}

在jni文件夹内创建include文件夹。 在include下创建一个头文件。cpp中的所有变量和函数要在声明之后才能够直接使用。 .h文件中都是声明。

#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"

cpp文件

#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.0glRotatef(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 registerNativeMethodsjint 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"

Android.mk

#Description:makefile of Helloworld  LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_CFLAGS    := -WallLOCAL_MODULE    := myegl_jniLOCAL_C_INCLUDES :=$(LOCAL_PATH)/includeLOCAL_CPP_EXTENSION := .cppLOCAL_LDLIBS += -llog -lGLESv1_CMLOCAL_SRC_FILES := com_example_nativeegl_MyRenderer.cppinclude $(BUILD_SHARED_LIBRARY)

在项目根目录想执行ndk-build编译jni出.so库。




原创粉丝点击