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