您的位置:首页 > 移动开发 > Android开发

采用JNI方法利用opengl es 1.x在android上绘图

2011-09-22 21:12 393 查看
我们可以在jni层上编写opengl代码, 进行3d 图形的绘制,下面这个例子就是在一个绘制四面体的例子, 实例的绘制代码是在jni层实现的, 采用c++语言编写。

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 应用程序即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