title: OpenGL ES 2.0 diffuse lighting: model shows up black
body: <p>This problem bothers me for about a week...
  I tried to load stl files and show it on the screen. The file was read properly. Rendering without adding light was pretty good. After I add lighting and shader codes, the model is still there but turns out black.</p>
  
  <p>I followed the example downloaded from link below this article:
  <a href="http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/" rel="nofollow">http://www.learnopengles.com/android-lesson-two-ambient-and-diffuse-lighting/</a></p>
  
  <p>The shader code was completely as the same as the example. The program links fine. The Shaders compile fine, too. I can't find out where the problem is. PLZ help me.</p>
  
  <p>My Renderer:</p>
  
  <pre><code>public class MyGLRenderer implements GLSurfaceView.Renderer {
  
   private Test test;
   private Light1 light1;
  
   private float range = 145;
  
   private final float[] mMVMMatrix = new float[16];
   private final float[] mMVPMatrix = new float[16];
   private final float[] mModelMatrix = new float[16];
   private final float[] mProjectionMatrix = new float[16];
   private final float[] mViewMatrix = new float[16];
   protected final static float[] mLightPosInEyeSpace = new float[4];
   private final float[] mLightModelMatrix = new float[16];
   private final float[] mLightPosInModelSpace = new float[] {0.0f, 0.0f, 0.0f, 1.0f};
   private final float[] mLightPosInWorldSpace = new float[4];
  
   private final float[] mTempMatrix = new float[16];
   public static final float[] mAccumulatedMatrix = new float[16];
   private final float[] mCurrMatrix = new float[16];
  
  
   public void onSurfaceCreated(GL10 unused, EGLConfig config) {
      // Set the background frame color
      GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
      GLES20.glEnable(GLES20.GL_DEPTH_TEST);
      GLES20.glDepthFunc(GLES20.GL_LEQUAL);
      Matrix.setIdentityM(mTempMatrix, 0);
      Matrix.setIdentityM(mAccumulatedMatrix, 0);
  
      light1 = new Light1();
      test = new Test();
  
   }
  
   public void onDrawFrame(GL10 unused) {
      GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
  
      Matrix.setIdentityM(mViewMatrix, 0);
      Matrix.setIdentityM(mModelMatrix, 0);
      Matrix.setIdentityM(mCurrMatrix, 0);
      Matrix.setIdentityM(mLightModelMatrix, 0);
  
      Matrix.multiplyMV(mLightPosInWorldSpace, 0, mLightModelMatrix, 0, mLightPosInModelSpace, 0);
      Matrix.multiplyMV(mLightPosInEyeSpace, 0, mViewMatrix, 0, mLightPosInWorldSpace, 0);
  
      Matrix.rotateM(mCurrMatrix, 0, mAngleY, 0.0f, 1.0f, 0.0f);
      Matrix.rotateM(mCurrMatrix, 0, mAngleX, 1.0f, 0, 0.0f);
      mAngleX = 0.0f;
      mAngleY = 0.0f;
  
      Matrix.multiplyMM(mTempMatrix, 0, mCurrMatrix, 0, mAccumulatedMatrix, 0);
      System.arraycopy(mTempMatrix, 0, mAccumulatedMatrix, 0, 16);
  
      Matrix.multiplyMM(mTempMatrix, 0, mModelMatrix, 0, mAccumulatedMatrix, 0);
      System.arraycopy(mTempMatrix, 0, mModelMatrix, 0, 16);
  
      Matrix.translateM(mModelMatrix, 0, -test.meanX, -test.meanY, -test.meanZ);
  
      Matrix.multiplyMM(mMVMMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
      Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMMatrix, 0);
  
      light1.draw(mMVPMatrix);
  
      test.draw(mMVPMatrix, mMVMMatrix);
   }
  
   public void onSurfaceChanged(GL10 gl, int width, int height) {
      GLES20.glViewport(0, 0, width, height);
  
      float ratio = (float) width / height;
      Matrix.orthoM(mProjectionMatrix, 0, -range*ratio, range*ratio, -range, range, -range, range);
   }
  
   public final static int loadShader(int type, String shaderCode){
      int shader = GLES20.glCreateShader(type);
      GLES20.glShaderSource(shader, shaderCode);
      GLES20.glCompileShader(shader);
      return shader;
   }
  
   public static volatile float mAngleX;
   public static volatile float mAngleY;
  
   public static void setAngleX(float angle) {mAngleX = angle;}
  
   public float getAngleX() {
       return mAngleX;
   }
  
   public static void setAngleY(float angle) {
      mAngleY = angle;
   }
  
   public float getAngleY() {
      return mAngleY;
   }}
  </code></pre>
  
  <p>My code to draw where the light is:</p>
  
  <pre><code>public class Light1 {
  private final String vertexShaderCode =
          "uniform mat4 u_MVPMatrix;      \n"
                  +   "attribute vec4 a_Position;     \n"
                  + "void main()                    \n"
                  + "{                              \n"
                  + "   gl_Position = u_MVPMatrix   \n"
                  + "               * a_Position;   \n"
                  + "   gl_PointSize = 5.0;         \n"
                  + "}                              \n";
  
  private final String fragmentShaderCode =
          "precision mediump float;       \n"
                  + "void main()                    \n"
                  + "{                              \n"
                  + "   gl_FragColor = vec4(1.0,    \n"
                  + "   1.0, 1.0, 1.0);             \n"
                  + "}                              \n";
  
  
  
  //Light*******************
  public static float[] lightLocation = new float[] {150, 150, 0};//*********ok
  private final int mProgram;
  //Light*******************
  
  
  public Light1() {
      // initialize byte buffer for the draw list
      int vertexShader = MyGLRenderer.loadShader(
              GLES20.GL_VERTEX_SHADER,
              vertexShaderCode);
      int fragmentShader = MyGLRenderer.loadShader(
              GLES20.GL_FRAGMENT_SHADER,
              fragmentShaderCode);
  
      mProgram = GLES20.glCreateProgram();
      GLES20.glAttachShader(mProgram, vertexShader);
      GLES20.glAttachShader(mProgram, fragmentShader);
      GLES20.glLinkProgram(mProgram);
  }
  
  public void draw(float[] mvpMatrix) {
  
      GLES20.glUseProgram(mProgram);
      final int pointMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "u_MVPMatrix");
      final int pointPositionHandle = GLES20.glGetAttribLocation(mProgram, "a_Position");
  
      GLES20.glVertexAttrib3f(pointPositionHandle, lightLocation[0], lightLocation[1], lightLocation[2]);
  
      GLES20.glUniformMatrix4fv(pointMVPMatrixHandle, 1, false, mvpMatrix, 0);
  
      GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 1);
  
      GLES20.glDisableVertexAttribArray(pointPositionHandle);
  }}
  </code></pre>
  
  <p>My Model Code:</p>
  
  <pre><code>public class Test {
  final String vertexShaderCode =
          "uniform mat4 u_MVPMatrix;      \n"     // A constant representing the combined model/view/projection matrix.
                  + "uniform mat4 u_MVMatrix;       \n"       // A constant representing the combined model/view matrix.
                  + "uniform vec3 u_LightPos;       \n"       // The position of the light in eye space.
  
                  + "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.
                  + "attribute vec3 a_Normal;       \n"       // Per-vertex normal information we will pass in.
  
                  + "varying vec4 v_Color;          \n"       // This will be passed into the fragment shader.
  
                  + "void main()                    \n"   // The entry point for our vertex shader.
                  + "{                              \n"
                  // Transform the vertex into eye space.
                  + "   vec3 modelViewVertex = vec3(u_MVMatrix * a_Position);              \n"
                  // Transform the normal's orientation into eye space.
                  + "   vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));     \n"
                  // Will be used for attenuation.
                  + "   float distance = length(u_LightPos - modelViewVertex);             \n"
                  // Get a lighting direction vector from the light to the vertex.
                  + "   vec3 lightVector = normalize(u_LightPos - modelViewVertex);        \n"
                  // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
                  // pointing in the same direction then it will get max illumination.
                  + "   float diffuse = max(dot(modelViewNormal, lightVector), 0.1);       \n"
                  // Attenuate the light based on distance.
                  + "   diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));  \n"
                  // Multiply the color by the illumination level. It will be interpolated across the triangle.
                  + "   v_Color = a_Color * diffuse;                                       \n"
                  // gl_Position is a special variable used to store the final position.
                  // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
                  + "   gl_Position = u_MVPMatrix * a_Position;                            \n"
                  + "}                                                                     \n";
  
  private final String fragmentShaderCode =
          "precision mediump float;       \n"     // Set the default precision to medium. We don't need as high of a
                  // 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.
                  + "{                              \n"
                  + "   gl_FragColor = v_Color;     \n"       // Pass the color directly through the pipeline.
                  + "}                              \n";
  
  private FloatBuffer vertexBuffer;
  private FloatBuffer colorBuffer;
  private FloatBuffer normalBuffer;
  
  private final int mProgram;
  
  private int mPositionHandle;
  private int mNormalHandle;
  private int mLightLocationHandle;
  private int mColorHandle;
  private int mMVPMatrixHandle;
  private int mMVMatrixHandle;
  
  final int COORDS_PER_VERTEX = 3;
  float[] squareCoords;
  float[] coordsNormals;
  
  float color[];
  
  public Test() {
      squareCoords = GlassUI10.ReadStlBinary("test.stl");
      coordsNormals = VectorCalculate.getNormByPtArray(squareCoords);
      color = new float[squareCoords.length/3*4];
      for(int i = 0; i &lt; color.length/4 ; i = i+4)
      {
          color[i+0] =0.3f;
          color[i+1] =0.7f;
          color[i+2] =0.6f;
          color[i+3] =1.3f;
      }
      System.gc();
      Log.v("TestLoaded: ", "Loaded");
  
      // initialize vertex byte buffer for shape coordinates
      ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4);
      bb.order(ByteOrder.nativeOrder());
      vertexBuffer = bb.asFloatBuffer();
      vertexBuffer.put(squareCoords);
      vertexBuffer.position(0);
  
      colorBuffer = ByteBuffer.allocateDirect(color.length * 4)
              .order(ByteOrder.nativeOrder()).asFloatBuffer();
      colorBuffer.put(color).position(0);
  
      ByteBuffer nb = ByteBuffer.allocateDirect(coordsNormals.length * 4);
      nb.order(ByteOrder.nativeOrder());
      normalBuffer = nb.asFloatBuffer();
      normalBuffer.put(coordsNormals);
      normalBuffer.position(0);
  
      // initialize byte buffer for the draw list
      int vertexShader = MyGLRenderer.loadShader(
              GLES20.GL_VERTEX_SHADER,
              vertexShaderCode);//*********ok
      int fragmentShader = MyGLRenderer.loadShader(
              GLES20.GL_FRAGMENT_SHADER,
              fragmentShaderCode);//*********ok
  
      mProgram = GLES20.glCreateProgram();
      GLES20.glAttachShader(mProgram, vertexShader);
      GLES20.glAttachShader(mProgram, fragmentShader);
      GLES20.glBindAttribLocation(mProgram, 0, "a_Position");
      GLES20.glBindAttribLocation(mProgram, 1, "a_Color");
      GLES20.glBindAttribLocation(mProgram, 2, "a_Normal");
  
  
  
      GLES20.glLinkProgram(mProgram);
  }
  
  public void draw(float[] mvpMatrix, float[] mvMatrix) {
  
      GLES20.glUseProgram(mProgram);
  
      mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "u_MVPMatrix");
      mMVMatrixHandle = GLES20.glGetUniformLocation(mProgram, "u_MVMatrix");
      mLightLocationHandle = GLES20.glGetUniformLocation(mProgram, "u_LightPos");
      mPositionHandle = GLES20.glGetAttribLocation(mProgram, "a_Position");
      mColorHandle = GLES20.glGetUniformLocation(mProgram, "a_Color");
      mNormalHandle = GLES20.glGetAttribLocation(mProgram, "a_Normal");
  
      vertexBuffer.position(0);
      GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, vertexBuffer);
      GLES20.glEnableVertexAttribArray(mPositionHandle);
  
      colorBuffer.position(0);
      GLES20.glVertexAttribPointer(mColorHandle, 4, GLES20.GL_FLOAT, false, 0, colorBuffer);
      GLES20.glEnableVertexAttribArray(mColorHandle);
  
      normalBuffer.position(0);
      GLES20.glVertexAttribPointer(mNormalHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, normalBuffer);
      GLES20.glEnableVertexAttribArray(mNormalHandle);
  
      GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mvMatrix, 0);
  
      GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
  
      GLES20.glUniform3f(mLightLocationHandle, MyGLRenderer.mLightPosInEyeSpace[0],  MyGLRenderer.mLightPosInEyeSpace[1],  MyGLRenderer.mLightPosInEyeSpace[2]);
  
      GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, squareCoords.length/COORDS_PER_VERTEX);              GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
  
      GLES20.glDisableVertexAttribArray(mPositionHandle);
  }}
  </code></pre>
  
  <p>Any answer will be appreciated!</p>