Make block renderers aware of visible faces

This doesn't work entirely right, so it's disabled for the most part.
This commit is contained in:
Drew DeVault 2015-09-20 16:34:06 -04:00
parent 2d0ce96cc0
commit 35bac852e6
16 changed files with 129 additions and 58 deletions

View File

@ -18,16 +18,16 @@ namespace TrueCraft.Client.Rendering
}
public static VertexPositionNormalColorTexture[] RenderBlock(IBlockProvider provider, BlockDescriptor descriptor,
Vector3 offset, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Vector3 offset, int indiciesOffset, out int[] indicies)
{
var textureMap = provider.GetTextureMap(descriptor.Metadata);
if (textureMap == null)
textureMap = new Tuple<int, int>(0, 0); // TODO: handle this better
return Renderers[descriptor.ID].Render(descriptor, offset, textureMap, indiciesOffset, out indicies);
return Renderers[descriptor.ID].Render(descriptor, offset, faces, textureMap, indiciesOffset, out indicies);
}
public virtual VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
var texCoords = new Vector2(textureMap.Item1, textureMap.Item2);
var texture = new[]
@ -39,23 +39,42 @@ namespace TrueCraft.Client.Rendering
};
for (int i = 0; i < texture.Length; i++)
texture[i] *= new Vector2(16f / 256f);
return CreateUniformCube(offset, texture, indiciesOffset, out indicies, Color.White);
return CreateUniformCube(offset, texture, faces, indiciesOffset, out indicies, Color.White);
}
protected VertexPositionNormalColorTexture[] CreateUniformCube(Vector3 offset, Vector2[] texture, int indiciesOffset, out int[] indicies, Color color)
protected VertexPositionNormalColorTexture[] CreateUniformCube(Vector3 offset, Vector2[] texture,
VisibleFaces faces, int indiciesOffset, out int[] indicies, Color color)
{
indicies = new int[6 * 6];
var verticies = new VertexPositionNormalColorTexture[4 * 6];
faces = VisibleFaces.All; // Temporary
int totalFaces = 0;
uint f = (uint)faces;
while (f != 0)
{
if ((f & 1) == 1)
totalFaces++;
f >>= 1;
}
indicies = new int[6 * totalFaces];
var verticies = new VertexPositionNormalColorTexture[4 * totalFaces];
int[] _indicies;
int textureIndex = 0;
int sidesSoFar = 0;
for (int _side = 0; _side < 6; _side++)
{
if ((faces & VisibleForCubeFace[_side]) == 0)
{
textureIndex += 4;
continue;
}
var side = (CubeFace)_side;
var quad = CreateQuad(side, offset, texture, textureIndex % texture.Length, indiciesOffset,
out _indicies, color);
Array.Copy(quad, 0, verticies, _side * 4, 4);
Array.Copy(_indicies, 0, indicies, _side * 6, 6);
Array.Copy(quad, 0, verticies, sidesSoFar * 4, 4);
Array.Copy(_indicies, 0, indicies, sidesSoFar * 6, 6);
textureIndex += 4;
sidesSoFar++;
}
return verticies;
}
@ -86,6 +105,16 @@ namespace TrueCraft.Client.Rendering
NegativeY = 5
}
protected static readonly VisibleFaces[] VisibleForCubeFace =
{
VisibleFaces.South,
VisibleFaces.North,
VisibleFaces.East,
VisibleFaces.West,
VisibleFaces.Top,
VisibleFaces.Bottom
};
protected static readonly Vector3[][] CubeMesh;
protected static readonly Vector3[] CubeNormals =
@ -163,6 +192,12 @@ namespace TrueCraft.Client.Rendering
new Vector3(-0.5f, -0.5f, 0.5f),
new Vector3(0.5f, -0.5f, 0.5f)
};
// TEMP
return;
for (int i = 0; i < CubeMesh.Length; i++)
for (int j = 0; j < CubeMesh[0].Length; j++)
CubeMesh[i][j] *= new Vector3(0.5f);
}
}
}

View File

@ -54,9 +54,9 @@ namespace TrueCraft.Client.Rendering.Blocks
};
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
return CreateUniformCube(offset, Texture, indiciesOffset, out indicies, Color.White);
return CreateUniformCube(offset, Texture, faces, indiciesOffset, out indicies, Color.White);
}
}
}

