mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-22 12:03:01 -04:00
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:
parent
8ed8d02cc1
commit
7a7c5f1586
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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]++;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user