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

http://blog.csdn.net/fengbingchun/article/details/11618707


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,将其内容改为:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.filltriangle.android;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.util.Log;  
  6. import android.view.WindowManager;  
  7.   
  8. import java.io.File;  
  9.   
  10. public class FillTriangleActivity extends Activity {  
  11.   
  12.     GL2JNIView mView;  
  13.   
  14.     @Override protected void onCreate(Bundle icicle) {  
  15.         super.onCreate(icicle);  
  16.         mView = new GL2JNIView(getApplication());  
  17.     setContentView(mView);  
  18.     }  
  19.   
  20.     @Override protected void onPause() {  
  21.         super.onPause();  
  22.         mView.onPause();  
  23.     }  
  24.   
  25.     @Override protected void onResume() {  
  26.         super.onResume();  
  27.         mView.onResume();  
  28.     }  
  29.   
  30. }  

3、 新建2个java文件,选中com.filltriangle.android,点击右键,New-->Class,Name:GL2JNILib和Name:GL2JNIView;

4、GL2JNILib.java文件内容为:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.filltriangle.android;  
  2.   
  3. //Wrapper for native library  
  4.   
  5. public class GL2JNILib {  
  6.   
  7.   static {  
  8.       System.loadLibrary("gl2jni");  
  9.   }  
  10.   
  11.  /** 
  12.   * @param width the current view width 
  13.   * @param height the current view height 
  14.   */  
  15.   public static native void init(int width, int height);  
  16.   public static native void step();  
  17. }  

