Android OpenGL ES 开发教程(27):材质及光照示例

jerry OpenGL ES 2015年11月25日 收藏

设置物体表面材料(Material)的反光属性(颜色和材质)的方法如下:

public void glMaterialf(int face,int pname,float param)
public void glMaterialfv(int face,int pname,float[] params,int offset)
public void glMaterialfv(int face,int pname,FloatBuffer params)

  • face : 在OpenGL ES中只能使用GL_FRONT_AND_BACK,表示修改物体的前面和后面的材质光线属性。
  • pname: 参数类型,可以有GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, GL_SHININESS。这些参数用在光照方程。
  • param:  参数的值。

其中GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR ,GL_EMISSION为颜色RGBA值,GL_SHININESS 值可以从0到128,值越大,光的散射越小:

此外,方法glLightModleXX给出了光照模型的参数

public void glLightModelf(int pname,float param)
public void glLightModelfv(int pname,float[] params,int offset)
public void glLightModelfv(int pname,FloatBuffer params)

  • pname: 参数类型,可以为GL_LIGHT_MODEL_AMBIENT和GL_LIGHT_MODEL_TWO_SIDE
  • params: 参数的值。

最终顶点的颜色由这些参数(光源,材质光学属性,光照模型)综合决定(光照方程计算出)。

下面例子在场景中设置一个白色光源:

  1. public void initScene(GL10 gl){
  2. float[] amb = { 1.0f, 1.0f, 1.0f, 1.0f, };
  3. float[] diff = { 1.0f, 1.0f, 1.0f, 1.0f, };
  4. float[] spec = { 1.0f, 1.0f, 1.0f, 1.0f, };
  5. float[] pos = { 0.0f, 5.0f, 5.0f, 1.0f, };
  6. float[] spot_dir = { 0.0f, -1.0f, 0.0f, };
  7. gl.glEnable(GL10.GL_DEPTH_TEST);
  8. gl.glEnable(GL10.GL_CULL_FACE);
  9.  
  10. gl.glEnable(GL10.GL_LIGHTING);
  11. gl.glEnable(GL10.GL_LIGHT0);
  12. ByteBuffer abb
  13. = ByteBuffer.allocateDirect(amb.length*4);
  14. abb.order(ByteOrder.nativeOrder());
  15. FloatBuffer ambBuf = abb.asFloatBuffer();
  16. ambBuf.put(amb);
  17. ambBuf.position(0);
  18.  
  19. ByteBuffer dbb
  20. = ByteBuffer.allocateDirect(diff.length*4);
  21. dbb.order(ByteOrder.nativeOrder());
  22. FloatBuffer diffBuf = dbb.asFloatBuffer();
  23. diffBuf.put(diff);
  24. diffBuf.position(0);
  25.  
  26. ByteBuffer sbb
  27. = ByteBuffer.allocateDirect(spec.length*4);
  28. sbb.order(ByteOrder.nativeOrder());
  29. FloatBuffer specBuf = sbb.asFloatBuffer();
  30. specBuf.put(spec);
  31. specBuf.position(0);
  32.  
  33. ByteBuffer pbb
  34. = ByteBuffer.allocateDirect(pos.length*4);
  35. pbb.order(ByteOrder.nativeOrder());
  36. FloatBuffer posBuf = pbb.asFloatBuffer();
  37. posBuf.put(pos);
  38. posBuf.position(0);
  39.  
  40. ByteBuffer spbb
  41. = ByteBuffer.allocateDirect(spot_dir.length*4);
  42. spbb.order(ByteOrder.nativeOrder());
  43. FloatBuffer spot_dirBuf = spbb.asFloatBuffer();
  44. spot_dirBuf.put(spot_dir);
  45. spot_dirBuf.position(0);
  46.  
  47.  
  48. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambBuf);
  49. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, diffBuf);
  50. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, specBuf);
  51. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, posBuf);
  52. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPOT_DIRECTION,
  53. spot_dirBuf);
  54. gl.glLightf(GL10.GL_LIGHT0, GL10.GL_SPOT_EXPONENT, 0.0f);
  55. gl.glLightf(GL10.GL_LIGHT0, GL10.GL_SPOT_CUTOFF, 45.0f);
  56.  
  57. gl.glLoadIdentity();
  58. GLU.gluLookAt(gl,0.0f, 4.0f, 4.0f, 0.0f, 0.0f, 0.0f,
  59. 0.0f, 1.0f, 0.0f);
  60.  
  61. }

绘制一个球,并使用蓝色材质:

  1. public void drawScene(GL10 gl) {
  2. super.drawScene(gl);
  3.  
  4. float[] mat_amb = {0.2f * 0.4f, 0.2f * 0.4f,
  5. 0.2f * 1.0f, 1.0f,};
  6. float[] mat_diff = {0.4f, 0.4f, 1.0f, 1.0f,};
  7. float[] mat_spec = {1.0f, 1.0f, 1.0f, 1.0f,};
  8.  
  9.  
  10. ByteBuffer mabb
  11. = ByteBuffer.allocateDirect(mat_amb.length*4);
  12. mabb.order(ByteOrder.nativeOrder());
  13. FloatBuffer mat_ambBuf = mabb.asFloatBuffer();
  14. mat_ambBuf.put(mat_amb);
  15. mat_ambBuf.position(0);
  16.  
  17. ByteBuffer mdbb
  18. = ByteBuffer.allocateDirect(mat_diff.length*4);
  19. mdbb.order(ByteOrder.nativeOrder());
  20. FloatBuffer mat_diffBuf = mdbb.asFloatBuffer();
  21. mat_diffBuf.put(mat_diff);
  22. mat_diffBuf.position(0);
  23.  
  24. ByteBuffer msbb
  25. = ByteBuffer.allocateDirect(mat_spec.length*4);
  26. msbb.order(ByteOrder.nativeOrder());
  27. FloatBuffer mat_specBuf = msbb.asFloatBuffer();
  28. mat_specBuf.put(mat_spec);
  29. mat_specBuf.position(0);
  30.  
  31. gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,
  32. GL10.GL_AMBIENT, mat_ambBuf);
  33. gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,
  34. GL10.GL_DIFFUSE, mat_diffBuf);
  35. gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,
  36. GL10.GL_SPECULAR, mat_specBuf);
  37. gl.glMaterialf(GL10.GL_FRONT_AND_BACK,
  38. GL10.GL_SHININESS, 64.0f);
  39.  
  40. sphere.draw(gl);
  41.  
  42. }

下载