OpenGL ES 之三 對光源及材質的設計
有光源物體才顯立體 , 無光源則像是平面
在 Android 中模擬的定向光 (如太陽光)照射的場景效果 ,OpenGL ES 是通過
glLightfv(int light,int pname,float[] params,int offset) 的方法來設定定向光 .
light : 該参數設定 OpenGL ES 中的灯 , 用 GL_light0 ~ GL_light7 來表示8盞燈
pname : 是被設置的光源屬性 ,在被設置定向光時 , 應該設置成
定向光 GL_POSITION (0.0,0.0,1.0,0.0) 表示光源位置的座標 (x,y,z,w)
環境光 GL_AMBIENT (0.0,0.0,0.0,1.0) 表示光的環境強度
離散光 GL_DIFFUSE (0.0,0.0,0.0,1.0) 表示光的離散強度
反射光 GL_SPECULAR (0.0,0.0,0.0,1.0) 表示光的反射強度
params: 這個参數是一個float數組 ,由4部分組成 ,前3個值組成表示定向光方向的向量,
光的方向為從向量點處向原點照射. 如 {0,1,0,0} 表示沿 Y軸負方向的光 .
最後的 0 表示此光源為定向光 ; 如為環境光 GL_AMBIENT ,離散光 GL_DIFFUSE
則此参數給出的是丁光顏色的 R,G,B,A 4個色彩通道的值
offset : 為偏移量 ,設置為 0 ,表示第1個值在數組中的偏移量為 0 .
-------------------------------------------------------------------------------
物體的材質
設置材質的主要工作就是設置材質對於環境光,離散光 ,鏡面光的反射能力 ,例如 ,白色材質能反射
所有顏色的光 , 紅色材質只能反射紅色光 .
通過 public abstract void glMaterialfv(int face ,int pname ,float[]params ,int offset)
可以設置才值得相關屬性 .
face : 設置材質能反光的面 , 設置 GL10.GL_FRONT_AND_BACK , 表示正反面均可反射光線 .
pname : 設置環境光参數為 GL10.GL_AMBIENT
設置離散光参數為 GL10. GL_DIFFUSE
設置鏡面光参數為 GL10.GL_SPECULAR
設置高光 参數為 GL10.GL_SHININESS
params : 代表 R G B A 4個参數 ,對於高光反射 ,設置参數值越大 ,高量區域越小越暗
offset : 偏移量 , 一般設為 0
程式如下
public class MySurfaceView extends GLSurfaceView{
.........
mRenderer = new SceneRenderer(); //创建场景渲染器
setRenderer(mRenderer);//设置渲染器
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染
private class SceneRenderer implements GLSurfaceView.Renderer {
Ball ball=new Ball(3);
public SceneRenderer(){
}
public void onDrawFrame(GL10 gl){
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_LIGHTING); //允許光照
initMaterialWhite(gl); //初始化材質为白色
gl.glDisable(GL10.GL_LIGHT0); //每次繪製前,取消已开啟的灯光效果
initLight0(gl); //初始化0号灯
//最后的1表示是定位光,此为0号灯位置参数。
float[] positionParams0={0,0,light0PositionX,1};
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, positionParams0,0); //0号灯位置
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);//清除颜色缓沖
gl.glMatrixMode(GL10.GL_MODELVIEW); //設置當前矩陣為矩陣模式
gl.glLoadIdentity(); //設置當前矩陣為單位矩陣
gl.glTranslatef(-1, 0f, -1.8f); //平移
ball.drawSelf(gl); //繪製
gl.glLoadIdentity(); //恢复矩阵
gl.glTranslatef(1, 0f, -1.8f); //平移
ball.drawSelf(gl); //主體繪製
gl.glLoadIdentity(); //恢复矩阵
gl.glTranslatef(0, 0f, -2.8f); //平移
ball.drawSelf(gl); //繪製
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height); //設置视窗大小及位置
gl.glMatrixMode(GL10.GL_PROJECTION); //設置當前矩阵为投影矩阵
gl.glLoadIdentity(); //設置當前矩阵为单位矩阵
float ratio = (float) width / height; //計算透视投影的比例
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); //调用此方法計算產生透视投影矩阵
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glDisable(GL10.GL_DITHER); //關閉抗抖动
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST); //設置特定Hint项目的模式,這里為設置为使用快速模式
gl.glClearColor(0,0,0,0); //設置屏幕背景色黑色RGBA
gl.glShadeModel(GL10.GL_SMOOTH);//GL10.GL_SMOOTH GL10.GL_FLAT //設置着色模型为平滑着色
gl.glEnable(GL10.GL_DEPTH_TEST); //啟用深度测试
}
}
//初始化 GL_LIGHT0 光源
private void initLight0(GL10 gl)
{
gl.glEnable(GL10.GL_LIGHT0);//打开0号灯 ,红色
//環境光設置
float[] ambientParams={0.2f,0.03f,0.03f,1.0f};//光参数 RGBA
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambientParams,0);
//散射光設置
float[] diffuseParams={0.5f,0.1f,0.1f,1.0f};//光参数 RGBA
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, diffuseParams,0);
//反射光設置
float[] specularParams={1.0f,0.1f,0.1f,1.0f};//光参数 RGBA
gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, specularParams,0);
}
//t初始化材質顏色
private void initMaterialWhite(GL10 gl)
{
//環境光為白色材質
float ambientMaterial[] = {0.4f, 0.4f, 0.4f, 1.0f};
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, ambientMaterial,0);
//散射光為白色材質
float diffuseMaterial[] = {0.8f, 0.8f, 0.8f, 1.0f};
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, diffuseMaterial,0);
//高光材質為白色
float specularMaterial[] = {1.0f, 1.0f, 1.0f, 1.0f};
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, specularMaterial,0);
//高光反射区域,數越大高亮区域越小越暗
float shininessMaterial[] = {1.5f};
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, shininessMaterial,0);
}
}
留言列表