5、 GL2JNIView.java文件内容为:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.filltriangle.android;  
  2.   
  3. import android.content.Context;  
  4. import android.graphics.PixelFormat;  
  5. import android.opengl.GLSurfaceView;  
  6. import android.util.AttributeSet;  
  7. import android.util.Log;  
  8. import android.view.KeyEvent;  
  9. import android.view.MotionEvent;  
  10.   
  11. import javax.microedition.khronos.egl.EGL10;  
  12. import javax.microedition.khronos.egl.EGLConfig;  
  13. import javax.microedition.khronos.egl.EGLContext;  
  14. import javax.microedition.khronos.egl.EGLDisplay;  
  15. import javax.microedition.khronos.opengles.GL10;  
  16.   
  17. /** 
  18.  * A simple GLSurfaceView sub-class that demonstrate how to perform 
  19.  * OpenGL ES 2.0 rendering into a GL Surface. Note the following important 
  20.  * details: 
  21.  * 
  22.  * - The class must use a custom context factory to enable 2.0 rendering. 
  23.  *   See ContextFactory class definition below. 
  24.  * 
  25.  * - The class must use a custom EGLConfigChooser to be able to select 
  26.  *   an EGLConfig that supports 2.0. This is done by providing a config 
  27.  *   specification to eglChooseConfig() that has the attribute 
  28.  *   EGL10.ELG_RENDERABLE_TYPE containing the EGL_OPENGL_ES2_BIT flag 
  29.  *   set. See ConfigChooser class definition below. 
  30.  * 
  31.  * - The class must select the surface's format, then choose an EGLConfig 
  32.  *   that matches it exactly (with regards to red/green/blue/alpha channels 
  33.  *   bit depths). Failure to do so would result in an EGL_BAD_MATCH error. 
  34.  */  
  35.   
  36. class GL2JNIView extends GLSurfaceView {  
  37.     private static String TAG = "GL2JNIView";  
  38.     private static final boolean DEBUG = false;  
  39.   
  40.     public GL2JNIView(Context context) {  
  41.         super(context);  
  42.         init(false00);  
  43.     }  
  44.   
  45.     public GL2JNIView(Context context, boolean translucent, int depth, int stencil) {  
  46.         super(context);  
  47.         init(translucent, depth, stencil);  
  48.     }  
  49.   
  50.     private void init(boolean translucent, int depth, int stencil) {  
  51.   
  52.         /* By default, GLSurfaceView() creates a RGB_565 opaque surface. 
  53.          * If we want a translucent one, we should change the surface's 
  54.          * format here, using PixelFormat.TRANSLUCENT for GL Surfaces 
  55.          * is interpreted as any 32-bit surface with alpha by SurfaceFlinger. 
  56.          */  
  57.         if (translucent) {  
  58.             this.getHolder().setFormat(PixelFormat.TRANSLUCENT);  
  59.         }  
  60.   
  61.         /* Setup the context factory for 2.0 rendering. 
  62.          * See ContextFactory class definition below 
  63.          */  
  64.         setEGLContextFactory(new ContextFactory());  
  65.   
  66.         /* We need to choose an EGLConfig that matches the format of 
  67.          * our surface exactly. This is going to be done in our 
  68.          * custom config chooser. See ConfigChooser class definition 
  69.          * below. 
  70.          */    
  71.         setEGLConfigChooser( translucent ?  
  72.                              new ConfigChooser(8888, depth, stencil) :  
  73.                              new ConfigChooser(5650, depth, stencil) );  
  74.   
  75.         /* Set the renderer responsible for frame rendering */  
  76.         setRenderer(new Renderer());  
  77.     }  
  78.   
  79.     private static class ContextFactory implements GLSurfaceView.EGLContextFactory {  
  80.         private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;  
  81.         public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {  
  82.             Log.w(TAG, "creating OpenGL ES 2.0 context");  
  83.             checkEglError("Before eglCreateContext", egl);  
  84.             int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };  
  85.             EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);  
  86.             checkEglError("After eglCreateContext", egl);  
  87.             return context;  
  88.         }  
  89.   
  90.         public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {  
  91.             egl.eglDestroyContext(display, context);  
  92.         }  
  93.     }  
  94.   
  95.     private static void checkEglError(String prompt, EGL10 egl) {  
  96.         int error;  
  97.         while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {  
  98.             Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));  
  99.         }  
  100.     }  
  101.   
  102.     private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser {  
  103.   
  104.         public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) {  
  105.             mRedSize = r;  
  106.             mGreenSize = g;  
  107.             mBlueSize = b;  
  108.             mAlphaSize = a;  
  109.             mDepthSize = depth;  
  110.             mStencilSize = stencil;  
  111.         }  
  112.   
  113.         /* This EGL config specification is used to specify 2.0 rendering. 
  114.          * We use a minimum size of 4 bits for red/green/blue, but will 
  115.          * perform actual matching in chooseConfig() below. 
  116.          */  
  117.         private static int EGL_OPENGL_ES2_BIT = 4;  
  118.         private static int[] s_configAttribs2 =  
  119.         {  
  120.             EGL10.EGL_RED_SIZE, 4,  
  121.             EGL10.EGL_GREEN_SIZE, 4,  
  122.             EGL10.EGL_BLUE_SIZE, 4,  
  123.             EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,  
  124.             EGL10.EGL_NONE  
  125.         };  
  126.   
  127.         public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {  
  128.   
  129.             /* Get the number of minimally matching EGL configurations 
  130.              */  
  131.             int[] num_config = new int[1];  
  132.             egl.eglChooseConfig(display, s_configAttribs2, null0, num_config);  
  133.   
  134.             int numConfigs = num_config[0];  
  135.   
  136.             if (numConfigs <= 0) {  
  137.                 throw new IllegalArgumentException("No configs match configSpec");  
  138.             }  
  139.   
  140.             /* Allocate then read the array of minimally matching EGL configs 
  141.              */  
  142.             EGLConfig[] configs = new EGLConfig[numConfigs];  
  143.             egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config);  
  144.   
  145.             if (DEBUG) {  
  146.                  printConfigs(egl, display, configs);  
  147.             }  
  148.             /* Now return the "best" one 
  149.              */  
  150.             return chooseConfig(egl, display, configs);  
  151.         }  
  152.   
  153.         public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,  
  154.                 EGLConfig[] configs) {  
  155.             for(EGLConfig config : configs) {  
  156.                 int d = findConfigAttrib(egl, display, config,  
  157.                         EGL10.EGL_DEPTH_SIZE, 0);  
  158.                 int s = findConfigAttrib(egl, display, config,  
  159.                         EGL10.EGL_STENCIL_SIZE, 0);  
  160.   
  161.                 // We need at least mDepthSize and mStencilSize bits  
  162.                 if (d < mDepthSize || s < mStencilSize)  
  163.                     continue;  
  164.   
  165.                 // We want an *exact* match for red/green/blue/alpha  
  166.                 int r = findConfigAttrib(egl, display, config,  
  167.                         EGL10.EGL_RED_SIZE, 0);  
  168.                 int g = findConfigAttrib(egl, display, config,  
  169.                             EGL10.EGL_GREEN_SIZE, 0);  
  170.                 int b = findConfigAttrib(egl, display, config,  
  171.                             EGL10.EGL_BLUE_SIZE, 0);  
  172.                 int a = findConfigAttrib(egl, display, config,  
  173.                         EGL10.EGL_ALPHA_SIZE, 0);  
  174.   
  175.                 if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize)  
  176.                     return config;  
  177.             }  
  178.             return null;  
  179.         }  
  180.   
  181.         private int findConfigAttrib(EGL10 egl, EGLDisplay display,  
  182.                 EGLConfig config, int attribute, int defaultValue) {  
  183.   
  184.             if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {  
  185.                 return mValue[0];  
  186.             }  
  187.             return defaultValue;  
  188.         }  
  189.   
  190.         private void printConfigs(EGL10 egl, EGLDisplay display,  
  191.             EGLConfig[] configs) {  
  192.             int numConfigs = configs.length;  
  193.             Log.w(TAG, String.format("%d configurations", numConfigs));  
  194.             for (int i = 0; i < numConfigs; i++) {  
  195.                 Log.w(TAG, String.format("Configuration %d:\n", i));  
  196.                 printConfig(egl, display, configs[i]);  
  197.             }  
  198.         }  
  199.   
  200.         private void printConfig(EGL10 egl, EGLDisplay display,  
  201.                 EGLConfig config) {  
  202.             int[] attributes = {  
  203.                     EGL10.EGL_BUFFER_SIZE,  
  204.                     EGL10.EGL_ALPHA_SIZE,  
  205.                     EGL10.EGL_BLUE_SIZE,  
  206.                     EGL10.EGL_GREEN_SIZE,  
  207.                     EGL10.EGL_RED_SIZE,  
  208.                     EGL10.EGL_DEPTH_SIZE,  
  209.                     EGL10.EGL_STENCIL_SIZE,  
  210.                     EGL10.EGL_CONFIG_CAVEAT,  
  211.                     EGL10.EGL_CONFIG_ID,  
  212.                     EGL10.EGL_LEVEL,  
  213.                     EGL10.EGL_MAX_PBUFFER_HEIGHT,  
  214.                     EGL10.EGL_MAX_PBUFFER_PIXELS,  
  215.                     EGL10.EGL_MAX_PBUFFER_WIDTH,  
  216.                     EGL10.EGL_NATIVE_RENDERABLE,  
  217.                     EGL10.EGL_NATIVE_VISUAL_ID,  
  218.                     EGL10.EGL_NATIVE_VISUAL_TYPE,  
  219.                     0x3030// EGL10.EGL_PRESERVED_RESOURCES,  
  220.                     EGL10.EGL_SAMPLES,  
  221.                     EGL10.EGL_SAMPLE_BUFFERS,  
  222.                     EGL10.EGL_SURFACE_TYPE,  
  223.                     EGL10.EGL_TRANSPARENT_TYPE,  
  224.                     EGL10.EGL_TRANSPARENT_RED_VALUE,  
  225.                     EGL10.EGL_TRANSPARENT_GREEN_VALUE,  
  226.                     EGL10.EGL_TRANSPARENT_BLUE_VALUE,  
  227.                     0x3039// EGL10.EGL_BIND_TO_TEXTURE_RGB,  
  228.                     0x303A// EGL10.EGL_BIND_TO_TEXTURE_RGBA,  
  229.                     0x303B// EGL10.EGL_MIN_SWAP_INTERVAL,  
  230.                     0x303C// EGL10.EGL_MAX_SWAP_INTERVAL,  
  231.                     EGL10.EGL_LUMINANCE_SIZE,  
  232.                     EGL10.EGL_ALPHA_MASK_SIZE,  
  233.                     EGL10.EGL_COLOR_BUFFER_TYPE,  
  234.                     EGL10.EGL_RENDERABLE_TYPE,  
  235.                     0x3042 // EGL10.EGL_CONFORMANT  
  236.             };  
  237.             String[] names = {  
  238.                     "EGL_BUFFER_SIZE",  
  239.                     "EGL_ALPHA_SIZE",  
  240.                     "EGL_BLUE_SIZE",  
  241.                     "EGL_GREEN_SIZE",  
  242.                     "EGL_RED_SIZE",  
  243.                     "EGL_DEPTH_SIZE",  
  244.                     "EGL_STENCIL_SIZE",  
  245.                     "EGL_CONFIG_CAVEAT",  
  246.                     "EGL_CONFIG_ID",  
  247.                     "EGL_LEVEL",  
  248.                     "EGL_MAX_PBUFFER_HEIGHT",  
  249.                     "EGL_MAX_PBUFFER_PIXELS",  
  250.                     "EGL_MAX_PBUFFER_WIDTH",  
  251.                     "EGL_NATIVE_RENDERABLE",  
  252.                     "EGL_NATIVE_VISUAL_ID",  
  253.                     "EGL_NATIVE_VISUAL_TYPE",  
  254.                     "EGL_PRESERVED_RESOURCES",  
  255.                     "EGL_SAMPLES",  
  256.                     "EGL_SAMPLE_BUFFERS",  
  257.                     "EGL_SURFACE_TYPE",  
  258.                     "EGL_TRANSPARENT_TYPE",  
  259.                     "EGL_TRANSPARENT_RED_VALUE",  
  260.                     "EGL_TRANSPARENT_GREEN_VALUE",  
  261.                     "EGL_TRANSPARENT_BLUE_VALUE",  
  262.                     "EGL_BIND_TO_TEXTURE_RGB",  
  263.                     "EGL_BIND_TO_TEXTURE_RGBA",  
  264.                     "EGL_MIN_SWAP_INTERVAL",  
  265.                     "EGL_MAX_SWAP_INTERVAL",  
  266.                     "EGL_LUMINANCE_SIZE",  
  267.                     "EGL_ALPHA_MASK_SIZE",  
  268.                     "EGL_COLOR_BUFFER_TYPE",  
  269.                     "EGL_RENDERABLE_TYPE",  
  270.                     "EGL_CONFORMANT"  
  271.             };  
  272.             int[] value = new int[1];  
  273.             for (int i = 0; i < attributes.length; i++) {  
  274.                 int attribute = attributes[i];  
  275.                 String name = names[i];  
  276.                 if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {  
  277.                     Log.w(TAG, String.format("  %s: %d\n", name, value[0]));  
  278.                 } else {  
  279.                     // Log.w(TAG, String.format("  %s: failed\n", name));  
  280.                     while (egl.eglGetError() != EGL10.EGL_SUCCESS);  
  281.                 }  
  282.             }  
  283.         }  
  284.   
  285.         // Subclasses can adjust these values:  
  286.         protected int mRedSize;  
  287.         protected int mGreenSize;  
  288.         protected int mBlueSize;  
  289.         protected int mAlphaSize;  
  290.         protected int mDepthSize;  
  291.         protected int mStencilSize;  
  292.         private int[] mValue = new int[1];  
  293.     }  
  294.   
  295.     private static class Renderer implements GLSurfaceView.Renderer {  
  296.         public void onDrawFrame(GL10 gl) {  
  297.             GL2JNILib.step();  
  298.         }  
  299.   
  300.         public void onSurfaceChanged(GL10 gl, int width, int height) {  
  301.             GL2JNILib.init(width, height);  
  302.         }  
  303.   
  304.         public void onSurfaceCreated(GL10 gl, EGLConfig config) {  
  305.             // Do nothing.  
  306.         }  
  307.     }  
  308. }  

