Brief shockwave experiment

This commit is contained in:
Anuken
2022-03-07 10:37:53 -05:00
parent 46489f9893
commit 5603672983
5 changed files with 186 additions and 27 deletions

View File

@@ -9,7 +9,9 @@ import arc.graphics.g3d.*;
import arc.graphics.gl.*;
import arc.math.geom.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
import mindustry.game.EventType.*;
import mindustry.type.*;
import static mindustry.Vars.*;
@@ -28,6 +30,7 @@ public class Shaders{
public static CloudShader clouds;
public static PlanetGridShader planetGrid;
public static AtmosphereShader atmosphere;
public static ShockwaveShader shockwave;
public static MeshShader mesh;
public static Shader unlit;
public static Shader screenspace;
@@ -67,6 +70,9 @@ public class Shaders{
atmosphere = new AtmosphereShader();
unlit = new LoadShader("planet", "unlit");
screenspace = new LoadShader("screenspace", "screenspace");
//disabled for now...
//shockwave = new ShockwaveShader();
}
public static class AtmosphereShader extends LoadShader{
@@ -350,6 +356,112 @@ public class Shaders{
}
}
public static class ShockwaveShader extends LoadShader{
static final int max = 64;
static final int size = 5;
static final String[] uniformNames = new String[max];
//x y radius life[1-0] lifetime
protected FloatSeq data = new FloatSeq();
protected boolean hadAny = false;
protected FrameBuffer buffer = new FrameBuffer();
public float lifetime = 20f;
static{
for(int i = 0; i < max; i++){
uniformNames[i] = "u_shockwaves[" + i + "]";
}
}
public ShockwaveShader(){
super("shockwave", "screenspace");
Events.run(Trigger.update, () -> {
if(state.isPaused()) return;
if(state.isMenu()){
data.size = 0;
return;
}
var items = data.items;
for(int i = 0; i < data.size; i += size){
//decrease lifetime
items[i + 3] -= Time.delta / items[i + 4];
if(items[i + 3] <= 0f){
//swap with head.
if(data.size > size){
System.arraycopy(items, data.size - size, items, i, size);
}
data.size -= size;
i -= size;
}
}
});
Events.run(Trigger.preDraw, () -> {
hadAny = data.size > 0;
if(hadAny){
buffer.resize(Core.graphics.getWidth(), Core.graphics.getHeight());
buffer.begin(Color.clear);
}
});
Events.run(Trigger.postDraw, () -> {
if(hadAny){
buffer.end();
Draw.blend(Blending.disabled);
buffer.blit(this);
Draw.blend();
}
});
}
@Override
public void apply(){
int count = data.size / 4;
setUniformi("u_shockwave_count", count);
if(count > 0){
setUniformf("u_resolution", Core.camera.width, Core.camera.height);
setUniformf("u_campos", Core.camera.position.x - Core.camera.width/2f, Core.camera.position.y - Core.camera.height/2f);
var items = data.items;
for(int i = 0; i < count; i++){
int offset = i * size;
setUniformf(uniformNames[i],
items[offset], items[offset + 1], //xy
items[offset + 2] * (1f - items[offset + 3]), //radius * time
items[offset + 3] //time
//lifetime ignored
);
}
}
}
public void add(float x, float y, float radius){
add(x, y, radius, 20f);
}
public void add(float x, float y, float radius, float lifetime){
//replace first entry
if(data.size / size >= max){
var items = data.items;
items[0] = x;
items[1] = y;
items[2] = radius;
items[3] = 1f;
items[4] = lifetime;
}else{
data.addAll(x, y, radius, 1f, lifetime);
}
}
}
public static class LoadShader extends Shader{
public LoadShader(String frag, String vert){
super(getShaderFi(vert + ".vert"), getShaderFi(frag + ".frag"));