您的位置:首页 > 移动开发 > Android开发

Android OpenGL ES材质及光照示例

2014-04-19 18:30 615 查看
转自/article/1356827.html

设置物体表面材料(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: 参数的值。

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

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



[java] view
plaincopyprint?

public void initScene(GL10 gl){

float[] amb = { 1.0f, 1.0f, 1.0f, 1.0f, };

float[] diff = { 1.0f, 1.0f, 1.0f, 1.0f, };

float[] spec = { 1.0f, 1.0f, 1.0f, 1.0f, };

float[] pos = { 0.0f, 5.0f, 5.0f, 1.0f, };

float[] spot_dir = { 0.0f, -1.0f, 0.0f, };

gl.glEnable(GL10.GL_DEPTH_TEST);

gl.glEnable(GL10.GL_CULL_FACE);



gl.glEnable(GL10.GL_LIGHTING);

gl.glEnable(GL10.GL_LIGHT0);

ByteBuffer abb

= ByteBuffer.allocateDirect(amb.length*4);

abb.order(ByteOrder.nativeOrder());

FloatBuffer ambBuf = abb.asFloatBuffer();

ambBuf.put(amb);

ambBuf.position(0);



ByteBuffer dbb

= ByteBuffer.allocateDirect(diff.length*4);

dbb.order(ByteOrder.nativeOrder());

FloatBuffer diffBuf = dbb.asFloatBuffer();

diffBuf.put(diff);

diffBuf.position(0);



ByteBuffer sbb

= ByteBuffer.allocateDirect(spec.length*4);

sbb.order(ByteOrder.nativeOrder());

FloatBuffer specBuf = sbb.asFloatBuffer();

specBuf.put(spec);

specBuf.position(0);



ByteBuffer pbb

= ByteBuffer.allocateDirect(pos.length*4);

pbb.order(ByteOrder.nativeOrder());

FloatBuffer posBuf = pbb.asFloatBuffer();

posBuf.put(pos);

posBuf.position(0);



ByteBuffer spbb

= ByteBuffer.allocateDirect(spot_dir.length*4);

spbb.order(ByteOrder.nativeOrder());

FloatBuffer spot_dirBuf = spbb.asFloatBuffer();

spot_dirBuf.put(spot_dir);

spot_dirBuf.position(0);



gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambBuf);

gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, diffBuf);

gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, specBuf);

gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, posBuf);

gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPOT_DIRECTION,

spot_dirBuf);

gl.glLightf(GL10.GL_LIGHT0, GL10.GL_SPOT_EXPONENT, 0.0f);

gl.glLightf(GL10.GL_LIGHT0, GL10.GL_SPOT_CUTOFF, 45.0f);



gl.glLoadIdentity();

GLU.gluLookAt(gl,0.0f, 4.0f, 4.0f, 0.0f, 0.0f, 0.0f,

0.0f, 1.0f, 0.0f);



}

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

[java] view
plaincopyprint?

public void drawScene(GL10 gl) {

super.drawScene(gl);



float[] mat_amb = {0.2f * 0.4f, 0.2f * 0.4f,

0.2f * 1.0f, 1.0f,};

float[] mat_diff = {0.4f, 0.4f, 1.0f, 1.0f,};

float[] mat_spec = {1.0f, 1.0f, 1.0f, 1.0f,};



ByteBuffer mabb

= ByteBuffer.allocateDirect(mat_amb.length*4);

mabb.order(ByteOrder.nativeOrder());

FloatBuffer mat_ambBuf = mabb.asFloatBuffer();

mat_ambBuf.put(mat_amb);

mat_ambBuf.position(0);



ByteBuffer mdbb

= ByteBuffer.allocateDirect(mat_diff.length*4);

mdbb.order(ByteOrder.nativeOrder());

FloatBuffer mat_diffBuf = mdbb.asFloatBuffer();

mat_diffBuf.put(mat_diff);

mat_diffBuf.position(0);



ByteBuffer msbb

= ByteBuffer.allocateDirect(mat_spec.length*4);

msbb.order(ByteOrder.nativeOrder());

FloatBuffer mat_specBuf = msbb.asFloatBuffer();

mat_specBuf.put(mat_spec);

mat_specBuf.position(0);



gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,

GL10.GL_AMBIENT, mat_ambBuf);

gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,

GL10.GL_DIFFUSE, mat_diffBuf);

gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,

GL10.GL_SPECULAR, mat_specBuf);

gl.glMaterialf(GL10.GL_FRONT_AND_BACK,

GL10.GL_SHININESS, 64.0f);



sphere.draw(gl);



}



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: