首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

利用JNI技术在Android中调用C++方式的OpenGL ES 2.0函数

2013-09-13 
利用JNI技术在Android中调用C++形式的OpenGL ES 2.0函数1、打开Eclipse,File--New--Project…--Android--

利用JNI技术在Android中调用C++形式的OpenGL ES 2.0函数

1、                 打开Eclipse,File-->New-->Project…-->Android-->AndroidApplication Project,Next-->Application Name:FillTriangle, PackageName:com.filltriangle.android,Minimum Required SDK:API 10Android2.3.3(Gingerbread),Next-->不勾选Create customlauncher icon,Next-->选中Blank Activity,Next-->Activity Name:FillTriangle,Finish-->Runas Android Application,查看是否一切运行正常;

2、                 打开FillTriangleActivity.java,将其内容改为:

/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */// OpenGL ES 2.0 code#include <jni.h>#include <android/log.h>#include <GLES2/gl2.h>#include <GLES2/gl2ext.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);    }}static const char gVertexShader[] =     "attribute vec4 vPosition;\n"    "void main() {\n"    "  gl_Position = vPosition;\n"    "}\n";static const char gFragmentShader[] =     "precision mediump float;\n"    "void main() {\n"    "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"    "}\n";GLuint loadShader(GLenum shaderType, const char* pSource) {    GLuint shader = glCreateShader(shaderType);    if (shader) {        glShaderSource(shader, 1, &pSource, NULL);        glCompileShader(shader);        GLint compiled = 0;        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);        if (!compiled) {            GLint infoLen = 0;            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);            if (infoLen) {                char* buf = (char*) malloc(infoLen);                if (buf) {                    glGetShaderInfoLog(shader, infoLen, NULL, buf);                    LOGE("Could not compile shader %d:\n%s\n",                            shaderType, buf);                    free(buf);                }                glDeleteShader(shader);                shader = 0;            }        }    }    return shader;}GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);    if (!vertexShader) {        return 0;    }    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);    if (!pixelShader) {        return 0;    }    GLuint program = glCreateProgram();    if (program) {        glAttachShader(program, vertexShader);        checkGlError("glAttachShader");        glAttachShader(program, pixelShader);        checkGlError("glAttachShader");        glLinkProgram(program);        GLint linkStatus = GL_FALSE;        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);        if (linkStatus != GL_TRUE) {            GLint bufLength = 0;            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);            if (bufLength) {                char* buf = (char*) malloc(bufLength);                if (buf) {                    glGetProgramInfoLog(program, bufLength, NULL, buf);                    LOGE("Could not link program:\n%s\n", buf);                    free(buf);                }            }            glDeleteProgram(program);            program = 0;        }    }    return program;}GLuint gProgram;GLuint gvPositionHandle;bool setupGraphics(int w, int h) {    printGLString("Version", GL_VERSION);    printGLString("Vendor", GL_VENDOR);    printGLString("Renderer", GL_RENDERER);    printGLString("Extensions", GL_EXTENSIONS);    LOGI("setupGraphics(%d, %d)", w, h);    gProgram = createProgram(gVertexShader, gFragmentShader);    if (!gProgram) {        LOGE("Could not create program.");        return false;    }    gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");    checkGlError("glGetAttribLocation");    LOGI("glGetAttribLocation(\"vPosition\") = %d\n",            gvPositionHandle);    glViewport(0, 0, w, h);    checkGlError("glViewport");    return true;}const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,        0.5f, -0.5f };void renderFrame() {    static float grey;    grey += 0.01f;    if (grey > 1.0f) {        grey = 0.0f;    }    glClearColor(grey, grey, grey, 1.0f);    checkGlError("glClearColor");    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);    checkGlError("glClear");    glUseProgram(gProgram);    checkGlError("glUseProgram");    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);    checkGlError("glVertexAttribPointer");    glEnableVertexAttribArray(gvPositionHandle);    checkGlError("glEnableVertexAttribArray");    glDrawArrays(GL_TRIANGLES, 0, 3);    checkGlError("glDrawArrays");}extern "C" {    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height);    JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);};JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height){    setupGraphics(width, height);}JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj){    renderFrame();}

12、利用NDK生成.so文件:选中工程,点击右键-->Properties-->Builders-->New,新建立一个Builder,在弹出的对话框上点中Program,点击OK;在弹出对话框EditConfiguration中,配置选项卡Main:Location中填入NDK安装目录,D:\ProgramFiles\Android\android-sdk\android-ndk-r9\ndk-build.cmd;WorkingDirectory中填入工程的根目录,E:\Test\Android\FillTriangle,点击Apply;配置选项卡Refresh,勾选Refreshresources upon completion, The entire workspace, Recursively includesub-folders,点击Apply;配置Build Options选项卡,勾选Allocate Console(necessary for input), After a “Clean”, Duringmanual builds, During auto builds, Specify working set of relevant resources,点击SpecifyResources..,勾选FillTriangle工程的jni目录,点击Finish,点击Apply,点击OK,会在\libs\armeabi目录下生成相应的libgl2jni.so库;

13、运行该工程,会显示绿色三角。

 

参考文献:

1、  以上代码来自adt-bundle-windows-x86_64-20130729中的例程;

2、 http://blog.csdn.net/fengbingchun/article/details/11580983



热点排行