title: OpenGL diffuse light
body: <p>I met some problems when implementing diffuse light.<br>
  correct result may look like the picture on left <a href="http://i.stack.imgur.com/dBdpK.png" rel="nofollow">diffuse light picture</a><br>
  The right side is incorrect result.<br>
  The problems are below<br>
  1.There is no lighting effect in the beginning.I have to rotate the object to some degree the lighting effect will appear.<br>
  2.The object mixed some triangle in it. (I have checked my read file(.obj &amp;.mtl) part already. It's correct.)<br>
  3.I only turn on the diffuse light. But the lighting effect seems to ambient light.<br>
  My light source position is (0, 0, 5), eye position is(0, 0, 0);</p>
  
  <p>my vertex shader   </p>
  
  <pre><code>attribute vec4 vertexPosition;
  attribute vec3 vertexNormal_objectSpace;
  
  varying vec4 vv4color;
  
  uniform mat4 mvp; //model, viewing, projection transformation matrix
  uniform mat4 NormalMatrix;
  
  struct LightSourceParameters 
  {
      vec4 ambient;
      vec4 diffuse;
      vec4 specular;
      vec4 position;
      vec4 halfVector;
      vec3 spotDirection;
      float spotExponent;
      float spotCutoff; // (range: [0.0,90.0], 180.0)
      float spotCosCutoff; // (range: [1.0,0.0],-1.0)
      float constantAttenuation;
      float linearAttenuation;
      float quadraticAttenuation;
  };
  
  struct MaterialParameters 
  {
      vec4 ambient;
      vec4 diffuse;
      vec4 specular;
      float shininess;
  };
  
  uniform MaterialParameters Material;
  uniform LightSourceParameters LightSource[3]; //because I have to implement three light sources(directional, point, specular light)  
  
  void main() 
  {
      vec3 normal, TransformedNormal, lightDirection;
      vec4 ambient, diffuse;                                      
      float NdotL;
  
      ambient = LightSource[0].ambient * Material.ambient;            
      TransformedNormal = vec3(vec4(vertexNormal_objectSpace, 0.0) * NormalMatrix);
      normal = normalize(TransformedNormal);                  
      lightDirection = normalize(vec3(LightSource[0].position));
      NdotL = max(dot(normal, lightDirection), 0.0);              
      diffuse = LightSource[0].diffuse * Material.diffuse * NdotL;    
  
      vv4color = ambient + diffuse; //vv4color pass to fragment shader
      gl_Position = mvp * vertexPosition;
  }  
  </code></pre>
  
  <p>my display function    </p>
  
  <pre><code>void onDisplay(void)
  {
      Matrix4 MVP, modelView, NormalMatrix;
      int i=0;
  
      // clear canvas
      glClearColor(0.5f, 0.0f, 0.0f, 1.0f);   
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
      glEnableVertexAttribArray(iLocPosition);
      glEnableVertexAttribArray(iLocNormal);
  
      geo_rotate = geo_rotate_x * geo_rotate_y * geo_rotate_z;
      Geo = geo_rotate * geo_scale * geo_trans;
  
      modelView = View * Geo; 
      modelView = modelView.transpose();  //row-major -&gt; column-major 
      modelView = modelView.invert();     //normal transformation(transpose after inverse)
      NormalMatrix = modelView.transpose();
  
      MVP = Proj * View * Geo * Norm;
      MVP = MVP.transpose();  
  
      glUniformMatrix3fv(iLocEyePosition, 1, GL_FALSE, &amp;eye[0]);  
      glUniformMatrix4fv(iLocNormalMatrix, 1, GL_FALSE, &amp;NormalMatrix[0]);    //bind uniform matrix to shader
      glUniformMatrix4fv(iLocMVP, 1, GL_FALSE, &amp;MVP[0]);
  
      group = OBJ-&gt;groups;
      for(i=0; i&lt;OBJ-&gt;numgroups-1; i++)
      {
          //pass model material value to the shader
          glUniform4fv(iLocMAmbient, 1, material[i].ambient);
          glUniform4fv(iLocMDiffuse, 1, material[i].diffuse);
          glUniform4fv(iLocMSpecular, 1, material[i].specular);   
          glUniform1f(iLocMShininess, material[i].shininess);
  
          glVertexAttribPointer(iLocPosition, 3, GL_FLOAT, GL_FALSE, 0, V[i]);    //bind array pointers to shader
          glVertexAttribPointer(iLocNormal, 3, GL_FLOAT, GL_FALSE, 0, N[i]);
          glDrawArrays(GL_TRIANGLES, 0, group-&gt;numtriangles*3);                   //draw the array we just bound
  
          group = group-&gt;next;
      }
      glutSwapBuffers();
  }
  </code></pre>
  
  <p>Thank you all of you.</p>