commit e6519ac88033b9fa0fdafc685a4051b7cddb6c27
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Mar 27 13:51:08 2018 +0100

    Up library requirements to OpenGL ES 3.1 (needed for the upcoming GL_SHADER_STORAGE_BUFFER)

diff --git a/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java b/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
index 63c7757..931e55d 100644
--- a/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
+++ b/src/main/java/org/distorted/library/effect/PostprocessEffectBlur.java
@@ -19,7 +19,7 @@
 
 package org.distorted.library.effect;
 
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 
 import org.distorted.library.main.DistortedFramebuffer;
 import org.distorted.library.main.DistortedOutputSurface;
@@ -164,7 +164,7 @@ public class PostprocessEffectBlur extends PostprocessEffect
 
     int offset = radius + radius*radius/4;
     radius = (radius+1)/2;
-    GLES30.glViewport(0, 0, (int)w, (int)h);
+    GLES31.glViewport(0, 0, (int)w, (int)h);
 
     // horizontal blur
     for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w;
@@ -173,14 +173,14 @@ public class PostprocessEffectBlur extends PostprocessEffect
     buffer.bindForOutput(1);
     buffer.setAsInput(0);
 
-    GLES30.glUniform1f ( mProgram1.mUniform[0] , n );
-    GLES30.glUniform1i ( mProgram1.mUniform[1] , 0 );
-    GLES30.glUniform1fv( mProgram1.mUniform[2] , radius+1, mOffsets,0);
-    GLES30.glUniform1fv( mProgram1.mUniform[3] , radius+1, weightsCache,offset);
-    GLES30.glUniform1i ( mProgram1.mUniform[4] , radius);
-    GLES30.glVertexAttribPointer(mProgram1.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-    GLES30.glVertexAttribPointer(mProgram1.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    GLES31.glUniform1f ( mProgram1.mUniform[0] , n );
+    GLES31.glUniform1i ( mProgram1.mUniform[1] , 0 );
+    GLES31.glUniform1fv( mProgram1.mUniform[2] , radius+1, mOffsets,0);
+    GLES31.glUniform1fv( mProgram1.mUniform[3] , radius+1, weightsCache,offset);
+    GLES31.glUniform1i ( mProgram1.mUniform[4] , radius);
+    GLES31.glVertexAttribPointer(mProgram1.mAttribute[0], POS_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glVertexAttribPointer(mProgram1.mAttribute[1], TEX_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadTexture);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
 
     // vertical blur
     for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h;
@@ -189,18 +189,18 @@ public class PostprocessEffectBlur extends PostprocessEffect
     buffer.bindForOutput(0);
     buffer.setAsInput(1);
 
-    GLES30.glColorMask(true,true,true,true);
-    GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
-    GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
-
-    GLES30.glUniform1f ( mProgram2.mUniform[0] , n );
-    GLES30.glUniform1i ( mProgram2.mUniform[1] , 0 );
-    GLES30.glUniform1fv( mProgram2.mUniform[2] , radius+1, mOffsets,0);
-    GLES30.glUniform1fv( mProgram2.mUniform[3] , radius+1, weightsCache,offset);
-    GLES30.glUniform1i ( mProgram2.mUniform[4] , radius);
-    GLES30.glVertexAttribPointer(mProgram2.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-    GLES30.glVertexAttribPointer(mProgram2.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    GLES31.glColorMask(true,true,true,true);
+    GLES31.glClearColor(0.0f,0.0f,0.0f,0.0f);
+    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
+
+    GLES31.glUniform1f ( mProgram2.mUniform[0] , n );
+    GLES31.glUniform1i ( mProgram2.mUniform[1] , 0 );
+    GLES31.glUniform1fv( mProgram2.mUniform[2] , radius+1, mOffsets,0);
+    GLES31.glUniform1fv( mProgram2.mUniform[3] , radius+1, weightsCache,offset);
+    GLES31.glUniform1i ( mProgram2.mUniform[4] , radius);
+    GLES31.glVertexAttribPointer(mProgram2.mAttribute[0], POS_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glVertexAttribPointer(mProgram2.mAttribute[1], TEX_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadTexture);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
 
     DistortedRenderState.unuseStencilMark();
 
diff --git a/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java b/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
index 6257c32..51a101b 100644
--- a/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
+++ b/src/main/java/org/distorted/library/effect/PostprocessEffectGlow.java
@@ -19,7 +19,7 @@
 
 package org.distorted.library.effect;
 
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedFramebuffer;
@@ -169,7 +169,7 @@ public class PostprocessEffectGlow extends PostprocessEffect
     radius = (radius+1)/2;
 
     outBuffer.setAsOutput();
-    GLES30.glViewport(0, 0, (int)w, (int)h);
+    GLES31.glViewport(0, 0, (int)w, (int)h);
 
     // horizontal glow
     for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/w;
@@ -178,15 +178,15 @@ public class PostprocessEffectGlow extends PostprocessEffect
     outBuffer.bindForOutput(1);
     inBuffer.setAsInput(0);
 
-    GLES30.glUniform1f ( mProgram1.mUniform[0] , n );
-    GLES30.glUniform1i ( mProgram1.mUniform[1] , 0 );
-    GLES30.glUniform1fv( mProgram1.mUniform[2] , radius+1, mOffsets,0);
-    GLES30.glUniform1fv( mProgram1.mUniform[3] , radius+1, weightsCache,offset);
-    GLES30.glUniform1i ( mProgram1.mUniform[4] , radius);
-    GLES30.glUniform4f ( mProgram1.mUniform[5] , uniforms[index+1], uniforms[index+2], uniforms[index+3], uniforms[index+4]);
-    GLES30.glVertexAttribPointer(mProgram1.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-    GLES30.glVertexAttribPointer(mProgram1.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    GLES31.glUniform1f ( mProgram1.mUniform[0] , n );
+    GLES31.glUniform1i ( mProgram1.mUniform[1] , 0 );
+    GLES31.glUniform1fv( mProgram1.mUniform[2] , radius+1, mOffsets,0);
+    GLES31.glUniform1fv( mProgram1.mUniform[3] , radius+1, weightsCache,offset);
+    GLES31.glUniform1i ( mProgram1.mUniform[4] , radius);
+    GLES31.glUniform4f ( mProgram1.mUniform[5] , uniforms[index+1], uniforms[index+2], uniforms[index+3], uniforms[index+4]);
+    GLES31.glVertexAttribPointer(mProgram1.mAttribute[0], POS_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glVertexAttribPointer(mProgram1.mAttribute[1], TEX_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadTexture);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
 
     // vertical glow
     for(int i=0; i<=radius; i++) mOffsets[i] = offsetsCache[offset+i]/h;
@@ -195,15 +195,15 @@ public class PostprocessEffectGlow extends PostprocessEffect
     outBuffer.bindForOutput(0);
     outBuffer.setAsInput(1);
 
-    GLES30.glUniform1f ( mProgram2.mUniform[0] , n );
-    GLES30.glUniform1i ( mProgram2.mUniform[1] , 0 );
-    GLES30.glUniform1fv( mProgram2.mUniform[2] , radius+1, mOffsets,0);
-    GLES30.glUniform1fv( mProgram2.mUniform[3] , radius+1, weightsCache,offset);
-    GLES30.glUniform1i ( mProgram2.mUniform[4] , radius);
-    GLES30.glUniform4f ( mProgram1.mUniform[5] , uniforms[index+1], uniforms[index+2], uniforms[index+3], uniforms[index+4]);
-    GLES30.glVertexAttribPointer(mProgram2.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-    GLES30.glVertexAttribPointer(mProgram2.mAttribute[1], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, 0, mQuadTexture);
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    GLES31.glUniform1f ( mProgram2.mUniform[0] , n );
+    GLES31.glUniform1i ( mProgram2.mUniform[1] , 0 );
+    GLES31.glUniform1fv( mProgram2.mUniform[2] , radius+1, mOffsets,0);
+    GLES31.glUniform1fv( mProgram2.mUniform[3] , radius+1, weightsCache,offset);
+    GLES31.glUniform1i ( mProgram2.mUniform[4] , radius);
+    GLES31.glUniform4f ( mProgram1.mUniform[5] , uniforms[index+1], uniforms[index+2], uniforms[index+3], uniforms[index+4]);
+    GLES31.glVertexAttribPointer(mProgram2.mAttribute[0], POS_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glVertexAttribPointer(mProgram2.mAttribute[1], TEX_DATA_SIZE, GLES31.GL_FLOAT, false, 0, mQuadTexture);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
 
     DistortedRenderState.unuseStencilMark();
 
diff --git a/src/main/java/org/distorted/library/main/DistortedEffects.java b/src/main/java/org/distorted/library/main/DistortedEffects.java
index fbe2dc7..66cc3ea 100644
--- a/src/main/java/org/distorted/library/main/DistortedEffects.java
+++ b/src/main/java/org/distorted/library/main/DistortedEffects.java
@@ -20,7 +20,8 @@
 package org.distorted.library.main;
 
 import android.content.res.Resources;
-import android.opengl.GLES30;
+import android.opengl.GLES31;
+import android.util.Log;
 
 import org.distorted.library.R;
 import org.distorted.library.effect.Effect;
@@ -118,7 +119,7 @@ public class DistortedEffects
     EffectQueueFragment.getUniforms(mainProgramH);
     EffectQueueVertex.getUniforms(mainProgramH);
     EffectQueueMatrix.getUniforms(mainProgramH);
-    mMainTextureH= GLES30.glGetUniformLocation( mainProgramH, "u_Texture");
+    mMainTextureH= GLES31.glGetUniformLocation( mainProgramH, "u_Texture");
 
     // BLIT PROGRAM ////////////////////////////////////
     final InputStream blitVertStream = resources.openRawResource(R.raw.blit_vertex_shader);
@@ -133,13 +134,13 @@ public class DistortedEffects
       }
     catch(Exception e)
       {
-      android.util.Log.e("EFFECTS", "exception trying to compile BLIT program: "+e.getMessage());
+      Log.e("EFFECTS", "exception trying to compile BLIT program: "+e.getMessage());
       throw new RuntimeException(e.getMessage());
       }
 
     int blitProgramH = mBlitProgram.getProgramHandle();
-    mBlitTextureH  = GLES30.glGetUniformLocation( blitProgramH, "u_Texture");
-    mBlitDepthH    = GLES30.glGetUniformLocation( blitProgramH, "u_Depth");
+    mBlitTextureH  = GLES31.glGetUniformLocation( blitProgramH, "u_Texture");
+    mBlitDepthH    = GLES31.glGetUniformLocation( blitProgramH, "u_Depth");
 
     // BLIT DEPTH PROGRAM ////////////////////////////////////
     final InputStream blitDepthVertStream = resources.openRawResource(R.raw.blit_depth_vertex_shader);
@@ -151,14 +152,14 @@ public class DistortedEffects
       }
     catch(Exception e)
       {
-      android.util.Log.e("EFFECTS", "exception trying to compile BLIT DEPTH program: "+e.getMessage());
+      Log.e("EFFECTS", "exception trying to compile BLIT DEPTH program: "+e.getMessage());
       throw new RuntimeException(e.getMessage());
       }
 
     int blitDepthProgramH   = mBlitDepthProgram.getProgramHandle();
-    mBlitDepthTextureH      = GLES30.glGetUniformLocation( blitDepthProgramH, "u_Texture");
-    mBlitDepthDepthTextureH = GLES30.glGetUniformLocation( blitDepthProgramH, "u_DepthTexture");
-    mBlitDepthDepthH        = GLES30.glGetUniformLocation( blitDepthProgramH, "u_Depth");
+    mBlitDepthTextureH      = GLES31.glGetUniformLocation( blitDepthProgramH, "u_Texture");
+    mBlitDepthDepthTextureH = GLES31.glGetUniformLocation( blitDepthProgramH, "u_DepthTexture");
+    mBlitDepthDepthH        = GLES31.glGetUniformLocation( blitDepthProgramH, "u_Depth");
 
     // NORMAL PROGRAM //////////////////////////////////////
     final InputStream normalVertexStream   = resources.openRawResource(R.raw.normal_vertex_shader);
@@ -170,12 +171,12 @@ public class DistortedEffects
       }
     catch(Exception e)
       {
-      android.util.Log.e("EFFECTS", "exception trying to compile NORMAL program: "+e.getMessage());
+      Log.e("EFFECTS", "exception trying to compile NORMAL program: "+e.getMessage());
       throw new RuntimeException(e.getMessage());
       }
 
     int normalProgramH = mNormalProgram.getProgramHandle();
-    mNormalMVPMatrixH  = GLES30.glGetUniformLocation( normalProgramH, "u_MVPMatrix");
+    mNormalMVPMatrixH  = GLES31.glGetUniformLocation( normalProgramH, "u_MVPMatrix");
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -248,21 +249,21 @@ public class DistortedEffects
 
   private void displayNormals(MeshObject mesh)
     {
-    GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.mAttTFO[0]);
-    GLES30.glBeginTransformFeedback( GLES30.GL_POINTS);
+    GLES31.glBindBufferBase(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, 0, mesh.mAttTFO[0]);
+    GLES31.glBeginTransformFeedback( GLES31.GL_POINTS);
     DistortedRenderState.switchOffDrawing();
-    GLES30.glDrawArrays( GLES30.GL_POINTS, 0, mesh.numVertices);
+    GLES31.glDrawArrays( GLES31.GL_POINTS, 0, mesh.numVertices);
     DistortedRenderState.restoreDrawing();
-    GLES30.glEndTransformFeedback();
-    GLES30.glBindBufferBase(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
+    GLES31.glEndTransformFeedback();
+    GLES31.glBindBufferBase(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
 
     mNormalProgram.useProgram();
-    GLES30.glUniformMatrix4fv(mNormalMVPMatrixH, 1, false, mM.getMVP() , 0);
-    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mAttTFO[0]);
-    GLES30.glVertexAttribPointer(mNormalProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, 0);
-    GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
-    GLES30.glLineWidth(8.0f);
-    GLES30.glDrawArrays(GLES30.GL_LINES, 0, 2*mesh.numVertices);
+    GLES31.glUniformMatrix4fv(mNormalMVPMatrixH, 1, false, mM.getMVP() , 0);
+    GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.mAttTFO[0]);
+    GLES31.glVertexAttribPointer(mNormalProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES31.GL_FLOAT, false, 0, 0);
+    GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, 0);
+    GLES31.glLineWidth(8.0f);
+    GLES31.glDrawArrays(GLES31.GL_LINES, 0, 2*mesh.numVertices);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -276,34 +277,34 @@ public class DistortedEffects
     mF.compute(currTime,halfW,halfH);
     mP.compute(currTime);
 
-    GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
 
     mMainProgram.useProgram();
-    GLES30.glUniform1i(mMainTextureH, 0);
+    GLES31.glUniform1i(mMainTextureH, 0);
 
     if( Distorted.GLSL >= 300 )
       {
-      GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mesh.mAttVBO[0]);
-      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET0);
-      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET1);
-      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET2);
-      GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
+      GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mesh.mAttVBO[0]);
+      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET0);
+      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET1);
+      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, MeshObject.OFFSET2);
+      GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, 0);
       }
     else
       {
       mesh.mVertAttribs.position(0);
-      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
+      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[0], MeshObject.POS_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
       mesh.mVertAttribs.position(MeshObject.POS_DATA_SIZE);
-      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
+      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[1], MeshObject.NOR_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
       mesh.mVertAttribs.position(MeshObject.POS_DATA_SIZE+MeshObject.NOR_DATA_SIZE);
-      GLES30.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES30.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
+      GLES31.glVertexAttribPointer(mMainProgram.mAttribute[2], MeshObject.TEX_DATA_SIZE, GLES31.GL_FLOAT, false, MeshObject.VERTSIZE, mesh.mVertAttribs);
       }
 
     mM.send(surface,halfW,halfH,halfZ,marginInPixels);
     mV.send();
     mF.send();
 
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, mesh.numVertices);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, mesh.numVertices);
 
     if( mesh.mShowNormals ) displayNormals(mesh);
     }
