1919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich// OpenGL ES 2.0 code 2919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 3919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich#include <nativehelper/jni.h> 4919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich#define LOG_TAG "GL2JNI gl_code.cpp" 5919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich#include <utils/Log.h> 643123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich 7919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich#include <EGL/egl.h> 8919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich#include <GLES2/gl2.h> 9919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich#include <GLES2/gl2ext.h> 10919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 1143123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich#include <stdio.h> 12919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich#include <stdlib.h> 13919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich#include <math.h> 14919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 15919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevichstatic void printGLString(const char *name, GLenum s) { 16919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich const char *v = (const char *) glGetString(s); 17a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("GL %s = %s\n", name, v); 18919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich} 19919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 20919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevichstatic void checkGlError(const char* op) { 21919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich for (GLint error = glGetError(); error; error 22919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich = glGetError()) { 23a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("after %s() glError (0x%x)\n", op, error); 24919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 25919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich} 2643123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich 27919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevichstatic const char gVertexShader[] = "attribute vec4 vPosition;\n" 28919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich "void main() {\n" 29919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich " gl_Position = vPosition;\n" 30919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich "}\n"; 31919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 32919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevichstatic const char gFragmentShader[] = "precision mediump float;\n" 33919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich "void main() {\n" 34919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" 35919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich "}\n"; 36919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 37919583553781f1e1885fa17f76d54008ebeca3c1Jack PalevichGLuint loadShader(GLenum shaderType, const char* pSource) { 38919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich GLuint shader = glCreateShader(shaderType); 39919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (shader) { 40919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glShaderSource(shader, 1, &pSource, NULL); 41919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glCompileShader(shader); 42919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich GLint compiled = 0; 43919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 44919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (!compiled) { 45919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich GLint infoLen = 0; 46919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 47919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (infoLen) { 48919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich char* buf = (char*) malloc(infoLen); 49919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (buf) { 50919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glGetShaderInfoLog(shader, infoLen, NULL, buf); 51e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Could not compile shader %d:\n%s\n", 52919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich shaderType, buf); 53919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich free(buf); 54919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 55919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glDeleteShader(shader); 56919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich shader = 0; 57919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 58919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 59919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 60919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich return shader; 61919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich} 62919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 63919583553781f1e1885fa17f76d54008ebeca3c1Jack PalevichGLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { 64919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); 65919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (!vertexShader) { 66919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich return 0; 67919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 68919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 69919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); 70919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (!pixelShader) { 71919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich return 0; 72919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 73919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 74919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich GLuint program = glCreateProgram(); 75919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (program) { 76919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glAttachShader(program, vertexShader); 77919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich checkGlError("glAttachShader"); 78919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glAttachShader(program, pixelShader); 79919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich checkGlError("glAttachShader"); 80919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glLinkProgram(program); 81919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich GLint linkStatus = GL_FALSE; 82919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 83919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (linkStatus != GL_TRUE) { 84919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich GLint bufLength = 0; 85919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 86919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (bufLength) { 87919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich char* buf = (char*) malloc(bufLength); 88919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (buf) { 89919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glGetProgramInfoLog(program, bufLength, NULL, buf); 90e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Could not link program:\n%s\n", buf); 91919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich free(buf); 92919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 93919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 94919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glDeleteProgram(program); 95919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich program = 0; 96919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 97919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 98919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich return program; 99919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich} 100919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 101919583553781f1e1885fa17f76d54008ebeca3c1Jack PalevichGLuint gProgram; 102919583553781f1e1885fa17f76d54008ebeca3c1Jack PalevichGLuint gvPositionHandle; 103919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 104919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevichbool setupGraphics(int w, int h) { 105919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich printGLString("Version", GL_VERSION); 106919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich printGLString("Vendor", GL_VENDOR); 107919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich printGLString("Renderer", GL_RENDERER); 108919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich printGLString("Extensions", GL_EXTENSIONS); 109919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 110a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("setupGraphics(%d, %d)", w, h); 111919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich gProgram = createProgram(gVertexShader, gFragmentShader); 112919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (!gProgram) { 113e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Could not create program."); 114919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich return false; 115919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 116919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich gvPositionHandle = glGetAttribLocation(gProgram, "vPosition"); 117919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich checkGlError("glGetAttribLocation"); 118a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("glGetAttribLocation(\"vPosition\") = %d\n", 119919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich gvPositionHandle); 120919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 121919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glViewport(0, 0, w, h); 122919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich checkGlError("glViewport"); 123919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich return true; 124919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich} 125919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 126919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevichconst GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f, 127919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 0.5f, -0.5f }; 128919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 129919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevichvoid renderFrame() { 130919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich static float grey; 131919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich grey += 0.01f; 132919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich if (grey > 1.0f) { 133919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich grey = 0.0f; 134919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich } 135919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glClearColor(grey, grey, grey, 1.0f); 136919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich checkGlError("glClearColor"); 137919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 138919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich checkGlError("glClear"); 139919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 140919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glUseProgram(gProgram); 141919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich checkGlError("glUseProgram"); 142919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 143919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); 144919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich checkGlError("glVertexAttribPointer"); 145919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glEnableVertexAttribArray(gvPositionHandle); 146919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich checkGlError("glEnableVertexAttribArray"); 147919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich glDrawArrays(GL_TRIANGLES, 0, 3); 148919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich checkGlError("glDrawArrays"); 149919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich} 150919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 151919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevichextern "C" { 152919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height); 153919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj); 15443123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich}; 15543123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich 1560f036d43b00d602a073b413d0fc746c82ca1db7aBernhard RosenkränzerJNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height) 15743123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich{ 15843123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich setupGraphics(width, height); 15943123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich} 16043123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich 16143123766f5fc3a73df77a03390679ec536ebe6e0Jack PalevichJNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj) 16243123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich{ 16343123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich renderFrame(); 16443123766f5fc3a73df77a03390679ec536ebe6e0Jack Palevich} 165919583553781f1e1885fa17f76d54008ebeca3c1Jack Palevich 166