6、编译该工程,会在bin\classes\com\filltriangle\android文件夹下生成GL2JNILib.class等文件;

7、打开命令行窗口,将其定位到\bin\classes目录下,输入命令:javah –classpath  D:\ProgramFiles\Android\android-sdk\platforms\android-10\android.jar;(不用忘掉此分号) com.filltriangle.android.GL2JNILib,会在classes文件夹下生成com_filltriangle_android_GL2JNILib.h(说明:*.jar也可以是其它版本);

8、生成的com_filltriangle_android_GL2JNILib.h文件内容为:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /* DO NOT EDIT THIS FILE - it is machine generated */  
  2. #include <jni.h>  
  3. /* Header for class com_filltriangle_android_GL2JNILib */  
  4.   
  5. #ifndef _Included_com_filltriangle_android_GL2JNILib  
  6. #define _Included_com_filltriangle_android_GL2JNILib  
  7. #ifdef __cplusplus  
  8. extern "C" {  
  9. #endif  
  10. /* 
  11.  * Class:     com_filltriangle_android_GL2JNILib 
  12.  * Method:    init 
  13.  * Signature: (II)V 
  14.  */  
  15. JNIEXPORT void JNICALL Java_com_filltriangle_android_GL2JNILib_init  
  16.   (JNIEnv *, jclass, jint, jint);  
  17.   
  18. /* 
  19.  * Class:     com_filltriangle_android_GL2JNILib 
  20.  * Method:    step 
  21.  * Signature: ()V 
  22.  */  
  23. JNIEXPORT void JNICALL Java_com_filltriangle_android_GL2JNILib_step  
  24.   (JNIEnv *, jclass);  
  25.   
  26. #ifdef __cplusplus  
  27. }  
  28. #endif  
  29. #endif  

