[Android(安卓)NDK]Android(安卓)JNI开发例子 ---3 在JNI中实现openGL功能
16lz
2021-12-04
这个例子使用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); }}
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库。
更多相关文章
- android 自定义view
- android解决坚屏拍照和保存图片旋转90度的问题,并兼容4.0
- Android之adb环境变量配置
- android 目录结构,adb环境变量配置
- 链接器解析多重定义的全局变量
- 自定义带倒影和偏转的超炫Gallery
- android图像处理系统1.3
- Android(安卓)旋转屏幕捕获当前屏幕的状态
- Android(安卓)拍照及相册选图的那些坑