OpenGL ES 镜面光照

1、修改 Draw.java 的drawSphere方法

static public void drawSphere(GL10 gl,float r,int tiers,int blocks,boolean isLines){
		float tiersAnger =(float) (Math.PI / tiers);      // 一个层的角度差
		float blockAngle =(float) ((Math.PI *2) / blocks);// 一个圆每个的角度差
		
		List<Float> pos =new ArrayList<Float>();
		for(int i =0;i <tiers; i++){
			//一次画两个圆层
			float alpha0 =(float) ((-Math.PI/2) +(i *tiersAnger)) ;
			float alpha1 =(float) ((-Math.PI/2) +((i +1) *tiersAnger)) ;
			//y 值
			float y0 =(float) (Math.sin(alpha0) *r);
			float y1 =(float) (Math.sin(alpha1) *r);
			//圆半径
			float r0 =Math.abs((float) (Math.cos(alpha0) *r));
			float r1 =Math.abs((float) (Math.cos(alpha1) *r));
			
			for(int j=0;j <=blocks; j++){
				//圆坐标
				float x0 = (float) (Math.cos(j *blockAngle) *r0);
				float z0 = (float) (Math.sin(j *blockAngle) *r0);
				
				float x1 = (float) (Math.cos(j *blockAngle) *r1);
				float z1 = (float) (Math.sin(j *blockAngle) *r1);
				
				pos.add(x0);
				pos.add(y0);
				pos.add(z0);
				pos.add(x1);
				pos.add(y1);
				pos.add(z1);
			}
		}
		
		ByteBuffer pBB =BufferUtil.list2ByteBuffer(pos);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, pBB);
		if (isLines){
			gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, pos.size()/3);
		}else{
			gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, pos.size()/3);
		}
	}
2、修改 MyAbstractRenderer.java

添加属性

//光源 位置x值
	protected float light0_x=0;
	//光源 位置y值
	protected float light0_y=0;
	
    public float getLight0_x() {
		return light0_x;
	}
	public void setLight0_x(float light0_x) {
		this.light0_x = light0_x;
	}
	public float getLight0_y() {
		return light0_y;
	}
	public void setLight0_y(float light0_y) {
		this.light0_y = light0_y;
	}
3、修改 MainActivity.java onTouchEvent方法

final int Frame_Width =720;
	final int Frame_High  =1280;
	//继承了Activity的onTouchEvent方法,直接监听点击事件  
	@Override
	public boolean onTouchEvent(MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN) {  
            //当手指按下的时候  
            x1 = event.getX();  
            y1 = event.getY();  
            //Frame_Width Frame_High 250根据自己的设备情况 自己设置符合的值
            float lightX = ((-Frame_Width/2)+x1)/250;
            float lightY = ((Frame_High/2)-y1)/250;
           
            renderer.setLight0_x(lightX);
            renderer.setLight0_y(lightY);
        }  
        if(event.getAction() == MotionEvent.ACTION_UP) {  
        	float step=5f;
    		float xRotate=renderer.getxRotate();
    		float yRotate=renderer.getyRotate();
            //当手指离开的时候  
            x2 = event.getX();  
            y2 = event.getY();  
            if(y1 - y2 > 100) {  
            	//向上滑
            	renderer.setxRotate(xRotate-step);
            } else if(y2 - y1 > 100) {  
            	//向下滑
            	renderer.setxRotate(xRotate+step);
            } else if(x1 - x2 > 100) {  
            	//向左滑
            	renderer.setyRotate(yRotate-step);
            } else if(x2 - x1 > 100) {  
            	//向右滑
            	renderer.setyRotate(yRotate+step);
            }  
        }  
		
		return super.onTouchEvent(event);
	}
4、新建 MyLightingRenderer2.java

/*
 * 光照 光源
 * openGL分为三种光
 * 环境光(全局光 ambient light)
 * 散射光(diffuse light)
 * 镜面光(specular light)
 */
public class MyLightingRenderer2 extends MyAbstractRenderer {

	public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
	    //设置清屏色(背景)
	    gl.glClearColor(0, 0, 0, 1);
	    //启用顶点缓冲区
	    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		//启用深度测试 
		gl.glEnable(GL10.GL_DEPTH_TEST);
	}
	protected void drawBefore(GL10 gl) {
		//清除颜色缓冲区 |深度缓冲区
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
		
//		gl.glShadeModel(GL10.GL_FLAT);
	}
	
	protected void draw(GL10 gl) {
		//启用光照
		gl.glEnable(GL10.GL_LIGHTING);
//		//全局 环境光
//		//默认值是{0.2 ,0.2 ,0.2 ,1.f} 是非常暗淡
//		float []global_ambient ={0.5f ,0f ,1f ,1f};
//		gl.glLightModelfv(GL10.GL_LIGHT_MODEL_AMBIENT, BufferUtil.arr2FloatBuffer(global_ambient));
		
		//重放法线规范化(在转换之后和光照之前,通过一个由模型矩阵计算出来的因子来对法线向量进行缩放)
		gl.glEnable(GL10.GL_RESCALE_NORMAL);
		//设置光源 支持8个光源
		//0号灯光 
		gl.glEnable(GL10.GL_LIGHT0);
		float []ambient_light ={0.3f ,0f ,0f ,1f};
		float []diffuse_light ={0.7f ,0f ,0f ,1f};
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT,BufferUtil.arr2FloatBuffer(ambient_light));
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE,BufferUtil.arr2FloatBuffer(diffuse_light));
		
		//镜面光 //如果不定义任何材料的镜 面反射属性,将不会看到任何镜面光效
		float specular_light[] ={0.0f ,0.0f ,1.0f,1.0f};
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR,BufferUtil.arr2FloatBuffer(specular_light));
		
		//设置关于位置
		//最后一个只是1.0表示这就是光源的位置,如果是0 表示光源位于无限远 得到平行光
		float []lightPos ={light0_x ,light0_y  ,3f ,1.0f};
		gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, BufferUtil.arr2FloatBuffer(lightPos));
		
		//设置光源切角 切角3度
		gl.glLightf(GL10.GL_LIGHT0, GL10.GL_SPOT_CUTOFF, 3);
		
		//颜色追踪  与物理世界一样 物体什么颜色 反射什么光 (glColor4f 设置的值再与 光的rgb亮度值相乘 为最终的rgb值)
		gl.glEnable(GL10.GL_COLOR_MATERIAL);
		gl.glColor4f(1, 0, 0, 1);
		
		//设置 材料属性
		//镜面光 需要单独设置 材料属性
		float gray[] ={0f ,0f ,1f ,1f};
		gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, BufferUtil.arr2FloatBuffer(gray));
		//设置材料的镜面指数(亮度,1~128) (好像没什么效果)
		gl.glMaterialx(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, 128);
		
		Draw.drawSphere(gl, 0.9f, 32, 32,true);
	}
}
4、运行结果 根据屏幕点击 光源位置不同

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值