171 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C++
		
	
	
	
// OpenGL ES 2.0 code
 | 
						|
 | 
						|
#include <jni.h>
 | 
						|
#define LOG_TAG "GL2JNI gl_code.cpp"
 | 
						|
#include <android/log.h>
 | 
						|
 | 
						|
#define ALOG(priority, tag, ...) ((void)__android_log_print(ANDROID_##priority, tag, __VA_ARGS__))
 | 
						|
 | 
						|
#define ALOGI(...) ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)
 | 
						|
#define ALOGE(...) ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)
 | 
						|
 | 
						|
#include <EGL/egl.h>
 | 
						|
#include <GLES2/gl2.h>
 | 
						|
#include <GLES2/gl2ext.h>
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <math.h>
 | 
						|
 | 
						|
static void printGLString(const char *name, GLenum s) {
 | 
						|
    const char *v = (const char *) glGetString(s);
 | 
						|
    ALOGI("GL %s = %s\n", name, v);
 | 
						|
}
 | 
						|
 | 
						|
static void checkGlError(const char* op) {
 | 
						|
    for (GLint error = glGetError(); error; error
 | 
						|
            = glGetError()) {
 | 
						|
        ALOGI("after %s() glError (0x%x)\n", op, error);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static const char gVertexShader[] = "attribute vec4 vPosition;\n"
 | 
						|
    "void main() {\n"
 | 
						|
    "  gl_Position = vPosition;\n"
 | 
						|
    "}\n";
 | 
						|
 | 
						|
static const char gFragmentShader[] = "precision mediump float;\n"
 | 
						|
    "void main() {\n"
 | 
						|
    "  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
 | 
						|
    "}\n";
 | 
						|
 | 
						|
GLuint loadShader(GLenum shaderType, const char* pSource) {
 | 
						|
    GLuint shader = glCreateShader(shaderType);
 | 
						|
    if (shader) {
 | 
						|
        glShaderSource(shader, 1, &pSource, NULL);
 | 
						|
        glCompileShader(shader);
 | 
						|
        GLint compiled = 0;
 | 
						|
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
 | 
						|
        if (!compiled) {
 | 
						|
            GLint infoLen = 0;
 | 
						|
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
 | 
						|
            if (infoLen) {
 | 
						|
                char* buf = (char*) malloc(infoLen);
 | 
						|
                if (buf) {
 | 
						|
                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
 | 
						|
                    ALOGE("Could not compile shader %d:\n%s\n",
 | 
						|
                            shaderType, buf);
 | 
						|
                    free(buf);
 | 
						|
                }
 | 
						|
                glDeleteShader(shader);
 | 
						|
                shader = 0;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return shader;
 | 
						|
}
 | 
						|
 | 
						|
GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
 | 
						|
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
 | 
						|
    if (!vertexShader) {
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
 | 
						|
    if (!pixelShader) {
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    GLuint program = glCreateProgram();
 | 
						|
    if (program) {
 | 
						|
        glAttachShader(program, vertexShader);
 | 
						|
        checkGlError("glAttachShader");
 | 
						|
        glAttachShader(program, pixelShader);
 | 
						|
        checkGlError("glAttachShader");
 | 
						|
        glLinkProgram(program);
 | 
						|
        GLint linkStatus = GL_FALSE;
 | 
						|
        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
 | 
						|
        if (linkStatus != GL_TRUE) {
 | 
						|
            GLint bufLength = 0;
 | 
						|
            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
 | 
						|
            if (bufLength) {
 | 
						|
                char* buf = (char*) malloc(bufLength);
 | 
						|
                if (buf) {
 | 
						|
                    glGetProgramInfoLog(program, bufLength, NULL, buf);
 | 
						|
                    ALOGE("Could not link program:\n%s\n", buf);
 | 
						|
                    free(buf);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            glDeleteProgram(program);
 | 
						|
            program = 0;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    return program;
 | 
						|
}
 | 
						|
 | 
						|
GLuint gProgram;
 | 
						|
GLuint gvPositionHandle;
 | 
						|
 | 
						|
bool setupGraphics(int w, int h) {
 | 
						|
    printGLString("Version", GL_VERSION);
 | 
						|
    printGLString("Vendor", GL_VENDOR);
 | 
						|
    printGLString("Renderer", GL_RENDERER);
 | 
						|
    printGLString("Extensions", GL_EXTENSIONS);
 | 
						|
 | 
						|
    ALOGI("setupGraphics(%d, %d)", w, h);
 | 
						|
    gProgram = createProgram(gVertexShader, gFragmentShader);
 | 
						|
    if (!gProgram) {
 | 
						|
        ALOGE("Could not create program.");
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
    gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
 | 
						|
    checkGlError("glGetAttribLocation");
 | 
						|
    ALOGI("glGetAttribLocation(\"vPosition\") = %d\n",
 | 
						|
            gvPositionHandle);
 | 
						|
 | 
						|
    glViewport(0, 0, w, h);
 | 
						|
    checkGlError("glViewport");
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
 | 
						|
        0.5f, -0.5f };
 | 
						|
 | 
						|
void renderFrame() {
 | 
						|
    static float grey;
 | 
						|
    grey += 0.01f;
 | 
						|
    if (grey > 1.0f) {
 | 
						|
        grey = 0.0f;
 | 
						|
    }
 | 
						|
    glClearColor(grey, grey, grey, 1.0f);
 | 
						|
    checkGlError("glClearColor");
 | 
						|
    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 | 
						|
    checkGlError("glClear");
 | 
						|
 | 
						|
    glUseProgram(gProgram);
 | 
						|
    checkGlError("glUseProgram");
 | 
						|
 | 
						|
    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
 | 
						|
    checkGlError("glVertexAttribPointer");
 | 
						|
    glEnableVertexAttribArray(gvPositionHandle);
 | 
						|
    checkGlError("glEnableVertexAttribArray");
 | 
						|
    glDrawArrays(GL_TRIANGLES, 0, 3);
 | 
						|
    checkGlError("glDrawArrays");
 | 
						|
}
 | 
						|
 | 
						|
extern "C" {
 | 
						|
    JNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_init(JNIEnv * env, jobject obj, jint width, jint height);
 | 
						|
    JNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_step(JNIEnv * env, jobject obj);
 | 
						|
};
 | 
						|
 | 
						|
JNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_init(JNIEnv * /*env*/, jobject /*obj*/, jint width, jint height)
 | 
						|
{
 | 
						|
    setupGraphics(width, height);
 | 
						|
}
 | 
						|
 | 
						|
JNIEXPORT void JNICALL Java_com_android_gldual_GLDualLib_step(JNIEnv * /*env*/, jobject /*obj*/)
 | 
						|
{
 | 
						|
    renderFrame();
 | 
						|
}
 | 
						|
 |