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