View File

@ -91,14 +91,14 @@ namespace TrueCraft.Client.Rendering.Blocks
};
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
var texture = DryTexture;
if (descriptor.Metadata == (byte)FarmlandBlock.MoistureLevel.Moist)
texture = MoistTexture;
var overhead = new Vector3(0.5f, 0.5f, 0.5f);
var cube = CreateUniformCube(overhead, texture, indiciesOffset, out indicies, Color.White);
var cube = CreateUniformCube(overhead, texture, faces, indiciesOffset, out indicies, Color.White);
for (int i = 0; i < cube.Length; i++)
{
if (cube[i].Position.Y > 0)

View File

@ -93,7 +93,7 @@ namespace TrueCraft.Client.Rendering.Blocks
public static readonly Color BiomeColor = new Color(105, 169, 63);
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Microsoft.Xna.Framework.Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
var texture = Texture;
if (descriptor.Coordinates.Y < World.Height)
@ -103,7 +103,7 @@ namespace TrueCraft.Client.Rendering.Blocks
texture = SnowTexture;
}
}
var cube = CreateUniformCube(offset, texture, indiciesOffset, out indicies, Color.White);
var cube = CreateUniformCube(offset, texture, faces, indiciesOffset, out indicies, Color.White);
// Apply biome colors to top of cube
for (int i = (int)(CubeFace.PositiveY) * 4; i < (int)(CubeFace.PositiveY) * 4 + 4; i++)
{

View File

@ -25,7 +25,7 @@ namespace TrueCraft.Client.Rendering.Blocks
};
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
VertexPositionNormalColorTexture[] verticies;
Vector3 correction;
@ -54,7 +54,8 @@ namespace TrueCraft.Client.Rendering.Blocks
break;
default:
// Should never happen
verticies = CreateUniformCube(offset, Texture, indiciesOffset, out indicies, Color.White);
verticies = CreateUniformCube(offset, Texture, VisibleFaces.All,
indiciesOffset, out indicies, Color.White);
correction = Vector3.Zero;
break;
}

View File

@ -36,17 +36,20 @@ namespace TrueCraft.Client.Rendering.Blocks
};
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
switch ((WoodBlock.WoodType)descriptor.Metadata)
{
case WoodBlock.WoodType.Spruce:
return CreateUniformCube(offset, SpruceTextures, indiciesOffset, out indicies, GrassRenderer.BiomeColor);
return CreateUniformCube(offset, SpruceTextures, VisibleFaces.All,
indiciesOffset, out indicies, GrassRenderer.BiomeColor);
case WoodBlock.WoodType.Birch:
return CreateUniformCube(offset, BaseTextures, indiciesOffset, out indicies, GrassRenderer.BiomeColor);
return CreateUniformCube(offset, BaseTextures, VisibleFaces.All,
indiciesOffset, out indicies, GrassRenderer.BiomeColor);
case WoodBlock.WoodType.Oak:
default:
return CreateUniformCube(offset, BaseTextures, indiciesOffset, out indicies, GrassRenderer.BiomeColor);
return CreateUniformCube(offset, BaseTextures, VisibleFaces.All,
indiciesOffset, out indicies, GrassRenderer.BiomeColor);
}
}
}

View File

@ -124,17 +124,17 @@ namespace TrueCraft.Client.Rendering.Blocks
};
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
switch ((WoodBlock.WoodType)descriptor.Metadata)
{
case WoodBlock.WoodType.Spruce:
return CreateUniformCube(offset, SpruceTexture, indiciesOffset, out indicies, Color.White);
return CreateUniformCube(offset, SpruceTexture, faces, indiciesOffset, out indicies, Color.White);
case WoodBlock.WoodType.Birch:
return CreateUniformCube(offset, BirchTexture, indiciesOffset, out indicies, Color.White);
return CreateUniformCube(offset, BirchTexture, faces, indiciesOffset, out indicies, Color.White);
case WoodBlock.WoodType.Oak:
default:
return CreateUniformCube(offset, BaseTexture, indiciesOffset, out indicies, Color.White);
return CreateUniformCube(offset, BaseTexture, faces, indiciesOffset, out indicies, Color.White);
}
}
}

