android opengl es 粒子效果实例代码


概述:粒子系统采用许多形状简单的微小粒子作为基本元素,用它们来表示不规则模糊物体,系统中的每个粒子都有各自的生命周期,我们可以管理它们从创建到消亡的时间,它们都要经历“产生”、“运动”、“消亡”这三个阶段。

下面我们做个简单的粒子效果,但感觉我做的效果跟原先想象的,有点不一样,还得继续改进,呵呵。

代码如下:


1、Activity类代码

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class ParticleOpenglActivity extends Activity {
    GLSurfaceView gView;
    private ParticleRenderer particleRenderer;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        initBitmap.init(this.getResources());
        gView = new GLSurfaceView(this);
        particleRenderer = new ParticleRenderer();
        gView.setRenderer(particleRenderer);
        setContentView(gView);
    }
}

2、bitmap初始化类

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
/**
 * 将图片转成bitmap
 * 
 *
 */
public class initBitmap {

	public static Bitmap bitmap;
	
	public static void init(Resources res){
		bitmap = BitmapFactory.decodeResource(res, R.drawable.particle3) ;
	}
}

3、粒子属性类


/**
 * 
 * 粒子属性类
 *
 */
public class Particle {
	boolean active; //是否激活状态
	float live;//粒子生命
	float fade; //衰减速度
	
	float r;  //红色值
	float g;  //绿色值
	float b;  //蓝色值
	
	//变量x.y和z控制粒子在屏幕上显示的位置.

	float x;  //x位置
	float y;  //y位置
	float z;  //z位置
	
	//这三个变量控制粒子在每个轴上移动的快慢和方向.如果xi是负价粒
	//子将会向左移动,正值将会向右移动.

	float xi; // x方向
	float yi; // y方向
	float zi; // z方向
	/**
	 * 每一个变量可被看成加速度.如果xg正值时,粒子将会被拉倒右边,负值
	 * 将拉向左边.所以如果粒子向左移动(负的)而我们给它一个正的加速度,粒子速度将变慢.
	 */
	float xg;  //x方向重力加速度
	float yg;  //y方向重力加速度
	float zg;  //z方向重力加速度
}

4、渲染类



import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Random;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.graphics.Bitmap;
import android.opengl.GLUtils;
import android.opengl.GLSurfaceView.Renderer;

/**
 * 粒子系统效果实现类
 *
 * date:2012-07-03
 */
public class ParticleRenderer implements Renderer {

	private int[] textures = new int[1];
	private Bitmap bitmap = initBitmap.bitmap;
	private static final int MAX_PARTICLE = 1000; //最大数
	private boolean rainbow = true; //是否为彩虹模式
	private float slowdown = 2.0f;//减速粒子
	private float xspeed ; //x方向上的速度
	private float yspeed;//y方向上的速度
	private float zoom = -30.0f;//沿Z轴缩放
	private int loop ; //循环变量
	private int color; //当前的颜色
	private int delay; //彩虹效果延迟
	private Random random = new Random();
	//创建一个粒子数组
	private Particle particles[] = new Particle[MAX_PARTICLE];
	//存储12中不同的颜色.对每一个颜色从0到11
	private float colors[][] = {
			{1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f},
			{0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f},
			{0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f}};
	
	FloatBuffer vertexBuffer;
	FloatBuffer coordBuffer;
	private float[] vertexs = new float[12];
	private float[] coords = new float[8];
	
	
	
	//初始化缓冲
	public void initBuffer(){
		ByteBuffer verbb = ByteBuffer.allocateDirect(vertexs.length * 4);
		verbb.order(ByteOrder.nativeOrder());
		vertexBuffer = verbb.asFloatBuffer();
		vertexBuffer.put(vertexs);
		vertexBuffer.position(0);
		
		ByteBuffer coordbb = ByteBuffer.allocateDirect(coords.length * 4);
		coordbb.order(ByteOrder.nativeOrder());
		coordBuffer = coordbb.asFloatBuffer();
		coordBuffer.put(coords);
		coordBuffer.position(0);
	}
	
