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

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

代码如下:

1、Activity类代码

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;public class ParticleOpenglActivity extends Activity {GLSurfaceView gView;private ParticleRenderer particleRenderer;@Overridepublic 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到11private 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;// zgpar.zg = 0.0f;particles[loop] = par;}@Overridepublic 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则在原视角基础上加上zoomfloat 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;// 如果粒子生命小于0if (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();  }@Overridepublic 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();}@Overridepublic 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; //开始生命为1particles[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、运行效果:

android opengl es 粒子效果实例代码相关推荐

  1. 音视频开发之旅(16) OpenGL ES粒子效果-烟花爆炸

    目录 烟花爆竹场景和属性 实践以及遇到的问题 资料 收获 通过该篇的实践实现如下效果 一.烟花爆竹场景和属性 在上一篇 音视频开发之旅(15) OpenGL ES粒子系统 - 喷泉 的基础上 实现烟花 ...

  2. 音视频开发系列(41)OpenGL ES粒子效果-烟花爆炸

    通过该篇的实践实现如下效果 一.烟花爆竹场景和属性 在上一篇OpenGL ES粒子系统 - 喷泉的基础上 实现烟花爆炸效果. 在具体实践之前,先来想一想,烟花爆炸的场景和属性 场景:从中心点开始爆炸, ...

  3. 【Android OpenGL ES】阅读hello-gl2代码(二)Java代码

    AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xm ...

  4. Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...

  5. Android OpenGL ES 学习(五) -- 渐变色

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...

  6. Android OpenGL ES 学习(二) -- 图形渲染管线和GLSL

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...

  7. android平台下OpenGL ES 3.0实例详解顶点属性、顶点数组

    OpenGL ES 3.0学习实践 android平台下OpenGL ES 3.0从零开始 android平台下OpenGL ES 3.0绘制纯色背景 android平台下OpenGL ES 3.0绘 ...

  8. Android OpenGL ES 学习(九) – 坐标系统和实现3D效果

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...

  9. Android 自定义 圆环,Android自定义view实现圆环效果实例代码

    先上效果图,如果大家感觉不错,请参考实现代码. 重要的是如何实现自定义的view效果 (1)创建类,继承view,重写onDraw和onMesure方法 public class CirclePerc ...

最新文章

  1. 网络推广网站总结降低网站跳出率的技巧有哪些?
  2. 计算硼原子的基态能级B---库仑排斥能
  3. PHP guzzle异步请求数据,怎么在PHP中使用Guzzle执行POST和GET请求
  4. Java进阶:ArrayList线程安全问题和解决方案
  5. 三、自然语言处理研究内容
  6. android chrome iframe设置src属性无法启动app
  7. java8 例外网站_Java8兰巴达斯和例外
  8. 静态注册BroadcastReceiver内部类
  9. 想成长为一名实战型架构师?7大实战技能经验分享
  10. html5 的有那些新标签,Html5新标签都有那些
  11. 3、electron打包生成exe文件
  12. C++ 前向声明(转载)
  13. PowerShell: 如何使用powershell处理Excel
  14. 联想微型计算机拆装图解,笔记本电脑的拆卸图解
  15. html5调查问卷的计分实验,问卷调查实验
  16. 联想主板9针开关接线图_家庭配电箱总漏电保护,空气开关用63A还是40A好?看完彻底懂了...
  17. web下拉菜单代码html,简单的单级下拉菜单实现_html/css_WEB-ITnose
  18. 俄罗斯最大的盗版资源网站,解封了!
  19. matlab中signal pulses,MATLAB信号处理仿真-基带脉冲成形的数字滤波器
  20. 2022年,人工智能和数据发展呈现哪五大趋势?

热门文章

  1. C++教程[又能学英文,又能学编程]
  2. 30 个 Python 的最佳实践、小贴士和技巧,不可错过哟!
  3. 点赞!一个程序员花了14小时寻找问题疫苗的流向
  4. 揭秘!月薪30K的大牛到底看了哪些视频?【共2000G】
  5. 今日测试:javascript笔试最常见的一道题
  6. 外国小哥,把整个 CNN 都给可视化了,卷积、池化清清楚楚!
  7. 史上最全AI论文集结:近千篇论文分门别类整理好
  8. R统计绘图 - 热图美化
  9. bootsrap 外边距_Bootstrap 网格系统布局详解
  10. pyqt界面屏幕分辨率自适应_在Qt5和PyQt5中设置支持高分辨率屏幕自适应的方法