Skip to content

Commit

Permalink
Improved liquid drawing
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkite committed Oct 22, 2013
1 parent 5a451ca commit 71ed376
Showing 1 changed file with 172 additions and 9 deletions.
181 changes: 172 additions & 9 deletions Terrafirma/Render.cs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,106 @@ public void Draw(int width, int height,
if (tile.type == 103) //bowl
if (tile.u == 18) texw = 14;

//solid tile adjacent to water
if (tileInfos[tile.type].solid && (tiles[sx - 1, sy].liquid > 0 ||
tiles[sx + 1, sy].liquid > 0 || tiles[sx, sy - 1].liquid > 0 ||
tiles[sx, sy + 1].liquid > 0))
{
byte waterMask = 0;
double sideLevel = 0.0;
int v = 4;
int waterw = 16;
int waterh = 16;
double xpad = 0.0;
double ypad = 0.0;
//lrtb
int mask = 0;
Tile edge;
if ((edge = tiles[sx - 1, sy]).liquid > 0)
{
sideLevel = edge.liquid;
mask |= 8; //left
if (edge.isLava)
waterMask |= 2;
else if (edge.isHoney)
waterMask |= 4;
else
waterMask |= 1;
}
if ((edge = tiles[sx + 1, sy]).liquid > 0)
{
sideLevel = edge.liquid;
mask |= 4; //right
if (edge.isLava)
waterMask |= 2;
else if (edge.isHoney)
waterMask |= 4;
else
waterMask |= 1;
}
if ((edge = tiles[sx, sy - 1]).liquid > 0)
{
mask |= 2; //top
if (edge.isLava)
waterMask |= 2;
else if (edge.isHoney)
waterMask |= 4;
else
waterMask |= 1;
}
else if (!edge.isActive || !tileInfos[edge.type].solid)
v = 0; // water has a ripple
if ((edge = tiles[sx, sy + 1]).liquid > 0)
{
if (edge.liquid > 240)
mask |= 1; //bottom is high enough
if (edge.isLava)
waterMask |= 2;
else if (edge.isHoney)
waterMask |= 4;
else
waterMask |= 1;
}
if ((waterMask & 3) != 3) //don't render if water *and* lava
{
int waterid = 0; //water
if ((waterMask & 2) == 2) //lava
waterid = 1;
if ((waterMask & 4) == 4) //honey
waterid = 11;
if ((mask & 0xc) != 0 && (mask & 1) == 1) //bottom and any side?
mask |= 0xc; //same as both sides
if (tile.half || tile.slope > 0) //half block or slope?
mask |= 0x10;
sideLevel = (256 - sideLevel) / 32.0;
if (mask == 2) //hlrTb
waterh = 4;
else if (mask == 0x12) //HlrTb
waterh = 12;
else if ((mask & 0xf) == 1) //lrtB
{
waterh = 4;
ypad = 12.0 * scale / 16.0;
}
else if ((mask & 2) != 2) //t
{
waterh = (int)(16 - sideLevel * 2);
ypad = sideLevel * 2.0 * scale / 16.0;
if ((mask & 0x1c) == 0x8) //!half Lr
waterw = 4;
if ((mask & 0x1c) == 0x4) //!half lR
{
waterw = 4;
xpad = 12 * scale / 16.0;
}
}
double alpha = waterid == 0 ? 0.5 : 0.85;
Texture tex = Textures.GetLiquid(waterid);
drawTextureAlpha(tex, waterw, waterh, v * tex.width * 4,
pixels, (int)(px + xpad - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, 0, alpha);
}
}

if (tile.type == 5 && tile.v >= 198 && tile.u >= 22) //tree leaves
{
Delayed delay = new Delayed();
Expand Down Expand Up @@ -676,15 +776,23 @@ public void Draw(int width, int height,
}
}
// draw liquid
if (tile.liquid > 0)
if (tile.liquid > 0 && (!tile.isActive || !tileInfos[tile.type].solid))
{
UInt32 c = tile.isLava ? lavaColor : tile.isHoney ? honeyColor : waterColor;
uint r = (uint)((c >> 16) * lightR);
uint g = (uint)(((c >> 8) & 0xff) * lightG);
uint b = (uint)((c & 0xff) * lightB);
c = (r << 16) | (g << 8) | b;
drawOverlay(c, tile.isLava ? 0.85 : 0.5, tile.liquid,
pixels, (int)(px - shiftx), (int)(py - shifty), width, height, scale / 16.0);
int waterLevel = (int)((255 - tile.liquid) / 16.0);
int waterid = 0;
if (tile.isLava) waterid = 1;
if (tile.isHoney) waterid = 11;
double alpha = waterid == 0 ? 0.5 : 0.85;
int waterh = 16 - waterLevel;
int v = 0;
double ypad = waterLevel * scale / 16.0;
//water above, no ripple
if (tiles[sx, sy - 1].liquid > 32 || (tiles[sx,sy-1].isActive && tileInfos[tiles[sx,sy-1].type].solid))
v = 4;

Texture tex = Textures.GetLiquid(waterid);
drawTextureAlpha(tex, 16, waterh, v * tex.width * 4,
pixels, (int)(px - shiftx), (int)(py + ypad - shifty), width, height, scale / 16.0, lightR, lightG, lightB, 0, alpha);
}
if (wires && tile.actuator)
{
Expand Down Expand Up @@ -1087,7 +1195,10 @@ void drawTexture(Texture tex, int bw, int bh, int tofs,
continue;
}
int t = tofs + (int)(y / zoom) * tex.width * 4;
if (t >= tex.data.Length) continue;
//if we go off the end of the texture (like with water)
//we should duplicate the last line.
while (t >= tex.data.Length)
t -= tex.width * 4;
int b = bofs;
for (int x = 0; x < tw; x++)
{
Expand Down Expand Up @@ -1123,6 +1234,58 @@ void drawTexture(Texture tex, int bw, int bh, int tofs,
bofs += w * 4;
}
}
void drawTextureAlpha(Texture tex, int bw, int bh, int tofs,
byte[] pixels, int px, int py,
int w, int h, double zoom, double lightR, double lightG, double lightB, byte paint, double alpha)
{
int tw = (int)(bw * zoom + 0.5);
int th = (int)(bh * zoom + 0.5);
int skipx = 0, skipy = 0;
if (px < 0) skipx = -px;
if (px + tw >= w) tw = w - px;
if (bw <= 0) return;
if (py < 0) skipy = -py;
if (py + th >= h) th = h - py;
if (bh <= 0) return;

int bofs = py * w * 4 + px * 4;
for (int y = 0; y < th; y++)
{
if (y < skipy)
{
bofs += w * 4;
continue;
}
int t = tofs + (int)(y / zoom) * tex.width * 4;
//if we go off the end of the texture (like with water)
//we should duplicate the last line.
while (t >= tex.data.Length)
t -= tex.width * 4;
int b = bofs;
for (int x = 0; x < tw; x++)
{
int tx = t + (int)(x / zoom) * 4;
if (x < skipx || tex.data[tx + 3] == 0)
{
b += 4;
continue;
}
byte blue = tex.data[tx++];
byte green = tex.data[tx++];
byte red = tex.data[tx++];
if (paint > 0)
applyPaint(paint, ref red, ref green, ref blue);
UInt32 c = (uint)(blue * lightB) | ((uint)(green * lightG) << 8) | ((uint)(red * lightR) << 16);
UInt32 orig = (UInt32)(pixels[b] | (pixels[b + 1] << 8) | (pixels[b + 2] << 16));
orig = alphaBlend(orig, c, alpha);
pixels[b++] = (byte)(orig & 0xff);
pixels[b++] = (byte)((orig >> 8) & 0xff);
pixels[b++] = (byte)((orig >> 16) & 0xff);
pixels[b++] = 0xff;
}
bofs += w * 4;
}
}
void drawTextureFlip(Texture tex, int bw, int bh, int tofs,
byte[] pixels, int px, int py,
int w, int h, double zoom, double lightR, double lightG, double lightB,byte paint)
Expand Down

0 comments on commit 71ed376

Please sign in to comment.