@@ -318,11 +319,11 @@ public class DistortedEffects
     {
     mBlitProgram.useProgram();
 
-    GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
-    GLES30.glUniform1i(mBlitTextureH, 0);
-    GLES30.glUniform1f( mBlitDepthH , 1.0f-surface.mNear);
-    GLES30.glVertexAttribPointer(mBlitProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    GLES31.glUniform1i(mBlitTextureH, 0);
+    GLES31.glUniform1f( mBlitDepthH , 1.0f-surface.mNear);
+    GLES31.glVertexAttribPointer(mBlitProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -331,12 +332,12 @@ public class DistortedEffects
     {
     mBlitDepthProgram.useProgram();
 
-    GLES30.glViewport(0, 0, surface.mWidth, surface.mHeight );
-    GLES30.glUniform1i(mBlitDepthTextureH, 0);
-    GLES30.glUniform1i(mBlitDepthDepthTextureH, 1);
-    GLES30.glUniform1f( mBlitDepthDepthH , 1.0f-surface.mNear);
-    GLES30.glVertexAttribPointer(mBlitDepthProgram.mAttribute[0], 2, GLES30.GL_FLOAT, false, 0, mQuadPositions);
-    GLES30.glDrawArrays(GLES30.GL_TRIANGLE_STRIP, 0, 4);
+    GLES31.glViewport(0, 0, surface.mWidth, surface.mHeight );
+    GLES31.glUniform1i(mBlitDepthTextureH, 0);
+    GLES31.glUniform1i(mBlitDepthDepthTextureH, 1);
+    GLES31.glUniform1f( mBlitDepthDepthH , 1.0f-surface.mNear);
+    GLES31.glVertexAttribPointer(mBlitDepthProgram.mAttribute[0], 2, GLES31.GL_FLOAT, false, 0, mQuadPositions);
+    GLES31.glDrawArrays(GLES31.GL_TRIANGLE_STRIP, 0, 4);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/main/DistortedFramebuffer.java b/src/main/java/org/distorted/library/main/DistortedFramebuffer.java
index 7f4fb32..622aac9 100644
--- a/src/main/java/org/distorted/library/main/DistortedFramebuffer.java
+++ b/src/main/java/org/distorted/library/main/DistortedFramebuffer.java
@@ -19,7 +19,7 @@
 
 package org.distorted.library.main;
 
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
@@ -43,56 +43,56 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
     {
     if( mColorCreated==NOT_CREATED_YET )
       {
-      GLES30.glGenTextures( mNumColors, mColorH, 0);
-      GLES30.glGenFramebuffers(1, mFBOH, 0);
-      GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFBOH[0]);
+      GLES31.glGenTextures( mNumColors, mColorH, 0);
+      GLES31.glGenFramebuffers(1, mFBOH, 0);
+      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
 
       for(int i=0; i<mNumColors; i++)
         {
-        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mColorH[i]);
-        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_REPEAT);
-        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_REPEAT);
-        GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
-        GLES30.glTexParameterf(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);
-        GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA, mWidth, mHeight, 0, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, null);
+        GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[i]);
+        GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_S, GLES31.GL_REPEAT);
+        GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_T, GLES31.GL_REPEAT);
+        GLES31.glTexParameterf(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MIN_FILTER, GLES31.GL_NEAREST);
+        GLES31.glTexParameterf(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MAG_FILTER, GLES31.GL_LINEAR);
+        GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_RGBA, mWidth, mHeight, 0, GLES31.GL_RGBA, GLES31.GL_UNSIGNED_BYTE, null);
         }
