opengl es 光照效果,材质设置

             之前讲到了opengl es基本图形的绘制,变换,下面我们来看看光照和材质的应用。

             光照模型:

             为图形添加光照,就能使图形看上去有立体效果。在 OpenGL 光照模型中光源和光照效果可以细分为红,绿,蓝三个部分,光源由红,绿,蓝强度来定义,而物体表面材料由其反射红,绿,蓝的程度和方向来定义。

          OpenGL 光照模型中最终的光照效果可以分为四个组成部分:Emitted(光源), ambient(环境光),diffuse(漫射光)和specular(镜面反射光),最终结果由这四种光叠加而成。

          Emitted : 发光物体或光源

  ambient: 指光线经过多次反射后已经无法得知其方向,该光源如果射到某个平面,其反射方向为所有方向。Ambient 不依赖于光源的方向

 diffuse:只依赖于光源的方向和法线的方向

 specular : 一般指物体被光源直射的高亮区域。specular 依赖于光源的方向,法线的方向和视角的方向

         opengl es设置光照效果基本步骤:

         1、设置光源

       2、设置法线

       3、设置物体材料熟悉

设置光源:

OpenGL ES 中可以最多同时使用八个光源,分别使用0到7表示。

OpenGL ES光源可以分为

        平行光源, 代表由位于无限远处均匀发光体,太阳可以近似控制平行光源。

        点光源,如灯泡就是一个点光源,发出的光可以指向360度,可以为点光源设置光衰减属性或者让点光源只能射向某个方向。

        打开光源:

 打开光源总开关:
gl.glEnable(GL10.GL_LIGHTING);
再打开某个光源:
gl.glEnable(GL10.GL_LIGHTI0);//这里打开0号光源

设置光源属性:

         public void glLightfv(int light,int pname, FloatBuffer params)
 public void glLightfv(int light,int pname,float[] params,int offset)
 public void glLightf(int light,int pname,float param)
 light 指光源的序号,OpenGL ES可以设置从0到7共八个光源。
 pname: 光源参数名称,可以有如下:GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION, GL_AMBIENT, GL_DIFFUSE,GL_SPECULAR, GL_SPOT_DIRECTION, GL_POSITION
 params 参数的值(数组或是Buffer类型)。

         

其中为光源设置颜色的参数类型为 GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,可以分别指定R,G,B,A 的值。

指定光源的位置的参数为 GL_POSITION,值为(x,y,z,w):

平行光将 w 设为0.0,(x,y,z)为平行光的方向,

对于点光源,将 w 设成非0值,通常设为1.0. (x,y,z)为点光源的坐标位置

将点光源设置成聚光灯,需要同时设置 GL_SPOT_DIRECTION,GL_SPOT_CUTOFF 等参数,GL_POSITION的设置和点光源类似:将 w 设成非0值,通常设为1.0. (x,y,z)为点光源的坐标位置。而对于GL_SPOT_DIRECTION 参数,设置聚光的方向(x,y,z)

GL_SPOT_CUTOFF 参数设置聚光等发散角度(0到90度)

GL_SPOT_EXPONENT 给出了聚光灯光源汇聚光的程度,值越大,则聚光区域越小(聚光能力更强)

设置法线:设置了法线,光源才能在所会物体上出现光照效果

glNormal3f(float nx,float ny,float nz)                 为后续所有平面设置同样的方向,直到重新设置新的法线为止
glNormalPointer(int type,int stride, Buffer pointer)   为某个顶点设置法线


设置物体材质:

