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);

}

}

 

賈雷 發表在 痞客邦 PIXNET 留言(0) 人氣()