openGL es2.0 粒子系统之烟花
生活随笔
收集整理的這篇文章主要介紹了
openGL es2.0 粒子系统之烟花
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、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 粒子系统之烟花的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端技能图谱笔记
- 下一篇: 京东云,走进产业数字化深处