summaryrefslogtreecommitdiff
path: root/platform/android/src/example_custom_layer.cpp
blob: 516a8f2cd57bda1aea246327b8cbe97072edf533 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <jni.h>
#include <GLES2/gl2.h>

#include <mbgl/style/layers/custom_layer.hpp>

static const GLchar * vertexShaderSource = "attribute vec2 a_pos; void main() { gl_Position = vec4(a_pos, 0, 1); }";
static const GLchar * fragmentShaderSource = "void main() { gl_FragColor = vec4(0, 1, 0, 1); }";

class ExampleCustomLayer {
public:
    ~ExampleCustomLayer() {
        if (program) {
            glDeleteBuffers(1, &buffer);
            glDetachShader(program, vertexShader);
            glDetachShader(program, fragmentShader);
            glDeleteShader(vertexShader);
            glDeleteShader(fragmentShader);
            glDeleteProgram(program);
        }
    }

    void initialize() {
        program = glCreateProgram();
        vertexShader = glCreateShader(GL_VERTEX_SHADER);
        fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

        glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
        glCompileShader(vertexShader);
        glAttachShader(program, vertexShader);
        glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
        glCompileShader(fragmentShader);
        glAttachShader(program, fragmentShader);
        glLinkProgram(program);
        a_pos = glGetAttribLocation(program, "a_pos");

        GLfloat background[] = { -1,-1, 1,-1, -1,1, 1,1 };
        glGenBuffers(1, &buffer);
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), background, GL_STATIC_DRAW);
    }

    void render() {
        glUseProgram(program);
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glEnableVertexAttribArray(a_pos);
        glVertexAttribPointer(a_pos, 2, GL_FLOAT, GL_FALSE, 0, NULL);
        glDisable(GL_STENCIL_TEST);
        glDisable(GL_DEPTH_TEST);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }

    GLuint program = 0;
    GLuint vertexShader = 0;
    GLuint fragmentShader = 0;
    GLuint buffer = 0;
    GLuint a_pos = 0;
};

jlong JNICALL nativeCreateContext(JNIEnv*, jobject) {
    return reinterpret_cast<jlong>(new ExampleCustomLayer());
}

void nativeInitialize(void *context) {
    reinterpret_cast<ExampleCustomLayer*>(context)->initialize();
}

void nativeRender(void *context, const mbgl::style::CustomLayerRenderParameters& /*parameters*/) {
    reinterpret_cast<ExampleCustomLayer*>(context)->render();
}

void nativeDenitialize(void *context) {
    delete reinterpret_cast<ExampleCustomLayer*>(context);
}

extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
    JNIEnv *env = nullptr;
    vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);

    jclass customLayerClass = env->FindClass("com/mapbox/mapboxsdk/testapp/model/customlayer/ExampleCustomLayer");

    JNINativeMethod methods[] = {
        {"createContext", "()J", reinterpret_cast<void *>(&nativeCreateContext)}
    };

    if (env->RegisterNatives(customLayerClass, methods, 1) < 0) {
        env->ExceptionDescribe();
        return JNI_ERR;
    }

    env->SetStaticLongField(customLayerClass,
        env->GetStaticFieldID(customLayerClass, "InitializeFunction", "J"),
        reinterpret_cast<jlong>(nativeInitialize));

    env->SetStaticLongField(customLayerClass,
        env->GetStaticFieldID(customLayerClass, "RenderFunction", "J"),
        reinterpret_cast<jlong>(nativeRender));

    env->SetStaticLongField(customLayerClass,
        env->GetStaticFieldID(customLayerClass, "DeinitializeFunction", "J"),
        reinterpret_cast<jlong>(nativeDenitialize));

    return JNI_VERSION_1_6;
}

extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *, void *) {
}