-      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, mColorH[0], 0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
-      GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, 0);
+      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[0], 0);
+      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
+      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
 
       mColorCreated = checkStatus("color");
       }
     if( mDepthStencilCreated==NOT_CREATED_YET ) // we need to create a new DEPTH or STENCIL attachment
       {
-      GLES30.glGenTextures(1, mDepthStencilH, 0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mDepthStencilH[0]);
-      GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_REPEAT);
-      GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_REPEAT);
-      GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
-      GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST);
+      GLES31.glGenTextures(1, mDepthStencilH, 0);
+      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mDepthStencilH[0]);
+      GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_S, GLES31.GL_REPEAT);
+      GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_T, GLES31.GL_REPEAT);
+      GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MIN_FILTER, GLES31.GL_NEAREST);
+      GLES31.glTexParameteri(GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MAG_FILTER, GLES31.GL_NEAREST);
 
       if( mDepthStencil==DEPTH_NO_STENCIL )
         {
-        GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_DEPTH_COMPONENT, mWidth, mHeight, 0, GLES30.GL_DEPTH_COMPONENT, GLES30.GL_UNSIGNED_INT, null);
+        GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_DEPTH_COMPONENT, mWidth, mHeight, 0, GLES31.GL_DEPTH_COMPONENT, GLES31.GL_UNSIGNED_INT, null);
         }
       else if( mDepthStencil==BOTH_DEPTH_STENCIL )
         {
-        GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_DEPTH24_STENCIL8, mWidth, mHeight, 0, GLES30.GL_DEPTH_STENCIL, GLES30.GL_UNSIGNED_INT_24_8, null);
+        GLES31.glTexImage2D(GLES31.GL_TEXTURE_2D, 0, GLES31.GL_DEPTH24_STENCIL8, mWidth, mHeight, 0, GLES31.GL_DEPTH_STENCIL, GLES31.GL_UNSIGNED_INT_24_8, null);
         }
 
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
-      GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFBOH[0]);
+      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
+      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
 
       if( mDepthStencil==DEPTH_NO_STENCIL )
         {
-        GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_DEPTH_ATTACHMENT, GLES30.GL_TEXTURE_2D, mDepthStencilH[0], 0);
+        GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_ATTACHMENT, GLES31.GL_TEXTURE_2D, mDepthStencilH[0], 0);
         }
       else if( mDepthStencil==BOTH_DEPTH_STENCIL )
         {
-        GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_DEPTH_STENCIL_ATTACHMENT, GLES30.GL_TEXTURE_2D, mDepthStencilH[0], 0);
+        GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_STENCIL_ATTACHMENT, GLES31.GL_TEXTURE_2D, mDepthStencilH[0], 0);
         }
 
-      GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, 0);
+      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
 
       mDepthStencilCreated = checkStatus("depth");
       }
@@ -101,12 +101,12 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
       // OpenGL ES 3.0.5 spec, chapter 4.4.2.4 :
       // "Note that the texture image is specifically not detached from any other framebuffer objects.
       //  Detaching the texture image from any other framebuffer objects is the responsibility of the application."
-      GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFBOH[0]);
-      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_DEPTH_ATTACHMENT        , GLES30.GL_TEXTURE_2D, 0, 0);
-      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_DEPTH_STENCIL_ATTACHMENT, GLES30.GL_TEXTURE_2D, 0, 0);
-      GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, 0);
+      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
+      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_ATTACHMENT        , GLES31.GL_TEXTURE_2D, 0, 0);
+      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_DEPTH_STENCIL_ATTACHMENT, GLES31.GL_TEXTURE_2D, 0, 0);
+      GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, 0);
 
-      GLES30.glDeleteTextures(1, mDepthStencilH, 0);
+      GLES31.glDeleteTextures(1, mDepthStencilH, 0);
       mDepthStencilH[0]=0;
       }
     }
@@ -115,15 +115,15 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
 
   private int checkStatus(String message)
     {
-    int status = GLES30.glCheckFramebufferStatus(GLES30.GL_FRAMEBUFFER);
+    int status = GLES31.glCheckFramebufferStatus(GLES31.GL_FRAMEBUFFER);
 
-    if(status != GLES30.GL_FRAMEBUFFER_COMPLETE)
+    if(status != GLES31.GL_FRAMEBUFFER_COMPLETE)
       {
       android.util.Log.e("DistortedFramebuffer", "FRAMEBUFFER INCOMPLETE, "+message+" error="+status);
 
-      GLES30.glDeleteTextures(1, mColorH, 0);
-      GLES30.glDeleteTextures(1, mDepthStencilH, 0);
-      GLES30.glDeleteFramebuffers(1, mFBOH, 0);
+      GLES31.glDeleteTextures(1, mColorH, 0);
+      GLES31.glDeleteTextures(1, mDepthStencilH, 0);
+      GLES31.glDeleteFramebuffers(1, mFBOH, 0);
       mFBOH[0]= 0;
 
       return FAILED_TO_CREATE;
@@ -139,19 +139,19 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
     {
     if( mColorH[0]>0 )
       {
-      GLES30.glDeleteTextures(1, mColorH, 0);
+      GLES31.glDeleteTextures(1, mColorH, 0);
       mColorH[0] = 0;
       mColorCreated = NOT_CREATED_YET;
       }
 
     if( mDepthStencilH[0]>0 )
       {
-      GLES30.glDeleteTextures(1, mDepthStencilH, 0);
+      GLES31.glDeleteTextures(1, mDepthStencilH, 0);
       mDepthStencilH[0]=0;
       mDepthStencilCreated = NOT_CREATED_YET;
       }
 
-    GLES30.glDeleteFramebuffers(1, mFBOH, 0);
+    GLES31.glDeleteFramebuffers(1, mFBOH, 0);
     mFBOH[0] = 0;
     }
 
@@ -225,8 +225,8 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
     {
     if( mColorH[0]>0 )
       {
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mColorH[0]);
+      GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
+      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[0]);
       return true;
       }
 
@@ -243,8 +243,8 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
     {
     if( texture>=0 && texture<mNumColors && mColorH[texture]>0 )
       {
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mColorH[texture]);
+      GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
+      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[texture]);
       return true;
       }
 
@@ -257,7 +257,7 @@ public class DistortedFramebuffer extends DistortedOutputSurface implements Dist
     {
     if( texture>=0 && texture<mNumColors && mColorH[texture]>0 )
       {
-      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, mColorH[texture], 0);
+      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mColorH[texture], 0);
       }
     }
 
diff --git a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
index ab60a4f..aeffd88 100644
--- a/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
+++ b/src/main/java/org/distorted/library/main/DistortedOutputSurface.java
@@ -19,7 +19,7 @@
 
 package org.distorted.library.main;
 
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 import android.opengl.Matrix;
 
 import org.distorted.library.effect.EffectQuality;
@@ -128,7 +128,7 @@ public static final int DEBUG_FPS = 1;
 
     mClearDepth = 1.0f;
     mClearStencil = 0;
-    mClear = GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT;
+    mClear = GLES31.GL_DEPTH_BUFFER_BIT | GLES31.GL_COLOR_BUFFER_BIT;
 
     mBuffer = new DistortedOutputSurface[1+EffectQuality.LENGTH];
 
@@ -194,20 +194,20 @@ public static final int DEBUG_FPS = 1;
 
     DistortedObject.toDo(); // create the FBOs immediately. This is safe as we must be holding the OpenGL context now.
 
-    GLES30.glStencilMask(0xff);
-    GLES30.glDepthMask(true);
-    GLES30.glColorMask(true,true,true,true);
-    GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
-    GLES30.glClearDepthf(1.0f);
-    GLES30.glClearStencil(0);
+    GLES31.glStencilMask(0xff);
+    GLES31.glDepthMask(true);
+    GLES31.glColorMask(true,true,true,true);
+    GLES31.glClearColor(0.0f,0.0f,0.0f,0.0f);
+    GLES31.glClearDepthf(1.0f);
+    GLES31.glClearStencil(0);
 
     for(int j=0; j<EffectQuality.LENGTH; j++)
       {
       mBuffer[j].setAsOutput();
-      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, mBuffer[j].mColorH[1], 0);
-      GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT|GLES30.GL_DEPTH_BUFFER_BIT|GLES30.GL_STENCIL_BUFFER_BIT);
-      GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, mBuffer[j].mColorH[0], 0);
-      GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
+      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[1], 0);
+      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT);
+      GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, mBuffer[j].mColorH[0], 0);
+      GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
       }
     }
 
@@ -215,35 +215,35 @@ public static final int DEBUG_FPS = 1;
 
   private int blitWithDepth(long currTime, DistortedOutputSurface buffer)
     {
-    GLES30.glViewport(0, 0, mWidth, mHeight);
+    GLES31.glViewport(0, 0, mWidth, mHeight);
     setAsOutput(currTime);
-    GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mColorH[0]);
-    GLES30.glActiveTexture(GLES30.GL_TEXTURE1);
-    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, buffer.mDepthStencilH[0]);
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mColorH[0]);
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, buffer.mDepthStencilH[0]);
 
