zoukankan      html  css  js  c++  java
  • 利用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: ", 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 ", name, value[0]));  
    278.                 } else {  
    279.                     // Log.w(TAG, String.format("  %s: failed ", 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、编译该工程,会在binclassescomfilltriangleandroid文件夹下生成GL2JNILib.class等文件;

    7、打开命令行窗口,将其定位到inclasses目录下,输入命令:javah –classpath  D:ProgramFilesAndroidandroid-sdkplatformsandroid-10android.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 ", 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) ", op, error);  
    42.     }  
    43. }  
    44.   
    45. static const char gVertexShader[] =   
    46.     "attribute vec4 vPosition; "  
    47.     "void main() { "  
    48.     "  gl_Position = vPosition; "  
    49.     "} ";  
    50.   
    51. static const char gFragmentShader[] =   
    52.     "precision mediump float; "  
    53.     "void main() { "  
    54.     "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); "  
    55.     "} ";  
    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: %s ",  
    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: %s ", 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 ",  
    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:ProgramFilesAndroidandroid-sdkandroid-ndk-r9 dk-build.cmd;WorkingDirectory中填入工程的根目录,E:TestAndroidFillTriangle,点击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,会在libsarmeabi目录下生成相应的libgl2jni.so库;

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

     

    参考文献:

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

    2、 http://blog.csdn.net/fengbingchun/article/details/11580983
  • 相关阅读:
    关于控制地址控件的代码
    获取某个设计项列表界面上查询框中的值的代码
    js中不同值的替换
    js截取字符串方法实例
    抛异常语句的种类及区别
    从获取结果中去除重复记录
    泛微E8升级E9代码修改
    中控考勤数据转换
    WEB打印,分页首行自动带出栏目标题
    VS附加进程调试IIS网站
  • 原文地址:https://www.cnblogs.com/nafio/p/9137394.html
Copyright © 2011-2022 走看看