Use a single VB per chunk, instead of one per 1D atlas, and another one per 1D atlas for translucent

This commit is contained in:
UnknownShadow200 2018-05-31 15:40:02 +10:00
parent 8ed8d02cc1
commit 7a7c5f1586
10 changed files with 326 additions and 284 deletions

View File

@ -151,15 +151,15 @@ namespace ClassicalSharp {
int index = part.vIndex[Side.Left];
if (aY0_Z0 + aY1_Z1 > aY0_Z1 + aY1_Z0) {
part.vertices[index ] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col1_0);
part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
part.vertices[index + 2] = new VertexP3fT2fC4b(x1, y1, z2 + (count - 1), u2, v2, col0_1);
part.vertices[index + 3] = new VertexP3fT2fC4b(x1, y2, z2 + (count - 1), u2, v1, col1_1);
vertices[index ] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col1_0);
vertices[index + 1] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
vertices[index + 2] = new VertexP3fT2fC4b(x1, y1, z2 + (count - 1), u2, v2, col0_1);
vertices[index + 3] = new VertexP3fT2fC4b(x1, y2, z2 + (count - 1), u2, v1, col1_1);
} else {
part.vertices[index ] = new VertexP3fT2fC4b(x1, y2, z2 + (count - 1), u2, v1, col1_1);
part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col1_0);
part.vertices[index + 2] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
part.vertices[index + 3] = new VertexP3fT2fC4b(x1, y1, z2 + (count - 1), u2, v2, col0_1);
vertices[index ] = new VertexP3fT2fC4b(x1, y2, z2 + (count - 1), u2, v1, col1_1);
vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col1_0);
vertices[index + 2] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
vertices[index + 3] = new VertexP3fT2fC4b(x1, y1, z2 + (count - 1), u2, v2, col0_1);
}
part.vIndex[Side.Left] += 4;
}
@ -193,15 +193,15 @@ namespace ClassicalSharp {
int index = part.vIndex[Side.Right];
if (aY0_Z0 + aY1_Z1 > aY0_Z1 + aY1_Z0) {
part.vertices[index ] = new VertexP3fT2fC4b(x2, y2, z1, u1, v1, col1_0);
part.vertices[index + 1] = new VertexP3fT2fC4b(x2, y2, z2 + (count - 1), u2, v1, col1_1);
part.vertices[index + 2] = new VertexP3fT2fC4b(x2, y1, z2 + (count - 1), u2, v2, col0_1);
part.vertices[index + 3] = new VertexP3fT2fC4b(x2, y1, z1, u1, v2, col0_0);
vertices[index ] = new VertexP3fT2fC4b(x2, y2, z1, u1, v1, col1_0);
vertices[index + 1] = new VertexP3fT2fC4b(x2, y2, z2 + (count - 1), u2, v1, col1_1);
vertices[index + 2] = new VertexP3fT2fC4b(x2, y1, z2 + (count - 1), u2, v2, col0_1);
vertices[index + 3] = new VertexP3fT2fC4b(x2, y1, z1, u1, v2, col0_0);
} else {
part.vertices[index ] = new VertexP3fT2fC4b(x2, y2, z2 + (count - 1), u2, v1, col1_1);
part.vertices[index + 1] = new VertexP3fT2fC4b(x2, y1, z2 + (count - 1), u2, v2, col0_1);
part.vertices[index + 2] = new VertexP3fT2fC4b(x2, y1, z1, u1, v2, col0_0);
part.vertices[index + 3] = new VertexP3fT2fC4b(x2, y2, z1, u1, v1, col1_0);
vertices[index ] = new VertexP3fT2fC4b(x2, y2, z2 + (count - 1), u2, v1, col1_1);
vertices[index + 1] = new VertexP3fT2fC4b(x2, y1, z2 + (count - 1), u2, v2, col0_1);
vertices[index + 2] = new VertexP3fT2fC4b(x2, y1, z1, u1, v2, col0_0);
vertices[index + 3] = new VertexP3fT2fC4b(x2, y2, z1, u1, v1, col1_0);
}
part.vIndex[Side.Right] += 4;
}
@ -235,15 +235,15 @@ namespace ClassicalSharp {
int index = part.vIndex[Side.Front];
if (aX1_Y1 + aX0_Y0 > aX0_Y1 + aX1_Y0) {
part.vertices[index ] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v2, col1_0);
part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
part.vertices[index + 2] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_1);
part.vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_1);
vertices[index ] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v2, col1_0);
vertices[index + 1] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
vertices[index + 2] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_1);
vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_1);
} else {
part.vertices[index ] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_1);
part.vertices[index + 2] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_1);
part.vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v2, col1_0);
vertices[index ] = new VertexP3fT2fC4b(x1, y1, z1, u1, v2, col0_0);
vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_1);
vertices[index + 2] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_1);
vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v2, col1_0);
}
part.vIndex[Side.Front] += 4;
}
@ -277,15 +277,15 @@ namespace ClassicalSharp {
int index = part.vIndex[Side.Back];
if (aX1_Y1 + aX0_Y0 > aX0_Y1 + aX1_Y0) {
part.vertices[index ] = new VertexP3fT2fC4b(x1, y2, z2, u1, v1, col0_1);
part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y1, z2, u1, v2, col0_0);
part.vertices[index + 2] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z2, u2, v2, col1_0);
part.vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v1, col1_1);
vertices[index ] = new VertexP3fT2fC4b(x1, y2, z2, u1, v1, col0_1);
vertices[index + 1] = new VertexP3fT2fC4b(x1, y1, z2, u1, v2, col0_0);
vertices[index + 2] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z2, u2, v2, col1_0);
vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v1, col1_1);
} else {
part.vertices[index ] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v1, col1_1);
part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z2, u1, v1, col0_1);
part.vertices[index + 2] = new VertexP3fT2fC4b(x1, y1, z2, u1, v2, col0_0);
part.vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z2, u2, v2, col1_0);
vertices[index ] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v1, col1_1);
vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z2, u1, v1, col0_1);
vertices[index + 2] = new VertexP3fT2fC4b(x1, y1, z2, u1, v2, col0_0);
vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z2, u2, v2, col1_0);
}
part.vIndex[Side.Back] += 4;
}
@ -319,15 +319,15 @@ namespace ClassicalSharp {
int index = part.vIndex[Side.Bottom];
if (aX0_Z1 + aX1_Z0 > aX0_Z0 + aX1_Z1) {
part.vertices[index ] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z2, u2, v2, col1_1);
part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y1, z2, u1, v2, col0_1);
part.vertices[index + 2] = new VertexP3fT2fC4b(x1, y1, z1, u1, v1, col0_0);
part.vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v1, col1_0);
vertices[index ] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z2, u2, v2, col1_1);
vertices[index + 1] = new VertexP3fT2fC4b(x1, y1, z2, u1, v2, col0_1);
vertices[index + 2] = new VertexP3fT2fC4b(x1, y1, z1, u1, v1, col0_0);
vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v1, col1_0);
} else {
part.vertices[index ] = new VertexP3fT2fC4b(x1, y1, z2, u1, v2, col0_1);
part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y1, z1, u1, v1, col0_0);
part.vertices[index + 2] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v1, col1_0);
part.vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z2, u2, v2, col1_1);
vertices[index ] = new VertexP3fT2fC4b(x1, y1, z2, u1, v2, col0_1);
vertices[index + 1] = new VertexP3fT2fC4b(x1, y1, z1, u1, v1, col0_0);
vertices[index + 2] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z1, u2, v1, col1_0);
vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y1, z2, u2, v2, col1_1);
}
part.vIndex[Side.Bottom] += 4;
}
@ -361,15 +361,15 @@ namespace ClassicalSharp {
int index = part.vIndex[Side.Top];
if (aX0_Z0 + aX1_Z1 > aX0_Z1 + aX1_Z0) {
part.vertices[index ] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_0);
part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_0);
part.vertices[index + 2] = new VertexP3fT2fC4b(x1, y2, z2, u1, v2, col0_1);
part.vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v2, col1_1);
vertices[index ] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_0);
vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_0);
vertices[index + 2] = new VertexP3fT2fC4b(x1, y2, z2, u1, v2, col0_1);
vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v2, col1_1);
} else {
part.vertices[index ] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_0);
part.vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z2, u1, v2, col0_1);
part.vertices[index + 2] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v2, col1_1);
part.vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_0);
vertices[index ] = new VertexP3fT2fC4b(x1, y2, z1, u1, v1, col0_0);
vertices[index + 1] = new VertexP3fT2fC4b(x1, y2, z2, u1, v2, col0_1);
vertices[index + 2] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z2, u2, v2, col1_1);
vertices[index + 3] = new VertexP3fT2fC4b(x2 + (count - 1), y2, z1, u2, v1, col1_0);
}
part.vIndex[Side.Top] += 4;
}

