一、Java代码

package com.gzdxid.particles;import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.graphics.Color;
import android.opengl.GLES20;public class ParticleSystem {private int mProgram;private int muMVPMatrixHandle;private int muTimeHandle;private int maPositionHandle;private int maColorHandle;private int maDirectionVectorHandle;private int maParticleStartTimeHandle;private static final int BYTES_PER_FLOAT = 4;private static final int POSITION_COMPONENT_COUNT = 3;private static final int COLOR_COMPONENT_COUNT = 3;private static final int VECTOR_COMPONENT_COUNT = 3;private static final int PARTICLE_START_TIME_COMPONENT_COUNT = 1;private static final int TOTAL_COMPONENT_COUNT = POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT + VECTOR_COMPONENT_COUNT + PARTICLE_START_TIME_COMPONENT_COUNT;private static final int STRIDE = TOTAL_COMPONENT_COUNT * BYTES_PER_FLOAT;private int maxParticleCount;private float[] particles;private FloatBuffer mVertexArrayBuffer;private int nextParticle=0;private int currentParticleCount;private int[] vboID;public ParticleSystem(int maxParticleCount,int mProgram) {initVertex(maxParticleCount);initShader(mProgram);}private void initVertex(int maxParticleCount) {this.maxParticleCount=maxParticleCount;particles=new float[maxParticleCount*TOTAL_COMPONENT_COUNT];vboID=new int[1];ByteBuffer vbb=ByteBuffer.allocateDirect(maxParticleCount*TOTAL_COMPONENT_COUNT*4);vbb.order(ByteOrder.nativeOrder());mVertexArrayBuffer=vbb.asFloatBuffer();}private void initShader(int mProgram) {this.mProgram=mProgram;muMVPMatrixHandle=GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");muTimeHandle=GLES20.glGetUniformLocation(mProgram, "uTime");maPositionHandle=GLES20.glGetAttribLocation(mProgram, "aPosition");maColorHandle=GLES20.glGetAttribLocation(mProgram, "aColor");maDirectionVectorHandle=GLES20.glGetAttribLocation(mProgram, "aDirectionVector");maParticleStartTimeHandle=GLES20.glGetAttribLocation(mProgram, "aParticleStartTime");}public void addParticle(Point3 position,int color,Vector3 direction,float particleStartTime){int particleOffset=nextParticle*TOTAL_COMPONENT_COUNT;int currentOffset=particleOffset;nextParticle++;if(currentParticleCount<maxParticleCount){currentParticleCount++;}if(nextParticle==maxParticleCount){nextParticle=0;}particles[currentOffset++]=position.Px;particles[currentOffset++]=position.Py;particles[currentOffset++]=position.Pz;particles[currentOffset++]=Color.red(color)/255f;particles[currentOffset++]=Color.green(color)/255f;particles[currentOffset++]=Color.blue(color)/255f;particles[currentOffset++]=direction.Vx;particles[currentOffset++]=direction.Vy;particles[currentOffset++]=direction.Vz;particles[currentOffset++]=particleStartTime;mVertexArrayBuffer.position(particleOffset);mVertexArrayBuffer.put(particles, particleOffset, TOTAL_COMPONENT_COUNT);mVertexArrayBuffer.position(0);}public void drawSelf(float[] viewProjectionMatrix,float elapsedTime){int dataOffset=0;GLES20.glUseProgram(mProgram);GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, viewProjectionMatrix, 0);GLES20.glUniform1f(muTimeHandle, elapsedTime);GLES20.glGenBuffers(1, vboID,0);GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboID[0]);GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, mVertexArrayBuffer.capacity()*BYTES_PER_FLOAT, mVertexArrayBuffer, GLES20.GL_DYNAMIC_DRAW);GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboID[0]);GLES20.glEnableVertexAttribArray(maPositionHandle);GLES20.glVertexAttribPointer(maPositionHandle, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, dataOffset);dataOffset+=POSITION_COMPONENT_COUNT*BYTES_PER_FLOAT;GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboID[0]);GLES20.glEnableVertexAttribArray(maColorHandle);GLES20.glVertexAttribPointer(maColorHandle, COLOR_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, dataOffset);dataOffset+=COLOR_COMPONENT_COUNT*BYTES_PER_FLOAT;GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboID[0]);GLES20.glEnableVertexAttribArray(maDirectionVectorHandle);GLES20.glVertexAttribPointer(maDirectionVectorHandle, VECTOR_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, dataOffset);dataOffset+=VECTOR_COMPONENT_COUNT*BYTES_PER_FLOAT;GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboID[0]);GLES20.glEnableVertexAttribArray(maParticleStartTimeHandle);GLES20.glVertexAttribPointer(maParticleStartTimeHandle, PARTICLE_START_TIME_COMPONENT_COUNT, GLES20.GL_FLOAT, false, STRIDE, dataOffset);GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);GLES20.glDrawArrays(GLES20.GL_POINTS, 0, currentParticleCount);GLES20.glDeleteBuffers(1, vboID,0);GLES20.glDisableVertexAttribArray(maPositionHandle);GLES20.glDisableVertexAttribArray(maColorHandle);GLES20.glDisableVertexAttribArray(maDirectionVectorHandle);GLES20.glDisableVertexAttribArray(maParticleStartTimeHandle);}}
package com.gzdxid.particles;import java.util.Random;import android.opengl.Matrix;public class ParticleShooter {private Point3 position;private int color;private float angleVariance;private float speedVariance;private float[] directionVector=new float[4];private final Random random=new Random();private float[] resultVector=new float[4];private float[] rotationMatrix=new float[16];public ParticleShooter(Point3 position,Vector3 direction,int color,float angleVarianceInDegrees,float speedVariance) {this.position=position;this.color=color;this.speedVariance=speedVariance;this.angleVariance=angleVarianceInDegrees;directionVector[0]=direction.Vx;directionVector[1]=direction.Vy;directionVector[2]=direction.Vz;directionVector[3]=0;}public void toParticleSystem(ParticleSystem particleSystem,float currentTime,int count){for(int i=0;i<count;i++){Matrix.setRotateEulerM(rotationMatrix, 0, (random.nextFloat()-0.5f)*angleVariance,(random.nextFloat()-0.5f)*angleVariance, (random.nextFloat()-0.5f)*angleVariance);Matrix.multiplyMV(resultVector, 0, rotationMatrix, 0, directionVector, 0);float speedAdjustment=1f+random.nextFloat()*speedVariance;Vector3 thisDirection=new Vector3(resultVector[0]*speedAdjustment, resultVector[1]*speedAdjustment, resultVector[2]*speedAdjustment);particleSystem.addParticle(position, color, thisDirection, currentTime);}}
}
package com.gzdxid.particles;public class Vector3 {protected float Vx;protected float Vy;protected float Vz;public Vector3(float x,float y,float z) {Vx=x;Vy=y;Vz=z;}
}
package com.gzdxid.particles;public class Point3 {protected float Px;protected float Py;protected float Pz;public Point3(float x,float y,float z) {Px=x;Py=y;Pz=z;}
}

二、顶点着色器:

uniform mat4 uMVPMatrix;
uniform float uTime;attribute vec3 aPosition;
attribute vec3 aColor;
attribute vec3 aDirectionVector;
attribute float aParticleStartTime;varying vec3 vColor;
varying float vElapsedTime;void main()
{vColor=aColor;vElapsedTime=uTime-aParticleStartTime;vec3 currentPosition=aPosition+(aDirectionVector*vElapsedTime);float gravityFactor=vElapsedTime*vElapsedTime/10.0;currentPosition.y-=gravityFactor;gl_Position=uMVPMatrix*vec4(currentPosition,1.0);gl_PointSize=25.0;
}

三、片源着色器:

precision mediump float;varying vec3 vColor;
varying float vElapsedTime;void main()
{float xDistance=0.5-gl_PointCoord.x;float yDistance=0.5-gl_PointCoord.y;float distanceFromCenter=sqrt(xDistance*xDistance+yDistance*yDistance);if(distanceFromCenter>0.5){discard;}else{gl_FragColor=vec4(vColor/vElapsedTime,1.0);}
}

四、使用方法:

public void initParticle(){final Point3 position=new Point3(0, 0, 0);final Vector3 particleDirection=new Vector3(0f, 0.5f, 0);final float angleVarianceInDegrees=10f;final float speedVariance=1f;globalStartTime=System.nanoTime();particleSystem=new ParticleSystem(10000, ShaderManager.getParticleColorShaderProgram());particleShooter=new ParticleShooter(position, particleDirection, Color.rgb(255, 50, 5), angleVarianceInDegrees, speedVariance);grainShooter=new GrainShooter(2, 8000, ShaderManager.getGrainColorShaderProgram());}
private void drawParticle(){float currentTime=(System.nanoTime()-globalStartTime)/1000000000f;GLES20.glEnable(GLES20.GL_BLEND);GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE);MatrixState.pushMatrix();MatrixState.translate(-0.2f, -0.6f, 0);particleShooter.toParticleSystem(particleSystem, currentTime, 5);particleSystem.drawSelf(MatrixState.getFinalMatrix(),currentTime);MatrixState.popMatrix();GLES20.glDisable(GLES20.GL_BLEND);GLES20.glEnable(GLES20.GL_DEPTH_TEST);GLES20.glEnable(GLES20.GL_CULL_FACE);MatrixState.pushMatrix();MatrixState.rotate(-180, 1, 0, 0);MatrixState.translate(-0.2f, 0.2f, 0);grainShooter.drawSelf();MatrixState.popMatrix();GLES20.glDisable(GLES20.GL_DEPTH_TEST);GLES20.glDisable(GLES20.GL_CULL_FACE);}

openGL es2.0 粒子系统之烟花相关推荐

  1. Eclipse中通过Android模拟器调用OpenGL ES2.0函数操作步骤

    1.  先按照http://blog.csdn.net/fengbingchun/article/details/10439281中操作搭建好基本的Android开发环境: 2.  打开Eclipse ...

  2. OpenGL ES的性能范围(OpenGL ES2.0官方文档)

    http://blog.csdn.net/mengtnt/article/details/7773304 OpenGL ES 1.1和OpengGL ES2.0的规范中,都定义了每种实现必须支持的最低 ...

  3. iOS OpenGL ES2.0教程   Lesson03 旋转

    iOS OpenGL ES2.0教程    Lesson03  旋转 注:可供翻译的课程只有前两课.从这节课起,我试着根据我对OpenGL ES的理解写接下去的课程,希望能和大家一起学习. 在上节课中 ...

  4. 初识 OpenGL ES2.0

    原文链接:Android OpenGLES2.0(一)--了解OpenGLES2.0 OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API ...

  5. OpenGL ES2.0 – Iphone开发指引

    原文链接地址:http://www.raywenderlich.com/3664/opengl-es-2-0-for-iphone-tutorial 免责申明(必读!):本博客提供的所有教程的翻译原稿 ...

  6. opengl es2.0 渲染文字

    在OpenGL 家族中是没有提供直接渲染文字的接口,所以我们要在opengl中显示文字,就需要借助于其他的三方库或者自己解析绘制文字,然后使用opengl中的绘制接口去渲染出文字 这里我使用的free ...

  7. opengl es2.0 使用字符偏移图渲染文字

    在OpenGL 家族中是没有提供直接渲染文字的接口,所以我们要在opengl中显示文字,就需要借助于其他的三方库或者自己解析绘制文字,然后使用opengl中的绘制接口去渲染出文字 这里我使用的free ...

  8. android双指滑动方向,OpenGL ES2.0实现手指滑动平移、双指缩放Android

    主要是实现了手指在屏幕上滑动实现平移,两个手指进行缩放.主要是这部分矩阵还挺麻烦的. 效果图如下所示: 核心部分代码如下 触控事件处理: @SuppressLint("ClickableVi ...

  9. Android 基于OpenGL ES2.0 的CircleProgressBar

    之前想在播放器上加一个那种卡顿的转转提示: 类似: https://github.com/lsjwzh/MaterialLoadingProgressBar 这种效果的 由于当时没想到怎么在openg ...

最新文章

  1. tensorflow 做加法
  2. cross join
  3. 用 C 语言开发一门编程语言 — 变量元素设计
  4. 哪一个不是linux常用的shell,Linux下查看使用的是哪种shell的方法汇总
  5. grep -q用于if逻辑判断
  6. bzoj 3373: [Usaco2004 Mar]Lying Livestock 说谎的牲畜
  7. TeamCity安装
  8. java简历的专业技能,java程序员专业技能简历范文
  9. atmega168p与328p_atmega328P 写入 Boot Loader的那点事
  10. jsp在线预览Word文档操作步骤(自己测试的)
  11. 华为HCIE云计算培训笔记第一天
  12. 苹果cms永久免费影视建站程序
  13. 计算机运行慢提速小技巧,教你为Win7系统加速的五个技巧
  14. 国内首届 Flutter Festival 为热爱开启!
  15. extjs6 清除grid中combo列的值
  16. 中国云计算产业渐成熟 加速传统产业转型升级
  17. Google广告投放技巧,开始Google广告投放
  18. MATLAB--数字图像处理 特征点匹配
  19. 第九章 java常用类
  20. 电脑连不上手机热点问题

热门文章

  1. Eclipse中调试Python代码--调试FWTools2.4.7中的gdal_retile.py
  2. 联想RS550服务器安装Ubuntu16.04
  3. 微信开发公众号本地调试
  4. 老婆学计算机视频,教老婆学电脑-5.14
  5. SDH原理--1.SDH概述
  6. WiFi模块吞吐量测试
  7. 核心频率个加速频率_【硬件资讯】AMD:锐龙3系列加速频率再提2%
  8. 怎么调用计算机cad,CAD电脑版怎么使用教程
  9. poscms清除html,poscms用法总结(非定制开发,不涉及后台代码)
  10. Google Gmail Oauth Client ID 认证指南