View File

@ -188,7 +188,8 @@ namespace TrueCraft.Client.Rendering.Blocks
}
}
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
if (descriptor.ID == SlabBlock.BlockID)
return RenderSlab(descriptor, offset, textureMap, indiciesOffset, out indicies);
@ -198,7 +199,9 @@ namespace TrueCraft.Client.Rendering.Blocks
protected virtual VertexPositionNormalColorTexture[] RenderSlab(BlockDescriptor descriptor, Vector3 offset, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
var result = CreateUniformCube(offset, GetTextureMap((SlabBlock.SlabMaterial)descriptor.Metadata), indiciesOffset, out indicies, Color.White);
var result = CreateUniformCube(offset,
GetTextureMap((SlabBlock.SlabMaterial)descriptor.Metadata), VisibleFaces.All,
indiciesOffset, out indicies, Color.White);
for (int i = 0; i < 6; i++)
{
var face = (CubeFace)i;
@ -227,9 +230,11 @@ namespace TrueCraft.Client.Rendering.Blocks
return result;
}
protected virtual VertexPositionNormalColorTexture[] RenderDoubleSlab(BlockDescriptor descriptor, Vector3 offset, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
protected virtual VertexPositionNormalColorTexture[] RenderDoubleSlab(BlockDescriptor descriptor,
Vector3 offset, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
return CreateUniformCube(offset, GetTextureMap((SlabBlock.SlabMaterial)descriptor.Metadata), indiciesOffset, out indicies, Color.White);
return CreateUniformCube(offset, GetTextureMap((SlabBlock.SlabMaterial)descriptor.Metadata),
VisibleFaces.All, indiciesOffset, out indicies, Color.White);
}
}
}

View File

@ -25,10 +25,10 @@ namespace TrueCraft.Client.Rendering.Blocks
};
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
var overhead = new Vector3(0.5f, 0.5f, 0.5f);
var cube = CreateUniformCube(overhead, Texture, indiciesOffset, out indicies, Color.White);
var cube = CreateUniformCube(overhead, Texture, faces, indiciesOffset, out indicies, Color.White);
var heightMultiplier = new Vector3(1, ((descriptor.Metadata + 1) / 16f), 1);
for (int i = 0; i < cube.Length; i++)
{

View File

@ -53,9 +53,9 @@ namespace TrueCraft.Client.Rendering.Blocks
};
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
return CreateUniformCube(offset, Texture, indiciesOffset, out indicies, Color.White);
return CreateUniformCube(offset, Texture, faces, indiciesOffset, out indicies, Color.White);
}
}
}

View File

@ -51,11 +51,11 @@ namespace TrueCraft.Client.Rendering.Blocks
};
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
var overhead = new Vector3(0.5f, 0.5f, 0.5f);
var centerized = new Vector3(7f / 16f, 0, 7f / 16f);
var cube = CreateUniformCube(overhead, Texture, indiciesOffset, out indicies, Color.White);
var cube = CreateUniformCube(overhead, Texture, VisibleFaces.All, indiciesOffset, out indicies, Color.White);
for (int i = 0; i < cube.Length; i++)
{
cube[i].Position.X *= 1f / 8f;

View File

@ -101,7 +101,7 @@ namespace TrueCraft.Client.Rendering.Blocks
}
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
if (descriptor.ID == RoseBlock.BlockID)
return RenderQuads(descriptor, offset, RoseTexture, indiciesOffset, out indicies, Color.White);

View File

@ -26,16 +26,16 @@ namespace TrueCraft.Client.Rendering.Blocks
};
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
// TODO: Rest of water rendering (shape and level and so on)
var overhead = new Vector3(0.5f, 0.5f, 0.5f);
var cube = CreateUniformCube(overhead, Texture, indiciesOffset, out indicies, Color.White);
var cube = CreateUniformCube(overhead, Texture, faces, indiciesOffset, out indicies, Color.DarkBlue);
for (int i = 0; i < cube.Length; i++)
{
if (cube[i].Position.Y > 0)
{
cube[i].Position.Y *= 15f / 16f;
cube[i].Position.Y *= 14f / 16f;
}
cube[i].Position += offset;
cube[i].Position -= overhead;

View File

@ -35,7 +35,7 @@ namespace TrueCraft.Client.Rendering
}
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
// Wheat is rendered by rendering the four vertical faces of a cube, then moving them
// towards the middle. We also render a second set of four faces so that you can see