-    GLES30.glDisable(GLES30.GL_STENCIL_TEST);
-    GLES30.glStencilMask(0x00);
+    GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+    GLES31.glStencilMask(0x00);
 
     DistortedEffects.blitDepthPriv(this);
-    GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
-    GLES30.glActiveTexture(GLES30.GL_TEXTURE1);
-    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
+    GLES31.glActiveTexture(GLES31.GL_TEXTURE1);
+    GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, 0);
 
     // clear buffers
-    GLES30.glStencilMask(0xff);
-    GLES30.glDepthMask(true);
-    GLES30.glColorMask(true,true,true,true);
-    GLES30.glClearColor(0.0f,0.0f,0.0f,0.0f);
-    GLES30.glClearDepthf(1.0f);
-    GLES30.glClearStencil(0);
+    GLES31.glStencilMask(0xff);
+    GLES31.glDepthMask(true);
+    GLES31.glColorMask(true,true,true,true);
+    GLES31.glClearColor(0.0f,0.0f,0.0f,0.0f);
+    GLES31.glClearDepthf(1.0f);
+    GLES31.glClearStencil(0);
 
     buffer.setAsOutput();
-    GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[1], 0);
-    GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT|GLES30.GL_DEPTH_BUFFER_BIT|GLES30.GL_STENCIL_BUFFER_BIT);
-    GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, buffer.mColorH[0], 0);
-    GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
+    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[1], 0);
+    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT|GLES31.GL_DEPTH_BUFFER_BIT|GLES31.GL_STENCIL_BUFFER_BIT);
+    GLES31.glFramebufferTexture2D(GLES31.GL_FRAMEBUFFER, GLES31.GL_COLOR_ATTACHMENT0, GLES31.GL_TEXTURE_2D, buffer.mColorH[0], 0);
+    GLES31.glClear(GLES31.GL_COLOR_BUFFER_BIT);
 
     return 1;
     }
@@ -410,16 +410,16 @@ public static final int DEBUG_FPS = 1;
  */
   public void setAsOutput(long time)
     {
-    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFBOH[0]);
+    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
 
     if( mTime!=time )
       {
       mTime = time;
       DistortedRenderState.colorDepthStencilOn();
-      GLES30.glClearColor(mClearR, mClearG, mClearB, mClearA);
-      GLES30.glClearDepthf(mClearDepth);
-      GLES30.glClearStencil(mClearStencil);
-      GLES30.glClear(mClear);
+      GLES31.glClearColor(mClearR, mClearG, mClearB, mClearA);
+      GLES31.glClearDepthf(mClearDepth);
+      GLES31.glClearStencil(mClearStencil);
+      GLES31.glClear(mClear);
       DistortedRenderState.colorDepthStencilRestore();
       }
     }
@@ -433,7 +433,7 @@ public static final int DEBUG_FPS = 1;
 
   public void setAsOutput()
     {
-    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, mFBOH[0]);
+    GLES31.glBindFramebuffer(GLES31.GL_FRAMEBUFFER, mFBOH[0]);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -473,7 +473,7 @@ public static final int DEBUG_FPS = 1;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
- * Set the (R,G,B,A) values of GLES30.glClearColor() to set up color with which to clear
+ * Set the (R,G,B,A) values of GLES31.glClearColor() to set up color with which to clear
  * this Surface at the beginning of each frame.
  *
  * @param r the Red component. Default: 0.0f