设置物体表面材料(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,值越大,光的散射越小:


下面看设置光源和材质的例子,具体代码都有注释:

   public void drawLight(GL10 gl){
        //环境光强度
        float[] amb_light = {1f,0f, 0f, 1f };
        //漫反射光强度
        float[] diff_light = { 1f, 0f, 0f, 1f };
        //镜面反射光强度
        float[] spec_light = {1f, 0f, 0f, 1f };

        //光源位置
        float[] pos_light = {1f, 0f, 0f, 0.2f};

        //光源方向
        float[] spot_dir = { -1f, 0f,  0f, };
        //获取浮点型环境光材质数据
        amb_mat_buffer= BufferUtils.getFloatBuffer(amb_mat);
        //获取浮点型漫反射光材质数据
        diff_mat_buffer= BufferUtils.getFloatBuffer(diff_mat);
        //获取浮点型镜面反射光材质数据
        spec_mat_buffer= BufferUtils.getFloatBuffer(spec_mat);
        //获取浮点型本身颜色数据
        emi_mat_buffer= BufferUtils.getFloatBuffer(emi_mat);
        //获取浮点型环境光数据
        FloatBuffer amb_light_buffer= BufferUtils.getFloatBuffer(amb_light);
        //获取浮点型漫反射光数据
        FloatBuffer diff_light_buffer= BufferUtils.getFloatBuffer(diff_light);
        //获取浮点型镜面反射光数据
        FloatBuffer spec_light_buffer= BufferUtils.getFloatBuffer(spec_light);
        //获取浮点型光源位置数据
        FloatBuffer pos_light_buffer= BufferUtils.getFloatBuffer(pos_light);
        //获取浮点型光源方向数据
        FloatBuffer spot_dir_buffer= BufferUtils.getFloatBuffer(spot_dir);


        angle++;
        angle = angle%360;
        angle = 60;
        ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length*2);
        ibb.order(ByteOrder.nativeOrder());
        ShortBuffer mIndixBuffer = ibb.asShortBuffer();
        mIndixBuffer.put(indices);
        mIndixBuffer.position(0);

        ByteBuffer cbb
                = ByteBuffer.allocateDirect(cubeColors.length * 4);
        cbb.order(ByteOrder.nativeOrder());
        colorBuffer = cbb.asFloatBuffer();
        colorBuffer.put(cubeColors);
        colorBuffer.position(0);

        ByteBuffer vbb
                = ByteBuffer.allocateDirect(cubeVertices.length*4);
        vbb.order(ByteOrder.nativeOrder());
        FloatBuffer vertex = vbb.asFloatBuffer();
        vertex.put(cubeVertices);
        vertex.position(0);

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        // 启用顶点座标数据
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        //启用法线设置
        gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

        //打开光源总开关
        gl.glEnable(GL10.GL_LIGHTING);

        //打开0号光源
        gl.glEnable(GL10.GL_LIGHT0);

        //设置光源位置
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, pos_light_buffer);

        //设置光源方向
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPOT_DIRECTION , spot_dir_buffer);

        //设置光源种类
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT ,  amb_light_buffer );
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE , diff_light_buffer );
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, spec_light_buffer);
        //设置聚光强度
        gl.glLightf(GL10.GL_LIGHT0, GL10.GL_SPOT_EXPONENT, 64f);
        //设置聚光角度
        gl.glLightf(GL10.GL_LIGHT0, GL10.GL_SPOT_CUTOFF, 45f);
        //设置材质种类
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, amb_mat_buffer);
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_DIFFUSE, diff_mat_buffer);
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,GL10.GL_SPECULAR, spec_mat_buffer);
        //设置镜面指数
        gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, shini_mat);

        // 启用顶点颜色数据
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

        // 重置当前的模型视图矩阵
        gl.glLoadIdentity();
        // 沿着Y轴旋转
        gl.glRotatef(angle, 0.2f, 1f, 0f);

        // 设置顶点的位置数据
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vbb);
        //设置顶点法线
        gl.glNormalPointer(GL10.GL_FLOAT, 0, vbb);

        // 设置顶点的颜色数据
        gl.glColorPointer(4, GL10.GL_FLOAT, 0, cbb);

        //绘制三角形,按照顶点数组画三角形
//        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP  , 0, 24);
        //绘制三角形,按照mIndixBuffer中索引画三角形
        gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, mIndixBuffer);

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
        gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
    }

demo下载地址:链接:http://pan.baidu.com/s/1c2oXQes 密码:7jz2











  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值