Render voxels with an approximately-correct z-offset.

This commit is contained in:
Paul Chote
2016-08-09 10:15:44 +01:00
parent c312cf9171
commit f0306e7cc2
4 changed files with 50 additions and 12 deletions

View File

@@ -14,6 +14,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Primitives;
namespace OpenRA.Mods.Common.Graphics
{
@@ -107,7 +108,12 @@ namespace OpenRA.Mods.Common.Graphics
{
var groundPos = voxel.pos - new WVec(0, 0, wr.World.Map.DistanceAboveTerrain(voxel.pos).Length);
var groundZ = wr.World.Map.Grid.TileSize.Height * (groundPos.Z - voxel.pos.Z) / 1024f;
var pxOrigin = wr.ScreenPosition(voxel.pos);
var pxOrigin = wr.Screen3DPosition(voxel.pos);
// HACK: We don't have enough texture channels to pass the depth data to the shader
// so for now just offset everything forward so that the back corner is rendered at pos.
pxOrigin -= new float3(0, 0, Screen3DBounds(wr).Second.X);
var shadowOrigin = pxOrigin - groundZ * (new float2(renderProxy.ShadowDirection, 1));
var psb = renderProxy.ProjectedShadowBounds;
@@ -135,12 +141,13 @@ namespace OpenRA.Mods.Common.Graphics
var c = Color.Purple;
var psb = renderProxy.ProjectedShadowBounds;
// TODO: add float3 support to WorldRgbaColorRenderer
Game.Renderer.WorldRgbaColorRenderer.DrawPolygon(new[]
{
shadowOrigin + psb[1],
shadowOrigin + psb[3],
shadowOrigin + psb[0],
shadowOrigin + psb[2]
shadowOrigin + psb[1].XY,
shadowOrigin + psb[3].XY,
shadowOrigin + psb[0].XY,
shadowOrigin + psb[2].XY
}, iz, c);
// Draw voxel bounding box
@@ -190,6 +197,11 @@ namespace OpenRA.Mods.Common.Graphics
}
public Rectangle ScreenBounds(WorldRenderer wr)
{
return Screen3DBounds(wr).First;
}
Pair<Rectangle, float2> Screen3DBounds(WorldRenderer wr)
{
var pxOrigin = wr.ScreenPosition(voxel.pos);
var draw = voxel.voxels.Where(v => v.DisableFunc == null || !v.DisableFunc());
@@ -198,8 +210,11 @@ namespace OpenRA.Mods.Common.Graphics
var minX = float.MaxValue;
var minY = float.MaxValue;
var minZ = float.MaxValue;
var maxX = float.MinValue;
var maxY = float.MinValue;
var maxZ = float.MinValue;
foreach (var v in draw)
{
var bounds = v.Voxel.Bounds(v.FrameFunc());
@@ -208,7 +223,7 @@ namespace OpenRA.Mods.Common.Graphics
float sx, sy, sz;
wr.ScreenVectorComponents(v.OffsetFunc(), out sx, out sy, out sz);
var pxPos = pxOrigin + new float2(sx, sy);
var pxPos = pxOrigin + new float3(sx, sy, sz);
var screenTransform = OpenRA.Graphics.Util.MatrixMultiply(cameraTransform, worldTransform);
for (var i = 0; i < 8; i++)
@@ -217,12 +232,14 @@ namespace OpenRA.Mods.Common.Graphics
var screen = OpenRA.Graphics.Util.MatrixVectorMultiply(screenTransform, vec);
minX = Math.Min(minX, pxPos.X + screen[0]);
minY = Math.Min(minY, pxPos.Y + screen[1]);
minZ = Math.Min(minZ, pxPos.Z + screen[2]);
maxX = Math.Max(maxX, pxPos.X + screen[0]);
maxY = Math.Max(maxY, pxPos.Y + screen[1]);
maxZ = Math.Max(minZ, pxPos.Z + screen[2]);
}
}
return Rectangle.FromLTRB((int)minX, (int)minY, (int)maxX, (int)maxY);
return Pair.New(Rectangle.FromLTRB((int)minX, (int)minY, (int)maxX, (int)maxY), new float2(minZ, maxZ));
}
}
}