title: Unable to get texture to render to quad in OpenGL ES 2.0 running on Android
body: <p>When I launch the project I get an ominously black quad rendered inside an expectedly cyan background. I have determined that the texture coordinates are being interpolated properly with the commented out line of code in the fragment shader. I have tried a number of different ways of loading a texture and have always got the same result.  The temporary bit of code that loads the 4 pixel texture is copied verbatim out of an example from a book. However I have included this as well just in case I have made an oversight.</p>
  
  <p>I have attempted to remove impertinent code.  But, I'm still quite new to this and continually learning the full meaning of much of the code.  Additionally, much of the code has been adapted from different sources.  So, I apologize for the messiness, inconsistent variable naming, and verbosity.  I do feel like the issue is in the first several lines.  Thanks in advance for all insight. Even any information on how I could go about debugging this would be appreciated; I feel quite in the dark when issues come up when working on this project. </p>
  
  <p>Draw Frame:</p>
  
  <pre><code>public void onDrawFrame(GL10 gl) 
  {
  
      GLES20.glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
  
      GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);                    
      update();
  
      GLES20.glUseProgram(mProgramHandle);
      GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureHandle);
      GLES20.glUniform1i(mTextureUniformHandle, 0);
  
      //For some reason I think the problem is in this area
  
      Matrix.setIdentityM(mModelMatrix, 0);
  
      quadVerts.position(mPositionOffset);
      GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, mStrideBytes, quadVerts);        
      GLES20.glEnableVertexAttribArray(mPositionHandle);
  
      quadVerts.position(mColorOffset);
      GLES20.glVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false, mStrideBytes, quadVerts);        
      GLES20.glEnableVertexAttribArray(mColorHandle);
  
      GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 0, quadTex);        
      GLES20.glEnableVertexAttribArray(2);
  
  
      Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
  
      Matrix.multiplyMM(mMVPMatrix, 0, mOrthographicMatrix, 0, mMVPMatrix, 0);
  
      GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
      GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 4);         
  
      //...    
      checkGlError("on draw frame: ");
  }
  </code></pre>
  
  <p>Surface Changed:</p>
  
  <pre><code>        public void onSurfaceChanged(GL10 glUnused, int width, int height) 
  {
      GLES20.glViewport(0, 0, width, height);
      w = width;
      h = height;
      final float near = 1.0f;
      final float far = 10.0f;
      Matrix.orthoM(mOrthographicMatrix, 0, 0, width, 0, height, near, far);
      float[] pVertsData =
          {
              20.0f, 20.0f, 0.0f, 
              1.0f, 1.0f, 1.0f, 1.0f,
  
              (float) width- 20.0f, 20.0f, 0.0f, 
              1.0f, 1.0f, 1.0f, 1.0f,
  
              (float) width - 20.0f, (float) height - 20.0f, 0.0f, 
              1.0f, 1.0f, 1.0f, 1.0f,
  
              20.0f, (float) height - 20.0f, 0.0f,
              1.0f, 1.0f, 1.0f, 1.0f
          };
  
      quadVerts = ByteBuffer.allocateDirect(pVertsData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
  
      quadVerts.put(pVertsData).position(0);
  
      float texture[] = 
          {
              0.0f, 0.0f,
              1.0f, 0.0f,
              1.0f, 1.0f,
              0.0f, 1.0f
          };
      quadTex = ByteBuffer.allocateDirect(texture.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
      quadTex.put(texture).position(0);
  
  checkGlError("surface changed: ");
  }
  </code></pre>
  
  <p>Surface Created:</p>
  
  <pre><code>public void onSurfaceCreated(GL10 glUnused, EGLConfig config) 
  {
      mParticleSystem = new ParticleSystem();
       //GLES20.glEnable(GLES20.GL_TEXTURE_2D);
       if (mTextureHandle != 1)
      mTextureHandle = loadGLTexture(activeContext, resourceID);
      GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  
      final float eyeX = 0.0f;
      final float eyeY = 0.0f;
      final float eyeZ = 1.5f;
  
      final float lookX = 0.0f;
      final float lookY = 0.0f;
      final float lookZ = -5.0f;
  
      final float upX = 0.0f;
      final float upY = 1.0f;
      final float upZ = 0.0f;
  
      Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ);
  
      final String vertexShader = 
              "uniform mat4 u_MVPMatrix;              \n"
  
          +   "attribute vec4 a_Position;             \n"
          +   "attribute vec4 a_Color;                \n"
          +   "attribute vec2 a_TexCoordinate;        \n"
  
          +   "//varying vec3 v_Position;             \n"
          +   "varying vec4 v_Color;                  \n"
          +   "varying vec2 v_TexCoordinate;          \n"
  
          +   "void main()                            \n"
          +   "{                                      \n"
          +   "   v_TexCoordinate = a_TexCoordinate;  \n"
          +   "   v_Color = a_Color;                  \n"
          +   "   gl_Position = u_MVPMatrix           \n"
          +   "               * a_Position;           \n"
          +   "}                                      \n";
  
      final String fragmentShader =
              "precision mediump float;       \n"
  
          +   "uniform sampler2D u_Texture;   \n" 
          +   "varying vec4 v_Color;          \n"
          +   "varying vec2 v_TexCoordinate;  \n"
          +   "void main()                    \n"
          +   "{                              \n" 
          +   "   vec4 baseColor;"
          +   "   baseColor = texture2D(u_Texture, v_TexCoordinate);      \n"
          +   "    " 
          +   "   gl_FragColor = baseColor;   \n" 
          +   "                           \n"
          +   "   //gl_FragColor = vec4(v_TexCoordinate.x, v_TexCoordinate.y, 0.0, 1.0);  \n"
          +   "   //gl_FragColor = v_Color;       \n"
  
          +   "}                              \n";
  
      //... Compile Shaders
  
  
      int programHandle = GLES20.glCreateProgram();
      if (programHandle != 0) 
      {
          GLES20.glAttachShader(programHandle, vertexShaderHandle);           
          GLES20.glAttachShader(programHandle, fragmentShaderHandle);
          GLES20.glBindAttribLocation(programHandle, 0, "a_Position");
          GLES20.glBindAttribLocation(programHandle, 1, "a_Color");
          GLES20.glBindAttribLocation(programHandle, 2, "a_TexCoordinate");
          GLES20.glLinkProgram(programHandle);
          final int[] linkStatus = new int[1];
          GLES20.glGetProgramiv(programHandle, GLES20.GL_LINK_STATUS, linkStatus, 0);
          if (linkStatus[0] == 0) 
          {               
              GLES20.glDeleteProgram(programHandle);
              programHandle = 0;
          }
      }
  
      if (programHandle == 0)
      {
          throw new RuntimeException("Error creating program.");
      }
      mMVPMatrixHandle = GLES20.glGetUniformLocation(programHandle, "u_MVPMatrix");        
      mPositionHandle = GLES20.glGetAttribLocation(programHandle, "a_Position");
      mColorHandle = GLES20.glGetAttribLocation(programHandle, "a_Color");
      mTextureUniformHandle = GLES20.glGetUniformLocation(programHandle, "u_Texture");
      mTextureCoordinateHandle = GLES20.glGetAttribLocation(programHandle, "a_TexCoordinate");
  
      //GLES20.glUseProgram(programHandle);  
      mProgramHandle = programHandle;
  checkGlError("surface created: ");
      }
  </code></pre>
  
  <p>Load Texture:</p>
  
  <pre><code>private int loadGLTexture(Context context, final int resourceId)
  {
  
  
      final int[] textureHandle = new int[1];
      GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
      GLES20.glPixelStorei(GLES20.GL_UNPACK_ALIGNMENT, 1);
          GLES20.glGenTextures(1, textureHandle, 0);
  
          byte[] pixels = 
              {  
                  (byte) 0xff,   0,   0, 
                  0, (byte) 0xff,   0, 
                  0,   0, (byte) 0xff,
                  (byte) 0xff, (byte) 0xff,   0
              };
  
          ByteBuffer pixelBuffer = ByteBuffer.allocateDirect(4*3);
          pixelBuffer.put(pixels).position(0);
          GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, textureHandle[0] );
          GLES20.glTexImage2D ( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, 2, 2, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, pixelBuffer );
          GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST );
          GLES20.glTexParameteri ( GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST );
          GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
          GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
  
  
      }
      if (textureHandle[0] == 0)
      {
          throw new RuntimeException("Error loading texture.");
      }
      checkGlError("create texture: ");
      return textureHandle[0];
  }
  </code></pre>
  
  <p>Code updated as suggested below.</p>