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