9、选中FillTriangle工程,点击右键-->New-->Folder新建一个jni文件夹,选中jni, -->New-->File,新建2个文件,名称分别为Android.mk和opengles_code.cpp;

10、Android.mk文件内容为:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. LOCAL_PATH:= $(call my-dir)  
  2.   
  3. include $(CLEAR_VARS)  
  4.   
  5. LOCAL_MODULE    :libgl2jni  
  6. LOCAL_CFLAGS    := -Werror  
  7. LOCAL_SRC_FILES :opengles_code.cpp  
  8. LOCAL_LDLIBS    := -llog -lGLESv2  
  9.   
  10. include $(BUILD_SHARED_LIBRARY)  

11、opengles_code.cpp文件内容为:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /* 
  2.  * Copyright (C) 2009 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. // OpenGL ES 2.0 code  
  18.   
  19. #include <jni.h>  
  20. #include <android/log.h>  
  21.   
  22. #include <GLES2/gl2.h>  
  23. #include <GLES2/gl2ext.h>  
  24.   
  25. #include <stdio.h>  
  26. #include <stdlib.h>  
  27. #include <math.h>  
  28.   
  29. #define  LOG_TAG    "libgl2jni"  
  30. #define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)  
  31. #define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)  
  32.   
  33. static void printGLString(const char *name, GLenum s) {  
  34.     const char *v = (const char *) glGetString(s);  
  35.     LOGI("GL %s = %s\n", name, v);  
  36. }  
  37.   
  38. static void checkGlError(const char* op) {  
  39.     for (GLint error = glGetError(); error; error  
  40.             = glGetError()) {  
  41.         LOGI("after %s() glError (0x%x)\n", op, error);  
  42.     }  
  43. }  
  44.   
  45. static const char gVertexShader[] =   
  46.     "attribute vec4 vPosition;\n"  
  47.     "void main() {\n"  
  48.     "  gl_Position = vPosition;\n"  
  49.     "}\n";  
  50.   
  51. static const char gFragmentShader[] =   
  52.     "precision mediump float;\n"  
  53.     "void main() {\n"  
  54.     "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"  
  55.     "}\n";  
  56.   
  57. GLuint loadShader(GLenum shaderType, const char* pSource) {  
  58.     GLuint shader = glCreateShader(shaderType);  
  59.     if (shader) {  
  60.         glShaderSource(shader, 1, &pSource, NULL);  
  61.         glCompileShader(shader);  
  62.         GLint compiled = 0;  
  63.         glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);  
  64.         if (!compiled) {  
  65.             GLint infoLen = 0;  
  66.             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);  
  67.             if (infoLen) {  
  68.                 char* buf = (char*) malloc(infoLen);  
  69.                 if (buf) {  
  70.                     glGetShaderInfoLog(shader, infoLen, NULL, buf);  
  71.                     LOGE("Could not compile shader %d:\n%s\n",  
  72.                             shaderType, buf);  
  73.                     free(buf);  
  74.                 }  
  75.                 glDeleteShader(shader);  
  76.                 shader = 0;  
  77.             }  
  78.         }  
  79.     }  
  80.     return shader;  
  81. }  
  82.   
  83. GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {  
  84.     GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);  
  85.     if (!vertexShader) {  
  86.         return 0;  
  87.     }  
  88.   
  89.     GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);  
  90.     if (!pixelShader) {  
  91.         return 0;  
  92.     }  
  93.   
  94.     GLuint program = glCreateProgram();  
  95.     if (program) {  
  96.         glAttachShader(program, vertexShader);  
  97.         checkGlError("glAttachShader");  
  98.         glAttachShader(program, pixelShader);  
  99.         checkGlError("glAttachShader");  
  100.         glLinkProgram(program);  
  101.         GLint linkStatus = GL_FALSE;  
  102.         glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);  
  103.         if (linkStatus != GL_TRUE) {  
  104.             GLint bufLength = 0;  
  105.             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);  
  106.             if (bufLength) {  
  107.                 char* buf = (char*) malloc(bufLength);  
  108.                 if (buf) {  
  109.                     glGetProgramInfoLog(program, bufLength, NULL, buf);  
  110.                     LOGE("Could not link program:\n%s\n", buf);  
  111.                     free(buf);  
  112.                 }  
  113.             }  
  114.             glDeleteProgram(program);  
  115.             program = 0;  
  116.         }  
  117.     }  
  118.     return program;  
  119. }  
  120.   
  121. GLuint gProgram;  
  122. GLuint gvPositionHandle;  
  123.   
  124. bool setupGraphics(int w, int h) {  
  125.     printGLString("Version", GL_VERSION);  
  126.     printGLString("Vendor", GL_VENDOR);  
  127.     printGLString("Renderer", GL_RENDERER);  
  128.     printGLString("Extensions", GL_EXTENSIONS);  
  129.   
  130.     LOGI("setupGraphics(%d, %d)", w, h);  
  131.     gProgram = createProgram(gVertexShader, gFragmentShader);  
  132.     if (!gProgram) {  
  133.         LOGE("Could not create program.");  
  134.         return false;  
  135.     }  
  136.     gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");  
  137.     checkGlError("glGetAttribLocation");  
  138.     LOGI("glGetAttribLocation(\"vPosition\") = %d\n",  
  139.             gvPositionHandle);  
  140.   
  141.     glViewport(0, 0, w, h);  
  142.     checkGlError("glViewport");  
  143.     return true;  
  144. }  
  145.   
  146. const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,  
  147.         0.5f, -0.5f };  
  148.   
  149. void renderFrame() {  
  150.     static float grey;  
  151.     grey += 0.01f;  
  152.     if (grey > 1.0f) {  
  153.         grey = 0.0f;  
  154.     }  
  155.     glClearColor(grey, grey, grey, 1.0f);  
  156.     checkGlError("glClearColor");  
  157.     glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);  
  158.     checkGlError("glClear");  
  159.   
  160.     glUseProgram(gProgram);  
  161.     checkGlError("glUseProgram");  
  162.   
  163.     glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);  
  164.     checkGlError("glVertexAttribPointer");  
  165.     glEnableVertexAttribArray(gvPositionHandle);  
  166.     checkGlError("glEnableVertexAttribArray");  
  167.     glDrawArrays(GL_TRIANGLES, 0, 3);  
  168.     checkGlError("glDrawArrays");  
  169. }  
  170.   
  171. extern "C" {  
  172.     JNIEXPORT void JNICALL Java_com_filltriangle_android_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height);  
  173.     JNIEXPORT void JNICALL Java_com_filltriangle_android_GL2JNILib_step(JNIEnv * env, jobject obj);  
  174. };  
  175.   
  176. JNIEXPORT void JNICALL Java_com_filltriangle_android_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height)  
  177. {  
  178.     setupGraphics(width, height);  
  179. }  
  180.   
  181. JNIEXPORT void JNICALL Java_com_filltriangle_android_GL2JNILib_step(JNIEnv * env, jobject obj)  
  182. {  
  183.     renderFrame();  
  184. }  

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
posted @ 2016-03-28 12:20  00000000O  阅读(873)  评论(0编辑  收藏  举报