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