title: 2d Triangle with OpenGL ES 2.0
body: <p><strong>EDIT 2:</strong> Take a look on the <a href="https://github.com/ibraim-gm/opengles2-2d-demos/blob/master/src/ibraim/opengles2/Triangle2dActivity.java" rel="nofollow noreferrer">Triangle2d sample</a> of <a href="https://github.com/ibraim-gm/opengles2-2d-demos" rel="nofollow noreferrer">this GitHub project</a> for a complete, working sample.</p>
  
  <p><strong>EDIT:</strong> See the <a href="https://stackoverflow.com/a/14203877/851863">accepted answer</a> for a link with a good explanation on how the ortographic matrix works. In the end, I tweaked the provided code a little:</p>
  
  <pre><code>  float[] mvp = {
       2f/width,   0f,         0f, 0f,
       0f,        -2f/height,  0f, 0f,
       0f,         0f,         0f, 0f,
      -1f,         1f,         0f, 1f
     };
  </code></pre>
  
  <p>Please note that my z is fixed in 0 and w fixed in 1. This matrix make the origin (0,0) at the bottom-left of the screen; if you want the origin at top-left, try:</p>
  
  <pre><code>  float[] mvp = {
       2f/width,   0f,         0f, 0f,
       0f,         2f/height,  0f, 0f,
       0f,         0f,         0f, 0f,
      -1f,        -1f,         0f, 1f
     };
  </code></pre>
  
  <p>Another problem was the call to <code>GLES20.glUniformMatrix4fv</code> which I changed to:</p>
  
  <pre><code>FloatBuffer b = ByteBuffer.allocateDirect(mvp.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
  b.put(mvp).position(0);
  GLES20.glUniformMatrix4fv(uMvpPos, b.limit() / mvp.length, false, b);
  </code></pre>
  
  <p>If you want to mess with this a bit, try <a href="http://www.bluebit.gr/matrix-calculator/matrix_multiplication.aspx" rel="nofollow noreferrer">this online calculator</a>. Just remember that the <strong>rows in your sorce file</strong> will be <strong>columns in the calculator</strong>.</p>
  
  <p><strong>Original Problem:</strong>
  I'm trying to draw a 2d triangle using OpenGLES 2.0 on android, but so far, not much success. These are my shaders:</p>
  
  <pre><code>(Vertex shader)
  uniform mat4    uMvp;
  attribute vec3 aPosition;
  attribute vec3 aColor;
  varying vec4 vColor;
  void main() {
    vColor = vec4(aColor.xyz, 1.0);
    vec4 position = vec4(aPosition.xyz, 1.0);
    gl_Position = uMvp * position;
  };
  
  (Fragment shader)
  precision mediump float;
  varying vec4 vColor;
  void main(void)
  {
    gl_FragColor = vColor;
  };
  </code></pre>
  
  <p>Then, in the onSurfaceChanged method of GLSurfaceView.Renderer, I put the following:</p>
  
  <pre><code>public void onSurfaceChanged(GL10 gl, int width, int height)
  {
    // here I load and compile the shaders and link the program.
    // in the end, I use GLES20.glUseProgram(programHandle);
    // (code omitted)
  
    // create the matrix for the uniform
    int uMvpPos = GLES20.glGetUniformLocation(programHandle, "uMvp");
    float[] mvp = {width, 0f, 0f, 0f,
                   0f, -height, 0f, 0f,
                   0f, 0f, -2f, 0f,
                   -1f, 1, -1f, 1};
    GLES20.glUniformMatrix4fv(uMvpPos, mvp.length * 4, false, mvp, 0);
  
    // set viewport and clear color to white
    GLES20.glViewport(0, 0, width, height);
    GLES20.glClearColor(1f, 1f, 1f,1.0f);
  }
  </code></pre>
  
  <p>I used the values of the matrix showed on <a href="https://gamedev.stackexchange.com/questions/4309/opengl-es-2-0-setting-up-2d-projection/4312#4312">this question</a>. My intent here is to work with coordinates in the same way as a canvas works: (0,0) on top-left of screen and (width, height) on bottom-right.</p>
  
  <p>And last but not least, this is the code of onDrawFrame:</p>
  
  <pre><code>public void onDrawFrame(GL10 gl)
  {
    int aPos = GLES20.glGetAttribLocation(programHandle,"aPosition");
    int aColor = GLES20.glGetAttribLocation(programHandle,"aColor");
  
    // assuming I correctly set up my coordinate system,
    // these are the triangle coordinates and color
    float[] data =
        {
          // XYZ, RGB
          100f, 100f, 0f,
          1f, 0f, 0f,
  
          50f, 50f, 0f,
          1f, 0f, 0f,
  
          150f, 50f, 0f,
          1f, 0f, 0f,
        };
  
    // put all my data into a float buffer
    // the '* 4' is because a float has 4 bytes
    FloatBuffer dataVertex = ByteBuffer.allocateDirect(data.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
    dataVertex.put(data).position(0);
  
    // set the POSITION values
    // attribute, dataSize(number of elements), data type, normalized?, size(bytes), data
    GLES20.glEnableVertexAttribArray(aPos);
    GLES20.glVertexAttribPointer(aPos, 3, GLES20.GL_FLOAT, false, 6 * 4, dataVertex);
  
    // set the COLOR values
    dataVertex.position(3); // offset
    GLES20.glEnableVertexAttribArray(aColor);
    GLES20.glVertexAttribPointer(aColor, 3, GLES20.GL_FLOAT, false, 6 * 4, dataVertex);
  
    // put a white background
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
  
    // and finally draw the triangle!
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
  }
  </code></pre>
  
  <p>The end result is... a boring white screen, without the triangle. I guess I'm committing a very simple mistake, but I just can't spot it. Any thoughts?</p>