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_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
158 JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj);
159 };
160
Java_com_android_gl2jni_GL2JNILib_init(JNIEnv *,jobject,jint width,jint height)161 JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * /*env*/, jobject /*obj*/, jint width, jint height)
162 {
163 setupGraphics(width, height);
164 }
165
Java_com_android_gl2jni_GL2JNILib_step(JNIEnv *,jobject)166 JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * /*env*/, jobject /*obj*/)
167 {
168 renderFrame();
169 }
170
171