Skip to content

Commit

Permalink
1. add particle feature
Browse files Browse the repository at this point in the history
  • Loading branch information
AlbertSnow committed Jul 7, 2017
1 parent 7fa98e7 commit 1dfc7c4
Show file tree
Hide file tree
Showing 16 changed files with 707 additions and 16 deletions.
15 changes: 8 additions & 7 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.albertsnow.myapplication">

<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />

<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
<supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />

Expand All @@ -14,19 +17,17 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<activity android:name=".MainActivity">

</activity>

<activity android:name=".MainActivity"></activity>
<activity android:name=".game.AirHockeyActivity">
</activity>
<activity android:name=".particle.ParticleActivity"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public void setVertexAttribPointer(int dataOffset, int attributeLocation,
}




public void updateBuffer(float[] vertexData, int start, int count) {
floatBuffer.position(start);
floatBuffer.put(vertexData, start, count);
floatBuffer.position(0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.example.albertsnow.myapplication.objects;

import com.example.albertsnow.myapplication.util.Geometry;

import java.util.Random;

import static android.opengl.Matrix.multiplyMV;
import static android.opengl.Matrix.setRotateEulerM;


/**
* Created by albertsnow on 7/5/17.
*/

public class ParticleShooter {
private final Geometry.Point position;
private final Geometry.Vector direction;
private final int color;

private final float angleVariance;
private final float speedVariance;

private final Random random = new Random();

private float[] rotationMatrix = new float[16];
private float[] directionVector = new float[4];
private float[] resultVector = new float[4];

public ParticleShooter(Geometry.Point position, Geometry.Vector direction, int color,
float angleVarianceInDegrees, float speedVariance) {
this.position = position;
this.direction = direction;
this.color = color;

this.angleVariance = angleVarianceInDegrees;
this.speedVariance = speedVariance;

directionVector[0] = direction.x;
directionVector[1] = direction.y;
directionVector[2] = direction.z;
}

public void addParticles(ParticleSystem particleSystem, float currentTime, int count) {
for (int i = 0; i < count; i++) {
setRotateEulerM(rotationMatrix, 0,
(random.nextFloat() - 0.5f) * angleVariance,
(random.nextFloat() - 0.5f) * angleVariance,
(random.nextFloat() - 0.5f) * angleVariance);

multiplyMV(
resultVector, 0,
rotationMatrix, 0,
directionVector, 0
);

float speedAdjustment = 1f + random.nextFloat() * speedVariance;

Geometry.Vector thisDirection = new Geometry.Vector(
resultVector[0] * speedAdjustment,
resultVector[1] * speedAdjustment,
resultVector[2] * speedAdjustment
);

particleSystem.addParticle(position, color, thisDirection, currentTime);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.example.albertsnow.myapplication.objects;

import android.graphics.Color;
import android.opengl.GLES20;
import android.util.Log;

import com.example.albertsnow.myapplication.data.VertexArray;
import com.example.albertsnow.myapplication.programs.ParticleShaderProgram;
import com.example.albertsnow.myapplication.util.Constants;
import com.example.albertsnow.myapplication.util.Geometry;


/**
* Created by albertsnow on 7/5/17.
*/

public class ParticleSystem {
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 = 3;

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 * Constants.BYTES_PER_FLOAT;
private static final String TAG = "ParticleSystemTag";

private final float[] particles;
private final VertexArray vertexArray;
private final int maxParticleCount;

private int currentParticleCount;
private int nextParticle;

public ParticleSystem(int maxParticleCount) {
particles = new float[maxParticleCount * TOTAL_COMPONENT_COUNT];
vertexArray = new VertexArray(particles);
this.maxParticleCount = maxParticleCount;
}

public void addParticle(Geometry.Point position, int color, Geometry.Vector director,
float particleStartTime) {
final int particleOffset = nextParticle * TOTAL_COMPONENT_COUNT;
int currentOffset = particleOffset;
nextParticle++;

if (currentParticleCount < maxParticleCount) {
currentParticleCount++;
}

if (nextParticle == maxParticleCount) {
nextParticle = 0;
}

particles[currentOffset++] = position.x;
particles[currentOffset++] = position.y;
particles[currentOffset++] = position.z;

particles[currentOffset++] = Color.red(color) / 255f;
particles[currentOffset++] = Color.green(color) / 255f;
particles[currentOffset++] = Color.blue(color) / 255f;

particles[currentOffset++] = director.x;
particles[currentOffset++] = director.y;
particles[currentOffset++] = director.z;
particles[currentOffset++] = particleStartTime;

vertexArray.updateBuffer(particles, particleOffset, TOTAL_COMPONENT_COUNT);

Log.i(TAG, "add particles, size: " + nextParticle);
Log.i(TAG, "add particles, x: " + position.x);
Log.i(TAG, "add particles, y: " + position.y);
Log.i(TAG, "add particles, z: " + position.z);
}


public void bindData(ParticleShaderProgram particleShaderProgram) {
int dataOffset = 0;
vertexArray.setVertexAttribPointer(dataOffset,
particleShaderProgram.getPositionLocation(),
POSITION_COMPONENT_COUNT, STRIDE);
dataOffset += POSITION_COMPONENT_COUNT;

vertexArray.setVertexAttribPointer(dataOffset,
particleShaderProgram.getColorLocation(),
COLOR_COMPONENT_COUNT, STRIDE);
dataOffset += COLOR_COMPONENT_COUNT;

vertexArray.setVertexAttribPointer(dataOffset,
particleShaderProgram.getDirectionVectorLocation(),
VECTOR_COMPONENT_COUNT, STRIDE);
dataOffset += VECTOR_COMPONENT_COUNT;

vertexArray.setVertexAttribPointer(dataOffset,
particleShaderProgram.getParticleStartTimeLocation(),
PARTICLE_START_TIME_COMPONENT_COUNT, STRIDE);
}

public void draw() {
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, currentParticleCount);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.example.albertsnow.myapplication.particle;

import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import com.example.albertsnow.myapplication.view.ParticlesRenderer;

public class ParticleActivity extends AppCompatActivity {

private GLSurfaceView surfaceView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_particle);
surfaceView = new GLSurfaceView(this);
surfaceView.setEGLContextClientVersion(2);
surfaceView.setRenderer(new ParticlesRenderer());
surfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

setContentView(surfaceView);
}

@Override
protected void onPause() {
super.onPause();
surfaceView.onPause();
}

@Override
protected void onResume() {
super.onResume();
surfaceView.onResume();
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.example.albertsnow.myapplication.programs;

import android.opengl.GLES20;

import com.example.albertsnow.myapplication.MyApplication;
import com.example.albertsnow.myapplication.R;

/**
* Created by albertsnow on 6/29/17.
*/

public class ParticleShaderProgram extends ShaderProgram{

private final int uMatrixLocation;
private final int uTimeLocation;
private final int uTextureUnitLocation;

private final int aPositionLocation;
private final int aColorLocation;
private final int aDirectionVectorLocation;
private final int aParticleStartTimeLocation;


public ParticleShaderProgram() {
super(MyApplication.getApplication(), R.raw.particle_vertex_shader,
R.raw.particle_fragment_shader);
uMatrixLocation = GLES20.glGetUniformLocation(program, U_MATRIX);
uTimeLocation = GLES20.glGetUniformLocation(program, U_TIME);
uTextureUnitLocation = GLES20.glGetUniformLocation(program, U_TEXTURE_UNIT);

aPositionLocation = GLES20.glGetAttribLocation(program, A_POSITION);
aColorLocation = GLES20.glGetAttribLocation(program, A_COLOR);
aDirectionVectorLocation = GLES20.glGetAttribLocation(program, A_DIRECTION_VECTOR);
aParticleStartTimeLocation = GLES20.glGetAttribLocation(program, A_PARTICLE_START_TIME);
}

public void setUniform(float[] matrix, float elapsedTime, int textureId) {
GLES20.glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);
GLES20.glUniform1f(uTimeLocation, elapsedTime);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glUniform1i(uTextureUnitLocation, 0);
}

public int getPositionLocation() {
return aPositionLocation;
}

public int getColorLocation() {
return aColorLocation;
}

public int getDirectionVectorLocation() {
return aDirectionVectorLocation;
}

public int getParticleStartTimeLocation() {
return aParticleStartTimeLocation;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ public class ShaderProgram {
protected static final String U_MATRIX = "u_Matrix";
protected static final String U_COLOR = "u_Color";
protected static final String U_TEXTURE_UNIT = "u_TextureUnit";
protected static final String U_TIME = "u_Time";

// Attribute constants
protected static final String A_DIRECTION_VECTOR = "a_DirectionVector";
protected static final String A_PARTICLE_START_TIME = "a_ParticleStartTime";
protected static final String A_POSITION = "a_Position";
protected static final String A_COLOR = "a_Color";
protected static final String A_TEXTURE_COORDINATES = "a_TextureCoordinates";
Expand Down
Loading

0 comments on commit 1dfc7c4

Please sign in to comment.