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