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