1 // OpenGL ES 1.0 code
2
3 #include <jni.h>
4 #define LOG_TAG "GLJNI 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 <GLES/gl.h>
13
14 #include <stdio.h>
15
16 #include <stdlib.h>
17 #include <math.h>
18
19 GLuint texture;
20 GLfloat background;
21
22 #define FIXED_ONE 0x10000
23
printGLString(const char * name,GLenum s)24 static void printGLString(const char *name, GLenum s) {
25 const char *v = (const char *) glGetString(s);
26 ALOGI("GL %s = %s\n", name, v);
27 }
28
gluLookAt(float eyeX,float eyeY,float eyeZ,float centerX,float centerY,float centerZ,float upX,float upY,float upZ)29 static void gluLookAt(float eyeX, float eyeY, float eyeZ,
30 float centerX, float centerY, float centerZ, float upX, float upY,
31 float upZ)
32 {
33 // See the OpenGL GLUT documentation for gluLookAt for a description
34 // of the algorithm. We implement it in a straightforward way:
35
36 float fx = centerX - eyeX;
37 float fy = centerY - eyeY;
38 float fz = centerZ - eyeZ;
39
40 // Normalize f
41 float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
42 fx *= rlf;
43 fy *= rlf;
44 fz *= rlf;
45
46 // Normalize up
47 float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
48 upX *= rlup;
49 upY *= rlup;
50 upZ *= rlup;
51
52 // compute s = f x up (x means "cross product")
53
54 float sx = fy * upZ - fz * upY;
55 float sy = fz * upX - fx * upZ;
56 float sz = fx * upY - fy * upX;
57
58 // compute u = s x f
59 float ux = sy * fz - sz * fy;
60 float uy = sz * fx - sx * fz;
61 float uz = sx * fy - sy * fx;
62
63 float m[16] ;
64 m[0] = sx;
65 m[1] = ux;
66 m[2] = -fx;
67 m[3] = 0.0f;
68
69 m[4] = sy;
70 m[5] = uy;
71 m[6] = -fy;
72 m[7] = 0.0f;
73
74 m[8] = sz;
75 m[9] = uz;
76 m[10] = -fz;
77 m[11] = 0.0f;
78
79 m[12] = 0.0f;
80 m[13] = 0.0f;
81 m[14] = 0.0f;
82 m[15] = 1.0f;
83
84 glMultMatrixf(m);
85 glTranslatef(-eyeX, -eyeY, -eyeZ);
86 }
87
init_scene(int width,int height)88 void init_scene(int width, int height)
89 {
90 printGLString("Version", GL_VERSION);
91 printGLString("Vendor", GL_VENDOR);
92 printGLString("Renderer", GL_RENDERER);
93 printGLString("Extensions", GL_EXTENSIONS);
94
95 glDisable(GL_DITHER);
96 glEnable(GL_CULL_FACE);
97
98 float ratio = width / height;
99 glViewport(0, 0, width, height);
100
101 glMatrixMode(GL_PROJECTION);
102 glLoadIdentity();
103 glFrustumf(-ratio, ratio, -1, 1, 1, 10);
104
105 glMatrixMode(GL_MODELVIEW);
106
107 glLoadIdentity();
108 gluLookAt(
109 0, 0, 3, // eye
110 0, 0, 0, // center
111 0, 1, 0); // up
112
113 glEnable(GL_TEXTURE_2D);
114 glEnableClientState(GL_VERTEX_ARRAY);
115 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
116 }
117
create_texture()118 void create_texture()
119 {
120 const unsigned int on = 0xff0000ff;
121 const unsigned int off = 0xffffffff;
122 const unsigned int pixels[] =
123 {
124 on, off, on, off, on, off, on, off,
125 off, on, off, on, off, on, off, on,
126 on, off, on, off, on, off, on, off,
127 off, on, off, on, off, on, off, on,
128 on, off, on, off, on, off, on, off,
129 off, on, off, on, off, on, off, on,
130 on, off, on, off, on, off, on, off,
131 off, on, off, on, off, on, off, on,
132 };
133
134 glGenTextures(1, &texture);
135 glBindTexture(GL_TEXTURE_2D, texture);
136 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
137 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
138 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
139 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
140 }
141
142 extern "C" {
143 JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj, jint width, jint height);
144 JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj);
145 JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_changeBackground(JNIEnv * env, jobject obj);
146 };
147
Java_com_android_gljni_GLJNILib_init(JNIEnv *,jobject,jint width,jint height)148 JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * /*env*/, jobject /*obj*/, jint width, jint height)
149 {
150 init_scene(width, height);
151 create_texture();
152 }
153
Java_com_android_gljni_GLJNILib_step(JNIEnv *,jobject)154 JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * /*env*/, jobject /*obj*/)
155 {
156 const GLfloat vertices[] = {
157 -1, -1, 0,
158 1, -1, 0,
159 1, 1, 0,
160 -1, 1, 0
161 };
162
163 const GLfixed texCoords[] = {
164 0, 0,
165 FIXED_ONE, 0,
166 FIXED_ONE, FIXED_ONE,
167 0, FIXED_ONE
168 };
169
170 const GLushort quadIndices[] = { 0, 1, 2, 0, 2, 3 };
171 glVertexPointer(3, GL_FLOAT, 0, vertices);
172 glTexCoordPointer(2, GL_FIXED, 0, texCoords);
173
174 int nelem = sizeof(quadIndices)/sizeof(quadIndices[0]);
175 static float grey;
176 grey += 0.01f;
177 if (grey > 1.0f) {
178 grey = 0.0f;
179 }
180 glClearColor(background, grey, grey, 1.0f);
181 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
182 glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, quadIndices);
183 }
184
Java_com_android_gljni_GLJNILib_changeBackground(JNIEnv *,jobject)185 JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_changeBackground(JNIEnv * /*env*/, jobject /*obj*/)
186 {
187 background = 1.0f - background;
188 }
189