diff --git a/src/main/java/org/distorted/library/main/DistortedRenderState.java b/src/main/java/org/distorted/library/main/DistortedRenderState.java
index 7709fe1..ae10754 100644
--- a/src/main/java/org/distorted/library/main/DistortedRenderState.java
+++ b/src/main/java/org/distorted/library/main/DistortedRenderState.java
@@ -19,7 +19,7 @@
 
 package org.distorted.library.main;
 
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 /**
@@ -71,20 +71,20 @@ public class DistortedRenderState
 
     mState.depthTest  = 1;
     mState.depthMask  = 1;
-    mState.depthFunc  = GLES30.GL_LEQUAL;
+    mState.depthFunc  = GLES31.GL_LEQUAL;
 
     mState.blend      = 1;
-    mState.blendSrc   = GLES30.GL_SRC_ALPHA;
-    mState.blendDst   = GLES30.GL_ONE_MINUS_SRC_ALPHA;
+    mState.blendSrc   = GLES31.GL_SRC_ALPHA;
+    mState.blendDst   = GLES31.GL_ONE_MINUS_SRC_ALPHA;
 
     mState.stencilTest     = 0;
     mState.stencilMask     = STENCIL_MASK;
-    mState.stencilFuncFunc = GLES30.GL_NEVER;
+    mState.stencilFuncFunc = GLES31.GL_NEVER;
     mState.stencilFuncRef  = 0;
     mState.stencilFuncMask = STENCIL_MASK;
-    mState.stencilOpSfail  = GLES30.GL_KEEP;
-    mState.stencilOpDpfail = GLES30.GL_KEEP;
-    mState.stencilOpDppass = GLES30.GL_KEEP;
+    mState.stencilOpSfail  = GLES31.GL_KEEP;
+    mState.stencilOpDpfail = GLES31.GL_KEEP;
+    mState.stencilOpDppass = GLES31.GL_KEEP;
 
     mClear = 0;
     }
@@ -98,31 +98,31 @@ public class DistortedRenderState
     cState.colorMaskG = 1;
     cState.colorMaskB = 1;
     cState.colorMaskA = 1;
-    GLES30.glColorMask(true,true,true,true);
+    GLES31.glColorMask(true,true,true,true);
 
     cState.depthTest = 1;
     cState.depthMask = 1;
-    cState.depthFunc = GLES30.GL_LEQUAL;
-    GLES30.glEnable(GLES30.GL_DEPTH_TEST);
-    GLES30.glDepthMask(true);
-    GLES30.glDepthFunc(cState.depthFunc);
+    cState.depthFunc = GLES31.GL_LEQUAL;
+    GLES31.glEnable(GLES31.GL_DEPTH_TEST);
+    GLES31.glDepthMask(true);
+    GLES31.glDepthFunc(cState.depthFunc);
 
     cState.stencilTest     = 0;
     cState.stencilMask     = STENCIL_MASK;
-    cState.stencilFuncFunc = GLES30.GL_NEVER;
+    cState.stencilFuncFunc = GLES31.GL_NEVER;
     cState.stencilFuncRef  = 0;
     cState.stencilFuncMask = STENCIL_MASK;
-    cState.stencilOpSfail  = GLES30.GL_KEEP;
-    cState.stencilOpDpfail = GLES30.GL_KEEP;
-    cState.stencilOpDppass = GLES30.GL_KEEP;
-    GLES30.glDisable(GLES30.GL_STENCIL_TEST);
-    GLES30.glStencilMask(cState.stencilMask);
+    cState.stencilOpSfail  = GLES31.GL_KEEP;
+    cState.stencilOpDpfail = GLES31.GL_KEEP;
+    cState.stencilOpDppass = GLES31.GL_KEEP;
+    GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+    GLES31.glStencilMask(cState.stencilMask);
 
     cState.blend      = 1;
-    cState.blendSrc   = GLES30.GL_SRC_ALPHA;
-    cState.blendDst   = GLES30.GL_ONE_MINUS_SRC_ALPHA;
-    GLES30.glEnable(GLES30.GL_BLEND);
-    GLES30.glBlendFunc(cState.blendSrc,cState.blendDst);
+    cState.blendSrc   = GLES31.GL_SRC_ALPHA;
+    cState.blendDst   = GLES31.GL_ONE_MINUS_SRC_ALPHA;
+    GLES31.glEnable(GLES31.GL_BLEND);
+    GLES31.glBlendFunc(cState.blendSrc,cState.blendDst);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -140,7 +140,7 @@ public class DistortedRenderState
       cState.colorMaskG = 1;
       cState.colorMaskB = 1;
       cState.colorMaskA = 1;
-      GLES30.glColorMask(true,true,true,true);
+      GLES31.glColorMask(true,true,true,true);
       }
 
     sState.depthMask = cState.depthMask;
@@ -148,7 +148,7 @@ public class DistortedRenderState
     if( cState.depthMask!=1 )
       {
       cState.depthMask = 1;
-      GLES30.glDepthMask(true);
+      GLES31.glDepthMask(true);
       }
 
     sState.stencilMask = cState.stencilMask;
@@ -156,7 +156,7 @@ public class DistortedRenderState
     if( cState.stencilMask!= STENCIL_MASK )
       {
       cState.stencilMask = STENCIL_MASK;
-      GLES30.glStencilMask(cState.stencilMask);
+      GLES31.glStencilMask(cState.stencilMask);
       }
     }
 
@@ -170,17 +170,17 @@ public class DistortedRenderState
       cState.colorMaskG = sState.colorMaskG;
       cState.colorMaskB = sState.colorMaskB;
       cState.colorMaskA = sState.colorMaskA;
-      GLES30.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
+      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
       }
     if( sState.depthMask!=cState.depthMask )
       {
       cState.depthMask = sState.depthMask;
-      GLES30.glDepthMask(cState.depthMask==1);
+      GLES31.glDepthMask(cState.depthMask==1);
       }
     if( sState.stencilMask!=cState.stencilMask )
       {
       cState.stencilMask = sState.stencilMask;
-      GLES30.glStencilMask(cState.stencilMask);
+      GLES31.glStencilMask(cState.stencilMask);
       }
     }
 
@@ -188,15 +188,15 @@ public class DistortedRenderState
 
   static void switchOffDrawing()
     {
-    GLES30.glEnable(GLES30.GL_SCISSOR_TEST);
-    GLES30.glScissor(0,0,0,0);
+    GLES31.glEnable(GLES31.GL_SCISSOR_TEST);
+    GLES31.glScissor(0,0,0,0);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   static void restoreDrawing()
     {
-    GLES30.glDisable(GLES30.GL_SCISSOR_TEST);
+    GLES31.glDisable(GLES31.GL_SCISSOR_TEST);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -209,33 +209,33 @@ public class DistortedRenderState
       {
       cState.stencilTest = 1;
       //android.util.Log.d("State", "stencil test on");
-      GLES30.glEnable(GLES30.GL_STENCIL_TEST);
+      GLES31.glEnable(GLES31.GL_STENCIL_TEST);
       }
 
     sState.stencilFuncFunc = cState.stencilFuncFunc;
     sState.stencilFuncRef  = cState.stencilFuncRef;
     sState.stencilFuncMask = cState.stencilFuncMask;
 
-    if( cState.stencilFuncFunc!=GLES30.GL_ALWAYS || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
+    if( cState.stencilFuncFunc!=GLES31.GL_ALWAYS || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
       {
-      cState.stencilFuncFunc = GLES30.GL_ALWAYS;
+      cState.stencilFuncFunc = GLES31.GL_ALWAYS;
       cState.stencilFuncRef  = 1;
       cState.stencilFuncMask = STENCIL_MASK;
       //android.util.Log.d("State", "stencil func on");
-      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
+      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
       }
 
     sState.stencilOpSfail = cState.stencilOpSfail;
     sState.stencilOpDpfail= cState.stencilOpDpfail;
     sState.stencilOpDppass= cState.stencilOpDppass;
 
-    if( cState.stencilOpSfail!=GLES30.GL_KEEP || cState.stencilOpDpfail!=GLES30.GL_KEEP || cState.stencilOpDppass!=GLES30.GL_REPLACE )
+    if( cState.stencilOpSfail!=GLES31.GL_KEEP || cState.stencilOpDpfail!=GLES31.GL_KEEP || cState.stencilOpDppass!=GLES31.GL_REPLACE )
       {
-      cState.stencilOpSfail = GLES30.GL_KEEP;
-      cState.stencilOpDpfail= GLES30.GL_KEEP;
-      cState.stencilOpDppass= GLES30.GL_REPLACE;
+      cState.stencilOpSfail = GLES31.GL_KEEP;
+      cState.stencilOpDpfail= GLES31.GL_KEEP;
+      cState.stencilOpDppass= GLES31.GL_REPLACE;
       //android.util.Log.d("State", "stencil op on");
-      GLES30.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
+      GLES31.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
       }
 
     sState.colorMaskR = cState.colorMaskR;
@@ -250,7 +250,7 @@ public class DistortedRenderState
       cState.colorMaskB = 0;
       cState.colorMaskA = 0;
       //android.util.Log.d("State", "switch off color writing");
-      GLES30.glColorMask(false,false,false,false);
+      GLES31.glColorMask(false,false,false,false);
       }
 
     sState.depthMask = cState.depthMask;
@@ -259,7 +259,7 @@ public class DistortedRenderState
       {
       cState.depthMask = 1;
       //android.util.Log.d("State", "switch on depth writing");
-      GLES30.glDepthMask(true);
+      GLES31.glDepthMask(true);
       }
 
     sState.stencilMask = cState.stencilMask;
@@ -268,7 +268,7 @@ public class DistortedRenderState
       {
       cState.stencilMask = STENCIL_MASK;
       //android.util.Log.d("State", "stencil mask on");
-      GLES30.glStencilMask(cState.stencilMask);
+      GLES31.glStencilMask(cState.stencilMask);
       }
     }
 
@@ -282,11 +282,11 @@ public class DistortedRenderState
 
       if (cState.stencilTest == 0)
         {
-        GLES30.glDisable(GLES30.GL_STENCIL_TEST);
+        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
         }
       else
         {
-        GLES30.glEnable(GLES30.GL_STENCIL_TEST);
+        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
         }
       }
     if( sState.colorMaskR!=cState.colorMaskR || sState.colorMaskG!=cState.colorMaskG || sState.colorMaskB!=cState.colorMaskB || sState.colorMaskA!=cState.colorMaskA)
@@ -295,17 +295,17 @@ public class DistortedRenderState
       cState.colorMaskG = sState.colorMaskG;
       cState.colorMaskB = sState.colorMaskB;
       cState.colorMaskA = sState.colorMaskA;
-      GLES30.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
+      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
       }
     if( sState.depthMask!=cState.depthMask )
       {
       cState.depthMask = sState.depthMask;
-      GLES30.glDepthMask(cState.depthMask==1);
+      GLES31.glDepthMask(cState.depthMask==1);
       }
     if( sState.stencilMask!=cState.stencilMask )
       {
       cState.stencilMask = sState.stencilMask;
-      GLES30.glStencilMask(cState.stencilMask);
+      GLES31.glStencilMask(cState.stencilMask);
       }
     }
 
@@ -322,19 +322,19 @@ public class DistortedRenderState
     if( cState.stencilTest!=1 )
       {
       cState.stencilTest = 1;
-      GLES30.glEnable(GLES30.GL_STENCIL_TEST);
+      GLES31.glEnable(GLES31.GL_STENCIL_TEST);
       }
 
     sState.stencilFuncFunc = cState.stencilFuncFunc;
     sState.stencilFuncRef  = cState.stencilFuncRef;
     sState.stencilFuncMask = cState.stencilFuncMask;
 
-    if( cState.stencilFuncFunc!=GLES30.GL_EQUAL || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
+    if( cState.stencilFuncFunc!=GLES31.GL_EQUAL || cState.stencilFuncRef!=1 || cState.stencilFuncMask!=STENCIL_MASK )
       {
-      cState.stencilFuncFunc = GLES30.GL_EQUAL;
+      cState.stencilFuncFunc = GLES31.GL_EQUAL;
       cState.stencilFuncRef  = 1;
       cState.stencilFuncMask = STENCIL_MASK;
-      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
+      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
       }
 
     sState.stencilMask = cState.stencilMask;
@@ -342,7 +342,7 @@ public class DistortedRenderState
     if( cState.stencilMask!= 0x00 )
       {
       cState.stencilMask = 0x00;
-      GLES30.glStencilMask(cState.stencilMask);
+      GLES31.glStencilMask(cState.stencilMask);
       }
 
     sState.depthMask = cState.depthMask;
@@ -350,7 +350,7 @@ public class DistortedRenderState
     if( cState.depthMask!=0 )
       {
       cState.depthMask = 0;
-      GLES30.glDepthMask(false);
+      GLES31.glDepthMask(false);
       }
 
     sState.depthTest = cState.depthTest;
@@ -358,7 +358,7 @@ public class DistortedRenderState
     if( cState.depthTest!=0 )
       {
       cState.depthTest = 0;
-      GLES30.glDisable(GLES30.GL_DEPTH_TEST);
+      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
       }
     }
 
@@ -376,11 +376,11 @@ public class DistortedRenderState
 
       if (cState.stencilTest == 0)
         {
-        GLES30.glDisable(GLES30.GL_STENCIL_TEST);
+        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
         }
       else
         {
-        GLES30.glEnable(GLES30.GL_STENCIL_TEST);
+        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
         }
       }
     if( sState.stencilFuncFunc!=cState.stencilFuncFunc || sState.stencilFuncRef!=cState.stencilFuncRef || sState.stencilFuncMask!=cState.stencilFuncMask )
@@ -388,17 +388,17 @@ public class DistortedRenderState
       cState.stencilFuncFunc = sState.stencilFuncFunc;
       cState.stencilFuncRef  = sState.stencilFuncRef ;
       cState.stencilFuncMask = sState.stencilFuncMask;
-      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
+      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
       }
     if( sState.stencilMask!=cState.stencilMask )
       {
       cState.stencilMask = sState.stencilMask;
-      GLES30.glStencilMask(cState.stencilMask);
+      GLES31.glStencilMask(cState.stencilMask);
       }
     if( sState.depthMask!=cState.depthMask )
       {
       cState.depthMask = sState.depthMask;
-      GLES30.glDepthMask(cState.depthMask==1);
+      GLES31.glDepthMask(cState.depthMask==1);
       }
     if( sState.depthTest!=cState.depthTest )
       {
@@ -406,11 +406,11 @@ public class DistortedRenderState
 
       if (cState.depthTest == 0)
         {
-        GLES30.glDisable(GLES30.GL_DEPTH_TEST);
+        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
         }
       else
         {
-        GLES30.glEnable(GLES30.GL_DEPTH_TEST);
+        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
         }
       }
     }
@@ -430,7 +430,7 @@ public class DistortedRenderState
       cState.colorMaskG = mState.colorMaskG;
       cState.colorMaskB = mState.colorMaskB;
       cState.colorMaskA = mState.colorMaskA;
-      GLES30.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
+      GLES31.glColorMask(cState.colorMaskR==1,cState.colorMaskG==1,cState.colorMaskB==1,cState.colorMaskA==1);
       }
 
     /////////////////////////////////////////////////////
@@ -442,12 +442,12 @@ public class DistortedRenderState
       if (cState.depthTest == 0)
         {
         //android.util.Log.d("State", "disabling depth test");
-        GLES30.glDisable(GLES30.GL_DEPTH_TEST);
+        GLES31.glDisable(GLES31.GL_DEPTH_TEST);
         }
       else
         {
         //android.util.Log.d("State", "enable depth test");
-        GLES30.glEnable(GLES30.GL_DEPTH_TEST);
+        GLES31.glEnable(GLES31.GL_DEPTH_TEST);
         }
       }
 
@@ -457,7 +457,7 @@ public class DistortedRenderState
       {
       //android.util.Log.d("State", "setting depth func");
       cState.depthFunc = mState.depthFunc;
-      GLES30.glDepthFunc(cState.depthFunc);
+      GLES31.glDepthFunc(cState.depthFunc);
       }
 
     /////////////////////////////////////////////////////
@@ -466,7 +466,7 @@ public class DistortedRenderState
       {
       //android.util.Log.d("State", "setting depth mask");
       cState.depthMask = mState.depthMask;
-      GLES30.glDepthMask(cState.depthMask==1);
+      GLES31.glDepthMask(cState.depthMask==1);
       }
 
     /////////////////////////////////////////////////////
@@ -478,12 +478,12 @@ public class DistortedRenderState
       if (cState.blend == 0)
         {
         //android.util.Log.d("State", "disabling blending");
-        GLES30.glDisable(GLES30.GL_BLEND);
+        GLES31.glDisable(GLES31.GL_BLEND);
         }
       else
         {
         //android.util.Log.d("State", "enabling blending");
-        GLES30.glEnable(GLES30.GL_BLEND);
+        GLES31.glEnable(GLES31.GL_BLEND);
         }
       }
 
@@ -494,7 +494,7 @@ public class DistortedRenderState
       //android.util.Log.d("State", "setting blend function");
       cState.blendSrc = mState.blendSrc;
       cState.blendDst = mState.blendDst;
-      GLES30.glBlendFunc(cState.blendSrc,cState.blendDst);
+      GLES31.glBlendFunc(cState.blendSrc,cState.blendDst);
       }
 
     /////////////////////////////////////////////////////
@@ -506,12 +506,12 @@ public class DistortedRenderState
       if (cState.stencilTest == 0)
         {
         //android.util.Log.d("State", "disabling stencil test");
-        GLES30.glDisable(GLES30.GL_STENCIL_TEST);
+        GLES31.glDisable(GLES31.GL_STENCIL_TEST);
         }
       else
         {
         //android.util.Log.d("State", "enabling stencil test");
-        GLES30.glEnable(GLES30.GL_STENCIL_TEST);
+        GLES31.glEnable(GLES31.GL_STENCIL_TEST);
         }
       }
 
@@ -523,7 +523,7 @@ public class DistortedRenderState
       cState.stencilFuncFunc = mState.stencilFuncFunc;
       cState.stencilFuncRef  = mState.stencilFuncRef ;
       cState.stencilFuncMask = mState.stencilFuncMask;
-      GLES30.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
+      GLES31.glStencilFunc(cState.stencilFuncFunc,cState.stencilFuncRef,cState.stencilFuncMask);
       }
 
     /////////////////////////////////////////////////////
@@ -534,7 +534,7 @@ public class DistortedRenderState
       cState.stencilOpSfail = mState.stencilOpSfail;
       cState.stencilOpDpfail= mState.stencilOpDpfail;
       cState.stencilOpDppass= mState.stencilOpDppass;
-      GLES30.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
+      GLES31.glStencilOp(cState.stencilOpSfail,cState.stencilOpDpfail,cState.stencilOpDppass);
       }
 
     /////////////////////////////////////////////////////
@@ -543,7 +543,7 @@ public class DistortedRenderState
       {
       //android.util.Log.d("State", "setting stencil mask");
       cState.stencilMask = mState.stencilMask;
-      GLES30.glStencilMask(cState.stencilMask);
+      GLES31.glStencilMask(cState.stencilMask);
       }
 
     /////////////////////////////////////////////////////
@@ -551,7 +551,7 @@ public class DistortedRenderState
     if( mClear!=0 )
       {
       //android.util.Log.d("State", "clearing buffer");
-      GLES30.glClear(mClear);
+      GLES31.glClear(mClear);
       }
     }
 
@@ -583,18 +583,18 @@ public class DistortedRenderState
 
   void glEnable(int test)
     {
-         if( test==GLES30.GL_DEPTH_TEST   ) mState.depthTest   = 1;
-    else if( test==GLES30.GL_STENCIL_TEST ) mState.stencilTest = 1;
-    else if( test==GLES30.GL_BLEND        ) mState.blend       = 1;
+         if( test==GLES31.GL_DEPTH_TEST   ) mState.depthTest   = 1;
+    else if( test==GLES31.GL_STENCIL_TEST ) mState.stencilTest = 1;
+    else if( test==GLES31.GL_BLEND        ) mState.blend       = 1;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   void glDisable(int test)
     {
-         if( test==GLES30.GL_DEPTH_TEST   ) mState.depthTest   = 0;
-    else if( test==GLES30.GL_STENCIL_TEST ) mState.stencilTest = 0;
-    else if( test==GLES30.GL_BLEND        ) mState.blend       = 0;
+         if( test==GLES31.GL_DEPTH_TEST   ) mState.depthTest   = 0;
+    else if( test==GLES31.GL_STENCIL_TEST ) mState.stencilTest = 0;
+    else if( test==GLES31.GL_BLEND        ) mState.blend       = 0;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/library/main/DistortedScreen.java b/src/main/java/org/distorted/library/main/DistortedScreen.java
index 31ab5fe..741f55d 100644
--- a/src/main/java/org/distorted/library/main/DistortedScreen.java
+++ b/src/main/java/org/distorted/library/main/DistortedScreen.java
@@ -21,14 +21,10 @@ package org.distorted.library.main;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.pm.ConfigurationInfo;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
-import android.opengl.GLES30;
-import android.opengl.GLSurfaceView;
+import android.opengl.GLES31;
 
 import org.distorted.library.effect.MatrixEffectMove;
 import org.distorted.library.type.Static3D;
@@ -123,10 +119,10 @@ public class DistortedScreen extends DistortedOutputSurface
     if (fpsTexture.setAsInput())
       {
       setAsOutput(time);
-      GLES30.glColorMask(true,true,true,true);
-      GLES30.glDepthMask(false);
-      GLES30.glDisable(GLES30.GL_STENCIL_TEST);
-      GLES30.glDisable(GLES30.GL_DEPTH_TEST);
+      GLES31.glColorMask(true,true,true,true);
+      GLES31.glDepthMask(false);
+      GLES31.glDisable(GLES31.GL_STENCIL_TEST);
+      GLES31.glDisable(GLES31.GL_DEPTH_TEST);
       fpsEffects.drawPriv(fpsW/2.0f, fpsH/2.0f, fpsMesh, this, time, 0);
       }
     }
diff --git a/src/main/java/org/distorted/library/main/DistortedTexture.java b/src/main/java/org/distorted/library/main/DistortedTexture.java
index a572d8a..7d52b82 100644
--- a/src/main/java/org/distorted/library/main/DistortedTexture.java
+++ b/src/main/java/org/distorted/library/main/DistortedTexture.java
@@ -23,7 +23,7 @@ import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Paint;
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 import android.opengl.GLUtils;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -64,18 +64,18 @@ public class DistortedTexture extends DistortedSurface implements DistortedInput
       if( mColorCreated==NOT_CREATED_YET )
         {
         mColorCreated = CREATED;
-        GLES30.glGenTextures(1, mColorH, 0);
-        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mColorH[0]);
-        GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR );
-        GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR );
-        GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE );
-        GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE );
-        GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, flipBitmap(mBmp), 0);
+        GLES31.glGenTextures(1, mColorH, 0);
+        GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[0]);
+        GLES31.glTexParameteri ( GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MIN_FILTER, GLES31.GL_LINEAR );
+        GLES31.glTexParameteri ( GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_MAG_FILTER, GLES31.GL_LINEAR );
+        GLES31.glTexParameteri ( GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_S, GLES31.GL_CLAMP_TO_EDGE );
+        GLES31.glTexParameteri ( GLES31.GL_TEXTURE_2D, GLES31.GL_TEXTURE_WRAP_T, GLES31.GL_CLAMP_TO_EDGE );
+        GLUtils.texImage2D(GLES31.GL_TEXTURE_2D, 0, flipBitmap(mBmp), 0);
         }
       else
         {
-        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mColorH[0]);
-        GLUtils.texSubImage2D(GLES30.GL_TEXTURE_2D, 0,0,0,flipBitmap(mBmp));
+        GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[0]);
+        GLUtils.texSubImage2D(GLES31.GL_TEXTURE_2D, 0,0,0,flipBitmap(mBmp));
         }
 
       mBmp = null;
@@ -89,7 +89,7 @@ public class DistortedTexture extends DistortedSurface implements DistortedInput
     {
     if( mColorH[0]>0 )
       {
-      GLES30.glDeleteTextures(1, mColorH, 0);
+      GLES31.glDeleteTextures(1, mColorH, 0);
       mColorH[0] = 0;
       mColorCreated = NOT_CREATED_YET;
       }
@@ -139,8 +139,8 @@ public class DistortedTexture extends DistortedSurface implements DistortedInput
     {
     if( mColorH[0]>0 )
       {
-      GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
-      GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mColorH[0]);
+      GLES31.glActiveTexture(GLES31.GL_TEXTURE0);
+      GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mColorH[0]);
       return true;
       }
 
diff --git a/src/main/java/org/distorted/library/main/EffectQueueFragment.java b/src/main/java/org/distorted/library/main/EffectQueueFragment.java
index 0d3e82c..7e0fbb3 100644
--- a/src/main/java/org/distorted/library/main/EffectQueueFragment.java
+++ b/src/main/java/org/distorted/library/main/EffectQueueFragment.java
@@ -19,7 +19,7 @@
 
 package org.distorted.library.main;
 
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 
 import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.FragmentEffect;
@@ -46,9 +46,9 @@ class EffectQueueFragment extends EffectQueue
 
   static void getUniforms(int mProgramH)
     {
-    mNumEffectsH= GLES30.glGetUniformLocation( mProgramH, "fNumEffects");
-    mNameH      = GLES30.glGetUniformLocation( mProgramH, "fName");
-    mUniformsH  = GLES30.glGetUniformLocation( mProgramH, "fUniforms");
+    mNumEffectsH= GLES31.glGetUniformLocation( mProgramH, "fNumEffects");
+    mNameH      = GLES31.glGetUniformLocation( mProgramH, "fName");
+    mUniformsH  = GLES31.glGetUniformLocation( mProgramH, "fUniforms");
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -87,12 +87,12 @@ class EffectQueueFragment extends EffectQueue
   
   void send()
     {
-    GLES30.glUniform1i( mNumEffectsH, mNumEffects);
+    GLES31.glUniform1i( mNumEffectsH, mNumEffects);
 
     if( mNumEffects>0 )
       {
-      GLES30.glUniform1iv( mNameH    ,                 mNumEffects, mName    ,0);
-      GLES30.glUniform4fv( mUniformsH,(NUM_UNIFORMS/4)*mNumEffects, mUniforms,0);
+      GLES31.glUniform1iv( mNameH    ,                 mNumEffects, mName    ,0);
+      GLES31.glUniform4fv( mUniformsH,(NUM_UNIFORMS/4)*mNumEffects, mUniforms,0);
       }  
     }
   }
diff --git a/src/main/java/org/distorted/library/main/EffectQueueMatrix.java b/src/main/java/org/distorted/library/main/EffectQueueMatrix.java
index 0bf7d4d..22c0dad 100644
--- a/src/main/java/org/distorted/library/main/EffectQueueMatrix.java
+++ b/src/main/java/org/distorted/library/main/EffectQueueMatrix.java
@@ -19,7 +19,7 @@
 
 package org.distorted.library.main;
 
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 import android.opengl.Matrix;
 
 import org.distorted.library.effect.EffectType;
@@ -103,9 +103,9 @@ class EffectQueueMatrix extends EffectQueue
 
   static void getUniforms(int mProgramH)
     {
-    mObjDH     = GLES30.glGetUniformLocation(mProgramH, "u_objD");
-    mMVPMatrixH= GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix");
-    mMVMatrixH = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrix"); 
+    mObjDH     = GLES31.glGetUniformLocation(mProgramH, "u_objD");
+    mMVPMatrixH= GLES31.glGetUniformLocation(mProgramH, "u_MVPMatrix");
+    mMVMatrixH = GLES31.glGetUniformLocation(mProgramH, "u_MVMatrix"); 
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -158,8 +158,8 @@ class EffectQueueMatrix extends EffectQueue
     if( marginInPixels!=0 ) magnify(projection,halfX,halfY,halfZ, marginInPixels);
     Matrix.multiplyMM(mMVPMatrix, 0, projection.mProjectionMatrix, 0, mViewMatrix, 0);
 
-    GLES30.glUniform3f( mObjDH , halfX, halfY, halfZ);
-    GLES30.glUniformMatrix4fv(mMVMatrixH , 1, false, mViewMatrix, 0);
-    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
+    GLES31.glUniform3f( mObjDH , halfX, halfY, halfZ);
+    GLES31.glUniformMatrix4fv(mMVMatrixH , 1, false, mViewMatrix, 0);
+    GLES31.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
     }
   }
diff --git a/src/main/java/org/distorted/library/main/EffectQueueVertex.java b/src/main/java/org/distorted/library/main/EffectQueueVertex.java
index da2ffc0..9909201 100644
--- a/src/main/java/org/distorted/library/main/EffectQueueVertex.java
+++ b/src/main/java/org/distorted/library/main/EffectQueueVertex.java
@@ -19,7 +19,7 @@
 
 package org.distorted.library.main;
 
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 
 import org.distorted.library.effect.EffectType;
 import org.distorted.library.effect.VertexEffect;
@@ -46,9 +46,9 @@ class EffectQueueVertex extends EffectQueue
 
   static void getUniforms(int mProgramH)
     {
-    mNumEffectsH= GLES30.glGetUniformLocation( mProgramH, "vNumEffects");
-    mNameH      = GLES30.glGetUniformLocation( mProgramH, "vName");
-    mUniformsH  = GLES30.glGetUniformLocation( mProgramH, "vUniforms");
+    mNumEffectsH= GLES31.glGetUniformLocation( mProgramH, "vNumEffects");
+    mNameH      = GLES31.glGetUniformLocation( mProgramH, "vName");
+    mUniformsH  = GLES31.glGetUniformLocation( mProgramH, "vUniforms");
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -88,12 +88,12 @@ class EffectQueueVertex extends EffectQueue
 
   void send()
     {
-    GLES30.glUniform1i( mNumEffectsH, mNumEffects);
+    GLES31.glUniform1i( mNumEffectsH, mNumEffects);
       
     if( mNumEffects>0 )
       {
-      GLES30.glUniform1iv( mNameH    ,                 mNumEffects, mName    ,0);
-      GLES30.glUniform4fv( mUniformsH,(NUM_UNIFORMS/4)*mNumEffects, mUniforms,0);
+      GLES31.glUniform1iv( mNameH    ,                 mNumEffects, mName    ,0);
+      GLES31.glUniform4fv( mUniformsH,(NUM_UNIFORMS/4)*mNumEffects, mUniforms,0);
       }
     }
   }
diff --git a/src/main/java/org/distorted/library/main/MeshObject.java b/src/main/java/org/distorted/library/main/MeshObject.java
index dfe7106..f7db6a0 100644
--- a/src/main/java/org/distorted/library/main/MeshObject.java
+++ b/src/main/java/org/distorted/library/main/MeshObject.java
@@ -19,7 +19,7 @@
 
 package org.distorted.library.main;
 
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 
 import java.nio.FloatBuffer;
 
@@ -77,17 +77,17 @@ public abstract class MeshObject extends DistortedObject
      {
      if( mAttVBO[0]<0 )
        {
-       GLES30.glGenBuffers(1, mAttVBO, 0);
-       GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mAttVBO[0]);
-       GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, numVertices*VERTSIZE, mVertAttribs, GLES30.GL_STATIC_READ);
-       GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
+       GLES31.glGenBuffers(1, mAttVBO, 0);
+       GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, mAttVBO[0]);
+       GLES31.glBufferData(GLES31.GL_ARRAY_BUFFER, numVertices*VERTSIZE, mVertAttribs, GLES31.GL_STATIC_READ);
+       GLES31.glBindBuffer(GLES31.GL_ARRAY_BUFFER, 0);
        }
      if( mAttTFO[0]<0 && Distorted.GLSL >= 300 )
        {
-       GLES30.glGenBuffers(1, mAttTFO, 0);
-       GLES30.glBindBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, mAttTFO[0]);
-       GLES30.glBufferData(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, numVertices*TFSIZE, null, GLES30.GL_STATIC_READ);
-       GLES30.glBindBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0);
+       GLES31.glGenBuffers(1, mAttTFO, 0);
+       GLES31.glBindBuffer(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, mAttTFO[0]);
+       GLES31.glBufferData(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, numVertices*TFSIZE, null, GLES31.GL_STATIC_READ);
+       GLES31.glBindBuffer(GLES31.GL_TRANSFORM_FEEDBACK_BUFFER, 0);
        }
      }
 
@@ -98,12 +98,12 @@ public abstract class MeshObject extends DistortedObject
      {
      if( mAttVBO[0]>=0 )
        {
-       GLES30.glDeleteBuffers(1, mAttVBO, 0);
+       GLES31.glDeleteBuffers(1, mAttVBO, 0);
        mAttVBO[0] = -1;
        }
      if( mAttTFO[0]>=0 )
        {
-       GLES30.glDeleteBuffers(1, mAttTFO, 0);
+       GLES31.glDeleteBuffers(1, mAttTFO, 0);
        mAttTFO[0] = -1;
        }
      }
diff --git a/src/main/java/org/distorted/library/program/DistortedProgram.java b/src/main/java/org/distorted/library/program/DistortedProgram.java
index d4d655e..505f808 100644
--- a/src/main/java/org/distorted/library/program/DistortedProgram.java
+++ b/src/main/java/org/distorted/library/program/DistortedProgram.java
@@ -19,7 +19,7 @@
 
 package org.distorted.library.program;
 
-import android.opengl.GLES30;
+import android.opengl.GLES31;
 
 import java.io.BufferedReader;
 import java.io.IOException;
@@ -54,16 +54,16 @@ public class DistortedProgram
   private int createAndLinkProgram(final int vertexShaderHandle, final int fragmentShaderHandle, final String[] attributes, final String[] feedbackVaryings)
   throws LinkingException
     {
-    int programHandle = GLES30.glCreateProgram();
+    int programHandle = GLES31.glCreateProgram();
 
     if (programHandle != 0)
       {
-      GLES30.glAttachShader(programHandle, vertexShaderHandle);
-      GLES30.glAttachShader(programHandle, fragmentShaderHandle);
+      GLES31.glAttachShader(programHandle, vertexShaderHandle);
+      GLES31.glAttachShader(programHandle, fragmentShaderHandle);
 
       if( feedbackVaryings!=null )
         {
-        GLES30.glTransformFeedbackVaryings(programHandle, feedbackVaryings, GLES30.GL_INTERLEAVED_ATTRIBS);
+        GLES31.glTransformFeedbackVaryings(programHandle, feedbackVaryings, GLES31.GL_INTERLEAVED_ATTRIBS);
         }
 
       if (attributes != null)
@@ -72,24 +72,24 @@ public class DistortedProgram
 
         for (int i = 0; i < size; i++)
           {
-          GLES30.glBindAttribLocation(programHandle, i, attributes[i]);
+          GLES31.glBindAttribLocation(programHandle, i, attributes[i]);
           }
         }
 
-      GLES30.glLinkProgram(programHandle);
+      GLES31.glLinkProgram(programHandle);
 
       final int[] linkStatus = new int[1];
-      GLES30.glGetProgramiv(programHandle, GLES30.GL_LINK_STATUS, linkStatus, 0);
+      GLES31.glGetProgramiv(programHandle, GLES31.GL_LINK_STATUS, linkStatus, 0);
 
-      if (linkStatus[0] != GLES30.GL_TRUE )
+      if (linkStatus[0] != GLES31.GL_TRUE )
         {
-        String error = GLES30.glGetProgramInfoLog(programHandle);
-        GLES30.glDeleteProgram(programHandle);
+        String error = GLES31.glGetProgramInfoLog(programHandle);
+        GLES31.glDeleteProgram(programHandle);
         throw new LinkingException(error);
         }
 
       final int[] numberOfUniforms = new int[1];
-      GLES30.glGetProgramiv(programHandle, GLES30.GL_ACTIVE_UNIFORMS, numberOfUniforms, 0);
+      GLES31.glGetProgramiv(programHandle, GLES31.GL_ACTIVE_UNIFORMS, numberOfUniforms, 0);
 
       //android.util.Log.d("program", "number of active uniforms="+numberOfUniforms[0]);
       }
@@ -283,32 +283,32 @@ public class DistortedProgram
   private static int compileShader(final int shaderType, final String shaderSource)
   throws FragmentCompilationException,VertexCompilationException
     {
-    int shaderHandle = GLES30.glCreateShader(shaderType);
+    int shaderHandle = GLES31.glCreateShader(shaderType);
 
     if (shaderHandle != 0)
       {
-      GLES30.glShaderSource(shaderHandle, shaderSource);
-      GLES30.glCompileShader(shaderHandle);
+      GLES31.glShaderSource(shaderHandle, shaderSource);
+      GLES31.glCompileShader(shaderHandle);
       final int[] compileStatus = new int[1];
-      GLES30.glGetShaderiv(shaderHandle, GLES30.GL_COMPILE_STATUS, compileStatus, 0);
+      GLES31.glGetShaderiv(shaderHandle, GLES31.GL_COMPILE_STATUS, compileStatus, 0);
 
-      if (compileStatus[0] != GLES30.GL_TRUE )
+      if (compileStatus[0] != GLES31.GL_TRUE )
         {
-        GLES30.glDeleteShader(shaderHandle);
+        GLES31.glDeleteShader(shaderHandle);
         shaderHandle = 0;
         }
       }
 
     if (shaderHandle == 0)
       {
-      String error = GLES30.glGetShaderInfoLog(shaderHandle);
+      String error = GLES31.glGetShaderInfoLog(shaderHandle);
 
       //android.util.Log.e("Program", "error compiling :"+error);
 
       switch(shaderType)
         {
-        case GLES30.GL_VERTEX_SHADER  : throw new VertexCompilationException(error);
-        case GLES30.GL_FRAGMENT_SHADER: throw new FragmentCompilationException(error);
+        case GLES31.GL_VERTEX_SHADER  : throw new VertexCompilationException(error);
+        case GLES31.GL_FRAGMENT_SHADER: throw new FragmentCompilationException(error);
         default                       : throw new RuntimeException(error);
         }
       }
@@ -360,8 +360,8 @@ android.util.Log.d("Program", end.substring(0,40));
     final String vertexShader   = readTextFileFromRawResource(vertex  , true );
     final String fragmentShader = readTextFileFromRawResource(fragment, false);
 
-    final int vertexShaderHandle   = compileShader(GLES30.GL_VERTEX_SHADER  , vertexHeader   + vertexShader  );
-    final int fragmentShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragmentHeader + fragmentShader);
+    final int vertexShaderHandle   = compileShader(GLES31.GL_VERTEX_SHADER  , vertexHeader   + vertexShader  );
+    final int fragmentShaderHandle = compileShader(GLES31.GL_FRAGMENT_SHADER, fragmentHeader + fragmentShader);
 
     mProgramHandle = createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle, mAttributeName, glslVersion>= 300 ? feedback:null );
 
@@ -369,7 +369,7 @@ android.util.Log.d("Program", end.substring(0,40));
 
     for(int i=0; i<mNumAttributes; i++)
       {
-      mAttribute[i] = GLES30.glGetAttribLocation( mProgramHandle, mAttributeName[i]);
+      mAttribute[i] = GLES31.glGetAttribLocation( mProgramHandle, mAttributeName[i]);
       }
 
     if( mNumUniforms>0 )
@@ -379,7 +379,7 @@ android.util.Log.d("Program", end.substring(0,40));
 
       for(int i=0; i<mNumUniforms; i++)
         {
-        mUniform[i] = GLES30.glGetUniformLocation( mProgramHandle, mUniformName[i]);
+        mUniform[i] = GLES31.glGetUniformLocation( mProgramHandle, mUniformName[i]);
         }
       }
     else mUniform = null;
@@ -403,8 +403,8 @@ android.util.Log.d("Program", end.substring(0,40));
     vertexShader   = insertEnabledEffects(vertexShader  ,enabledVertex  );
     fragmentShader = insertEnabledEffects(fragmentShader,enabledFragment);
 
-    final int vertexShaderHandle   = compileShader(GLES30.GL_VERTEX_SHADER  , vertexHeader   + vertexShader  );
-    final int fragmentShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragmentHeader + fragmentShader);
+    final int vertexShaderHandle   = compileShader(GLES31.GL_VERTEX_SHADER  , vertexHeader   + vertexShader  );
+    final int fragmentShaderHandle = compileShader(GLES31.GL_FRAGMENT_SHADER, fragmentHeader + fragmentShader);
 
     mProgramHandle = createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle, mAttributeName, glslVersion>= 300 ? feedback:null );
 
@@ -412,7 +412,7 @@ android.util.Log.d("Program", end.substring(0,40));
 
     for(int i=0; i<mNumAttributes; i++)
       {
-      mAttribute[i] = GLES30.glGetAttribLocation( mProgramHandle, mAttributeName[i]);
+      mAttribute[i] = GLES31.glGetAttribLocation( mProgramHandle, mAttributeName[i]);
       }
 
     if( mNumUniforms>0 )
@@ -422,7 +422,7 @@ android.util.Log.d("Program", end.substring(0,40));
 
       for(int i=0; i<mNumUniforms; i++)
         {
-        mUniform[i] = GLES30.glGetUniformLocation( mProgramHandle, mUniformName[i]);
+        mUniform[i] = GLES31.glGetUniformLocation( mProgramHandle, mUniformName[i]);
         }
       }
     else mUniform = null;
@@ -465,8 +465,8 @@ android.util.Log.d("Program", end.substring(0,40));
     doAttributes(vertex  , true );
     doAttributes(fragment, false);
 
-    final int vertexShaderHandle   = compileShader(GLES30.GL_VERTEX_SHADER  , vertex  );
-    final int fragmentShaderHandle = compileShader(GLES30.GL_FRAGMENT_SHADER, fragment);
+    final int vertexShaderHandle   = compileShader(GLES31.GL_VERTEX_SHADER  , vertex  );
+    final int fragmentShaderHandle = compileShader(GLES31.GL_FRAGMENT_SHADER, fragment);
 
     mProgramHandle = createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle, mAttributeName, null );
 
@@ -474,7 +474,7 @@ android.util.Log.d("Program", end.substring(0,40));
 
     for(int i=0; i<mNumAttributes; i++)
       {
-      mAttribute[i] = GLES30.glGetAttribLocation( mProgramHandle, mAttributeName[i]);
+      mAttribute[i] = GLES31.glGetAttribLocation( mProgramHandle, mAttributeName[i]);
       }
 
     if( mNumUniforms>0 )
@@ -484,7 +484,7 @@ android.util.Log.d("Program", end.substring(0,40));
 
       for(int i=0; i<mNumUniforms; i++)
         {
-        mUniform[i] = GLES30.glGetUniformLocation( mProgramHandle, mUniformName[i]);
+        mUniform[i] = GLES31.glGetUniformLocation( mProgramHandle, mUniformName[i]);
         }
       }
     else mUniform = null;
@@ -507,10 +507,10 @@ android.util.Log.d("Program", end.substring(0,40));
  */
   public void useProgram()
     {
-    GLES30.glUseProgram(mProgramHandle);
+    GLES31.glUseProgram(mProgramHandle);
 
     for(int i=0; i<mNumAttributes; i++)
-      GLES30.glEnableVertexAttribArray(mAttribute[i]);
+      GLES31.glEnableVertexAttribArray(mAttribute[i]);
     }
   }
 
