Funny experiments with colored floors

This commit is contained in:
Anuken
2025-07-12 19:22:53 -04:00
parent e53201347f
commit 88b2f9c2bc
3 changed files with 112 additions and 3 deletions

View File

@@ -514,7 +514,14 @@ public class FloorRenderer{
@Override
protected void draw(Texture texture, float[] spriteVertices, int offset, int count){
throw new IllegalArgumentException("cache vertices unsupported");
if(spriteVertices.length != spriteSize){
throw new IllegalArgumentException("cached vertices must be in non-mixcolor format (20 per sprite, 5 per vertex)");
}
float[] verts = vertices;
int idx = vidx;
System.arraycopy(spriteVertices, offset, verts, idx, spriteSize);
vidx += spriteSize;
}
}
}

View File

@@ -2,9 +2,20 @@ package mindustry.world.blocks.environment;
import arc.graphics.*;
import arc.graphics.g2d.*;
import arc.math.geom.*;
import arc.util.*;
import mindustry.*;
import mindustry.world.*;
import mindustry.world.blocks.*;
public class ColoredFloor extends Floor{
/** If the alpha value of the color is set to this value, different colors are ignored and no border is drawn. */
public static final int flagIgnoreDifferentColor = 1;
/** If the alpha value of the color is set to this value, colors are interpolated across corners. This is essentially linear filtering for the whole "image". */
public static final int flagSmoothBlend = 2;
private static final float[] verts = new float[20];
public Color defaultColor = Color.white;
protected int defaultColorRgba;
@@ -23,10 +34,92 @@ public class ColoredFloor extends Floor{
public void drawBase(Tile tile){
//make sure to mask out the alpha channel - it's generally undesirable, and leads to invisible blocks when the data is not initialized
Draw.color(tile.extraData | 0xff);
super.drawBase(tile);
if((tile.extraData & 0xff) == flagSmoothBlend){
//Only autotiling is supported right now for the sake of simplicity
int bits = 0;
for(int i = 0; i < 8; i++){
Tile other = tile.nearby(Geometry.d8[i]);
//force flagIgnoreDifferentColor by bypassing checkAutotileSame
if(other != null && other.floor().blendGroup == blendGroup){
bits |= (1 << i);
}
}
var region = autotileRegions[TileBitmask.values[bits]];
float s = Vars.tilesize/2f;
float x = tile.worldx(), y = tile.worldy();
verts[0] = x - s;
verts[1] = y - s;
verts[2] = sample(this, tile.x, tile.y, tile.x - 1, tile.y - 1, tile.x, tile.y - 1, tile.x - 1, tile.y);
verts[3] = region.u;
verts[4] = region.v2;
verts[5] = x + s;
verts[6] = y - s;
verts[7] = sample(this, tile.x, tile.y, tile.x, tile.y - 1, tile.x + 1, tile.y - 1, tile.x + 1, tile.y);
verts[8] = region.u2;
verts[9] = region.v2;
verts[10] = x + s;
verts[11] = y + s;
verts[12] = sample(this, tile.x, tile.y, tile.x + 1, tile.y + 1, tile.x, tile.y + 1, tile.x + 1, tile.y);
verts[13] = region.u2;
verts[14] = region.v;
verts[15] = x - s;
verts[16] = y + s;
verts[17] = sample(this, tile.x, tile.y, tile.x - 1, tile.y + 1, tile.x, tile.y + 1, tile.x - 1, tile.y);
verts[18] = region.u;
verts[19] = region.v;
Draw.vert(region.texture, verts, 0, verts.length);
}else{
super.drawBase(tile);
}
Draw.color();
}
static float sample(Block target, int tx1, int ty1, int tx2, int ty2, int tx3, int ty3, int tx4, int ty4){
int total = 0;
float r = 0f, g = 0f, b = 0f;
Tile t1 = Vars.world.tile(tx1, ty1);
Tile t2 = Vars.world.tile(tx2, ty2);
Tile t3 = Vars.world.tile(tx3, ty3);
Tile t4 = Vars.world.tile(tx4, ty4);
//manually unrolled loops, hooray
if(t1 != null && t1.floor() == target){
total ++;
r += Color.ri(t1.extraData);
g += Color.gi(t1.extraData);
b += Color.bi(t1.extraData);
}
if(t2 != null && t2.floor() == target){
total ++;
r += Color.ri(t2.extraData);
g += Color.gi(t2.extraData);
b += Color.bi(t2.extraData);
}
if(t3 != null && t3.floor() == target){
total ++;
r += Color.ri(t3.extraData);
g += Color.gi(t3.extraData);
b += Color.bi(t3.extraData);
}
if(t4 != null && t4.floor() == target){
total ++;
r += Color.ri(t4.extraData);
g += Color.gi(t4.extraData);
b += Color.bi(t4.extraData);
}
return Color.toFloatBits((int)(r/total), (int)(g/total), (int)(b/total), 255);
}
@Override
public void drawOverlay(Tile tile){
//make sure color doesn't carry over
@@ -40,6 +133,11 @@ public class ColoredFloor extends Floor{
tile.extraData = defaultColorRgba;
}
@Override
public boolean checkAutotileSame(Tile tile, @Nullable Tile other){
return other != null && other.floor().blendGroup == blendGroup && ((tile.extraData & 0xff) == flagIgnoreDifferentColor || tile.extraData == other.extraData);
}
@Override
public int minimapColor(Tile tile){
return tile.extraData | 0xff;

View File

@@ -229,7 +229,7 @@ public class Floor extends Block{
for(int i = 0; i < 8; i++){
Tile other = tile.nearby(Geometry.d8[i]);
if(other != null && other.floor().blendGroup == blendGroup){
if(checkAutotileSame(tile, other)){
bits |= (1 << i);
}
}
@@ -246,6 +246,10 @@ public class Floor extends Block{
drawOverlay(tile);
}
public boolean checkAutotileSame(Tile tile, @Nullable Tile other){
return other != null && other.floor().blendGroup == blendGroup;
}
public int variant(int x, int y){
return Mathf.randomSeed(Point2.pack(x, y), 0, Math.max(0, variantRegions.length - 1));
}