	//随机生成0~999数
	public int rand(){
		return Math.abs(random.nextInt(1000));
	}
	// 初始化粒子
    public void initParticle(int num, int color, float xDir, float yDir,
            float zDir) {
        Particle par = new Particle();
        par.active = true;
        par.live = 1.0f;
        par.fade = rand() % 100 / 1000.0f + 0.003f;
       //我们分配粒子一种新的颜色.
        par.r = colors[color][0];
        par.g = colors[color][1];
        par.b = colors[color][2];

        // 在粒子从新设置之后,将给它新的移动速度/方向
        par.xi = xDir;
        par.yi = yDir;
        par.zi = zDir;
        
        par.xg = 0.0f;
        par.yg = -0.5f;
        // zg
        par.zg = 0.0f;

        particles[loop] = par;
    }
    
	@Override
	public void onDrawFrame(GL10 gl) {
		
		initBuffer();//初始化
		
		gl.glClear(GL10.GL_DEPTH_BUFFER_BIT|GL10.GL_COLOR_BUFFER_BIT);
		gl.glLoadIdentity();
		
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		
		//顶点和纹理设置
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, coordBuffer);
		
		for (loop = 0; loop < MAX_PARTICLE; loop++) {
            if (particles[loop].active) {  //激活
                // 返回X轴的位置
                float x = particles[loop].x;
                // 返回Y轴的位置
                float y = particles[loop].y;
                // 返回Z轴的位置,zoom则在原视角基础上加上zoom
                float z = particles[loop].z + zoom;
                // 设置粒子颜色
                gl.glColor4f(particles[loop].r, particles[loop].g,
                        particles[loop].b, particles[loop].live);
                
                coordBuffer.clear();
                vertexBuffer.clear();
                
                coordBuffer.put(1.0f);
                coordBuffer.put(1.0f);
                vertexBuffer.put(x + 0.5f);
                vertexBuffer.put(y + 0.5f);
                vertexBuffer.put(z);
                
                coordBuffer.put(1.0f);
                coordBuffer.put(0.0f);
                vertexBuffer.put(x + 0.5f);
                vertexBuffer.put(y);
                vertexBuffer.put(z);
                
                coordBuffer.put(0.0f);
                coordBuffer.put(1.0f);
                vertexBuffer.put(x);
                vertexBuffer.put(y + 0.5f);
                vertexBuffer.put(z);
                
                coordBuffer.put(0.0f);
                coordBuffer.put(0.0f);
                vertexBuffer.put(x);
                vertexBuffer.put(y);
                vertexBuffer.put(z);
                // 绘制
                gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
                
                //我们也重新设定粒子在屏幕中心放置.我们重新设定粒子的x,y和z位置为零
                particles[loop].x += particles[loop].xi / (slowdown * 1000);
                // 更新Y坐标的位置
                particles[loop].y += particles[loop].yi / (slowdown * 1000);
                // 更新Z坐标的位置
                particles[loop].z += particles[loop].zi / (slowdown * 1000);

                // 更新X轴方向速度大小
                particles[loop].xi += particles[loop].xg;
                // 更新Y轴方向速度大小
                particles[loop].yi += particles[loop].yg;
                // 更新Z轴方向速度大小
                particles[loop].zi += particles[loop].zg;

                // 减少粒子的生命值
                particles[loop].live -= particles[loop].fade;

                // 如果粒子生命小于0
                if (particles[loop].live < 0.0f) { 
                	
                    particles[loop] = new Particle();
                    particles[loop].active = true;
                    particles[loop].live = 1.0f; 
					particles[loop].fade = (float)(rand()%100)/1000.0f +0.003f;
					//我们也重新设定粒子在屏幕中心放置.我们重新设定粒子的x,y和z位置为零
					particles[loop].x = 0.0f;
					particles[loop].y = 0.0f;
					particles[loop].z = 0.0f;
					//在粒子从新设置之后,将给它新的移动速度/方向
					particles[loop].xi = xspeed +(float)((rand()%50)-33.0f)* 12.0f ;//x方向
					particles[loop].yi = yspeed+(float)((rand()%50)-33.0f) * 12.0f;//y方向
					particles[loop].zi = (float)((rand()%50)-33.0f)* 12.0f ; //z方向
					//最后我们分配粒子一种新的颜色.
					particles[loop].r = colors[color][0];
					particles[loop].g = colors[color][1];
					particles[loop].b = colors[color][2];
					
                }

            }
        }
			
			gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
			gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
			gl.glFinish();	
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// 设置场景大小
		gl.glViewport(0, 0, width, height);
		if (height == 0) {
			height = 1;
		}
		float ratio = (float) width / height;
		// 投影矩阵
		gl.glMatrixMode(GL10.GL_PROJECTION);
		// 重置视图
		gl.glLoadIdentity();
		// 设置视图的大小
		gl.glFrustumf(-ratio, ratio, -1, 1, 1, 200);
		// 设置观察模型
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
		// 黑色背景色
		gl.glClearColorx(0, 0, 0, 0);
		// 启用阴影平滑
		gl.glShadeModel(GL10.GL_SMOOTH);
		// 注意:关闭深度测试
		gl.glDisable(GL10.GL_DEPTH_TEST);
		//启用混合	
		gl.glEnable(GL10.GL_BLEND);
		

		// 启用纹理
		gl.glEnable(GL10.GL_TEXTURE_2D);
		// 创建纹理
		 gl.glGenTextures(1, textures, 0);
		// 绑定纹理
		 gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
		 //生成纹理
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

		//线性滤波
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
				GL10.GL_LINEAR);//放大时
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
				GL10.GL_LINEAR);//缩小时	
		
		/**
		 * 初始化所有的粒子
		 */
		for (loop = 0; loop < MAX_PARTICLE; loop++) {
			
			particles[loop] = new Particle();
			particles[loop].active = true; //激活
			particles[loop].live = 1.0f; //开始生命为1
			particles[loop].fade = (float)(rand()%100)/1000.0f + 0.003f;//随机生成衰减速率
			particles[loop].r = colors[loop *(12/MAX_PARTICLE)][0];
			particles[loop].g = colors[loop *(12/MAX_PARTICLE)][1];
			particles[loop].b = colors[loop *(12/MAX_PARTICLE)][2];
			
			particles[loop].xi = (float)((rand()%50)-26.0f)* 12.0f;//x方向
			particles[loop].yi = (float)((rand()%50)-25.0f)* 12.0f;//y方向
			particles[loop].zi = (float)((rand()%50)-25.0f)* 12.0f;//z方向
			
			particles[loop].xg = 0.0f; //x方向上的加速度
			particles[loop].yg = -0.9f;//y方向上的加速度
			particles[loop].zg = 0.0f;//z方向上的加速度
			
		}		
	}
}


5、运行效果:












  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android OpenGL ES 3 是 Android 平台上的三维图形渲染接口,它是基于 OpenGL ES 3.0 标准实现的。OpenGL ES 是一种面向嵌入式系统的精简版 OpenGL,它专门用于在移动设备等资源受限的环境中进行实时图形渲染。 Android OpenGL ES 3 带来了很多新的功能和改进,为开发者提供了更强大的图形渲染能力。其中一些重要的特性包括可编程着色器、多重采样抗锯齿、高精度着色、纹理压缩等。 通过可编程着色器,开发者可以通过编写自定义的顶点和片元着色器来实现更复杂的图形效果。这允许开发者更灵活地处理顶点和像素数据,从而实现更高质量的渲染。 多重采样抗锯齿是一种抗锯齿技术,通过在渲染过程中对像素进行多次采样,最后再对采样结果进行平均,从而减少图像边缘的锯齿状边缘。这可以提供更平滑和真实感的图像。 高精度着色是一项改进,它使得在渲染过程中可以使用更高精度的数据表示,从而减少了计算误差,提供更准确的渲染效果。 纹理压缩是一项优化技术,它允许图像纹理在被加载到 GPU 之前进行压缩,从而减少了纹理数据的存储空间和传输带宽。这可以提高应用程序的性能和效率。 综上所述,Android OpenGL ES 3 是一个强大的图形渲染接口,它增加了很多新功能和改进,可以帮助开发者实现更高质量、更真实感的图形效果,提高应用程序的性能和效率。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值