当前位置: 代码迷 >> Android >> 【Android开发学习17】Android OpenGL ES 日照市与混合glDrawElements
  详细解决方案

【Android开发学习17】Android OpenGL ES 日照市与混合glDrawElements

热度:34   发布时间:2016-05-01 11:36:38.0
【Android开发学习17】Android OpenGL ES 光照与混合glDrawElements

一、基础知识:


1..光照介绍:

环境光:
 来自四面八方,所有场景中的对象都处于环境光的照射中。

漫射光:
 由特定的光源产生,并在场景中的对象表面产生反射。
 处于漫射光直接照射下的任何对象表面都变得很亮,而几乎未被照射到的区域就显示得要暗一些。

 


2.光照使用:
①设定光源参数:
 //定义环境光(r,g,b,a)
 FloatBuffer lightAmbient = FloatBuffer.wrap(new float[]{0.5f,0.5f,0.5f,1.0f});
 //定义漫射光
 FloatBuffer lightDiffuse = FloatBuffer.wrap(new float[]{1.0f,1.0f,1.0f,1.0f});

 //定义光源的位置(前三个参数为坐标X,Y,Z; 第四个参数为1.0f,是告诉OpenGl这里指定的坐标就是光源的位置)
 FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f,0.0f,2.0f,1.0f});

②设置光源:
 glLightfv (
  int light,  // 光源的ID
  int pname,   // 光源的类型
  FloatBuffer params // 光源的数组
 )
设定的属性,主要由第二个参数决定:
GL_AMBIENT 环境光(光源泛光强度的RGBA值)
GL_DIFFUSE 漫射光(光源漫反射强度的RGBA值)
GL_SPECULAR 高光(光源镜面反射强度的RGBA值)
GL_POSITION 位置(光源的位置)
GL_SPOT_DIRECTION 方向(聚光灯的方向)
GL_SPOT_CUTOFF 光的角度(聚光灯的截止角度)

 //设置环境光
 gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient);
 //设置漫射光
 gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse);
 //设置光源的位置
 gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition);

③启用光源:
 //启用一号光源
 gl.glEnable(GL10.GL_LIGHT1);

 

3、混合实现:
如果开启混合,则根据Alpha值来显示透明效果;
如果未开启混合,则不会显示透明效果;

①在onSurfaceCreated方法中加入代码:
 //设置光线,,1.0f为全光线,a=50%
 gl.glColor4f(1.0f,1.0f,1.0f,0.5f); 
 // 基于源象素alpha通道值的半透明混合函数
 gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE); 

其中,glColor4f以全亮度绘制此物体,并对其进行50%的alpha混合(半透明)。
当混合选项打开时,此物体将会产生50%的透明效果,
alpha通道的值为0.0意味着物体材质是完全透明的,
为1.0则意味着完全不透明。

 

②打开混合开关:      
 gl.glEnable(GL10.GL_BLEND);   // 打开混合

 

二、实现:

1. 界面编辑:
res\layout\main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    ><TextView      android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:text="@string/hello"    /></LinearLayout>


 

2.代码编辑:
\src\com\yarin\android\Examples\Activity01.java

package com.yarin.android.Examples_12_07;import android.app.Activity;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.opengl.GLSurfaceView;import android.os.Bundle;import android.view.KeyEvent;public class Activity01 extends Activity{	GLRender render = new GLRender();		/** Called when the activity is first created. */	@Override	public void onCreate(Bundle savedInstanceState)	{		super.onCreate(savedInstanceState);		GLImage.load(this.getResources());		GLSurfaceView glView = new GLSurfaceView(this);				glView.setRenderer(render);		setContentView(glView);	}}class GLImage{	public static Bitmap mBitmap;	public static void load(Resources resources)	{		mBitmap = BitmapFactory.decodeResource(resources, R.drawable.img);	}}


 

\src\com\yarin\android\Examples\GLRender.java

