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_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height); 158 JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj); 159 }; 160 161 JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * /*env*/, jobject /*obj*/, jint width, jint height) 162 { 163 setupGraphics(width, height); 164 } 165 166 JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * /*env*/, jobject /*obj*/) 167 { 168 renderFrame(); 169 } 170 171