View File

@ -82,19 +82,6 @@ namespace TrueCraft.Client.Rendering
return (result != null);
}
[Flags]
public enum VisibleFaces
{
None = 0,
North = 1,
South = 2,
East = 4,
West = 8,
Top = 16,
Bottom = 32,
All = North | South | East | West | Top | Bottom
}
private class RenderState
{
public readonly List<VertexPositionNormalColorTexture> Verticies
@ -139,16 +126,39 @@ namespace TrueCraft.Client.Rendering
{
continue;
}
if (chunk.GetBlockId(next) != 0)
var provider = BlockRepository.GetBlockProvider(chunk.GetBlockId(next));
if (provider.Opaque)
{
VisibleFaces faces;
state.DrawableCoordinates.TryGetValue(next, out faces);
if (!state.DrawableCoordinates.TryGetValue(next, out faces))
faces = VisibleFaces.None;
faces |= AdjacentCoordFaces[i];
state.DrawableCoordinates[next] = faces;
}
}
}
private void AddTransparentBlock(Coordinates3D coords, RenderState state, ReadOnlyChunk chunk)
{
// Add adjacent blocks
VisibleFaces faces = VisibleFaces.None;
for (int i = 0; i < AdjacentCoordinates.Length; i++)
{
var next = coords + AdjacentCoordinates[i];
if (next.X < 0 || next.X >= Chunk.Width
|| next.Y < 0 || next.Y >= Chunk.Height
|| next.Z < 0 || next.Z >= Chunk.Depth)
{
faces |= AdjacentCoordFaces[i];
continue;
}
if (chunk.GetBlockId(next) == 0)
faces |= AdjacentCoordFaces[i];
}
if (faces != VisibleFaces.None)
state.DrawableCoordinates[coords] = faces;
}
private void UpdateFacesFromAdjacent(Coordinates3D adjacent, ReadOnlyChunk chunk,
VisibleFaces mod, ref VisibleFaces faces)
{
@ -219,7 +229,11 @@ namespace TrueCraft.Client.Rendering
if (id != 0 && coords.Y == 0)
AddBottomBlock(coords, state, chunk);
if (!provider.Opaque)
{
AddAdjacentBlocks(coords, state, chunk);
if (id != 0)
AddTransparentBlock(coords, state, chunk);
}
else
{
if (coords.X == 0 || coords.X == Chunk.Width - 1 ||
@ -250,7 +264,7 @@ namespace TrueCraft.Client.Rendering
if (provider.RenderOpaque)
{
int[] i;
var v = BlockRenderer.RenderBlock(provider, descriptor,
var v = BlockRenderer.RenderBlock(provider, descriptor, coords.Value,
new Vector3(chunk.X * Chunk.Width + c.X, c.Y, chunk.Z * Chunk.Depth + c.Z),
state.Verticies.Count, out i);
state.Verticies.AddRange(v);
@ -259,7 +273,7 @@ namespace TrueCraft.Client.Rendering
else
{
int[] i;
var v = BlockRenderer.RenderBlock(provider, descriptor,
var v = BlockRenderer.RenderBlock(provider, descriptor, coords.Value,
new Vector3(chunk.X * Chunk.Width + c.X, c.Y, chunk.Z * Chunk.Depth + c.Z),
state.Verticies.Count, out i);
state.Verticies.AddRange(v);
@ -268,4 +282,17 @@ namespace TrueCraft.Client.Rendering
}
}
}
[Flags]
public enum VisibleFaces
{
None = 0,
North = 1,
South = 2,
East = 4,
West = 8,
Top = 16,
Bottom = 32,
All = North | South | East | West | Top | Bottom
}
}

View File

@ -24,7 +24,7 @@ namespace TrueCraft.Client.Rendering
}
public override VertexPositionNormalColorTexture[] Render(BlockDescriptor descriptor, Vector3 offset,
Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
VisibleFaces faces, Tuple<int, int> textureMap, int indiciesOffset, out int[] indicies)
{
return RenderQuads(descriptor, offset, Texture, indiciesOffset, out indicies, Color.White);
}