package com.yarin.android.Examples_12_07;import java.nio.ByteBuffer;import java.nio.FloatBuffer;import java.nio.IntBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.opengl.GLUtils;import android.opengl.GLSurfaceView.Renderer;import android.view.KeyEvent;public class GLRender implements Renderer{	boolean key = true;	float xrot, yrot;	float xspeed, yspeed;	float z = -5.0f;	int one = 0x10000;		//光线参数	FloatBuffer lightAmbient = FloatBuffer.wrap(new float[]{0.5f,0.5f,0.5f,1.0f}); 	FloatBuffer lightDiffuse = FloatBuffer.wrap(new float[]{1.0f,1.0f,1.0f,1.0f}); 	FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f,0.0f,2.0f,1.0f}); 		int filter = 1;		int [] texture;		IntBuffer vertices = IntBuffer.wrap(new int[]{			-one,-one,one,			one,-one,one,			one,one,one,			-one,one,one,						-one,-one,-one,			-one,one,-one,			one,one,-one,			one,-one,-one,						-one,one,-one,			-one,one,one,			one,one,one,			one,one,-one,						-one,-one,-one,			one,-one,-one,			one,-one,one,			-one,-one,one,						one,-one,-one,			one,one,-one,			one,one,one,			one,-one,one,						-one,-one,-one,			-one,-one,one,			-one,one,one,			-one,one,-one,				});		IntBuffer normals = IntBuffer.wrap(new int[]{			0,0,one,			0,0,one,			0,0,one,			0,0,one,						0,0,one,			0,0,one,			0,0,one,			0,0,one,						0,one,0,			0,one,0,			0,one,0,			0,one,0,						0,-one,0,			0,-one,0,			0,-one,0,			0,-one,0,						one,0,0,			one,0,0,			one,0,0,			one,0,0,						-one,0,0,			-one,0,0,			-one,0,0,			-one,0,0,	});		IntBuffer texCoords = IntBuffer.wrap(new int[]{		one,0,0,0,0,one,one,one,			0,0,0,one,one,one,one,0,		one,one,one,0,0,0,0,one,		0,one,one,one,one,0,0,0,		0,0,0,one,one,one,one,0,		one,0,0,0,0,one,one,one,	});		ByteBuffer indices = ByteBuffer.wrap(new byte[]{			0,1,3,2,			4,5,7,6,			8,9,11,10,			12,13,15,14,			16,17,19,18,			20,21,23,22,	});		@Override	public void onDrawFrame(GL10 gl)	{		// 清除屏幕和深度缓存		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);				gl.glMatrixMode(GL10.GL_MODELVIEW);		// 重置当前的模型观察矩阵		gl.glLoadIdentity();				gl.glEnable(GL10.GL_LIGHTING);				////////////////		gl.glTranslatef(0.0f, 0.0f, z);				//设置旋转		gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);		gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);		//设置纹理		gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[filter]);				gl.glNormalPointer(GL10.GL_FIXED, 0, normals);		gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices);		gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords);		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);						//绘制四边形		gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24,  GL10.GL_UNSIGNED_BYTE, indices);			    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);	    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);	    gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);	    //修改旋转角度	    xrot+=0.3f; 	    yrot+=0.2f;	    	    //gl.glDisable(GL10.GL_BLEND);		// 关闭混合	    //gl.glEnable(GL10.GL_DEPTH_TEST);	// 打开深度测试	    ///*	    //混合开关	    if (key)		{	    	gl.glEnable(GL10.GL_BLEND);			// 打开混合	    	gl.glDisable(GL10.GL_DEPTH_TEST);	// 关闭深度测试		}	    else 	    {	    	gl.glDisable(GL10.GL_BLEND);		// 关闭混合	    	gl.glEnable(GL10.GL_DEPTH_TEST);	// 打开深度测试		}		//*/	}	@Override	public void onSurfaceChanged(GL10 gl, int width, int height)	{		float ratio = (float) width / height;		//设置OpenGL场景的大小		gl.glViewport(0, 0, width, height);		//设置投影矩阵		gl.glMatrixMode(GL10.GL_PROJECTION);		//重置投影矩阵		gl.glLoadIdentity();		// 设置视口的大小		gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);		// 选择模型观察矩阵		gl.glMatrixMode(GL10.GL_MODELVIEW);			// 重置模型观察矩阵		gl.glLoadIdentity();	}	@Override	public void onSurfaceCreated(GL10 gl, EGLConfig config)	{		gl.glDisable(GL10.GL_DITHER);		// 告诉系统对透视进行修正		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);		// 黑色背景		gl.glClearColor(0, 0, 0, 0);				gl.glEnable(GL10.GL_CULL_FACE);		// 启用阴影平滑		gl.glShadeModel(GL10.GL_SMOOTH);		// 启用深度测试		gl.glEnable(GL10.GL_DEPTH_TEST);				//设置光线,,1.0f为全光线,a=50%		gl.glColor4f(1.0f,1.0f,1.0f,0.5f);			// 基于源象素alpha通道值的半透明混合函数		gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE);				//纹理相关		IntBuffer textureBuffer = IntBuffer.allocate(3);		gl.glGenTextures(3, textureBuffer);		texture = textureBuffer.array();				gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0]);		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST); // ( NEW )		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST); // ( NEW )		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap, 0);				gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[1]);		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR); // ( NEW )		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR); // ( NEW )		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap, 0);				gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[2]);		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR); // ( NEW )		gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR); // ( NEW )		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap, 0);				//深度测试相关		gl.glClearDepthf(1.0f);		gl.glDepthFunc(GL10.GL_LEQUAL);		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);		gl.glEnable(GL10.GL_TEXTURE_2D);				//设置环境光	    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, lightAmbient);	    //设置漫射光	    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, lightDiffuse);	    //设置光源位置	    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition);	    	    //开启一号光源	    gl.glEnable(GL10.GL_LIGHT1);	    	    //开启混合	    gl.glEnable(GL10.GL_BLEND);	    	    key=true;	}}


 

 

三、效果:

 

 

 四、思考:

将四方体的每个面贴不同的图片,实现效果如下:

 

 

本文博客源地址:http://blog.csdn.net/ypist

 

  相关解决方案