Home | History | Annotate | Download | only in jni
      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_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height);
    173     JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);
    174 };
    175 
    176 JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj,  jint width, jint height)
    177 {
    178     setupGraphics(width, height);
    179 }
    180 
    181 JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj)
    182 {
    183     renderFrame();
    184 }
    185