title: OpenGL ES 2.0 GLSL Barrel Distortion Shader not working
body: <p>i took the code from the OpenGL ES 2.0 Tutorial from  : github.com/learnopengles/Learn-OpenGLES-Tutorials</p>
  
  <p>and customized the class "LessonOneRenderer" to test a barrel distortin Shader like mentioned on this site: </p>
  
  <p>www.geeks3d.com/20140213/glsl-shader-library-fish-eye-and-dome-and-barrel-distortion-post-processing-filters/2/</p>
  
  <p>This is the "untouched" Result without calling the distort() function:</p>
  
  <p><a href="http://fs1.directupload.net/images/150125/hw746rcn.png" rel="nofollow">http://fs1.directupload.net/images/150125/hw746rcn.png</a></p>
  
  <p>and the result calling the function : </p>
  
  <p><a href="http://fs2.directupload.net/images/150125/f84arxoj.png" rel="nofollow">http://fs2.directupload.net/images/150125/f84arxoj.png</a></p>
  
  <pre><code>/**
   * This class implements our custom renderer. Note that the GL10 parameter passed in is unused for OpenGL ES 2.0
   * renderers -- the static class GLES20 is used instead.
   */
  public class LessonOneRenderer implements GLSurfaceView.Renderer 
  {
      /**
       * Store the model matrix. This matrix is used to move models from object space (where each model can be thought
       * of being located at the center of the universe) to world space.
       */
      private float[] mModelMatrix = new float[16];
  
      /**
       * Store the view matrix. This can be thought of as our camera. This matrix transforms world space to eye space;
       * it positions things relative to our eye.
       */
      private float[] mViewMatrix = new float[16];
  
      /** Store the projection matrix. This is used to project the scene onto a 2D viewport. */
      private float[] mProjectionMatrix = new float[16];
  
      /** Allocate storage for the final combined matrix. This will be passed into the shader program. */
      private float[] mMVPMatrix = new float[16];
  
      /** Store our model data in a float buffer. */
      private final FloatBuffer mTriangle1Vertices;
  
  
      /** This will be used to pass in the transformation matrix. */
      private int mMVPMatrixHandle;
  
      /** This will be used to pass in model position information. */
      private int mPositionHandle;
  
      /** This will be used to pass in model color information. */
      private int mColorHandle;
  
      /** How many bytes per float. */
      private final int mBytesPerFloat = 4;
  
      /** How many elements per vertex. */
      private final int mStrideBytes = 7 * mBytesPerFloat;    
  
      /** Offset of the position data. */
      private final int mPositionOffset = 0;
  
      /** Size of the position data in elements. */
      private final int mPositionDataSize = 3;
  
      /** Offset of the color data. */
      private final int mColorOffset = 3;
  
      /** Size of the color data in elements. */
      private final int mColorDataSize = 4;       
  
  
  
  
  
      private FloatBuffer vertexBuffer;
      private ShortBuffer drawListBuffer;
  
      // number of coordinates per vertex in this array
      static final int COORDS_PER_VERTEX = 3;
                                  //   X      Y     Z 
      static float squareCoords[] = { -0.5f,  0.5f, 0.0f,   // top left
                                      -0.5f, -0.5f, 0.0f,   // bottom left
                                       0.5f, -0.5f, 0.0f,   // bottom right
                                       0.5f,  0.5f, 0.0f }; // top right
  
      private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
      float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
  
  
      static final int vertexStride = COORDS_PER_VERTEX * 4;
      static final int vertexCount = 4;
      private ByteBuffer dlb;
  
      /**
       * Initialize the model data.
       */
      public LessonOneRenderer()
      {   
  
  
           ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4); // (# of coordinate values * 4 bytes per float)
              bb.order(ByteOrder.nativeOrder());
              vertexBuffer = bb.asFloatBuffer();
              vertexBuffer.put(squareCoords);
              vertexBuffer.position(0);
  
              // initialize byte buffer for the draw list
              ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2); // (# of coordinate values * 2 bytes per short)
              dlb.order(ByteOrder.nativeOrder());
              drawListBuffer = dlb.asShortBuffer();
              drawListBuffer.put(drawOrder);
              drawListBuffer.position(0);
  
  
  
          // Define points for equilateral triangles.
  
          // This triangle is red, green, and blue.
          final float[] triangle1VerticesData = {
                  // X, Y, Z, 
                  // R, G, B, A
                  -0.5f,  0.5f, 0.0f,  // top left
                  1.0f, 0.0f, 0.0f, 1.0f,
  
                  -0.5f, -0.5f, 0.0f,// bottom left
                  0.0f, 0.0f, 1.0f, 1.0f,
  
                  0.5f, -0.5f, 0.0f, // bottom right
                  0.0f, 1.0f, 0.0f, 1.0f
                  ,
                  0.5f,  0.5f, 0.0f, // top right
                  0.0f, 1.0f, 0.0f, 1.0f
  
          };
  
  
          // Initialize the buffers.
          mTriangle1Vertices = ByteBuffer.allocateDirect(triangle1VerticesData.length * mBytesPerFloat)
          .order(ByteOrder.nativeOrder()).asFloatBuffer();    
          mTriangle1Vertices.put(triangle1VerticesData).position(0);
  
            // initialize byte buffer for the draw list
          dlb = ByteBuffer.allocateDirect(drawOrder.length * 2); // (# of coordinate values * 2 bytes per short)
          dlb.order(ByteOrder.nativeOrder());
          drawListBuffer = dlb.asShortBuffer();
          drawListBuffer.put(drawOrder);
          drawListBuffer.position(0);
  
  
      }
  
      @Override
      public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
      {
          // Set the background clear color to gray.
          GLES20.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
  
          // Position the eye behind the origin.
          final float eyeX = 0.0f;
          final float eyeY = 0.0f;
          final float eyeZ = 1.5f;
  
          // We are looking toward the distance
          final float lookX = 0.0f;
          final float lookY = 0.0f;
          final float lookZ = -5.0f;
  
          // Set our up vector. This is where our head would be pointing were we holding the camera.
          final float upX = 0.0f;
          final float upY = 1.0f;
          final float upZ = 0.0f;
  
          // Set the view matrix. This matrix can be said to represent the camera position.
          // NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination of a model and
          // view matrix. In OpenGL 2, we can keep track of these matrices separately if we choose.
          Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);
  
  
  
  
          final String vertexShader =
              "uniform mat4 u_MVPMatrix;      \n"     // A constant representing the combined model/view/projection matrix.
  
            + "attribute vec4 a_Position;     \n"     // Per-vertex position information we will pass in.
            + "attribute vec4 a_Color;        \n"     // Per-vertex color information we will pass in.              
            + "varying vec4 a_Pos;            \n"
            + "varying vec4 v_Color;          \n"     // This will be passed into the fragment shader.
            +" "
            +"vec4 Distort(vec4 p){                   \n"
            +"    float BarrelPower = 0.4;            \n"
            +"    vec2 v = p.xy / p.w;                \n"
            +"    float radius = length(v);           \n"
            +"    if (radius &gt; 0.0){                  \n"
            +"        float theta = atan(v.y,v.x);    \n"
            +"        radius = pow(radius, BarrelPower);\n"
            +"        v.x = radius * cos(theta);      \n"
            +"        v.y = radius * sin(theta);      \n"
            +"        p.xy = v.xy * p.w;              \n"
            +" }"
            +"                                        \n"
            +" return p;                              \n"
            +" }                                      \n"
            + "void main()                    \n"     // The entry point for our vertex shader.
            + "{                              \n"
            + "   v_Color = a_Color;          \n"     // Pass the color through to the fragment shader. 
            + "   vec4 P = u_MVPMatrix * a_Position;"                             // It will be interpolated across the triangle.
            + "   gl_Position = Distort(P);   \n"     // gl_Position is a special variable used to store the final position.
            + "                  \n"     // Multiply the vertex by the matrix to get the final point in                                                                    
            + "}                              \n";    // normalized screen coordinates.
  
          final String fragmentShader =
                      // Set the default precision to medium. We don't need as high of a 
             "varying vec4 a_Pos;"                                // precision in the fragment shader.                
            + "varying vec4 v_Color;          \n"     // This is the color from the vertex shader interpolated across the 
                                                      // triangle per fragment.             
            + "void main()                    \n"     // The entry point for our fragment shader.
            + "{   vec4 c = vec4(1.0);                           \n"
            + "   gl_FragColor = v_Color;    \n"      // Pass the color directly through the pipeline.          
            + "}                              \n";                                                
  
          // Load in the vertex shader.
          int vertexShaderHandle = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
  
          if (vertexShaderHandle != 0) 
          {
              // Pass in the shader source.
              GLES20.glShaderSource(vertexShaderHandle, vertexShader);
  
              // Compile the shader.
              GLES20.glCompileShader(vertexShaderHandle);
  
              // Get the compilation status.
              final int[] compileStatus = new int[1];
              GLES20.glGetShaderiv(vertexShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
  
              // If the compilation failed, delete the shader.
              if (compileStatus[0] == 0) 
              {               
                  GLES20.glDeleteShader(vertexShaderHandle);
                  vertexShaderHandle = 0;
              }
          }
  
          if (vertexShaderHandle == 0)
          {
              throw new RuntimeException("Error creating vertex shader.");
          }
  
          // Load in the fragment shader shader.
          int fragmentShaderHandle = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
  
          if (fragmentShaderHandle != 0) 
          {
              // Pass in the shader source.
              GLES20.glShaderSource(fragmentShaderHandle, fragmentShader);
  
              // Compile the shader.
              GLES20.glCompileShader(fragmentShaderHandle);
  
              // Get the compilation status.
              final int[] compileStatus = new int[1];
              GLES20.glGetShaderiv(fragmentShaderHandle, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
  
              // If the compilation failed, delete the shader.
              if (compileStatus[0] == 0) 
              {               
                  GLES20.glDeleteShader(fragmentShaderHandle);
                  fragmentShaderHandle = 0;
              }
          }
  
          if (fragmentShaderHandle == 0)
          {
              throw new RuntimeException("Error creating fragment shader.");
          }
  
          // Create a program object and store the handle to it.
          int programHandle = GLES20.glCreateProgram();
  
          if (programHandle != 0) 
          {
              // Bind the vertex shader to the program.
              GLES20.glAttachShader(programHandle, vertexShaderHandle);           
  
              // Bind the fragment shader to the program.
              GLES20.glAttachShader(programHandle, fragmentShaderHandle);
  
              // Bind attributes
              GLES20.glBindAttribLocation(programHandle, 0, "a_Position");
              GLES20.glBindAttribLocation(programHandle, 1, "a_Color");
  
              // Link the two shaders together into a program.
              GLES20.glLinkProgram(programHandle);
  
              // Get the link status.
              final int[] linkStatus = new int[1];
              GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);
  
              // If the link failed, delete the program.
              if (linkStatus[0] == 0) 
              {               
                  GLES20.glDeleteProgram(programHandle);
                  programHandle = 0;
              }
          }
  
          if (programHandle == 0)
          {
              throw new RuntimeException("Error creating program.");
          }
  
          // Set program handles. These will later be used to pass in values to the program.
          mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandle, "u_MVPMatrix");        
          mPositionHandle = GLES20.glGetAttribLocation(programHandle, "a_Position");
          mColorHandle = GLES20.glGetAttribLocation(programHandle, "a_Color");        
  
          // Tell OpenGL to use this program when rendering.
          GLES20.glUseProgram(programHandle);        
      }   
  
      @Override
      public void onSurfaceChanged(GL10 glUnused, int width, int height) 
      {
          // Set the OpenGL viewport to the same size as the surface.
          GLES20.glViewport(0, 0, width, height);
  
          // Create a new perspective projection matrix. The height will stay the same
          // while the width will vary as per aspect ratio.
          final float ratio = (float) width / height;
          final float left = -ratio;
          final float right = ratio;
          final float bottom = -1.0f;
          final float top = 1.0f;
          final float near = 1.0f;
          final float far = 10.0f;
  
          Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);
      }   
  
      @Override
      public void onDrawFrame(GL10 glUnused) 
      {
          GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);                    
  
          // Do a complete rotation every 10 seconds.
          long time = SystemClock.uptimeMillis() % 10000L;
          float angleInDegrees = (360.0f / 10000.0f) * ((int) time);
  
          // Draw the triangle facing straight on.
          //Matrix.setIdentityM(mModelMatrix, 0);
          //Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);        
          //drawTriangle(mTriangle1Vertices);
  
  
          //Draw Square
          Matrix.setIdentityM(mModelMatrix, 0);
          Matrix.translateM(mModelMatrix, 0, 0.0f, -0.7f, 0.0f);
  
          //Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);        
          this.drawSquare(mTriangle1Vertices);
  
  
          //Draw Square
          Matrix.setIdentityM(mModelMatrix, 0);
          Matrix.translateM(mModelMatrix, 0, 0.0f, 0.7f, 0.0f);
  
          //Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);        
          this.drawSquare(mTriangle1Vertices);
  
  
          // Draw one translated a bit down and rotated to be flat on the ground.
          //Matrix.setIdentityM(mModelMatrix, 0);
          //Matrix.translateM(mModelMatrix, 0, 0.0f, -1.0f, 0.0f);
          //Matrix.rotateM(mModelMatrix, 0, 90.0f, 1.0f, 0.0f, 0.0f);
          //Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);        
          //drawTriangle(mTriangle2Vertices);
  
          // Draw one translated a bit to the right and rotated to be facing to the left.
          //Matrix.setIdentityM(mModelMatrix, 0);
          //Matrix.translateM(mModelMatrix, 0, 1.0f, 0.0f, 0.0f);
          //Matrix.rotateM(mModelMatrix, 0, 90.0f, 0.0f, 1.0f, 0.0f);
          //Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
          //drawTriangle(mTriangle3Vertices);
  
  
  //        test.draw();
      }   
  
      /**
       * Draws a triangle from the given vertex data.
       * 
       * @param aTriangleBuffer The buffer containing the vertex data.
       */
      private void drawTriangle(final FloatBuffer aTriangleBuffer)
      {       
          // Pass in the position information
          aTriangleBuffer.position(mPositionOffset);
          GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
                  mStrideBytes, aTriangleBuffer);        
  
          GLES20.glEnableVertexAttribArray(mPositionHandle);        
  
          // Pass in the color information
          aTriangleBuffer.position(mColorOffset);
          GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false,
                  mStrideBytes, aTriangleBuffer);        
  
          GLES20.glEnableVertexAttribArray(mColorHandle);
  
          // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
          // (which currently contains model * view).
          Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
  
          // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
          // (which now contains model * view * projection).
          Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
  
          GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
          GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);                               
      }
  
      private void drawSquare(final FloatBuffer aTriangleBuffer)
      {       
          // Pass in the position information
          aTriangleBuffer.position(mPositionOffset);
          GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false,
                  mStrideBytes, aTriangleBuffer);        
  
          GLES20.glEnableVertexAttribArray(mPositionHandle);        
  
          // Pass in the color information
          aTriangleBuffer.position(mColorOffset);
          GLES20.glVertexAttribPointer(mColorHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false,
                  vertexStride, aTriangleBuffer);        
  
          GLES20.glEnableVertexAttribArray(mColorHandle);
  
          // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
          // (which currently contains model * view).
          Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
  
          // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
          // (which now contains model * view * projection).
          Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
  
          GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
          GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);                               
      }
  
  
  }
  </code></pre>
  
  <p>Does anybody have an idea what i'm missing to distort the squares like in the example?</p>