title: Android OpenGL ES 2.0
body: <p>Im trying to get a simple trinangle showing in a Android OpenGL ES 2.0 example. But nothing appears and i just dont get why :), i get no errors or anything, just a blue screen (that is my clear color). Maybe theres something wrong with the projection matrix placing my model outside?</p>
  
  <pre><code>package dk.madslee.modelviewer;
  
  import java.nio.ByteBuffer;
  import java.nio.ByteOrder;
  import java.nio.FloatBuffer;
  
  import javax.microedition.khronos.egl.EGLConfig;
  import javax.microedition.khronos.opengles.GL10;
  
  import android.app.Activity;
  import android.app.ActivityManager;
  import android.content.Context;
  import android.content.pm.ConfigurationInfo;
  import android.content.res.Resources;
  import android.opengl.GLES20;
  import android.opengl.GLSurfaceView;
  import android.opengl.Matrix;
  import android.os.Bundle;
  import android.util.Log;
  
  // http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/GLES20TriangleRenderer.html
  
  public class MainActivity extends Activity
  {
      @Override
      public void onCreate(Bundle savedInstanceState)
      {
          super.onCreate(savedInstanceState);
          final Resources resources = getResources();
          GLSurfaceView surfaceView = new GLSurfaceView(this);
          surfaceView.setEGLContextClientVersion(2); // enable OpenGL 2.0
  
          Log.e("opengl", Boolean.toString(detectOpenGLES20()));
  
          surfaceView.setRenderer(new GLSurfaceView.Renderer()
          {   
              public static final int FLOAT_BYTE_LENGTH = 4;
  
              private int mProgram;
              private int mVertexPositionAttributeLocation;
              private int mMVMatrixUniformLocation;
              private int mPMatrixUniformLocation;
  
              private float[] mMVMatrix = new float[16];
              private float[] mPMatrix = new float[16];
  
              private float[] mVertices = {
                  1.0f,  1.0f,  0.0f,
                  -1.0f,  1.0f,  0.0f,
                  1.0f, -1.0f,  0.0f,
              };
              private FloatBuffer mVertexBuffer;
  
              @Override
              public void onSurfaceCreated(GL10 gl, EGLConfig config)
              {
                  mVertexBuffer = ByteBuffer.allocateDirect(mVertices.length * FLOAT_BYTE_LENGTH).order(ByteOrder.nativeOrder()).asFloatBuffer();
                  mVertexBuffer.put(mVertices);
                  mVertexBuffer.position(0);
  
                  mProgram = createProgram();
                  mVertexPositionAttributeLocation = GLES20.glGetAttribLocation(mProgram, "aVertexPosition");
                  mMVMatrixUniformLocation = GLES20.glGetUniformLocation(mProgram, "uMVMatrix");
                  mPMatrixUniformLocation = GLES20.glGetUniformLocation(mProgram, "mPMatrix");
                  checkGlError("glGetUniformLocation");
  
                  Matrix.setLookAtM(mMVMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
              }
  
              @Override
              public void onSurfaceChanged(GL10 gl, int width, int height)
              {
                  GLES20.glViewport(0, 0, width, height);
  
                  Matrix.frustumM(mPMatrix, 0, -1, 1, -1, 1, 3, 7); // [UPDATED but didnt solve the problem]
              }
  
              @Override
              public void onDrawFrame(GL10 gl)
              {
                  GLES20.glClearColor(0, 0, 1.0f, 1.0f);
                  GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  
                  GLES20.glUseProgram(mProgram);
                  checkGlError("glUseProgram");
  
                  mVertexBuffer.position(0);
  
                  GLES20.glVertexAttribPointer(mVertexPositionAttributeLocation, 3, GLES20.GL_FLOAT, false, 3 * FLOAT_BYTE_LENGTH, mVertexBuffer);
                  checkGlError("glVertexAttribPointer");
  
                  GLES20.glEnableVertexAttribArray(mVertexPositionAttributeLocation);
                  checkGlError("glEnableVertexAttribArray");
  
                  GLES20.glUniformMatrix4fv(mMVMatrixUniformLocation, 1, false, mMVMatrix, 0);
                  GLES20.glUniformMatrix4fv(mPMatrixUniformLocation, 1, false, mPMatrix, 0);
                  checkGlError("glUniform4fv");
  
                  GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
                  checkGlError("glDrawArrays");
              }
  
              private int createProgram()
              {
                  int program = GLES20.glCreateProgram();
  
                  int vertexShader = getShader(GLES20.GL_VERTEX_SHADER, R.string.vertex_shader);
                  int fragmentShader = getShader(GLES20.GL_FRAGMENT_SHADER, R.string.fragment_shader);
  
                  GLES20.glAttachShader(program, vertexShader);
                  GLES20.glAttachShader(program, fragmentShader);
                  GLES20.glLinkProgram(program);
                  GLES20.glUseProgram(program);
  
                  return program;
              }
  
              private int getShader(int type, int source) 
              {
                  int shader = GLES20.glCreateShader(type);
                  String shaderSource = resources.getString(source);
                  GLES20.glShaderSource(shader, shaderSource);
                  GLES20.glCompileShader(shader);
  
                  int[] compiled = new int[1];
                  GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
                  if (compiled[0] == 0) 
                  {
                      Log.e("opengl", "Could not compile shader");
                      Log.e("opengl", GLES20.glGetShaderInfoLog(shader));
                      Log.e("opengl", shaderSource);
                  }
  
                  return shader;
              }
  
              private void checkGlError(String op) {
                  int error;
                  while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
                      Log.e("opengl", op + ": glError " + error);
                      throw new RuntimeException(op + ": glError " + error);
                  }
              }
          });
  
          setContentView(surfaceView);   
      }
  
      private boolean detectOpenGLES20() {
          ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
          ConfigurationInfo info = am.getDeviceConfigurationInfo();
          return (info.reqGlEsVersion &gt;= 0x20000);
      }
  }
  </code></pre>
  
  <p>My shaders looks like this</p>
  
  <p>Vertex</p>
  
  <pre><code>attribute vec3 aVertexPosition;
          uniform mat4 uMVMatrix;
          uniform mat4 uPMatrix;
  
          void main() {
              gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
          }
  </code></pre>
  
  <p>Fragment</p>
  
  <pre><code>precision highp float; 
          void main() {
            gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
          }
  </code></pre>