19bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich// OpenGL ES 2.0 code 29bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 39bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich#include <nativehelper/jni.h> 49bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich#define LOG_TAG "GL2JNI gl_code.cpp" 59bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich#include <utils/Log.h> 69bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 79bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich#include <EGL/egl.h> 89bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich#include <GLES2/gl2.h> 99bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich#include <GLES2/gl2ext.h> 109bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 119bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich#include <stdio.h> 129bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich#include <stdlib.h> 139bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich#include <math.h> 149bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 159bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevichstatic void printGLString(const char *name, GLenum s) { 169bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich const char *v = (const char *) glGetString(s); 17a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("GL %s = %s\n", name, v); 189bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich} 199bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 209bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevichstatic void checkGlError(const char* op) { 219bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich for (GLint error = glGetError(); error; error 229bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich = glGetError()) { 23a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("after %s() glError (0x%x)\n", op, error); 249bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 259bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich} 269bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 279bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevichstatic const char gVertexShader[] = "attribute vec4 vPosition;\n" 289bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich "void main() {\n" 299bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich " gl_Position = vPosition;\n" 309bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich "}\n"; 319bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 329bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevichstatic const char gFragmentShader[] = "precision mediump float;\n" 339bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich "void main() {\n" 349bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" 359bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich "}\n"; 369bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 379bd30f05e890b213e97b838e04024d8cd232dbc0Jack PalevichGLuint loadShader(GLenum shaderType, const char* pSource) { 389bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich GLuint shader = glCreateShader(shaderType); 399bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (shader) { 409bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glShaderSource(shader, 1, &pSource, NULL); 419bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glCompileShader(shader); 429bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich GLint compiled = 0; 439bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 449bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (!compiled) { 459bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich GLint infoLen = 0; 469bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 479bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (infoLen) { 489bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich char* buf = (char*) malloc(infoLen); 499bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (buf) { 509bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glGetShaderInfoLog(shader, infoLen, NULL, buf); 51e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Could not compile shader %d:\n%s\n", 529bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich shaderType, buf); 539bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich free(buf); 549bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 559bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glDeleteShader(shader); 569bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich shader = 0; 579bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 589bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 599bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 609bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich return shader; 619bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich} 629bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 639bd30f05e890b213e97b838e04024d8cd232dbc0Jack PalevichGLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { 649bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); 659bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (!vertexShader) { 669bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich return 0; 679bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 689bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 699bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); 709bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (!pixelShader) { 719bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich return 0; 729bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 739bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 749bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich GLuint program = glCreateProgram(); 759bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (program) { 769bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glAttachShader(program, vertexShader); 779bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich checkGlError("glAttachShader"); 789bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glAttachShader(program, pixelShader); 799bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich checkGlError("glAttachShader"); 809bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glLinkProgram(program); 819bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich GLint linkStatus = GL_FALSE; 829bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 839bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (linkStatus != GL_TRUE) { 849bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich GLint bufLength = 0; 859bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 869bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (bufLength) { 879bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich char* buf = (char*) malloc(bufLength); 889bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (buf) { 899bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glGetProgramInfoLog(program, bufLength, NULL, buf); 90e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Could not link program:\n%s\n", buf); 919bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich free(buf); 929bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 939bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 949bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glDeleteProgram(program); 959bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich program = 0; 969bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 979bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 989bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich return program; 999bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich} 1009bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 1019bd30f05e890b213e97b838e04024d8cd232dbc0Jack PalevichGLuint gProgram; 1029bd30f05e890b213e97b838e04024d8cd232dbc0Jack PalevichGLuint gvPositionHandle; 1039bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 1049bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevichbool setupGraphics(int w, int h) { 1059bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich printGLString("Version", GL_VERSION); 1069bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich printGLString("Vendor", GL_VENDOR); 1079bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich printGLString("Renderer", GL_RENDERER); 1089bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich printGLString("Extensions", GL_EXTENSIONS); 1099bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 110a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("setupGraphics(%d, %d)", w, h); 1119bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich gProgram = createProgram(gVertexShader, gFragmentShader); 1129bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (!gProgram) { 113e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Could not create program."); 1149bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich return false; 1159bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 1169bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich gvPositionHandle = glGetAttribLocation(gProgram, "vPosition"); 1179bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich checkGlError("glGetAttribLocation"); 118a19954ab377b46dbcb9cbe8a6ab6d458f2e32bcaSteve Block ALOGI("glGetAttribLocation(\"vPosition\") = %d\n", 1199bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich gvPositionHandle); 1209bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 1219bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glViewport(0, 0, w, h); 1229bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich checkGlError("glViewport"); 1239bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich return true; 1249bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich} 1259bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 1269bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevichconst GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f, 1279bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 0.5f, -0.5f }; 1289bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 1299bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevichvoid renderFrame() { 1309bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich static float grey; 1319bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich grey += 0.01f; 1329bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich if (grey > 1.0f) { 1339bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich grey = 0.0f; 1349bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich } 1359bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glClearColor(grey, grey, grey, 1.0f); 1369bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich checkGlError("glClearColor"); 1379bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 1389bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich checkGlError("glClear"); 1399bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 1409bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glUseProgram(gProgram); 1419bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich checkGlError("glUseProgram"); 1429bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 1439bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); 1449bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich checkGlError("glVertexAttribPointer"); 1459bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glEnableVertexAttribArray(gvPositionHandle); 1469bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich checkGlError("glEnableVertexAttribArray"); 1479bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich glDrawArrays(GL_TRIANGLES, 0, 3); 1489bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich checkGlError("glDrawArrays"); 1499bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich} 1509bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 1519bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevichextern "C" { 1529bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich JNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_init(JNIEnv * env, jobject obj, jint width, jint height); 1539bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich JNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_step(JNIEnv * env, jobject obj); 1549bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich}; 1559bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 1569bd30f05e890b213e97b838e04024d8cd232dbc0Jack PalevichJNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_init(JNIEnv * env, jobject obj, jint width, jint height) 1579bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich{ 1589bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich setupGraphics(width, height); 1599bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich} 1609bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 1619bd30f05e890b213e97b838e04024d8cd232dbc0Jack PalevichJNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_step(JNIEnv * env, jobject obj) 1629bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich{ 1639bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich renderFrame(); 1649bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich} 1659bd30f05e890b213e97b838e04024d8cd232dbc0Jack Palevich 166