Home | History | Annotate | Download | only in jni
      1 // OpenGL ES 2.0 code
      2 
      3 #include <jni.h>
      4 #define LOG_TAG "GL2JNI gl_code.cpp"
      5 #include <android/log.h>
      6 
      7 #define ALOG(priority, tag, ...) ((void)__android_log_print(ANDROID_##priority, tag, __VA_ARGS__))
      8 
      9 #define ALOGI(...) ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)
     10 #define ALOGE(...) ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)
     11 
     12 #include <EGL/egl.h>
     13 #include <GLES2/gl2.h>
     14 #include <GLES2/gl2ext.h>
     15 
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <math.h>
     19 
     20 static void printGLString(const char *name, GLenum s) {
     21     const char *v = (const char *) glGetString(s);
     22     ALOGI("GL %s = %s\n", name, v);
     23 }
     24 
     25 static void checkGlError(const char* op) {
     26     for (GLint error = glGetError(); error; error
     27             = glGetError()) {
     28         ALOGI("after %s() glError (0x%x)\n", op, error);
     29     }
     30 }
     31 
     32 static const char gVertexShader[] = "attribute vec4 vPosition;\n"
     33     "void main() {\n"
     34     "  gl_Position = vPosition;\n"
     35     "}\n";
     36 
     37 static const char gFragmentShader[] = "precision mediump float;\n"
     38     "void main() {\n"
     39     "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
     40     "}\n";
     41 
     42 GLuint loadShader(GLenum shaderType, const char* pSource) {
     43     GLuint shader = glCreateShader(shaderType);
     44     if (shader) {
     45         glShaderSource(shader, 1, &pSource, NULL);
     46         glCompileShader(shader);
     47         GLint compiled = 0;
     48         glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
     49         if (!compiled) {
     50             GLint infoLen = 0;
     51             glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
     52             if (infoLen) {
     53                 char* buf = (char*) malloc(infoLen);
     54                 if (buf) {
     55                     glGetShaderInfoLog(shader, infoLen, NULL, buf);
     56                     ALOGE("Could not compile shader %d:\n%s\n",
     57                             shaderType, buf);
     58                     free(buf);
     59                 }
     60                 glDeleteShader(shader);
     61                 shader = 0;
     62             }
     63         }
     64     }
     65     return shader;
     66 }
     67 
     68 GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
     69     GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
     70     if (!vertexShader) {
     71         return 0;
     72     }
     73 
     74     GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
     75     if (!pixelShader) {
     76         return 0;
     77     }
     78 
     79     GLuint program = glCreateProgram();
     80     if (program) {
     81         glAttachShader(program, vertexShader);
     82         checkGlError("glAttachShader");
     83         glAttachShader(program, pixelShader);
     84         checkGlError("glAttachShader");
     85         glLinkProgram(program);
     86         GLint linkStatus = GL_FALSE;
     87         glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
     88         if (linkStatus != GL_TRUE) {
     89             GLint bufLength = 0;
     90             glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
     91             if (bufLength) {
     92                 char* buf = (char*) malloc(bufLength);
     93                 if (buf) {
     94                     glGetProgramInfoLog(program, bufLength, NULL, buf);
     95                     ALOGE("Could not link program:\n%s\n", buf);
     96                     free(buf);
     97                 }
     98             }
     99             glDeleteProgram(program);
    100             program = 0;
    101         }
    102     }
    103     return program;
    104 }
    105 
    106 GLuint gProgram;
    107 GLuint gvPositionHandle;
    108 
    109 bool setupGraphics(int w, int h) {
    110     printGLString("Version", GL_VERSION);
    111     printGLString("Vendor", GL_VENDOR);
    112     printGLString("Renderer", GL_RENDERER);
    113     printGLString("Extensions", GL_EXTENSIONS);
    114 
    115     ALOGI("setupGraphics(%d, %d)", w, h);
    116     gProgram = createProgram(gVertexShader, gFragmentShader);
    117     if (!gProgram) {
    118         ALOGE("Could not create program.");
    119         return false;
    120     }
    121     gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
    122     checkGlError("glGetAttribLocation");
    123     ALOGI("glGetAttribLocation(\"vPosition\") = %d\n",
    124             gvPositionHandle);
    125 
    126     glViewport(0, 0, w, h);
    127     checkGlError("glViewport");
    128     return true;
    129 }
    130 
    131 const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
    132         0.5f, -0.5f };
    133 
    134 void renderFrame() {
    135     static float grey;
    136     grey += 0.01f;
    137     if (grey > 1.0f) {
    138         grey = 0.0f;
    139     }
    140     glClearColor(grey, grey, grey, 1.0f);
    141     checkGlError("glClearColor");
    142     glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    143     checkGlError("glClear");
    144 
    145     glUseProgram(gProgram);
    146     checkGlError("glUseProgram");
    147 
    148     glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
    149     checkGlError("glVertexAttribPointer");
    150     glEnableVertexAttribArray(gvPositionHandle);
    151     checkGlError("glEnableVertexAttribArray");
    152     glDrawArrays(GL_TRIANGLES, 0, 3);
    153     checkGlError("glDrawArrays");
    154 }
    155 
    156 extern "C" {
    157     JNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_init(JNIEnv * env, jobject obj, jint width, jint height);
    158     JNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_step(JNIEnv * env, jobject obj);
    159 };
    160 
    161 JNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_init(JNIEnv * /*env*/, jobject /*obj*/, jint width, jint height)
    162 {
    163     setupGraphics(width, height);
    164 }
    165 
    166 JNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_step(JNIEnv * /*env*/, jobject /*obj*/)
    167 {
    168     renderFrame();
    169 }
    170 
    171