View File

@ -36,6 +36,7 @@ namespace ClassicalSharp {
protected byte* counts;
protected int* bitFlags;
protected bool useBitFlags;
protected VertexP3fT2fC4b[] vertices;
bool BuildChunk(int x1, int y1, int z1, ref bool allAir) {
light = game.Lighting;
@ -162,9 +163,17 @@ namespace ClassicalSharp {
int x = info.CentreX - 8, y = info.CentreY - 8, z = info.CentreZ - 8;
if (!BuildChunk(x, y, z, ref info.AllAir)) return;
int totalVerts = TotalVerticesCount();
if (totalVerts == 0) return;
fixed (VertexP3fT2fC4b* ptr = vertices) {
// add an extra element to fix crashing on some GPUs
info.VbId = game.Graphics.CreateVb((IntPtr)ptr, VertexFormat.P3fT2fC4b, totalVerts + 1);
}
int offset = 0;
for (int i = 0; i < arraysCount; i++) {
SetPartInfo(normalParts[i], i, ref info.NormalParts);
SetPartInfo(translucentParts[i], i, ref info.TranslucentParts);
SetPartInfo(normalParts[i], ref offset, i, ref info.NormalParts);
SetPartInfo(translucentParts[i], ref offset, i, ref info.TranslucentParts);
}
#if OCCLUSION
@ -173,16 +182,13 @@ namespace ClassicalSharp {
#endif
}
void SetPartInfo(DrawInfo part, int i, ref ChunkPartInfo[] parts) {
void SetPartInfo(DrawInfo part, ref int offset, int i, ref ChunkPartInfo[] parts) {
int vertCount = part.VerticesCount();
if (vertCount == 0) return;
ChunkPartInfo info;
fixed (VertexP3fT2fC4b* ptr = part.vertices) {
// add an extra element to fix crashing on some GPUs
info.VbId = game.Graphics.CreateVb((IntPtr)ptr, VertexFormat.P3fT2fC4b, vertCount + 1);
}
info.VerticesCount = vertCount;
info.Offset = offset;
offset += vertCount;
info.LeftCount = (ushort)part.vCount[Side.Left];
info.RightCount = (ushort)part.vCount[Side.Right];
@ -193,8 +199,10 @@ namespace ClassicalSharp {
info.SpriteCount = part.spriteCount;
// Lazy initalize part arrays so we can save time in MapRenderer for chunks that only contain 1 or 2 part types.
if (parts == null)
if (parts == null) {
parts = new ChunkPartInfo[arraysCount];
for (int j = 0; j < parts.Length; j++) { parts[j].Offset = -1; }
}
parts[i] = info;
}

View File

@ -132,7 +132,7 @@ namespace ClassicalSharp {
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int col = fullBright ? FastColour.WhitePacked :
X >= offset ? light.LightCol_XSide_Fast(X - offset, Y, Z) : light.OutsideXSide;
drawer.Left(leftCount, col, texLoc, part.vertices, ref part.vIndex[Side.Left]);
drawer.Left(leftCount, col, texLoc, vertices, ref part.vIndex[Side.Left]);
}
if (rightCount != 0) {
@ -143,7 +143,7 @@ namespace ClassicalSharp {
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int col = fullBright ? FastColour.WhitePacked :
X <= (maxX - offset) ? light.LightCol_XSide_Fast(X + offset, Y, Z) : light.OutsideXSide;
drawer.Right(rightCount, col, texLoc, part.vertices, ref part.vIndex[Side.Right]);
drawer.Right(rightCount, col, texLoc, vertices, ref part.vIndex[Side.Right]);
}
if (frontCount != 0) {
@ -154,7 +154,7 @@ namespace ClassicalSharp {
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int col = fullBright ? FastColour.WhitePacked :
Z >= offset ? light.LightCol_ZSide_Fast(X, Y, Z - offset) : light.OutsideZSide;
drawer.Front(frontCount, col, texLoc, part.vertices, ref part.vIndex[Side.Front]);
drawer.Front(frontCount, col, texLoc, vertices, ref part.vIndex[Side.Front]);
}
if (backCount != 0) {
@ -165,7 +165,7 @@ namespace ClassicalSharp {
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int col = fullBright ? FastColour.WhitePacked :
Z <= (maxZ - offset) ? light.LightCol_ZSide_Fast(X, Y, Z + offset) : light.OutsideZSide;
drawer.Back(backCount, col, texLoc, part.vertices, ref part.vIndex[Side.Back]);
drawer.Back(backCount, col, texLoc, vertices, ref part.vIndex[Side.Back]);
}
if (bottomCount != 0) {
@ -175,7 +175,7 @@ namespace ClassicalSharp {
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int col = fullBright ? FastColour.WhitePacked : light.LightCol_YBottom_Fast(X, Y - offset, Z);
drawer.Bottom(bottomCount, col, texLoc, part.vertices, ref part.vIndex[Side.Bottom]);
drawer.Bottom(bottomCount, col, texLoc, vertices, ref part.vIndex[Side.Bottom]);
}
if (topCount != 0) {
@ -185,7 +185,7 @@ namespace ClassicalSharp {
DrawInfo part = isTranslucent ? translucentParts[i] : normalParts[i];
int col = fullBright ? FastColour.WhitePacked : light.LightCol_YTop_Fast(X, (Y + 1) - offset, Z);
drawer.Top(topCount, col, texLoc, part.vertices, ref part.vIndex[Side.Top]);
drawer.Top(topCount, col, texLoc, vertices, ref part.vIndex[Side.Top]);
}
}
}

View File

@ -35,7 +35,6 @@ namespace ClassicalSharp {
}
protected class DrawInfo {
public VertexP3fT2fC4b[] vertices;
public int[] vIndex = new int[6], vCount = new int[6];
public int spriteCount, sIndex, sAdvance;
@ -45,21 +44,18 @@ namespace ClassicalSharp {
return count;
}
public void ExpandToCapacity() {
int vertsCount = VerticesCount();
if (vertices == null || (vertsCount + 2) > vertices.Length) {
vertices = new VertexP3fT2fC4b[vertsCount + 2];
// ensure buffer is up to 64 bits aligned for last element
}
sIndex = 0;
public void CalcOffsets(ref int offset) {
sIndex = offset;
sAdvance = spriteCount / 4;
vIndex[Side.Left] = spriteCount;
vIndex[Side.Left] = spriteCount + offset;
vIndex[Side.Right] = vIndex[Side.Left] + vCount[Side.Left];
vIndex[Side.Front] = vIndex[Side.Right] + vCount[Side.Right];
vIndex[Side.Back] = vIndex[Side.Front] + vCount[Side.Front];
vIndex[Side.Bottom] = vIndex[Side.Back] + vCount[Side.Back];
vIndex[Side.Top] = vIndex[Side.Bottom] + vCount[Side.Bottom];
offset += VerticesCount();
}
public void ResetState() {
@ -92,10 +88,27 @@ namespace ClassicalSharp {
}
}
protected virtual void PostStretchTiles(int x1, int y1, int z1) {
int TotalVerticesCount() {
int vertsCount = 0;
for (int i = 0; i < normalParts.Length; i++) {
normalParts[i].ExpandToCapacity();
translucentParts[i].ExpandToCapacity();
vertsCount += normalParts[i].VerticesCount();
vertsCount += translucentParts[i].VerticesCount();
}
return vertsCount;
}
protected virtual void PostStretchTiles(int x1, int y1, int z1) {
int vertsCount = TotalVerticesCount();
if (vertices == null || (vertsCount + 2) > vertices.Length) {
vertices = new VertexP3fT2fC4b[vertsCount + 2];
// ensure buffer is up to 64 bits aligned for last element
}
// organised as: all N_0, all T_0, all N_1, all T1, etc
vertsCount = 0;
for (int i = 0; i < normalParts.Length; i++) {
normalParts[i].CalcOffsets(ref vertsCount);
translucentParts[i].CalcOffsets(ref vertsCount);
}
}
@ -142,31 +155,31 @@ namespace ClassicalSharp {
// Draw Z axis
int index = part.sIndex;
v.X = x1; v.Y = y1; v.Z = z1; v.U = u2; v.V = v2; part.vertices[index + 0] = v;
v.Y = y2; v.V = v1; part.vertices[index + 1] = v;
v.X = x2; v.Z = z2; v.U = u1; part.vertices[index + 2] = v;
v.Y = y1; v.V = v2; part.vertices[index + 3] = v;
v.X = x1; v.Y = y1; v.Z = z1; v.U = u2; v.V = v2; vertices[index + 0] = v;
v.Y = y2; v.V = v1; vertices[index + 1] = v;
v.X = x2; v.Z = z2; v.U = u1; vertices[index + 2] = v;
v.Y = y1; v.V = v2; vertices[index + 3] = v;
// Draw Z axis mirrored
index += part.sAdvance;
v.X = x2; v.Y = y1; v.Z = z2; v.U = u2; part.vertices[index + 0] = v;
v.Y = y2; v.V = v1; part.vertices[index + 1] = v;
v.X = x1; v.Z = z1; v.U = u1; part.vertices[index + 2] = v;
v.Y = y1; v.V = v2; part.vertices[index + 3] = v;
v.X = x2; v.Y = y1; v.Z = z2; v.U = u2; vertices[index + 0] = v;
v.Y = y2; v.V = v1; vertices[index + 1] = v;
v.X = x1; v.Z = z1; v.U = u1; vertices[index + 2] = v;
v.Y = y1; v.V = v2; vertices[index + 3] = v;
// Draw X axis
index += part.sAdvance;
v.X = x1; v.Y = y1; v.Z = z2; v.U = u2; part.vertices[index + 0] = v;
v.Y = y2; v.V = v1; part.vertices[index + 1] = v;
v.X = x2; v.Z = z1; v.U = u1; part.vertices[index + 2] = v;
v.Y = y1; v.V = v2; part.vertices[index + 3] = v;
v.X = x1; v.Y = y1; v.Z = z2; v.U = u2; vertices[index + 0] = v;
v.Y = y2; v.V = v1; vertices[index + 1] = v;
v.X = x2; v.Z = z1; v.U = u1; vertices[index + 2] = v;
v.Y = y1; v.V = v2; vertices[index + 3] = v;
// Draw X axis mirrored
index += part.sAdvance;
v.X = x2; v.Y = y1; v.Z = z1; v.U = u2; part.vertices[index + 0] = v;
v.Y = y2; v.V = v1; part.vertices[index + 1] = v;
v.X = x1; v.Z = z2; v.U = u1; part.vertices[index + 2] = v;
v.Y = y1; v.V = v2; part.vertices[index + 3] = v;
v.X = x2; v.Y = y1; v.Z = z1; v.U = u2; vertices[index + 0] = v;
v.Y = y2; v.V = v1; vertices[index + 1] = v;
v.X = x1; v.Z = z2; v.U = u1; vertices[index + 2] = v;
v.Y = y1; v.V = v2; vertices[index + 3] = v;
part.sIndex += 4;
}

View File

@ -231,12 +231,12 @@ namespace ClassicalSharp.Renderers {
info.OcclusionFlags = 0;
info.OccludedFlags = 0;
#endif
game.Graphics.DeleteVb(ref info.VbId);
if (info.NormalParts != null) {
ChunkPartInfo[] parts = info.NormalParts;
for (int i = 0; i < parts.Length; i++) {
game.Graphics.DeleteVb(ref parts[i].VbId);
if (parts[i].VerticesCount == 0) continue;
if (parts[i].Offset < 0) continue;
renderer.normalPartsCount[i]--;
}
info.NormalParts = null;
@ -245,8 +245,7 @@ namespace ClassicalSharp.Renderers {
if (info.TranslucentParts != null) {
ChunkPartInfo[] parts = info.TranslucentParts;
for (int i = 0; i < parts.Length; i++) {
game.Graphics.DeleteVb(ref parts[i].VbId);
if (parts[i].VerticesCount == 0) continue;
if (parts[i].Offset < 0) continue;
renderer.translucentPartsCount[i]--;
}
info.TranslucentParts = null;
@ -360,14 +359,14 @@ namespace ClassicalSharp.Renderers {
if (info.NormalParts != null) {
ChunkPartInfo[] parts = info.NormalParts;
for (int i = 0; i < parts.Length; i++) {
if (parts[i].VerticesCount == 0) continue;
if (parts[i].Offset < 0) continue;
renderer.normalPartsCount[i]++;
}
}
if (info.TranslucentParts != null) {
ChunkPartInfo[] parts = info.TranslucentParts;
for (int i = 0; i < parts.Length; i++) {
if (parts[i].VerticesCount == 0) continue;
if (parts[i].Offset < 0) continue;
renderer.translucentPartsCount[i]++;
}
}

View File

@ -11,7 +11,7 @@ using BlockID = System.UInt16;
namespace ClassicalSharp.Renderers {
public struct ChunkPartInfo {
public int VbId, VerticesCount, SpriteCount;
public int Offset, SpriteCount;
public ushort LeftCount, RightCount, FrontCount, BackCount, BottomCount, TopCount;
}
@ -25,6 +25,7 @@ namespace ClassicalSharp.Renderers {
public bool Visited = false, Occluded = false;
public byte OcclusionFlags, OccludedFlags, DistanceFlags;
#endif
public int VbId;
public ChunkPartInfo[] NormalParts;
public ChunkPartInfo[] TranslucentParts;
@ -42,7 +43,7 @@ namespace ClassicalSharp.Renderers {
}
}
public partial class MapRenderer {
public partial class MapRenderer {
Game game;
internal int _1DUsed = -1, chunksX, chunksY, chunksZ;
@ -177,10 +178,10 @@ namespace ClassicalSharp.Renderers {
if (info.NormalParts == null) continue;
ChunkPartInfo part = info.NormalParts[batch];
if (part.VerticesCount == 0) continue;
if (part.Offset < 0) continue;
usedNormal[batch] = true;
gfx.BindVb(part.VbId);
gfx.BindVb(info.VbId);
bool drawLeft = info.DrawLeft && part.LeftCount > 0;
bool drawRight = info.DrawRight && part.RightCount > 0;
bool drawBottom = info.DrawBottom && part.BottomCount > 0;
@ -188,7 +189,7 @@ namespace ClassicalSharp.Renderers {
bool drawFront = info.DrawFront && part.FrontCount > 0;
bool drawBack = info.DrawBack && part.BackCount > 0;
int offset = part.SpriteCount;
int offset = part.Offset + part.SpriteCount;
if (drawLeft && drawRight) {
gfx.FaceCulling = true;
gfx.DrawIndexedVb_TrisT2fC4b(part.LeftCount + part.RightCount, offset);
@ -231,20 +232,25 @@ namespace ClassicalSharp.Renderers {
}
if (part.SpriteCount == 0) continue;
offset = part.Offset;
int count = part.SpriteCount / 4; // 4 per sprite
gfx.FaceCulling = true;
if (info.DrawRight || info.DrawFront) {
gfx.DrawIndexedVb_TrisT2fC4b(count, 0); game.Vertices += count;
}
gfx.DrawIndexedVb_TrisT2fC4b(count, offset); game.Vertices += count;
} offset += count;
if (info.DrawLeft || info.DrawBack) {
gfx.DrawIndexedVb_TrisT2fC4b(count, count); game.Vertices += count;
}
gfx.DrawIndexedVb_TrisT2fC4b(count, offset); game.Vertices += count;
} offset += count;
if (info.DrawLeft || info.DrawFront) {
gfx.DrawIndexedVb_TrisT2fC4b(count, count * 2); game.Vertices += count;
}
gfx.DrawIndexedVb_TrisT2fC4b(count, offset); game.Vertices += count;
} offset += count;
if (info.DrawRight || info.DrawBack) {
gfx.DrawIndexedVb_TrisT2fC4b(count, count * 3); game.Vertices += count;
}
gfx.DrawIndexedVb_TrisT2fC4b(count, offset); game.Vertices += count;
} offset += count;
gfx.FaceCulling = false;
}
}
@ -256,10 +262,10 @@ namespace ClassicalSharp.Renderers {
if (info.TranslucentParts == null) continue;
ChunkPartInfo part = info.TranslucentParts[batch];
if (part.VerticesCount == 0) continue;
if (part.Offset < 0) continue;
usedTranslucent[batch] = true;
gfx.BindVb(part.VbId);
gfx.BindVb(info.VbId);
bool drawLeft = (inTranslucent || info.DrawLeft) && part.LeftCount > 0;
bool drawRight = (inTranslucent || info.DrawRight) && part.RightCount > 0;
bool drawBottom = (inTranslucent || info.DrawBottom) && part.BottomCount > 0;
@ -267,7 +273,7 @@ namespace ClassicalSharp.Renderers {
bool drawFront = (inTranslucent || info.DrawFront) && part.FrontCount > 0;
bool drawBack = (inTranslucent || info.DrawBack) && part.BackCount > 0;
int offset = 0;
int offset = part.Offset;
if (drawLeft && drawRight) {
gfx.DrawIndexedVb_TrisT2fC4b(part.LeftCount + part.RightCount, offset);
game.Vertices += (part.LeftCount + part.RightCount);

View File

@ -40,51 +40,39 @@ typedef struct Builder1DPart_ {
VertexP3fT2fC4b* fVertices[FACE_COUNT];
Int32 fCount[FACE_COUNT];
Int32 sCount, sOffset, sAdvance;
VertexP3fT2fC4b* vertices;
Int32 verticesBufferCount;
} Builder1DPart;
/* Part builder data, for both normal and translucent parts.
The first ATLAS1D_MAX_ATLASES_COUNT parts are for normal parts, remainder are for translucent parts. */
Builder1DPart Builder_Parts[ATLAS1D_MAX_ATLASES_COUNT * 2];
VertexP3fT2fC4b* Builder_Vertices;
Int32 Builder_VerticesElems;
static Int32 Builder1DPart_VerticesCount(Builder1DPart* part) {
Int32 count = part->sCount;
Int32 i;
Int32 i, count = part->sCount;
for (i = 0; i < FACE_COUNT; i++) { count += part->fCount[i]; }
return count;
}
static void Builder1DPart_Prepare(Builder1DPart* part) {
part->sOffset = 0;
part->sAdvance = (part->sCount / 4);
static void Builder1DPart_CalcOffsets(Builder1DPart* part, Int32* offset) {
Int32 pos = *offset, i;
part->sOffset = pos;
part->sAdvance = part->sCount >> 2;
/* ensure buffer can be accessed with 64 bytes alignment by putting 2 extra vertices at end. */
Int32 vCount = Builder1DPart_VerticesCount(part);
if (vCount > part->verticesBufferCount) {
Platform_MemFree(&part->vertices);
part->vertices = Platform_MemAlloc(vCount + 2, sizeof(VertexP3fT2fC4b));
part->verticesBufferCount = vCount;
if (part->vertices == NULL) {
ErrorHandler_Fail("Builder1DPart_Prepare - failed to allocate memory");
}
}
Int32 offset = part->sCount, i;
pos += part->sCount;
for (i = 0; i < FACE_COUNT; i++) {
part->fVertices[i] = &part->vertices[offset];
offset += part->fCount[i];
part->fVertices[i] = &Builder_Vertices[pos];
pos += part->fCount[i];
}
*offset = pos;
}
static void Builder1DPart_Reset(Builder1DPart* part) {
part->sCount = 0; part->sOffset = 0; part->sAdvance = 0;
Int32 i;
for (i = 0; i < FACE_COUNT; i++) {
part->fVertices[i] = NULL;
part->fCount[i] = 0;
static Int32 Builder_TotalVerticesCount(void) {
Int32 i, count = 0;
for (i = 0; i < ATLAS1D_MAX_ATLASES_COUNT * 2; i++) {
count += Builder1DPart_VerticesCount(&Builder_Parts[i]);
}
return count;
}
@ -101,22 +89,22 @@ static void Builder_AddVertices(BlockID block, Face face) {
part->fCount[face] += 4;
}
static void Builder_SetPartInfo(Builder1DPart* part, ChunkPartInfo* info, bool* hasParts) {
static void Builder_SetPartInfo(Builder1DPart* part, Int32* offset, ChunkPartInfo* info, bool* hasParts) {
Int32 vCount = Builder1DPart_VerticesCount(part);
info->Offset = -1;
if (vCount == 0) return;
/* add an extra element to fix crashing on some GPUs */
info->VbId = Gfx_CreateVb(part->vertices, VERTEX_FORMAT_P3FT2FC4B, vCount + 1);
info->HasVertices = true;
info->Offset = *offset;
*offset += vCount;
*hasParts = true;
info->XMinCount = (UInt16)part->fCount[FACE_XMIN];
info->XMaxCount = (UInt16)part->fCount[FACE_XMAX];
info->ZMinCount = (UInt16)part->fCount[FACE_ZMIN];
info->ZMaxCount = (UInt16)part->fCount[FACE_ZMAX];
info->YMinCount = (UInt16)part->fCount[FACE_YMIN];
info->YMaxCount = (UInt16)part->fCount[FACE_YMAX];
info->SpriteCountDiv4 = part->sCount >> 2;
info->Counts[FACE_XMIN] = part->fCount[FACE_XMIN];
info->Counts[FACE_XMAX] = part->fCount[FACE_XMAX];
info->Counts[FACE_ZMIN] = part->fCount[FACE_ZMIN];
info->Counts[FACE_ZMAX] = part->fCount[FACE_ZMAX];
info->Counts[FACE_YMIN] = part->fCount[FACE_YMIN];
info->Counts[FACE_YMAX] = part->fCount[FACE_YMAX];
info->SpriteCount = part->sCount;
}
@ -326,15 +314,20 @@ void Builder_MakeChunk(ChunkInfo* info) {
info->AllAir = allAir;
if (!hasMesh) return;
Int32 i, partsIndex = MapRenderer_Pack(x >> CHUNK_SHIFT, y >> CHUNK_SHIFT, z >> CHUNK_SHIFT);
Int32 totalVerts = Builder_TotalVerticesCount();
if (totalVerts == 0) return;
/* add an extra element to fix crashing on some GPUs */
info->VbId = Gfx_CreateVb(Builder_Vertices, VERTEX_FORMAT_P3FT2FC4B, totalVerts + 1);
Int32 i, offset = 0, partsIndex = MapRenderer_Pack(x >> CHUNK_SHIFT, y >> CHUNK_SHIFT, z >> CHUNK_SHIFT);
bool hasNormal = false, hasTranslucent = false;
for (i = 0; i < Atlas1D_Count; i++) {
for (i = 0; i < MapRenderer_1DUsedCount; i++) {
Int32 j = i + ATLAS1D_MAX_ATLASES_COUNT;
Int32 curIdx = partsIndex + i * MapRenderer_ChunksCount;
Builder_SetPartInfo(&Builder_Parts[i], &MapRenderer_PartsNormal[curIdx], &hasNormal);
Builder_SetPartInfo(&Builder_Parts[j], &MapRenderer_PartsTranslucent[curIdx], &hasTranslucent);
Builder_SetPartInfo(&Builder_Parts[i], &offset, &MapRenderer_PartsNormal[curIdx], &hasNormal);
Builder_SetPartInfo(&Builder_Parts[j], &offset, &MapRenderer_PartsTranslucent[curIdx], &hasTranslucent);
}
if (hasNormal) {
@ -361,18 +354,27 @@ static bool Builder_OccludedLiquid(Int32 chunkIndex) {
}
static void Builder_DefaultPreStretchTiles(Int32 x1, Int32 y1, Int32 z1) {
Int32 i;
for (i = 0; i < ATLAS1D_MAX_ATLASES_COUNT * 2; i++) {
Builder1DPart_Reset(&Builder_Parts[i]);
}
Platform_MemSet(Builder_Parts, 0, sizeof(Builder_Parts));
}
static void Builder_DefaultPostStretchTiles(Int32 x1, Int32 y1, Int32 z1) {
Int32 i;
for (i = 0; i < ATLAS1D_MAX_ATLASES_COUNT * 2; i++) {
Int32 vCount = Builder1DPart_VerticesCount(&Builder_Parts[i]);
if (vCount == 0) continue;
Builder1DPart_Prepare(&Builder_Parts[i]);
Int32 i, vertsCount = Builder_TotalVerticesCount();
if (vertsCount > Builder_VerticesElems) {
Platform_MemFree(&Builder_Vertices);
/* ensure buffer can be accessed with 64 bytes alignment by putting 2 extra vertices at end. */
Builder_Vertices = Platform_MemAlloc(vertsCount + 2, sizeof(VertexP3fT2fC4b));
Builder_VerticesElems = vertsCount;
if (Builder_Vertices == NULL) {
ErrorHandler_Fail("Builder1DPart_Prepare - failed to allocate memory");
}
}
vertsCount = 0;
for (i = 0; i < ATLAS1D_MAX_ATLASES_COUNT; i++) {
Int32 j = i + ATLAS1D_MAX_ATLASES_COUNT;
Builder1DPart_CalcOffsets(&Builder_Parts[i], &vertsCount);
Builder1DPart_CalcOffsets(&Builder_Parts[j], &vertsCount);
}
}
@ -410,31 +412,31 @@ static void Builder_DrawSprite(Int32 count) {
/* Draw Z axis */
Int32 index = part->sOffset;
v.X = x1; v.Y = y1; v.Z = z1; v.U = u2; v.V = v2; part->vertices[index + 0] = v;
v.Y = y2; v.V = v1; part->vertices[index + 1] = v;
v.X = x2; v.Z = z2; v.U = u1; part->vertices[index + 2] = v;
v.Y = y1; v.V = v2; part->vertices[index + 3] = v;
v.X = x1; v.Y = y1; v.Z = z1; v.U = u2; v.V = v2; Builder_Vertices[index + 0] = v;
v.Y = y2; v.V = v1; Builder_Vertices[index + 1] = v;
v.X = x2; v.Z = z2; v.U = u1; Builder_Vertices[index + 2] = v;
v.Y = y1; v.V = v2; Builder_Vertices[index + 3] = v;
/* Draw Z axis mirrored */
index += part->sAdvance;
v.X = x2; v.Y = y1; v.Z = z2; v.U = u2; part->vertices[index + 0] = v;
v.Y = y2; v.V = v1; part->vertices[index + 1] = v;
v.X = x1; v.Z = z1; v.U = u1; part->vertices[index + 2] = v;
v.Y = y1; v.V = v2; part->vertices[index + 3] = v;
v.X = x2; v.Y = y1; v.Z = z2; v.U = u2; Builder_Vertices[index + 0] = v;
v.Y = y2; v.V = v1; Builder_Vertices[index + 1] = v;
v.X = x1; v.Z = z1; v.U = u1; Builder_Vertices[index + 2] = v;
v.Y = y1; v.V = v2; Builder_Vertices[index + 3] = v;
/* Draw X axis */
index += part->sAdvance;
v.X = x1; v.Y = y1; v.Z = z2; v.U = u2; part->vertices[index + 0] = v;
v.Y = y2; v.V = v1; part->vertices[index + 1] = v;
v.X = x2; v.Z = z1; v.U = u1; part->vertices[index + 2] = v;
v.Y = y1; v.V = v2; part->vertices[index + 3] = v;
v.X = x1; v.Y = y1; v.Z = z2; v.U = u2; Builder_Vertices[index + 0] = v;
v.Y = y2; v.V = v1; Builder_Vertices[index + 1] = v;
v.X = x2; v.Z = z1; v.U = u1; Builder_Vertices[index + 2] = v;
v.Y = y1; v.V = v2; Builder_Vertices[index + 3] = v;
/* Draw X axis mirrored */
index += part->sAdvance;
v.X = x2; v.Y = y1; v.Z = z1; v.U = u2; part->vertices[index + 0] = v;
v.Y = y2; v.V = v1; part->vertices[index + 1] = v;
v.X = x1; v.Z = z2; v.U = u1; part->vertices[index + 2] = v;
v.Y = y1; v.V = v2; part->vertices[index + 3] = v;
v.X = x2; v.Y = y1; v.Z = z1; v.U = u2; Builder_Vertices[index + 0] = v;
v.Y = y2; v.V = v1; Builder_Vertices[index + 1] = v;
v.X = x1; v.Z = z2; v.U = u1; Builder_Vertices[index + 2] = v;
v.Y = y1; v.V = v2; Builder_Vertices[index + 3] = v;
part->sOffset += 4;
}
@ -643,7 +645,7 @@ static void NormalBuilder_RenderBlock(Int32 index) {
void NormalBuilder_SetActive(void) {
Builder_SetDefault();
Builder_StretchXLiquid = NormalBuilder_StretchXLiquid;
Builder_StretchX = NormalBuilder_StretchX;
Builder_StretchZ = NormalBuilder_StretchZ;
Builder_RenderBlock = NormalBuilder_RenderBlock;
Builder_StretchX = NormalBuilder_StretchX;
Builder_StretchZ = NormalBuilder_StretchZ;
Builder_RenderBlock = NormalBuilder_RenderBlock;
}

View File

@ -13,11 +13,16 @@
#include "Builder.h"
#include "Utils.h"
#include "ErrorHandler.h"
#include "Vectors.h"
Vector3I ChunkUpdater_ChunkPos;
UInt32* ChunkUpdater_Distances;
void ChunkInfo_Reset(ChunkInfo* chunk, Int32 x, Int32 y, Int32 z) {
chunk->CentreX = (UInt16)(x + 8);
chunk->CentreY = (UInt16)(y + 8);
chunk->CentreZ = (UInt16)(z + 8);
chunk->VbId = NULL;
chunk->Visible = true; chunk->Empty = false;
chunk->PendingDelete = false; chunk->AllAir = false;
@ -340,36 +345,30 @@ static void ChunkUpdater_ClearChunkCache_Handler(void* obj) {
}
#define ChunkUpdater_DeleteParts(parts, partsCount)\
if (parts != NULL) {\
ChunkPartInfo* ptr = parts;\
for (i = 0; i < MapRenderer_1DUsedCount; i++) {\
Gfx_DeleteVb(&ptr->VbId);\
if (ptr->HasVertices) { partsCount[i]--; }\
ptr += MapRenderer_ChunksCount;\
}\
parts = NULL;\
}
void ChunkUpdater_DeleteChunk(ChunkInfo* info) {
info->Empty = false; info->AllAir = false;
#if OCCLUSION
info.OcclusionFlags = 0;
info.OccludedFlags = 0;
#endif
Gfx_DeleteVb(&info->VbId);
Int32 i;
ChunkUpdater_DeleteParts(info->NormalParts, MapRenderer_NormalPartsCount);
ChunkUpdater_DeleteParts(info->TranslucentParts, MapRenderer_TranslucentPartsCount);
}
#define ChunkUpdater_AddParts(parts, partsCount)\
if (parts != NULL) {\
ChunkPartInfo* ptr = parts;\
for (i = 0; i < MapRenderer_1DUsedCount; i++) {\
if (ptr->HasVertices) { partsCount[i]++; }\
ptr += MapRenderer_ChunksCount;\
}\
if (info->NormalParts != NULL) {
ChunkPartInfo* ptr = info->NormalParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) {
if (ptr->Offset >= 0) { MapRenderer_NormalPartsCount[i]--; }
}
info->NormalParts = NULL;
}
if (info->TranslucentParts != NULL) {
ChunkPartInfo* ptr = info->TranslucentParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) {
if (ptr->Offset >= 0) { MapRenderer_TranslucentPartsCount[i]--; }
}
info->TranslucentParts = NULL;
}
}
void ChunkUpdater_BuildChunk(ChunkInfo* info, Int32* chunkUpdates) {
@ -382,10 +381,21 @@ void ChunkUpdater_BuildChunk(ChunkInfo* info, Int32* chunkUpdates) {
info->Empty = true;
return;
}
Int32 i;
ChunkUpdater_AddParts(info->NormalParts, MapRenderer_NormalPartsCount);
ChunkUpdater_AddParts(info->TranslucentParts, MapRenderer_TranslucentPartsCount);
if (info->NormalParts != NULL) {
ChunkPartInfo* ptr = info->NormalParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) {
if (ptr->Offset >= 0) { MapRenderer_NormalPartsCount[i]++; }
}
}
if (info->TranslucentParts != NULL) {
ChunkPartInfo* ptr = info->TranslucentParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) {
if (ptr->Offset >= 0) { MapRenderer_TranslucentPartsCount[i]++; }
}
}
}
static void ChunkUpdater_QuickSort(Int32 left, Int32 right) {

View File

@ -1,6 +1,7 @@
#ifndef CC_CHUNKUPDATER_H
#define CC_CHUNKUPDATER_H
#include "Vectors.h"
#include "Typedefs.h"
#include "Constants.h"
/* Manages the process of building/deleting chunk meshes.
Also sorts chunks so nearest chunks are ordered first, and calculates chunk visibility.
Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
@ -8,10 +9,9 @@
/* Describes a portion of the data needed for rendering a chunk. */
typedef struct ChunkPartInfo_ {
GfxResourceID VbId;
UInt16 HasVertices; /* Does this chunk have any vertices at all? */
UInt16 SpriteCountDiv4; /* Sprite vertices count, divided by 4 */
UInt16 XMinCount, XMaxCount, ZMinCount, ZMaxCount, YMinCount, YMaxCount; /* Counts per face */
Int32 Offset; /* -1 if no vertices at all */
Int32 SpriteCount; /* Sprite vertices count */
UInt16 Counts[FACE_COUNT]; /* Counts per face */
} ChunkPartInfo;
/* Describes data necessary for rendering a chunk. */
@ -35,13 +35,12 @@ typedef struct ChunkInfo_ {
public bool Visited = false, Occluded = false;
public byte OcclusionFlags, OccludedFlags, DistanceFlags;
#endif
GfxResourceID VbId;
ChunkPartInfo* NormalParts;
ChunkPartInfo* TranslucentParts;
} ChunkInfo;
void ChunkInfo_Reset(ChunkInfo* chunk, Int32 x, Int32 y, Int32 z);
Vector3I ChunkUpdater_ChunkPos;
UInt32* ChunkUpdater_Distances;
void ChunkUpdater_Init(void);
void ChunkUpdater_Free(void);

View File

@ -45,73 +45,78 @@ static void MapRenderer_RenderNormalBatch(UInt32 batch) {
if (info->NormalParts == NULL) continue;
ChunkPartInfo part = *(info->NormalParts + offset);
if (!part.HasVertices) continue;
if (part.Offset < 0) continue;
MapRenderer_HasNormalParts[batch] = true;
Gfx_BindVb(part.VbId);
bool drawXMin = info->DrawXMin && part.XMinCount > 0;
bool drawXMax = info->DrawXMax && part.XMaxCount > 0;
bool drawYMin = info->DrawYMin && part.YMinCount > 0;
bool drawYMax = info->DrawYMax && part.YMaxCount > 0;
bool drawZMin = info->DrawZMin && part.ZMinCount > 0;
bool drawZMax = info->DrawZMax && part.ZMaxCount > 0;
Gfx_BindVb(info->VbId);
bool drawXMin = info->DrawXMin && part.Counts[FACE_XMIN];
bool drawXMax = info->DrawXMax && part.Counts[FACE_XMAX];
bool drawYMin = info->DrawYMin && part.Counts[FACE_YMIN];
bool drawYMax = info->DrawYMax && part.Counts[FACE_YMAX];
bool drawZMin = info->DrawZMin && part.Counts[FACE_ZMIN];
bool drawZMax = info->DrawZMax && part.Counts[FACE_ZMAX];
UInt32 offset = part.SpriteCountDiv4 << 2;
Int32 offset = part.Offset + part.SpriteCount;
if (drawXMin && drawXMax) {
Gfx_SetFaceCulling(true);
Gfx_DrawIndexedVb_TrisT2fC4b(part.XMinCount + part.XMaxCount, offset);
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_XMIN] + part.Counts[FACE_XMAX], offset);
Gfx_SetFaceCulling(false);
Game_Vertices += part.XMinCount + part.XMaxCount;
Game_Vertices += part.Counts[FACE_XMIN] + part.Counts[FACE_XMAX];
} else if (drawXMin) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.XMinCount, offset);
Game_Vertices += part.XMinCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_XMIN], offset);
Game_Vertices += part.Counts[FACE_XMIN];
} else if (drawXMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.XMaxCount, offset + part.XMinCount);
Game_Vertices += part.XMaxCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_XMAX], offset + part.Counts[FACE_XMIN]);
Game_Vertices += part.Counts[FACE_XMAX];
}
offset += part.XMinCount + part.XMaxCount;
offset += part.Counts[FACE_XMIN] + part.Counts[FACE_XMAX];
if (drawZMin && drawZMax) {
Gfx_SetFaceCulling(true);
Gfx_DrawIndexedVb_TrisT2fC4b(part.ZMinCount + part.ZMaxCount, offset);
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_ZMIN] + part.Counts[FACE_ZMAX], offset);
Gfx_SetFaceCulling(false);
Game_Vertices += part.ZMinCount + part.ZMaxCount;
Game_Vertices += part.Counts[FACE_ZMIN] + part.Counts[FACE_ZMAX];
} else if (drawZMin) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.ZMinCount, offset);
Game_Vertices += part.ZMinCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_ZMIN], offset);
Game_Vertices += part.Counts[FACE_ZMIN];
} else if (drawZMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.ZMaxCount, offset + part.ZMinCount);
Game_Vertices += part.ZMaxCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_ZMAX], offset + part.Counts[FACE_ZMIN]);
Game_Vertices += part.Counts[FACE_ZMAX];
}
offset += part.ZMinCount + part.ZMaxCount;
offset += part.Counts[FACE_ZMIN] + part.Counts[FACE_ZMAX];
if (drawYMin && drawYMax) {
Gfx_SetFaceCulling(true);
Gfx_DrawIndexedVb_TrisT2fC4b(part.YMinCount + part.YMaxCount, offset);
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_YMIN] + part.Counts[FACE_YMAX], offset);
Gfx_SetFaceCulling(false);
Game_Vertices += part.YMaxCount + part.YMinCount;
Game_Vertices += part.Counts[FACE_YMAX] + part.Counts[FACE_YMIN];
} else if (drawYMin) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.YMinCount, offset);
Game_Vertices += part.YMinCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_YMIN], offset);
Game_Vertices += part.Counts[FACE_YMIN];
} else if (drawYMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.YMaxCount, offset + part.YMinCount);
Game_Vertices += part.YMaxCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_YMAX], offset + part.Counts[FACE_YMIN]);
Game_Vertices += part.Counts[FACE_YMAX];
}
if (part.SpriteCountDiv4 == 0) continue;
UInt32 count = part.SpriteCountDiv4; /* 4 per sprite */
if (part.SpriteCount == 0) continue;
offset = part.Offset;
Int32 count = part.SpriteCount >> 2; /* 4 per sprite */
Gfx_SetFaceCulling(true);
if (info->DrawXMax || info->DrawZMin) {
Gfx_DrawIndexedVb_TrisT2fC4b(count, 0); Game_Vertices += count;
}
Gfx_DrawIndexedVb_TrisT2fC4b(count, offset); Game_Vertices += count;
} offset += count;
if (info->DrawXMin || info->DrawZMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(count, count); Game_Vertices += count;
}
Gfx_DrawIndexedVb_TrisT2fC4b(count, offset); Game_Vertices += count;
} offset += count;
if (info->DrawXMin || info->DrawZMin) {
Gfx_DrawIndexedVb_TrisT2fC4b(count, count * 2); Game_Vertices += count;
}
Gfx_DrawIndexedVb_TrisT2fC4b(count, offset); Game_Vertices += count;
} offset += count;
if (info->DrawXMax || info->DrawZMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(count, count * 3); Game_Vertices += count;
Gfx_DrawIndexedVb_TrisT2fC4b(count, offset); Game_Vertices += count;
}
Gfx_SetFaceCulling(false);
}
@ -150,51 +155,51 @@ static void MapRenderer_RenderTranslucentBatch(UInt32 batch) {
if (info->TranslucentParts == NULL) continue;
ChunkPartInfo part = *(info->TranslucentParts + offset);
if (!part.HasVertices) continue;
if (part.Offset < 0) continue;
MapRenderer_HasTranslucentParts[batch] = true;
Gfx_BindVb(part.VbId);
bool drawXMin = (inTranslucent || info->DrawXMin) && part.XMinCount > 0;
bool drawXMax = (inTranslucent || info->DrawXMax) && part.XMaxCount > 0;
bool drawYMin = (inTranslucent || info->DrawYMin) && part.YMinCount > 0;
bool drawYMax = (inTranslucent || info->DrawYMax) && part.YMaxCount > 0;
bool drawZMin = (inTranslucent || info->DrawZMin) && part.ZMinCount > 0;
bool drawZMax = (inTranslucent || info->DrawZMax) && part.ZMaxCount > 0;
Gfx_BindVb(info->VbId);
bool drawXMin = (inTranslucent || info->DrawXMin) && part.Counts[FACE_XMIN];
bool drawXMax = (inTranslucent || info->DrawXMax) && part.Counts[FACE_XMAX];
bool drawYMin = (inTranslucent || info->DrawYMin) && part.Counts[FACE_YMIN];
bool drawYMax = (inTranslucent || info->DrawYMax) && part.Counts[FACE_YMAX];
bool drawZMin = (inTranslucent || info->DrawZMin) && part.Counts[FACE_ZMIN];
bool drawZMax = (inTranslucent || info->DrawZMax) && part.Counts[FACE_ZMAX];
UInt32 offset = 0;
Int32 offset = part.Offset;
if (drawXMin && drawXMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.XMinCount + part.XMaxCount, offset);
Game_Vertices += (part.XMinCount + part.XMaxCount);
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_XMIN] + part.Counts[FACE_XMAX], offset);
Game_Vertices += (part.Counts[FACE_XMIN] + part.Counts[FACE_XMAX]);
} else if (drawXMin) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.XMinCount, offset);
Game_Vertices += part.XMinCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_XMIN], offset);
Game_Vertices += part.Counts[FACE_XMIN];
} else if (drawXMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.XMaxCount, offset + part.XMinCount);
Game_Vertices += part.XMaxCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_XMAX], offset + part.Counts[FACE_XMIN]);
Game_Vertices += part.Counts[FACE_XMAX];
}
offset += part.XMinCount + part.XMaxCount;
offset += part.Counts[FACE_XMIN] + part.Counts[FACE_XMAX];
if (drawZMin && drawZMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.ZMinCount + part.ZMaxCount, offset);
Game_Vertices += (part.ZMinCount + part.ZMaxCount);
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_ZMIN] + part.Counts[FACE_ZMAX], offset);
Game_Vertices += (part.Counts[FACE_ZMIN] + part.Counts[FACE_ZMAX]);
} else if (drawZMin) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.ZMinCount, offset);
Game_Vertices += part.ZMinCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_ZMIN], offset);
Game_Vertices += part.Counts[FACE_ZMIN];
} else if (drawZMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.ZMaxCount, offset + part.ZMinCount);
Game_Vertices += part.ZMaxCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_ZMAX], offset + part.Counts[FACE_ZMIN]);
Game_Vertices += part.Counts[FACE_ZMAX];
}
offset += part.ZMinCount + part.ZMaxCount;
offset += part.Counts[FACE_ZMIN] + part.Counts[FACE_ZMAX];
if (drawYMin && drawYMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.YMinCount + part.YMaxCount, offset);
Game_Vertices += (part.YMinCount + part.YMaxCount);
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_YMIN] + part.Counts[FACE_YMAX], offset);
Game_Vertices += (part.Counts[FACE_YMIN] + part.Counts[FACE_YMAX]);
} else if (drawYMin) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.YMinCount, offset);
Game_Vertices += part.YMinCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_YMIN], offset);
Game_Vertices += part.Counts[FACE_YMIN];
} else if (drawYMax) {
Gfx_DrawIndexedVb_TrisT2fC4b(part.YMaxCount, offset + part.YMinCount);
Game_Vertices += part.YMaxCount;
Gfx_DrawIndexedVb_TrisT2fC4b(part.Counts[FACE_YMAX], offset + part.Counts[FACE_YMIN]);
Game_Vertices += part.Counts[FACE_YMAX];
}
}
}