void SetPartInfo(DrawInfo part, int i, ref ChunkPartInfo[] parts) { if (part.iCount == 0) { return; } ChunkPartInfo info; int vertCount = (part.iCount / 6 * 4) + 2; info.VbId = gfx.CreateVb(part.vertices, VertexFormat.P3fT2fC4b, vertCount); info.IndicesCount = part.iCount; info.LeftCount = (ushort)part.vCount[Side.Left]; info.RightCount = (ushort)part.vCount[Side.Right]; info.FrontCount = (ushort)part.vCount[Side.Front]; info.BackCount = (ushort)part.vCount[Side.Back]; info.BottomCount = (ushort)part.vCount[Side.Bottom]; info.TopCount = (ushort)part.vCount[Side.Top]; info.SpriteCount = part.spriteCount; info.LeftIndex = info.SpriteCount; info.RightIndex = info.LeftIndex + info.LeftCount; info.FrontIndex = info.RightIndex + info.RightCount; info.BackIndex = info.FrontIndex + info.FrontCount; info.BottomIndex = info.BackIndex + info.BackCount; info.TopIndex = info.BottomIndex + info.BottomCount; // Lazy initalize part arrays so we can save time in MapRenderer for chunks that only contain 1 or 2 part types. if (parts == null) { parts = new ChunkPartInfo[arraysCount]; } parts[i] = info; }
void SetPartInfo(DrawInfo part, 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.LeftCount = (ushort)part.vCount[Side.Left]; info.RightCount = (ushort)part.vCount[Side.Right]; info.FrontCount = (ushort)part.vCount[Side.Front]; info.BackCount = (ushort)part.vCount[Side.Back]; info.BottomCount = (ushort)part.vCount[Side.Bottom]; info.TopCount = (ushort)part.vCount[Side.Top]; 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) { parts = new ChunkPartInfo[arraysCount]; } parts[i] = info; }
void SetPartInfo(DrawInfo part, int i, ref ChunkPartInfo[] parts) { if (part.iCount == 0) { return; } ChunkPartInfo info; info.VbId = graphics.CreateVb(part.vertices, VertexFormat.Pos3fTex2fCol4b, part.vCount); info.IndicesCount = part.iCount; info.leftCount = (ushort)part.Count.left; info.rightCount = (ushort)part.Count.right; info.frontCount = (ushort)part.Count.front; info.backCount = (ushort)part.Count.back; info.bottomCount = (ushort)part.Count.bottom; info.topCount = (ushort)part.Count.top; info.spriteCount = (ushort)part.spriteCount; info.leftIndex = info.spriteCount; info.rightIndex = info.leftIndex + info.leftCount; info.frontIndex = info.rightIndex + info.rightCount; info.backIndex = info.frontIndex + info.frontCount; info.bottomIndex = info.backIndex + info.backCount; info.topIndex = info.bottomIndex + info.bottomCount; // Lazy initalize part arrays so we can save time in MapRenderer for chunks that only contain 1 or 2 part types. if (parts == null) { parts = new ChunkPartInfo[arraysCount]; } parts[i] = info; }
void RenderNormalBatch(int batch) { for (int i = 0; i < chunks.Length; i++) { ChunkInfo info = chunks[i]; if (info.NormalParts == null || !info.Visible || info.Occluded) { continue; } ChunkPartInfo part = info.NormalParts[batch]; if (part.IndicesCount == 0) { continue; } usedNormal[batch] = true; if (part.IndicesCount > maxIndices) { DrawBigPart(info, ref part); } else { DrawPart(info, ref part); } if (part.spriteCount > 0) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b(part.spriteCount, 0); api.FaceCulling = false; } game.Vertices += part.IndicesCount; } }
public void GetDrawInfo( int x, int y, int z, ref ChunkPartInfo[] normalParts, ref ChunkPartInfo[] translucentParts ) { if( !BuildChunk( x, y, z ) ) return; for( int i = 0; i < arraysCount; i++ ) { SetPartInfo( drawInfoNormal[i], i, ref normalParts ); SetPartInfo( drawInfoTranslucent[i], i, ref translucentParts ); } }
void DrawPart(ChunkInfo info, ref ChunkPartInfo part) { api.BindVb(part.VbId); bool drawLeft = info.DrawLeft && part.leftCount > 0; bool drawRight = info.DrawRight && part.rightCount > 0; bool drawBottom = info.DrawBottom && part.bottomCount > 0; bool drawTop = info.DrawTop && part.topCount > 0; bool drawFront = info.DrawFront && part.frontCount > 0; bool drawBack = info.DrawBack && part.backCount > 0; if (drawLeft && drawRight) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b(part.leftCount + part.rightCount, part.leftIndex); api.FaceCulling = false; } else if (drawLeft) { api.DrawIndexedVb_TrisT2fC4b(part.leftCount, part.leftIndex); } else if (drawRight) { api.DrawIndexedVb_TrisT2fC4b(part.rightCount, part.rightIndex); } if (drawFront && drawBack) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b(part.frontCount + part.backCount, part.frontIndex); api.FaceCulling = false; } else if (drawFront) { api.DrawIndexedVb_TrisT2fC4b(part.frontCount, part.frontIndex); } else if (drawBack) { api.DrawIndexedVb_TrisT2fC4b(part.backCount, part.backIndex); } if (drawBottom && drawTop) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b(part.bottomCount + part.topCount, part.bottomIndex); api.FaceCulling = false; } else if (drawBottom) { api.DrawIndexedVb_TrisT2fC4b(part.bottomCount, part.bottomIndex); } else if (drawTop) { api.DrawIndexedVb_TrisT2fC4b(part.topCount, part.topIndex); } }
public void GetDrawInfo( int x, int y, int z, ref ChunkPartInfo[] normalParts, ref ChunkPartInfo[] translucentParts, ref byte occlusionFlags ) { if( !BuildChunk( x, y, z ) ) return; for( int i = 0; i < arraysCount; i++ ) { SetPartInfo( drawInfoNormal[i], i, ref normalParts ); SetPartInfo( drawInfoTranslucent[i], i, ref translucentParts ); } if( normalParts != null || translucentParts != null ) occlusionFlags = 0;//(byte)ComputeOcclusion(); }
void DrawTranslucentPart(ChunkInfo info, ref ChunkPartInfo part) { api.BindVb(part.VbId); bool drawLeft = (drawAllFaces || info.DrawLeft) && part.leftCount > 0; bool drawRight = (drawAllFaces || info.DrawRight) && part.rightCount > 0; bool drawBottom = (drawAllFaces || info.DrawBottom) && part.bottomCount > 0; bool drawTop = (drawAllFaces || info.DrawTop) && part.topCount > 0; bool drawFront = (drawAllFaces || info.DrawFront) && part.frontCount > 0; bool drawBack = (drawAllFaces || info.DrawBack) && part.backCount > 0; if (drawLeft && drawRight) { api.DrawIndexedVb_TrisT2fC4b(part.leftCount + part.rightCount, part.leftIndex); } else if (drawLeft) { api.DrawIndexedVb_TrisT2fC4b(part.leftCount, part.leftIndex); } else if (drawRight) { api.DrawIndexedVb_TrisT2fC4b(part.rightCount, part.rightIndex); } if (drawFront && drawBack) { api.DrawIndexedVb_TrisT2fC4b(part.frontCount + part.backCount, part.frontIndex); } else if (drawFront) { api.DrawIndexedVb_TrisT2fC4b(part.frontCount, part.frontIndex); } else if (drawBack) { api.DrawIndexedVb_TrisT2fC4b(part.backCount, part.backIndex); } if (drawBottom && drawTop) { api.DrawIndexedVb_TrisT2fC4b(part.bottomCount + part.topCount, part.bottomIndex); } else if (drawBottom) { api.DrawIndexedVb_TrisT2fC4b(part.bottomCount, part.bottomIndex); } else if (drawTop) { api.DrawIndexedVb_TrisT2fC4b(part.topCount, part.topIndex); } }
void RenderTranslucentBatch(int batch) { for (int i = 0; i < chunks.Length; i++) { ChunkInfo info = chunks[i]; if (info.TranslucentParts == null || !info.Visible || info.Occluded) { continue; } ChunkPartInfo part = info.TranslucentParts[batch]; if (part.IndicesCount == 0) { continue; } DrawTranslucentPart(info, ref part); game.Vertices += part.IndicesCount; } }
void RenderTranslucentBatchDepthPass(int batch) { for (int i = 0; i < chunks.Length; i++) { ChunkInfo info = chunks[i]; if (info.TranslucentParts == null || !info.Visible || info.Occluded) { continue; } ChunkPartInfo part = info.TranslucentParts[batch]; if (part.IndicesCount == 0) { continue; } usedTranslucent[batch] = true; DrawTranslucentPart(info, ref part); } }
void SetPartInfo(DrawInfo part, ref int offset, int i, ref ChunkPartInfo[] parts) { int vertCount = part.VerticesCount(); if (vertCount == 0) { return; } ChunkPartInfo info; info.Offset = offset; offset += vertCount; #if GL11 fixed(VertexP3fT2fC4b *ptr = vertices) { VertexP3fT2fC4b *ptr2 = ptr + info.Offset; info.Vb = game.Graphics.CreateVb((IntPtr)ptr, VertexFormat.P3fT2fC4b, vertCount); } #endif info.LeftCount = (ushort)part.vCount[Side.Left]; info.RightCount = (ushort)part.vCount[Side.Right]; info.FrontCount = (ushort)part.vCount[Side.Front]; info.BackCount = (ushort)part.vCount[Side.Back]; info.BottomCount = (ushort)part.vCount[Side.Bottom]; info.TopCount = (ushort)part.vCount[Side.Top]; 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) { parts = new ChunkPartInfo[arraysCount]; for (int j = 0; j < parts.Length; j++) { parts[j].Offset = -1; } } parts[i] = info; }
void DrawPart( ChunkInfo info, ref ChunkPartInfo part ) { api.BindVb( part.VbId ); bool drawLeft = info.DrawLeft && part.leftCount > 0; bool drawRight = info.DrawRight && part.rightCount > 0; bool drawBottom = info.DrawBottom && part.bottomCount > 0; bool drawTop = info.DrawTop && part.topCount > 0; bool drawFront = info.DrawFront && part.frontCount > 0; bool drawBack = info.DrawBack && part.backCount > 0; if( drawLeft && drawRight ) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b( part.leftCount + part.rightCount, part.leftIndex ); api.FaceCulling = false; } else if( drawLeft ) { api.DrawIndexedVb_TrisT2fC4b( part.leftCount, part.leftIndex ); } else if( drawRight ) { api.DrawIndexedVb_TrisT2fC4b( part.rightCount, part.rightIndex ); } if( drawFront && drawBack ) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b( part.frontCount + part.backCount, part.frontIndex ); api.FaceCulling = false; } else if( drawFront ) { api.DrawIndexedVb_TrisT2fC4b( part.frontCount, part.frontIndex ); } else if( drawBack ) { api.DrawIndexedVb_TrisT2fC4b( part.backCount, part.backIndex ); } if( drawBottom && drawTop ) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b( part.bottomCount + part.topCount, part.bottomIndex ); api.FaceCulling = false; } else if( drawBottom ) { api.DrawIndexedVb_TrisT2fC4b( part.bottomCount, part.bottomIndex ); } else if( drawTop ) { api.DrawIndexedVb_TrisT2fC4b( part.topCount, part.topIndex ); } }
void DrawBigPart( ChunkInfo info, ref ChunkPartInfo part ) { api.BindVb( part.VbId ); bool drawLeft = info.DrawLeft && part.leftCount > 0; bool drawRight = info.DrawRight && part.rightCount > 0; bool drawBottom = info.DrawBottom && part.bottomCount > 0; bool drawTop = info.DrawTop && part.topCount > 0; bool drawFront = info.DrawFront && part.frontCount > 0; bool drawBack = info.DrawBack && part.backCount > 0; if( drawLeft && drawRight ) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b( part.leftCount + part.rightCount, part.leftIndex ); api.FaceCulling = false; } else if( drawLeft ) { api.DrawIndexedVb_TrisT2fC4b( part.leftCount, part.leftIndex ); } else if( drawRight ) { api.DrawIndexedVb_TrisT2fC4b( part.rightCount, part.rightIndex ); } if( drawFront && drawBack ) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b( part.frontCount + part.backCount, part.frontIndex ); api.FaceCulling = false; } else if( drawFront ) { api.DrawIndexedVb_TrisT2fC4b( part.frontCount, part.frontIndex ); } else if( drawBack ) { api.DrawIndexedVb_TrisT2fC4b( part.backCount, part.backIndex ); } // Special handling for top and bottom as these can go over 65536 vertices and we need to adjust the indices in this case. if( drawBottom && drawTop ) { api.FaceCulling = true; if( part.IndicesCount > maxIndices ) { int part1Count = maxIndices - part.bottomIndex; api.DrawIndexedVb_TrisT2fC4b( part1Count, part.bottomIndex ); api.DrawIndexedVb_TrisT2fC4b( part.bottomCount + part.topCount - part1Count, maxVertex, 0 ); } else { api.DrawIndexedVb_TrisT2fC4b( part.bottomCount + part.topCount, part.bottomIndex ); } api.FaceCulling = false; } else if( drawBottom ) { int part1Count; if( part.IndicesCount > maxIndices && ( part1Count = maxIndices - part.bottomIndex ) < part.bottomCount ) { api.DrawIndexedVb_TrisT2fC4b( part1Count, part.bottomIndex ); api.DrawIndexedVb_TrisT2fC4b( part.bottomCount - part1Count, maxVertex, 0 ); } else { api.DrawIndexedVb_TrisT2fC4b( part.bottomCount, part.bottomIndex ); } } else if( drawTop ) { int part1Count; if( part.IndicesCount > maxIndices && ( part1Count = maxIndices - part.topIndex ) < part.topCount ) { api.DrawIndexedVb_TrisT2fC4b( part1Count, part.topIndex ); api.DrawIndexedVb_TrisT2fC4b( part.topCount - part1Count, maxVertex, 0 ); } else { api.DrawIndexedVb_TrisT2fC4b( part.topCount, part.topIndex ); } } }
void DrawTranslucentPart( ChunkInfo info, ref ChunkPartInfo part ) { api.BindVb( part.VbId ); bool drawLeft = (drawAllFaces || info.DrawLeft) && part.leftCount > 0; bool drawRight = (drawAllFaces || info.DrawRight) && part.rightCount > 0; bool drawBottom = (drawAllFaces || info.DrawBottom) && part.bottomCount > 0; bool drawTop = (drawAllFaces || info.DrawTop) && part.topCount > 0; bool drawFront = (drawAllFaces || info.DrawFront) && part.frontCount > 0; bool drawBack = (drawAllFaces || info.DrawBack) && part.backCount > 0; if( drawLeft && drawRight ) { api.DrawIndexedVb_TrisT2fC4b( part.leftCount + part.rightCount, part.leftIndex ); } else if( drawLeft ) { api.DrawIndexedVb_TrisT2fC4b( part.leftCount, part.leftIndex ); } else if( drawRight ) { api.DrawIndexedVb_TrisT2fC4b( part.rightCount, part.rightIndex ); } if( drawFront && drawBack ) { api.DrawIndexedVb_TrisT2fC4b( part.frontCount + part.backCount, part.frontIndex ); } else if( drawFront ) { api.DrawIndexedVb_TrisT2fC4b( part.frontCount, part.frontIndex ); } else if( drawBack ) { api.DrawIndexedVb_TrisT2fC4b( part.backCount, part.backIndex ); } if( drawBottom && drawTop ) { api.DrawIndexedVb_TrisT2fC4b( part.bottomCount + part.topCount, part.bottomIndex ); } else if( drawBottom ) { api.DrawIndexedVb_TrisT2fC4b( part.bottomCount, part.bottomIndex ); } else if( drawTop ) { api.DrawIndexedVb_TrisT2fC4b( part.topCount, part.topIndex ); } }
void SetPartInfo( DrawInfo part, int i, ref ChunkPartInfo[] parts ) { if( part.iCount == 0 ) return; ChunkPartInfo info; info.VbId = graphics.CreateVb( part.vertices, VertexFormat.Pos3fTex2fCol4b, part.vCount ); info.IndicesCount = part.iCount; info.leftCount = (ushort)part.Count.left; info.rightCount = (ushort)part.Count.right; info.frontCount = (ushort)part.Count.front; info.backCount = (ushort)part.Count.back; info.bottomCount = (ushort)part.Count.bottom; info.topCount = (ushort)part.Count.top; info.spriteCount = (ushort)part.spriteCount; info.leftIndex = info.spriteCount; info.rightIndex = info.leftIndex + info.leftCount; info.frontIndex = info.rightIndex + info.rightCount; info.backIndex = info.frontIndex + info.frontCount; info.bottomIndex = info.backIndex + info.backCount; info.topIndex = info.bottomIndex + info.bottomCount; // Lazy initalize part arrays so we can save time in MapRenderer for chunks that only contain 1 or 2 part types. if( parts == null ) parts = new ChunkPartInfo[arraysCount]; parts[i] = info; }
void DeleteData( ref ChunkPartInfo[] parts ) { if( parts == null ) return; for( int i = 0; i < parts.Length; i++ ) { api.DeleteVb( parts[i].VbId ); } parts = null; }
void DrawBigPart(ChunkInfo info, ref ChunkPartInfo part) { api.BindVb(part.VbId); bool drawLeft = info.DrawLeft && part.leftCount > 0; bool drawRight = info.DrawRight && part.rightCount > 0; bool drawBottom = info.DrawBottom && part.bottomCount > 0; bool drawTop = info.DrawTop && part.topCount > 0; bool drawFront = info.DrawFront && part.frontCount > 0; bool drawBack = info.DrawBack && part.backCount > 0; if (drawLeft && drawRight) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b(part.leftCount + part.rightCount, part.leftIndex); api.FaceCulling = false; } else if (drawLeft) { api.DrawIndexedVb_TrisT2fC4b(part.leftCount, part.leftIndex); } else if (drawRight) { api.DrawIndexedVb_TrisT2fC4b(part.rightCount, part.rightIndex); } if (drawFront && drawBack) { api.FaceCulling = true; api.DrawIndexedVb_TrisT2fC4b(part.frontCount + part.backCount, part.frontIndex); api.FaceCulling = false; } else if (drawFront) { api.DrawIndexedVb_TrisT2fC4b(part.frontCount, part.frontIndex); } else if (drawBack) { api.DrawIndexedVb_TrisT2fC4b(part.backCount, part.backIndex); } // Special handling for top and bottom as these can go over 65536 vertices and we need to adjust the indices in this case. if (drawBottom && drawTop) { api.FaceCulling = true; if (part.IndicesCount > maxIndices) { int part1Count = maxIndices - part.bottomIndex; api.DrawIndexedVb_TrisT2fC4b(part1Count, part.bottomIndex); api.DrawIndexedVb_TrisT2fC4b(part.bottomCount + part.topCount - part1Count, maxVertex, 0); } else { api.DrawIndexedVb_TrisT2fC4b(part.bottomCount + part.topCount, part.bottomIndex); } api.FaceCulling = false; } else if (drawBottom) { int part1Count; if (part.IndicesCount > maxIndices && (part1Count = maxIndices - part.bottomIndex) < part.bottomCount) { api.DrawIndexedVb_TrisT2fC4b(part1Count, part.bottomIndex); api.DrawIndexedVb_TrisT2fC4b(part.bottomCount - part1Count, maxVertex, 0); } else { api.DrawIndexedVb_TrisT2fC4b(part.bottomCount, part.bottomIndex); } } else if (drawTop) { int part1Count; if (part.IndicesCount > maxIndices && (part1Count = maxIndices - part.topIndex) < part.topCount) { api.DrawIndexedVb_TrisT2fC4b(part1Count, part.topIndex); api.DrawIndexedVb_TrisT2fC4b(part.topCount - part1Count, maxVertex, 0); } else { api.DrawIndexedVb_TrisT2fC4b(part.topCount, part.topIndex); } } }