Add a sample showing how to use OpenGL ES 3.0
Change-Id: If834a23ad3ad2164e6fdc40f865ee28cfa93de7e
diff --git a/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-11.xml b/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-11.xml
new file mode 100644
index 0000000..9213c58
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-11.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.gles3jni">
+ <application
+ android:label="@string/gles3jni_activity">
+ <activity android:name="GLES3JNIActivity"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+ android:launchMode="singleTask"
+ android:configChanges="orientation|keyboardHidden">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+ <uses-feature android:glEsVersion="0x00020000"/>
+ <uses-sdk android:minSdkVersion="11"/>
+</manifest>
diff --git a/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-18.xml b/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-18.xml
new file mode 100644
index 0000000..7eea32f
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/AndroidManifest-18.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.gles3jni">
+ <application
+ android:label="@string/gles3jni_activity">
+ <activity android:name="GLES3JNIActivity"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+ android:launchMode="singleTask"
+ android:configChanges="orientation|keyboardHidden">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+ <uses-feature android:glEsVersion="0x00030000"/>
+ <uses-sdk android:minSdkVersion="18"/>
+</manifest>
diff --git a/ndk/platforms/android-18/samples/gles3jni/README b/ndk/platforms/android-18/samples/gles3jni/README
new file mode 100644
index 0000000..517eec3
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/README
@@ -0,0 +1,33 @@
+This sample demonstrates how to use OpenGL ES 3.0 from JNI/native code.
+
+The sample can be built two different ways:
+ * Compatible with API level 11 and later [*1]
+ * Require API level 18 or later.
+Both versions include an OpenGL ES 2.0 fallback path for devices that don't
+support OpenGL ES 3.0.
+
+To build and install the sample:
+$ ln -s AndroidManifest-$N.xml AndroidManifest.xml
+$ ln -s Android-$N.mk jni/Android.mk
+$ $ANDROID_SDK/tools/android update project --path . --target android-$N
+$ ../../ndk-build
+$ ant debug
+$ adb install bin/GLES3JNIActivity-debug.apk
+where $N is '11' or '18' and
+ANDROID_SDK is the root of your SDK installation.
+
+The OpenGL ES 3.0 rendering path uses a few new features compared to the
+OpenGL ES 2.0 path:
+
+* Instanced rendering and vertex attribute divisor to reduce the number of
+ draw calls and uniform changes.
+* Vertex array objects to reduce the number of calls required to set up
+ vertex attribute state on each frame.
+* Explicit assignment of attribute locations, eliminating the need to query
+ assignments.
+
+
+[*1] The only dependency on API level 11 is the call to
+ setEGLContextClientVersion in GLES3JNIView. With a custom
+ EGLConfigChooser and EGLContextFactory the sample would be compatible
+ with older API levels.
\ No newline at end of file
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/Android-11.mk b/ndk/platforms/android-18/samples/gles3jni/jni/Android-11.mk
new file mode 100644
index 0000000..baf17d2
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/Android-11.mk
@@ -0,0 +1,27 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libgles3jni
+LOCAL_CFLAGS := -Werror -DDYNAMIC_ES3
+LOCAL_SRC_FILES := gles3jni.cpp \
+ RendererES2.cpp \
+ RendererES3.cpp \
+ gl3stub.c
+LOCAL_LDLIBS := -llog -lGLESv2 -lEGL
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/Android-18.mk b/ndk/platforms/android-18/samples/gles3jni/jni/Android-18.mk
new file mode 100644
index 0000000..5111de5
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/Android-18.mk
@@ -0,0 +1,26 @@
+# Copyright 2013 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libgles3jni
+LOCAL_CFLAGS := -Werror
+LOCAL_SRC_FILES := gles3jni.cpp \
+ RendererES2.cpp \
+ RendererES3.cpp
+LOCAL_LDLIBS := -llog -lGLESv3 -lEGL
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/RendererES2.cpp b/ndk/platforms/android-18/samples/gles3jni/jni/RendererES2.cpp
new file mode 100644
index 0000000..d5f8d48
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/RendererES2.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gles3jni.h"
+#include <EGL/egl.h>
+
+static const char VERTEX_SHADER[] =
+ "#version 100\n"
+ "uniform mat2 scaleRot;\n"
+ "uniform vec2 offset;\n"
+ "attribute vec2 pos;\n"
+ "attribute vec4 color;\n"
+ "varying vec4 vColor;\n"
+ "void main() {\n"
+ " gl_Position = vec4(scaleRot*pos + offset, 0.0, 1.0);\n"
+ " vColor = color;\n"
+ "}\n";
+
+static const char FRAGMENT_SHADER[] =
+ "#version 100\n"
+ "precision mediump float;\n"
+ "varying vec4 vColor;\n"
+ "void main() {\n"
+ " gl_FragColor = vColor;\n"
+ "}\n";
+
+class RendererES2: public Renderer {
+public:
+ RendererES2();
+ virtual ~RendererES2();
+ bool init();
+
+private:
+ virtual float* mapOffsetBuf();
+ virtual void unmapOffsetBuf();
+ virtual float* mapTransformBuf();
+ virtual void unmapTransformBuf();
+ virtual void draw(unsigned int numInstances);
+
+ const EGLContext mEglContext;
+ GLuint mProgram;
+ GLuint mVB;
+ GLint mPosAttrib;
+ GLint mColorAttrib;
+ GLint mScaleRotUniform;
+ GLint mOffsetUniform;
+
+ float mOffsets[2*MAX_INSTANCES];
+ float mScaleRot[4*MAX_INSTANCES]; // array of 2x2 column-major matrices
+};
+
+Renderer* createES2Renderer() {
+ RendererES2* renderer = new RendererES2;
+ if (!renderer->init()) {
+ delete renderer;
+ return NULL;
+ }
+ return renderer;
+}
+
+RendererES2::RendererES2()
+: mEglContext(eglGetCurrentContext()),
+ mProgram(0),
+ mVB(0),
+ mPosAttrib(-1),
+ mColorAttrib(-1),
+ mScaleRotUniform(-1),
+ mOffsetUniform(-1)
+{}
+
+bool RendererES2::init() {
+ mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+ if (!mProgram)
+ return false;
+ mPosAttrib = glGetAttribLocation(mProgram, "pos");
+ mColorAttrib = glGetAttribLocation(mProgram, "color");
+ mScaleRotUniform = glGetUniformLocation(mProgram, "scaleRot");
+ mOffsetUniform = glGetUniformLocation(mProgram, "offset");
+
+ glGenBuffers(1, &mVB);
+ glBindBuffer(GL_ARRAY_BUFFER, mVB);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD), &QUAD[0], GL_STATIC_DRAW);
+
+ ALOGV("Using OpenGL ES 2.0 renderer");
+ return true;
+}
+
+RendererES2::~RendererES2() {
+ /* The destructor may be called after the context has already been
+ * destroyed, in which case our objects have already been destroyed.
+ *
+ * If the context exists, it must be current. This only happens when we're
+ * cleaning up after a failed init().
+ */
+ if (eglGetCurrentContext() != mEglContext)
+ return;
+ glDeleteBuffers(1, &mVB);
+ glDeleteProgram(mProgram);
+}
+
+float* RendererES2::mapOffsetBuf() {
+ return mOffsets;
+}
+
+void RendererES2::unmapOffsetBuf() {
+}
+
+float* RendererES2::mapTransformBuf() {
+ return mScaleRot;
+}
+
+void RendererES2::unmapTransformBuf() {
+}
+
+void RendererES2::draw(unsigned int numInstances) {
+ glUseProgram(mProgram);
+
+ glBindBuffer(GL_ARRAY_BUFFER, mVB);
+ glVertexAttribPointer(mPosAttrib, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, pos));
+ glVertexAttribPointer(mColorAttrib, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, rgba));
+ glEnableVertexAttribArray(mPosAttrib);
+ glEnableVertexAttribArray(mColorAttrib);
+
+ for (unsigned int i = 0; i < numInstances; i++) {
+ glUniformMatrix2fv(mScaleRotUniform, 1, GL_FALSE, mScaleRot + 4*i);
+ glUniform2fv(mOffsetUniform, 1, mOffsets + 2*i);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ }
+}
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/RendererES3.cpp b/ndk/platforms/android-18/samples/gles3jni/jni/RendererES3.cpp
new file mode 100644
index 0000000..a6e617b
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/RendererES3.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gles3jni.h"
+#include <EGL/egl.h>
+
+#define STR(s) #s
+#define STRV(s) STR(s)
+
+#define POS_ATTRIB 0
+#define COLOR_ATTRIB 1
+#define SCALEROT_ATTRIB 2
+#define OFFSET_ATTRIB 3
+
+static const char VERTEX_SHADER[] =
+ "#version 300 es\n"
+ "layout(location = " STRV(POS_ATTRIB) ") in vec2 pos;\n"
+ "layout(location=" STRV(COLOR_ATTRIB) ") in vec4 color;\n"
+ "layout(location=" STRV(SCALEROT_ATTRIB) ") in vec4 scaleRot;\n"
+ "layout(location=" STRV(OFFSET_ATTRIB) ") in vec2 offset;\n"
+ "out vec4 vColor;\n"
+ "void main() {\n"
+ " mat2 sr = mat2(scaleRot.xy, scaleRot.zw);\n"
+ " gl_Position = vec4(sr*pos + offset, 0.0, 1.0);\n"
+ " vColor = color;\n"
+ "}\n";
+
+static const char FRAGMENT_SHADER[] =
+ "#version 300 es\n"
+ "precision mediump float;\n"
+ "in vec4 vColor;\n"
+ "out vec4 outColor;\n"
+ "void main() {\n"
+ " outColor = vColor;\n"
+ "}\n";
+
+class RendererES3: public Renderer {
+public:
+ RendererES3();
+ virtual ~RendererES3();
+ bool init();
+
+private:
+ enum {VB_INSTANCE, VB_SCALEROT, VB_OFFSET, VB_COUNT};
+
+ virtual float* mapOffsetBuf();
+ virtual void unmapOffsetBuf();
+ virtual float* mapTransformBuf();
+ virtual void unmapTransformBuf();
+ virtual void draw(unsigned int numInstances);
+
+ const EGLContext mEglContext;
+ GLuint mProgram;
+ GLuint mVB[VB_COUNT];
+ GLuint mVBState;
+};
+
+Renderer* createES3Renderer() {
+ RendererES3* renderer = new RendererES3;
+ if (!renderer->init()) {
+ delete renderer;
+ return NULL;
+ }
+ return renderer;
+}
+
+RendererES3::RendererES3()
+: mEglContext(eglGetCurrentContext()),
+ mProgram(0),
+ mVBState(0)
+{
+ for (int i = 0; i < VB_COUNT; i++)
+ mVB[i] = 0;
+}
+
+bool RendererES3::init() {
+ mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+ if (!mProgram)
+ return false;
+
+ glGenBuffers(VB_COUNT, mVB);
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_INSTANCE]);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD), &QUAD[0], GL_STATIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
+ glBufferData(GL_ARRAY_BUFFER, MAX_INSTANCES * 4*sizeof(float), NULL, GL_DYNAMIC_DRAW);
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
+ glBufferData(GL_ARRAY_BUFFER, MAX_INSTANCES * 2*sizeof(float), NULL, GL_STATIC_DRAW);
+
+ glGenVertexArrays(1, &mVBState);
+ glBindVertexArray(mVBState);
+
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_INSTANCE]);
+ glVertexAttribPointer(POS_ATTRIB, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, pos));
+ glVertexAttribPointer(COLOR_ATTRIB, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (const GLvoid*)offsetof(Vertex, rgba));
+ glEnableVertexAttribArray(POS_ATTRIB);
+ glEnableVertexAttribArray(COLOR_ATTRIB);
+
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
+ glVertexAttribPointer(SCALEROT_ATTRIB, 4, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0);
+ glEnableVertexAttribArray(SCALEROT_ATTRIB);
+ glVertexAttribDivisor(SCALEROT_ATTRIB, 1);
+
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
+ glVertexAttribPointer(OFFSET_ATTRIB, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0);
+ glEnableVertexAttribArray(OFFSET_ATTRIB);
+ glVertexAttribDivisor(OFFSET_ATTRIB, 1);
+
+ ALOGV("Using OpenGL ES 3.0 renderer");
+ return true;
+}
+
+RendererES3::~RendererES3() {
+ /* The destructor may be called after the context has already been
+ * destroyed, in which case our objects have already been destroyed.
+ *
+ * If the context exists, it must be current. This only happens when we're
+ * cleaning up after a failed init().
+ */
+ if (eglGetCurrentContext() != mEglContext)
+ return;
+ glDeleteVertexArrays(1, &mVBState);
+ glDeleteBuffers(VB_COUNT, mVB);
+ glDeleteProgram(mProgram);
+}
+
+float* RendererES3::mapOffsetBuf() {
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_OFFSET]);
+ return (float*)glMapBufferRange(GL_ARRAY_BUFFER,
+ 0, MAX_INSTANCES * 2*sizeof(float),
+ GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+}
+
+void RendererES3::unmapOffsetBuf() {
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+}
+
+float* RendererES3::mapTransformBuf() {
+ glBindBuffer(GL_ARRAY_BUFFER, mVB[VB_SCALEROT]);
+ return (float*)glMapBufferRange(GL_ARRAY_BUFFER,
+ 0, MAX_INSTANCES * 4*sizeof(float),
+ GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+}
+
+void RendererES3::unmapTransformBuf() {
+ glUnmapBuffer(GL_ARRAY_BUFFER);
+}
+
+void RendererES3::draw(unsigned int numInstances) {
+ glUseProgram(mProgram);
+ glBindVertexArray(mVBState);
+ glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, numInstances);
+}
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.c b/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.c
new file mode 100644
index 0000000..b579f23
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gl3stub.h"
+#include <dlfcn.h>
+
+
+GLboolean gl3stubInit() {
+ void* so = dlopen("libGLESv3.so", RTLD_NOW | RTLD_GLOBAL);
+ if (!so)
+ return GL_FALSE;
+
+ #define DLSYM(s) s = dlsym(so, #s)
+ DLSYM(glReadBuffer);
+ DLSYM(glDrawRangeElements);
+ DLSYM(glTexImage3D);
+ DLSYM(glTexSubImage3D);
+ DLSYM(glCopyTexSubImage3D);
+ DLSYM(glCompressedTexImage3D);
+ DLSYM(glCompressedTexSubImage3D);
+ DLSYM(glGenQueries);
+ DLSYM(glDeleteQueries);
+ DLSYM(glIsQuery);
+ DLSYM(glBeginQuery);
+ DLSYM(glEndQuery);
+ DLSYM(glGetQueryiv);
+ DLSYM(glGetQueryObjectuiv);
+ DLSYM(glUnmapBuffer);
+ DLSYM(glGetBufferPointerv);
+ DLSYM(glDrawBuffers);
+ DLSYM(glUniformMatrix2x3fv);
+ DLSYM(glUniformMatrix3x2fv);
+ DLSYM(glUniformMatrix2x4fv);
+ DLSYM(glUniformMatrix4x2fv);
+ DLSYM(glUniformMatrix3x4fv);
+ DLSYM(glUniformMatrix4x3fv);
+ DLSYM(glBlitFramebuffer);
+ DLSYM(glRenderbufferStorageMultisample);
+ DLSYM(glFramebufferTextureLayer);
+ DLSYM(glMapBufferRange);
+ DLSYM(glFlushMappedBufferRange);
+ DLSYM(glBindVertexArray);
+ DLSYM(glDeleteVertexArrays);
+ DLSYM(glGenVertexArrays);
+ DLSYM(glIsVertexArray);
+ DLSYM(glGetIntegeri_v);
+ DLSYM(glBeginTransformFeedback);
+ DLSYM(glEndTransformFeedback);
+ DLSYM(glBindBufferRange);
+ DLSYM(glBindBufferBase);
+ DLSYM(glTransformFeedbackVaryings);
+ DLSYM(glGetTransformFeedbackVarying);
+ DLSYM(glVertexAttribIPointer);
+ DLSYM(glGetVertexAttribIiv);
+ DLSYM(glGetVertexAttribIuiv);
+ DLSYM(glVertexAttribI4i);
+ DLSYM(glVertexAttribI4ui);
+ DLSYM(glVertexAttribI4iv);
+ DLSYM(glVertexAttribI4uiv);
+ DLSYM(glGetUniformuiv);
+ DLSYM(glGetFragDataLocation);
+ DLSYM(glUniform1ui);
+ DLSYM(glUniform2ui);
+ DLSYM(glUniform3ui);
+ DLSYM(glUniform4ui);
+ DLSYM(glUniform1uiv);
+ DLSYM(glUniform2uiv);
+ DLSYM(glUniform3uiv);
+ DLSYM(glUniform4uiv);
+ DLSYM(glClearBufferiv);
+ DLSYM(glClearBufferuiv);
+ DLSYM(glClearBufferfv);
+ DLSYM(glClearBufferfi);
+ DLSYM(glGetStringi);
+ DLSYM(glCopyBufferSubData);
+ DLSYM(glGetUniformIndices);
+ DLSYM(glGetActiveUniformsiv);
+ DLSYM(glGetUniformBlockIndex);
+ DLSYM(glGetActiveUniformBlockiv);
+ DLSYM(glGetActiveUniformBlockName);
+ DLSYM(glUniformBlockBinding);
+ DLSYM(glDrawArraysInstanced);
+ DLSYM(glDrawElementsInstanced);
+ DLSYM(glFenceSync);
+ DLSYM(glIsSync);
+ DLSYM(glDeleteSync);
+ DLSYM(glClientWaitSync);
+ DLSYM(glWaitSync);
+ DLSYM(glGetInteger64v);
+ DLSYM(glGetSynciv);
+ DLSYM(glGetInteger64i_v);
+ DLSYM(glGetBufferParameteri64v);
+ DLSYM(glGenSamplers);
+ DLSYM(glDeleteSamplers);
+ DLSYM(glIsSampler);
+ DLSYM(glBindSampler);
+ DLSYM(glSamplerParameteri);
+ DLSYM(glSamplerParameteriv);
+ DLSYM(glSamplerParameterf);
+ DLSYM(glSamplerParameterfv);
+ DLSYM(glGetSamplerParameteriv);
+ DLSYM(glGetSamplerParameterfv);
+ DLSYM(glVertexAttribDivisor);
+ DLSYM(glBindTransformFeedback);
+ DLSYM(glDeleteTransformFeedbacks);
+ DLSYM(glGenTransformFeedbacks);
+ DLSYM(glIsTransformFeedback);
+ DLSYM(glPauseTransformFeedback);
+ DLSYM(glResumeTransformFeedback);
+ DLSYM(glGetProgramBinary);
+ DLSYM(glProgramBinary);
+ DLSYM(glProgramParameteri);
+ DLSYM(glInvalidateFramebuffer);
+ DLSYM(glInvalidateSubFramebuffer);
+ DLSYM(glTexStorage2D);
+ DLSYM(glTexStorage3D);
+ DLSYM(glGetInternalformativ);
+ #undef DLSYM
+
+ if (!glReadBuffer ||
+ !glDrawRangeElements ||
+ !glTexImage3D ||
+ !glTexSubImage3D ||
+ !glCopyTexSubImage3D ||
+ !glCompressedTexImage3D ||
+ !glCompressedTexSubImage3D ||
+ !glGenQueries ||
+ !glDeleteQueries ||
+ !glIsQuery ||
+ !glBeginQuery ||
+ !glEndQuery ||
+ !glGetQueryiv ||
+ !glGetQueryObjectuiv ||
+ !glUnmapBuffer ||
+ !glGetBufferPointerv ||
+ !glDrawBuffers ||
+ !glUniformMatrix2x3fv ||
+ !glUniformMatrix3x2fv ||
+ !glUniformMatrix2x4fv ||
+ !glUniformMatrix4x2fv ||
+ !glUniformMatrix3x4fv ||
+ !glUniformMatrix4x3fv ||
+ !glBlitFramebuffer ||
+ !glRenderbufferStorageMultisample ||
+ !glFramebufferTextureLayer ||
+ !glMapBufferRange ||
+ !glFlushMappedBufferRange ||
+ !glBindVertexArray ||
+ !glDeleteVertexArrays ||
+ !glGenVertexArrays ||
+ !glIsVertexArray ||
+ !glGetIntegeri_v ||
+ !glBeginTransformFeedback ||
+ !glEndTransformFeedback ||
+ !glBindBufferRange ||
+ !glBindBufferBase ||
+ !glTransformFeedbackVaryings ||
+ !glGetTransformFeedbackVarying ||
+ !glVertexAttribIPointer ||
+ !glGetVertexAttribIiv ||
+ !glGetVertexAttribIuiv ||
+ !glVertexAttribI4i ||
+ !glVertexAttribI4ui ||
+ !glVertexAttribI4iv ||
+ !glVertexAttribI4uiv ||
+ !glGetUniformuiv ||
+ !glGetFragDataLocation ||
+ !glUniform1ui ||
+ !glUniform2ui ||
+ !glUniform3ui ||
+ !glUniform4ui ||
+ !glUniform1uiv ||
+ !glUniform2uiv ||
+ !glUniform3uiv ||
+ !glUniform4uiv ||
+ !glClearBufferiv ||
+ !glClearBufferuiv ||
+ !glClearBufferfv ||
+ !glClearBufferfi ||
+ !glGetStringi ||
+ !glCopyBufferSubData ||
+ !glGetUniformIndices ||
+ !glGetActiveUniformsiv ||
+ !glGetUniformBlockIndex ||
+ !glGetActiveUniformBlockiv ||
+ !glGetActiveUniformBlockName ||
+ !glUniformBlockBinding ||
+ !glDrawArraysInstanced ||
+ !glDrawElementsInstanced ||
+ !glFenceSync ||
+ !glIsSync ||
+ !glDeleteSync ||
+ !glClientWaitSync ||
+ !glWaitSync ||
+ !glGetInteger64v ||
+ !glGetSynciv ||
+ !glGetInteger64i_v ||
+ !glGetBufferParameteri64v ||
+ !glGenSamplers ||
+ !glDeleteSamplers ||
+ !glIsSampler ||
+ !glBindSampler ||
+ !glSamplerParameteri ||
+ !glSamplerParameteriv ||
+ !glSamplerParameterf ||
+ !glSamplerParameterfv ||
+ !glGetSamplerParameteriv ||
+ !glGetSamplerParameterfv ||
+ !glVertexAttribDivisor ||
+ !glBindTransformFeedback ||
+ !glDeleteTransformFeedbacks ||
+ !glGenTransformFeedbacks ||
+ !glIsTransformFeedback ||
+ !glPauseTransformFeedback ||
+ !glResumeTransformFeedback ||
+ !glGetProgramBinary ||
+ !glProgramBinary ||
+ !glProgramParameteri ||
+ !glInvalidateFramebuffer ||
+ !glInvalidateSubFramebuffer ||
+ !glTexStorage2D ||
+ !glTexStorage3D ||
+ !glGetInternalformativ)
+ {
+ dlclose(so);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/* Function pointer definitions */
+GL_APICALL void (* GL_APIENTRY glReadBuffer) (GLenum mode);
+GL_APICALL void (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+GL_APICALL void (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids);
+GL_APICALL void (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids);
+GL_APICALL GLboolean (* GL_APIENTRY glIsQuery) (GLuint id);
+GL_APICALL void (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id);
+GL_APICALL void (* GL_APIENTRY glEndQuery) (GLenum target);
+GL_APICALL void (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params);
+GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer) (GLenum target);
+GL_APICALL void (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params);
+GL_APICALL void (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length);
+GL_APICALL void (* GL_APIENTRY glBindVertexArray) (GLuint array);
+GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays);
+GL_APICALL void (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays);
+GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray) (GLuint array);
+GL_APICALL void (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data);
+GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode);
+GL_APICALL void (* GL_APIENTRY glEndTransformFeedback) (void);
+GL_APICALL void (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GL_APICALL void (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer);
+GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v);
+GL_APICALL void (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params);
+GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name);
+GL_APICALL void (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0);
+GL_APICALL void (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1);
+GL_APICALL void (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index);
+GL_APICALL void (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GL_APICALL void (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
+GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName);
+GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+GL_APICALL void (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
+GL_APICALL GLsync (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean (* GL_APIENTRY glIsSync) (GLsync sync);
+GL_APICALL void (* GL_APIENTRY glDeleteSync) (GLsync sync);
+GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params);
+GL_APICALL void (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+GL_APICALL void (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data);
+GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params);
+GL_APICALL void (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers);
+GL_APICALL void (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers);
+GL_APICALL GLboolean (* GL_APIENTRY glIsSampler) (GLuint sampler);
+GL_APICALL void (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler);
+GL_APICALL void (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param);
+GL_APICALL void (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param);
+GL_APICALL void (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param);
+GL_APICALL void (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param);
+GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params);
+GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor);
+GL_APICALL void (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id);
+GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids);
+GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids);
+GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback) (GLuint id);
+GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback) (void);
+GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback) (void);
+GL_APICALL void (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+GL_APICALL void (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
+GL_APICALL void (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value);
+GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.h b/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.h
new file mode 100644
index 0000000..7a02bf2
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/gl3stub.h
@@ -0,0 +1,491 @@
+#ifndef __gl3_h_
+#define __gl3_h_
+
+/*
+ * stub gl3.h for dynamic loading, based on:
+ * gl3.h last updated on $Date: 2013-02-12 14:37:24 -0800 (Tue, 12 Feb 2013) $
+ *
+ * Changes:
+ * - Added #include <GLES2/gl2.h>
+ * - Removed duplicate OpenGL ES 2.0 declarations
+ * - Converted OpenGL ES 3.0 function prototypes to function pointer
+ * declarations
+ * - Added gl3stubInit() declaration
+ */
+
+#include <GLES2/gl2.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2013 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/* Call this function before calling any OpenGL ES 3.0 functions. It will
+ * return GL_TRUE if the OpenGL ES 3.0 was successfully initialized, GL_FALSE
+ * otherwise. */
+GLboolean gl3stubInit();
+
+/*-------------------------------------------------------------------------
+ * Data type definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES 3.0 */
+
+typedef unsigned short GLhalf;
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+
+/*-------------------------------------------------------------------------
+ * Token definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES core versions */
+#define GL_ES_VERSION_3_0 1
+
+/* OpenGL ES 3.0 */
+
+#define GL_READ_BUFFER 0x0C02
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_COLOR 0x1800
+#define GL_DEPTH 0x1801
+#define GL_STENCIL 0x1802
+#define GL_RED 0x1903
+#define GL_RGB8 0x8051
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_HALF_FLOAT 0x140B
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_RG8 0x822B
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_COPY_READ_BUFFER_BINDING GL_COPY_READ_BUFFER
+#define GL_COPY_WRITE_BUFFER_BINDING GL_COPY_WRITE_BUFFER
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_RGB10_A2UI 0x906F
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+
+/*-------------------------------------------------------------------------
+ * Entrypoint definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES 3.0 */
+
+extern GL_APICALL void (* GL_APIENTRY glReadBuffer) (GLenum mode);
+extern GL_APICALL void (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+extern GL_APICALL void (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+extern GL_APICALL void (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+extern GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+extern GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+extern GL_APICALL void (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids);
+extern GL_APICALL void (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsQuery) (GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glEndQuery) (GLenum target);
+extern GL_APICALL void (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params);
+extern GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer) (GLenum target);
+extern GL_APICALL void (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params);
+extern GL_APICALL void (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+extern GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+extern GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+extern GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length);
+extern GL_APICALL void (* GL_APIENTRY glBindVertexArray) (GLuint array);
+extern GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays);
+extern GL_APICALL void (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray) (GLuint array);
+extern GL_APICALL void (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data);
+extern GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode);
+extern GL_APICALL void (* GL_APIENTRY glEndTransformFeedback) (void);
+extern GL_APICALL void (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+extern GL_APICALL void (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer);
+extern GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+extern GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+extern GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v);
+extern GL_APICALL void (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params);
+extern GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name);
+extern GL_APICALL void (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0);
+extern GL_APICALL void (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1);
+extern GL_APICALL void (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+extern GL_APICALL void (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+extern GL_APICALL void (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+extern GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index);
+extern GL_APICALL void (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+extern GL_APICALL void (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
+extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+extern GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName);
+extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+extern GL_APICALL void (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+extern GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+extern GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
+extern GL_APICALL GLsync (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsSync) (GLsync sync);
+extern GL_APICALL void (* GL_APIENTRY glDeleteSync) (GLsync sync);
+extern GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+extern GL_APICALL void (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+extern GL_APICALL void (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params);
+extern GL_APICALL void (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+extern GL_APICALL void (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data);
+extern GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params);
+extern GL_APICALL void (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers);
+extern GL_APICALL void (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsSampler) (GLuint sampler);
+extern GL_APICALL void (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param);
+extern GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor);
+extern GL_APICALL void (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids);
+extern GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback) (GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback) (void);
+extern GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback) (void);
+extern GL_APICALL void (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+extern GL_APICALL void (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
+extern GL_APICALL void (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value);
+extern GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+extern GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+extern GL_APICALL void (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.cpp b/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.cpp
new file mode 100644
index 0000000..23f2b05
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <jni.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "gles3jni.h"
+
+const Vertex QUAD[4] = {
+ // Square with diagonal < 2 so that it fits in a [-1 .. 1]^2 square
+ // regardless of rotation.
+ {{-0.7f, -0.7f}, {0x00, 0xFF, 0x00}},
+ {{ 0.7f, -0.7f}, {0x00, 0x00, 0xFF}},
+ {{-0.7f, 0.7f}, {0xFF, 0x00, 0x00}},
+ {{ 0.7f, 0.7f}, {0xFF, 0xFF, 0xFF}},
+};
+
+bool checkGlError(const char* funcName) {
+ GLint err = glGetError();
+ if (err != GL_NO_ERROR) {
+ ALOGE("GL error after %s(): 0x%08x\n", funcName, err);
+ return true;
+ }
+ return false;
+}
+
+GLuint createShader(GLenum shaderType, const char* src) {
+ GLuint shader = glCreateShader(shaderType);
+ if (!shader) {
+ checkGlError("glCreateShader");
+ return 0;
+ }
+ glShaderSource(shader, 1, &src, NULL);
+
+ GLint compiled = GL_FALSE;
+ glCompileShader(shader);
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLogLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
+ if (infoLogLen > 0) {
+ GLchar* infoLog = (GLchar*)malloc(infoLogLen);
+ if (infoLog) {
+ glGetShaderInfoLog(shader, infoLogLen, NULL, infoLog);
+ ALOGE("Could not compile %s shader:\n%s\n",
+ shaderType == GL_VERTEX_SHADER ? "vertex" : "fragment",
+ infoLog);
+ free(infoLog);
+ }
+ }
+ glDeleteShader(shader);
+ return 0;
+ }
+
+ return shader;
+}
+
+GLuint createProgram(const char* vtxSrc, const char* fragSrc) {
+ GLuint vtxShader = 0;
+ GLuint fragShader = 0;
+ GLuint program = 0;
+ GLint linked = GL_FALSE;
+
+ vtxShader = createShader(GL_VERTEX_SHADER, vtxSrc);
+ if (!vtxShader)
+ goto exit;
+
+ fragShader = createShader(GL_FRAGMENT_SHADER, fragSrc);
+ if (!fragShader)
+ goto exit;
+
+ program = glCreateProgram();
+ if (!program) {
+ checkGlError("glCreateProgram");
+ goto exit;
+ }
+ glAttachShader(program, vtxShader);
+ glAttachShader(program, fragShader);
+
+ glLinkProgram(program);
+ glGetProgramiv(program, GL_LINK_STATUS, &linked);
+ if (!linked) {
+ ALOGE("Could not link program");
+ GLint infoLogLen = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLen);
+ if (infoLogLen) {
+ GLchar* infoLog = (GLchar*)malloc(infoLogLen);
+ if (infoLog) {
+ glGetProgramInfoLog(program, infoLogLen, NULL, infoLog);
+ ALOGE("Could not link program:\n%s\n", infoLog);
+ free(infoLog);
+ }
+ }
+ glDeleteProgram(program);
+ program = 0;
+ }
+
+exit:
+ glDeleteShader(vtxShader);
+ glDeleteShader(fragShader);
+ return program;
+}
+
+static void printGlString(const char* name, GLenum s) {
+ const char* v = (const char*)glGetString(s);
+ ALOGV("GL %s: %s\n", name, v);
+}
+
+// ----------------------------------------------------------------------------
+
+Renderer::Renderer()
+: mNumInstances(0),
+ mLastFrameNs(0)
+{
+ memset(mScale, 0, sizeof(mScale));
+ memset(mAngularVelocity, 0, sizeof(mAngularVelocity));
+ memset(mAngles, 0, sizeof(mAngles));
+}
+
+Renderer::~Renderer() {
+}
+
+void Renderer::resize(int w, int h) {
+ float* offsets = mapOffsetBuf();
+ calcSceneParams(w, h, offsets);
+ unmapOffsetBuf();
+
+ for (unsigned int i = 0; i < mNumInstances; i++) {
+ mAngles[i] = drand48() * TWO_PI;
+ mAngularVelocity[i] = MAX_ROT_SPEED * (2.0*drand48() - 1.0);
+ }
+
+ mLastFrameNs = 0;
+
+ glViewport(0, 0, w, h);
+}
+
+void Renderer::calcSceneParams(unsigned int w, unsigned int h,
+ float* offsets) {
+ // number of cells along the larger screen dimension
+ const float NCELLS_MAJOR = MAX_INSTANCES_PER_SIDE;
+ // cell size in scene space
+ const float CELL_SIZE = 2.0f / NCELLS_MAJOR;
+
+ // Calculations are done in "landscape", i.e. assuming dim[0] >= dim[1].
+ // Only at the end are values put in the opposite order if h > w.
+ const float dim[2] = {fmaxf(w,h), fminf(w,h)};
+ const float aspect[2] = {dim[0] / dim[1], dim[1] / dim[0]};
+ const float scene2clip[2] = {1.0f, aspect[0]};
+ const int ncells[2] = {
+ NCELLS_MAJOR,
+ (int)floorf(NCELLS_MAJOR * aspect[1])
+ };
+
+ float centers[2][MAX_INSTANCES_PER_SIDE];
+ for (int d = 0; d < 2; d++) {
+ float offset = -ncells[d] / NCELLS_MAJOR; // -1.0 for d=0
+ for (int i = 0; i < ncells[d]; i++) {
+ centers[d][i] = scene2clip[d] * (CELL_SIZE*(i + 0.5f) + offset);
+ }
+ }
+
+ int major = w >= h ? 0 : 1;
+ int minor = w >= h ? 1 : 0;
+ // outer product of centers[0] and centers[1]
+ for (int i = 0; i < ncells[0]; i++) {
+ for (int j = 0; j < ncells[1]; j++) {
+ int idx = i*ncells[1] + j;
+ offsets[2*idx + major] = centers[0][i];
+ offsets[2*idx + minor] = centers[1][j];
+ }
+ }
+
+ mNumInstances = ncells[0] * ncells[1];
+ mScale[major] = 0.5f * CELL_SIZE * scene2clip[0];
+ mScale[minor] = 0.5f * CELL_SIZE * scene2clip[1];
+}
+
+void Renderer::step() {
+ timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ uint64_t nowNs = now.tv_sec*1000000000ull + now.tv_nsec;
+
+ if (mLastFrameNs > 0) {
+ float dt = float(nowNs - mLastFrameNs) * 0.000000001f;
+
+ for (unsigned int i = 0; i < mNumInstances; i++) {
+ mAngles[i] += mAngularVelocity[i] * dt;
+ if (mAngles[i] >= TWO_PI) {
+ mAngles[i] -= TWO_PI;
+ } else if (mAngles[i] <= -TWO_PI) {
+ mAngles[i] += TWO_PI;
+ }
+ }
+
+ float* transforms = mapTransformBuf();
+ for (unsigned int i = 0; i < mNumInstances; i++) {
+ float s = sinf(mAngles[i]);
+ float c = cosf(mAngles[i]);
+ transforms[4*i + 0] = c * mScale[0];
+ transforms[4*i + 1] = s * mScale[1];
+ transforms[4*i + 2] = -s * mScale[0];
+ transforms[4*i + 3] = c * mScale[1];
+ }
+ unmapTransformBuf();
+ }
+
+ mLastFrameNs = nowNs;
+}
+
+void Renderer::render() {
+ step();
+
+ glClearColor(0.2f, 0.2f, 0.3f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ draw(mNumInstances);
+ checkGlError("Renderer::render");
+}
+
+// ----------------------------------------------------------------------------
+
+static Renderer* g_renderer = NULL;
+
+extern "C" {
+ JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv* env, jobject obj);
+ JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_resize(JNIEnv* env, jobject obj, jint width, jint height);
+ JNIEXPORT void JNICALL Java_com_android_gles3jni_GLES3JNILib_step(JNIEnv* env, jobject obj);
+};
+
+#if !defined(DYNAMIC_ES3)
+static GLboolean gl3stubInit() {
+ return GL_TRUE;
+}
+#endif
+
+JNIEXPORT void JNICALL
+Java_com_android_gles3jni_GLES3JNILib_init(JNIEnv* env, jobject obj) {
+ if (g_renderer) {
+ delete g_renderer;
+ g_renderer = NULL;
+ }
+
+ printGlString("Version", GL_VERSION);
+ printGlString("Vendor", GL_VENDOR);
+ printGlString("Renderer", GL_RENDERER);
+ printGlString("Extensions", GL_EXTENSIONS);
+
+ const char* versionStr = (const char*)glGetString(GL_VERSION);
+ if (strstr(versionStr, "OpenGL ES 3.") && gl3stubInit()) {
+ g_renderer = createES3Renderer();
+ } else if (strstr(versionStr, "OpenGL ES 2.")) {
+ g_renderer = createES2Renderer();
+ } else {
+ ALOGE("Unsupported OpenGL ES version");
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_com_android_gles3jni_GLES3JNILib_resize(JNIEnv* env, jobject obj, jint width, jint height) {
+ if (g_renderer) {
+ g_renderer->resize(width, height);
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_com_android_gles3jni_GLES3JNILib_step(JNIEnv* env, jobject obj) {
+ if (g_renderer) {
+ g_renderer->render();
+ }
+}
diff --git a/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.h b/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.h
new file mode 100644
index 0000000..dde779c
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/jni/gles3jni.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GLES3JNI_H
+#define GLES3JNI_H 1
+
+#include <android/log.h>
+#include <math.h>
+
+#if DYNAMIC_ES3
+#include "gl3stub.h"
+#else
+#include <GLES3/gl3.h>
+#endif
+
+#define DEBUG 1
+
+#define LOG_TAG "GLES3JNI"
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+#if DEBUG
+#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
+#else
+#define ALOGV(...)
+#endif
+
+// ----------------------------------------------------------------------------
+// Types, functions, and data used by both ES2 and ES3 renderers.
+// Defined in gles3jni.cpp.
+
+#define MAX_INSTANCES_PER_SIDE 16
+#define MAX_INSTANCES (MAX_INSTANCES_PER_SIDE * MAX_INSTANCES_PER_SIDE)
+#define TWO_PI (2.0 * M_PI)
+#define MAX_ROT_SPEED (0.3 * TWO_PI)
+
+// This demo uses three coordinate spaces:
+// - The model (a quad) is in a [-1 .. 1]^2 space
+// - Scene space is either
+// landscape: [-1 .. 1] x [-1/(2*w/h) .. 1/(2*w/h)]
+// portrait: [-1/(2*h/w) .. 1/(2*h/w)] x [-1 .. 1]
+// - Clip space in OpenGL is [-1 .. 1]^2
+//
+// Conceptually, the quads are rotated in model space, then scaled (uniformly)
+// and translated to place them in scene space. Scene space is then
+// non-uniformly scaled to clip space. In practice the transforms are combined
+// so vertices go directly from model to clip space.
+
+struct Vertex {
+ GLfloat pos[2];
+ GLubyte rgba[4];
+};
+extern const Vertex QUAD[4];
+
+// returns true if a GL error occurred
+extern bool checkGlError(const char* funcName);
+extern GLuint createShader(GLenum shaderType, const char* src);
+extern GLuint createProgram(const char* vtxSrc, const char* fragSrc);
+
+// ----------------------------------------------------------------------------
+// Interface to the ES2 and ES3 renderers, used by JNI code.
+
+class Renderer {
+public:
+ virtual ~Renderer();
+ void resize(int w, int h);
+ void render();
+
+protected:
+ Renderer();
+
+ // return a pointer to a buffer of MAX_INSTANCES * sizeof(vec2).
+ // the buffer is filled with per-instance offsets, then unmapped.
+ virtual float* mapOffsetBuf() = 0;
+ virtual void unmapOffsetBuf() = 0;
+ // return a pointer to a buffer of MAX_INSTANCES * sizeof(vec4).
+ // the buffer is filled with per-instance scale and rotation transforms.
+ virtual float* mapTransformBuf() = 0;
+ virtual void unmapTransformBuf() = 0;
+
+ virtual void draw(unsigned int numInstances) = 0;
+
+private:
+ void calcSceneParams(unsigned int w, unsigned int h, float* offsets);
+ void step();
+
+ unsigned int mNumInstances;
+ float mScale[2];
+ float mAngularVelocity[MAX_INSTANCES];
+ uint64_t mLastFrameNs;
+ float mAngles[MAX_INSTANCES];
+};
+
+extern Renderer* createES2Renderer();
+extern Renderer* createES3Renderer();
+
+#endif // GLES3JNI_H
diff --git a/ndk/platforms/android-18/samples/gles3jni/res/values/strings.xml b/ndk/platforms/android-18/samples/gles3jni/res/values/strings.xml
new file mode 100644
index 0000000..375efc6
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- This file contains resource definitions for displayed strings, allowing
+ them to be changed based on the locale and options. -->
+
+<resources>
+ <!-- Simple strings. -->
+ <string name="gles3jni_activity">GLES3JNI</string>
+
+</resources>
diff --git a/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIActivity.java b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIActivity.java
new file mode 100644
index 0000000..5427418
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIActivity.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gles3jni;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+public class GLES3JNIActivity extends Activity {
+
+ GLES3JNIView mView;
+
+ @Override protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mView = new GLES3JNIView(getApplication());
+ setContentView(mView);
+ }
+
+ @Override protected void onPause() {
+ super.onPause();
+ mView.onPause();
+ }
+
+ @Override protected void onResume() {
+ super.onResume();
+ mView.onResume();
+ }
+}
diff --git a/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNILib.java b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNILib.java
new file mode 100644
index 0000000..811658f
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNILib.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gles3jni;
+
+// Wrapper for native library
+
+public class GLES3JNILib {
+
+ static {
+ System.loadLibrary("gles3jni");
+ }
+
+ public static native void init();
+ public static native void resize(int width, int height);
+ public static native void step();
+}
diff --git a/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIView.java b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIView.java
new file mode 100644
index 0000000..12624fd
--- /dev/null
+++ b/ndk/platforms/android-18/samples/gles3jni/src/com/android/gles3jni/GLES3JNIView.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gles3jni;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.opengles.GL10;
+
+class GLES3JNIView extends GLSurfaceView {
+ private static final String TAG = "GLES3JNI";
+ private static final boolean DEBUG = true;
+
+ public GLES3JNIView(Context context) {
+ super(context);
+ // Pick an EGLConfig with RGB8 color, 16-bit depth, no stencil,
+ // supporting OpenGL ES 2.0 or later backwards-compatible versions.
+ setEGLConfigChooser(8, 8, 8, 0, 16, 0);
+ setEGLContextClientVersion(2);
+ setRenderer(new Renderer());
+ }
+
+ private static class Renderer implements GLSurfaceView.Renderer {
+ public void onDrawFrame(GL10 gl) {
+ GLES3JNILib.step();
+ }
+
+ public void onSurfaceChanged(GL10 gl, int width, int height) {
+ GLES3JNILib.resize(width, height);
+ }
+
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ GLES3JNILib.init();
+ }
+ }
+}