openGL之光照1---openGL学习笔记(九)

 光的的成分包括三种:

 ①环境光:(ambient)没有方向,向四周均匀发散,全局因素。

 ②散射光:(diffuse)具有方向性,根据入射光角度均匀反射开来,物体表面的颜色主要取决于散射光。

 ③镜面光:(specular)具有很强的方向性。

opneGL中的光照同样是状态机,所以要使用光照,就要:

gl.glEnable(GL10.GL_LIGHTING);

在启用了光照之后,就要对三种光进行设置,如果没有对任何一种光进行设置的话,我们所绘制的物体将会很难看得清楚,这里我们先来看全局环境光。

设置光:gl.glLightModelfv();

两个参数,第一个为光的类型,第二个为指定光数据的缓冲区。光与颜色类似,都是由r,g,b,a四个值组成,所以,我们要指定光数据的缓冲区,就要先定义一个数组来指定各个分量的值。

float [] global_ambient = {1,1,1,1};
然后将这个数组转换成浮点缓冲区,就是第二个参数了。

为方便观察,我们设置一个透明的Dialog附在已经写好的Renderer上面,通过复选按钮控制是否开启光照,通过Seekbar控制r,g,b各分量值,如下图所示:

首先在Layout中画好xml,然后在Mainactivity中创建一个Dialog:

private void buildDialog() {
    d = new Dialog(this,android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
    d.setContentView(R.layout.light_setting);
    d.show();
}
注:主题要为透明,不然看不见后面的效果。

然后就需要为复选框和三个seekbar加监听器了,发现如果一个一个加监听器很麻烦,所以就要用到反射:

try {
    Class clazz = R.id.class;
    Field [] fs = clazz.getDeclaredFields();

    CheckBox box = null;
    SeekBar bar = null;

    for( Field f : fs ){
        int id = (Integer)f.get(null);
        View view = d.findViewById(id);
        if( view != null ){
            if( view instanceof CheckBox ){
                box = (CheckBox) view;
                box.setOnCheckedChangeListener(box1);
            }else if( view instanceof SeekBar ){
                bar = (SeekBar) view;
                bar.setOnSeekBarChangeListener(bar1);
            }
        }
    }
} catch (Exception e) {
    e.printStackTrace();
}
然后在监听器中对Checkbox和SeekBar进行处理就OK。

运行效果图:

附代码:

public class MyLightingRenderer extends AbstractRenderer{
    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//设置清屏色
        gl.glColor4f(1f, 1f, 1f, 1f);//设置绘图颜色
        gl.glMatrixMode(GL10.GL_MODELVIEW);//模型视图矩阵
        gl.glLoadIdentity();//加载单位矩阵
        GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);//放置眼球位置
        gl.glRotatef(xRotate, 1, 0, 0);//x轴旋转角度
        gl.glRotatef(yRotate, 0, 1, 0);//y轴旋转角度
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT);
        gl.glEnable(GL10.GL_DEPTH_TEST);

        gl.glColor4f(1f,1f,1f,1f);

        /*********************光照**************************/
        if(open_lighting){
            //启用光照
            gl.glEnable(GL10.GL_LIGHTING);
        }else{
            //禁止光照
            gl.glDisable(GL10.GL_LIGHTING);
        }
        float [] global_ambient = {r,g,b,a,};
        //设置全局环境光
        gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT,BufferUtils.arr2FloatBuffer(global_ambient));
        //画一个球
        BufferUtils.drawSphere(gl,0.4f,8,8);


    }
}
public class MainActivity extends Activity {
    private AbstractRenderer renderer;
    MyGLSurfaceView view;
    private Dialog d;
    private Resources r;


    protected void onCreate(Bundle savedInstanceState) {
        r = this.getResources();
        super.onCreate(savedInstanceState);
        view = new MyGLSurfaceView(this);
        //render渲染器
        renderer = new MyLightingRenderer();
//        view.setEGLConfigChooser(5,6,5,0,8,8);
        view.setRenderer(renderer);
//        view.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//默认渲染模式,持续渲染。
//        view.setRenderMode( GLSurfaceView.RENDERMODE_WHEN_DIRTY );//脏渲染(命令渲染)脏渲染模式下ondrawframe()方法只调用一次。
        setContentView(view);
        buildDialog();
        addCheckBoxEvent();
    }

    //添加复选框事件
    private void addCheckBoxEvent() {
        //匿名内部类:box监听
        CompoundButton.OnCheckedChangeListener box1 = new CompoundButton.OnCheckedChangeListener() {
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                /*
                //通过反射实现
                try {
                    int id = buttonView.getId();
                    String name = r.getResourceName( id );
                    Log.i("xiaoyu",name);
                    name.substring(name.lastIndexOf("_") + 1);
                    Class clazz = renderer.getClass();
                    Field f = clazz.getField(name);
                    f.setAccessible(true);
                    f.set(renderer,isChecked);
                } catch (Exception e) {
                    e.printStackTrace();
                }*/
                renderer.open_lighting = isChecked;

            }
        };
        //seekbar监听
        final SeekBar.OnSeekBarChangeListener bar1 = new SeekBar.OnSeekBarChangeListener(){
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                float scale = (float)progress/(float)seekBar.getMax();
                switch (seekBar.getId()){
                    case R.id.sb_r:
                        renderer.r = scale;
                    case R.id.sb_g:
                        renderer.g = scale;
                    case R.id.sb_b:
                        renderer.b = scale;
                }
            }
            public void onStartTrackingTouch(SeekBar seekBar) {

            }
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        };
/**************************利用反射给CheckBox和三个SeekBar加监听器*********************************/
        try {
            Class clazz = R.id.class;
            Field [] fs = clazz.getDeclaredFields();

            CheckBox box = null;
            SeekBar bar = null;

            for( Field f : fs ){
                int id = (Integer)f.get(null);
                View view = d.findViewById(id);
                if( view != null ){
                    if( view instanceof CheckBox ){
                        box = (CheckBox) view;
                        box.setOnCheckedChangeListener(box1);
                    }else if( view instanceof SeekBar ){
                        bar = (SeekBar) view;
                        bar.setOnSeekBarChangeListener(bar1);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void buildDialog() {
        d = new Dialog(this,android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
        d.setContentView(R.layout.light_setting);
        d.show();
    }


    class MyGLSurfaceView extends GLSurfaceView{

        public MyGLSurfaceView(Context context) {
            super(context);
        }

        public MyGLSurfaceView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        }





}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值