采用JNI方法利用opengl es 1.x在android上绘图
2014-05-12 00:00
429 查看
我们可以在jni层上编写opengl代码, 进行3d 图形的绘制,下面这个例子就是在一个绘制四面体的例子, 实例的绘制代码是在jni层实现的, 采用c++语言编写。
1. 首先, 创建上层应用程序相关类, 组织好调用路径。
这里主要是创建活动类, 渲染类以及相关辅助类。
主活动类代码如下:
其次创建opengl视图类,代码如下:
接着创建渲染类,代码如下:
最后,声明与jni 相对应的本地化方法, 加载相应的jni代码生成的库, 代码如下:
2. 编写jni绘制代码
在android工程的根目录下创建jni 文件夹, 新建两个文件, 一个是Android.mk文件,另一个就是我们实现绘制的代码文件,其中Android.mk文件的内容如下:
最后是相应的绘制代码,如下所示:
利用ndk-build工具将jni代码编译成库, 然后运行android 应用程序即可。
1. 首先, 创建上层应用程序相关类, 组织好调用路径。
这里主要是创建活动类, 渲染类以及相关辅助类。
主活动类代码如下:
import android.app.Activity; import android.os.Bundle; public class GL10JNIActivity extends Activity { private GL10JNIView mView; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); mView = new GL10JNIView(this); setContentView(mView); } @Override protected void onPause() { super.onPause(); mView.onPause(); } @Override protected void onResume() { super.onResume(); mView.onResume(); } }
其次创建opengl视图类,代码如下:
import android.content.Context; import android.opengl.GLSurfaceView; public class GL10JNIView extends GLSurfaceView { private static final String LOG_TAG = GL10JNIView.class.getSimpleName(); private MyRenderer myRenderer; public GL10JNIView(Context context) { super(context); setEGLConfigChooser(8, 8, 8, 8, 16, 0); myRenderer = new MyRenderer(context); setRenderer(myRenderer); } }
接着创建渲染类,代码如下:
import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.opengl.GLSurfaceView.Renderer; public class MyRenderer implements Renderer { public MyRenderer(Context ctx) { } @Override public void onDrawFrame(GL10 gl) { GL10JNILib.step(); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { GL10JNILib.resize(width, height); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { GL10JNILib.init(); } }
最后,声明与jni 相对应的本地化方法, 加载相应的jni代码生成的库, 代码如下:
public class GL10JNILib { static { System.loadLibrary("gl10jni"); } /** * @param width the current view width * @param height the current view height */ public static native void resize(int width, int height); public static native void step(); public static native void init(); }
2. 编写jni绘制代码
在android工程的根目录下创建jni 文件夹, 新建两个文件, 一个是Android.mk文件,另一个就是我们实现绘制的代码文件,其中Android.mk文件的内容如下:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libgl10jni LOCAL_CFLAGS := -Werror LOCAL_SRC_FILES := gl_code.cpp LOCAL_LDLIBS := -llog -lGLESv1_CM include $(BUILD_SHARED_LIBRARY)
最后是相应的绘制代码,如下所示:
#include <jni.h> #include <android/log.h> #include <GLES/gl.h> #include <GLES/glext.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #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__) static void printGLString(const char *name, GLenum s) { const char *v = (const char *) glGetString(s); LOGI("GL %s = %s\n", name, v); } static void checkGlError(const char* op) { for (GLint error = glGetError(); error; error = glGetError()) { LOGI("after %s() glError (0x%x)\n", op, error); } } bool init() { printGLString("Version", GL_VERSION); printGLString("Vendor", GL_VENDOR); printGLString("Renderer", GL_RENDERER); printGLString("Extensions", GL_EXTENSIONS); 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); // 告诉系统对透视进行修正 return true; } const 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 }; const 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 }; static GLfloat rtri; //三角形的旋转变量 static GLfloat rquad; //四边形的旋转变量 const GLfloat PI = 3.1415f; static 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 resize(int width, int height) { if (height==0) // 防止被零除 { height=1; // 将Height设为1 } 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 renderFrame() { 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(); } extern "C" { JNIEXPORT void JNICALL Java_com_test_fuyajun_GL10JNILib_resize(JNIEnv * env, jobject obj, jint width, jint height); JNIEXPORT void JNICALL Java_com_test_fuyajun_GL10JNILib_step(JNIEnv * env, jobject obj); JNIEXPORT void JNICALL Java_com_test_fuyajun_GL10JNILib_init(JNIEnv * env, jobject obj); }; JNIEXPORT void JNICALL Java_com_test_fuyajun_GL10JNILib_resize(JNIEnv * env, jobject obj, jint width, jint height) { resize(width, height); } JNIEXPORT void JNICALL Java_com_test_fuyajun_GL10JNILib_step(JNIEnv * env, jobject obj) { renderFrame(); } JNIEXPORT void JNICALL Java_com_test_fuyajun_GL10JNILib_init(JNIEnv * env, jobject obj) { init(); }
利用ndk-build工具将jni代码编译成库, 然后运行android 应用程序即可。
相关文章推荐
- 采用JNI方法利用opengl es 1.x在android上绘图
- android学习笔记---53_采用网页设计软件界面,以及使用android系统内置的浏览器,利用js调用java方法
- Android应用开发中,会经常要提交数据到服务器和从服务器得到数据,本文主要是给出了利用http协议采用HttpClient方式向服务器提交数据的方法。
- android 利用类的同名方法欺骗jni调用(二)
- 利用JNI技术在Android中调用C++形式的OpenGL ES 2.0函数
- android 利用类的同名方法欺骗jni调用(一)
- 利用OPENCV为android开发畸变校正的JNI库方法
- 利用JNI技术在Android中调用C++形式的OpenGL ES 2.0函数
- android学习笔记---53_采用网页设计软件界面,以及使用android系统内置的浏览器,利用js调用java方法
- 利用JNI技术在Android中调用C++形式的OpenGL ES 2.0函数
- 利用JNI技术在Android中调用C++形式的OpenGL ES 2.0函数
- 利用JNI技术在Android中调用C++形式的OpenGL ES 2.0函数
- Android OpenGL ES 绘图方法参数解析
- 利用HTTP协议实现Android文件上传至WEB服务器,采用PHP接收文件(参考网上自己实现)
- Android中JNI的使用方法
- 【转】Android下编译jni库的二种方法(含示例)
- Android JNI 动态注册方法(JNI_OnLoad)
- Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法
- Android游戏开发:如何利用Thread与Handler执行多线程的方法
- Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法