0
\$\begingroup\$

I am creating a Minecraft like terrain engine in XNA, and am having problems when I render water, sayings that the "numVertices" passed should be greater then zero - which they should always be. The terrain is seperated into regions 32x32x32 in size and the vertex buffers are set as dirty when a block is added, but when a water block is added, the region on which it has been added has its BuildVertexBuffers Function called passed with the parameter "BufferType.Water".

Here is the code:

private void BuildVertexBuffers(BufferType buffer)
{  
    if (buffer == BufferType.All || buffer == BufferType.None)
    {
        Console.WriteLine("FAAAAAAAAAAAAAAAAAAAAAAIL!");
    }

    if (buffer == BufferType.Water)
    {
        WaterVertices = new List<VertexPositionTextureLight>();
        WaterIndexList = new List<short>();
        offsetWater = 0;
    }
    else if (buffer == BufferType.Lava)
    {
    }
    else
    {
        SolidVertices = new List<VertexPositionTextureLight>();
        SolidIndexList = new List<short>();
        offsetSolid = 0;
    }

    for (short x = 0; x < Variables.REGION_SIZE_X; x++)
    {
        for (short y = 0; y < Variables.REGION_SIZE_Y; y++)
        {
            for (short z = 0; z < Variables.REGION_SIZE_Z; z++)
            {
                int X = (int)(index.X * Variables.REGION_SIZE_X + x);
                int Y = (int)(index.Y * Variables.REGION_SIZE_Y + y);
                int Z = (int)(index.Z * Variables.REGION_SIZE_Z + z);

                if (buffer == BufferType.Water && world.GetBlock(X, Y, Z).BlockType == BlockType.waterStill)
                {
                    BuildCube(buffer, WaterVertices, WaterIndexList, X, Y, Z, ref offsetWater);
                }
                else if (buffer == BufferType.Solid && world.GetBlock(X, Y, Z).BlockType != BlockType.waterStill)
                {
                    BuildCube(buffer, SolidVertices, SolidIndexList, X, Y, Z, ref offsetSolid);
                }
            }
        }
    }

    if (buffer == BufferType.Water)
    {   
        if (WaterVertices.Count > 0)
        {
            CopyToBuffers(ref WaterVertexBuffer, ref WaterIndices, WaterVertices, WaterIndexList);
        }
        else
        {
            WaterVertexBuffer = null;
        }
    }
    else if (buffer == BufferType.Lava)
    {
    }
    else
    {
        if (SolidVertices.Count > 0)
        {
            CopyToBuffers(ref SolidVertexBuffer, ref SolidIndices, SolidVertices, SolidIndexList);
        }
        else
        {
            SolidVertexBuffer = null;
        }
    }
}

public void BuildCube(BufferType buffer, List<VertexPositionTextureLight> vertices, List<short> indices, int X, int Y, int Z, ref int offset)
{
    bool above, below, left, right, front, back;

    above = !world.GetBlock(X, Y + 1, Z).TransparentSolid;
    below = !world.GetBlock(X, Y - 1, Z).TransparentSolid;
    left = !world.GetBlock(X - 1, Y, Z).TransparentSolid;
    right = !world.GetBlock(X + 1, Y, Z).TransparentSolid;
    front = !world.GetBlock(X, Y, Z + 1).TransparentSolid;
    back = !world.GetBlock(X, Y, Z - 1).TransparentSolid;

    bool notVisible = above && below && left && right && front && back;

    if (notVisible)
        return;
    if (world.GetBlock(X, Y, Z).BlockType == BlockType.none)
        return;

    if (!back)
        BuildCubeFace(vertices, indices, world.GetBlock(X, Y, Z), new Vector3(X, Y, Z), BlockFaceDirection.ZDecreasing, ref offset);
    if (!front)
        BuildCubeFace(vertices, indices, world.GetBlock(X, Y, Z), new Vector3(X, Y, Z), BlockFaceDirection.ZIncreasing, ref offset);
    if (!above)
        BuildCubeFace(vertices, indices, world.GetBlock(X, Y, Z), new Vector3(X, Y, Z), BlockFaceDirection.YIncreasing,ref  offset);
    if (!below)
        BuildCubeFace(vertices, indices, world.GetBlock(X, Y, Z), new Vector3(X, Y, Z), BlockFaceDirection.YDecreasing, ref offset);
    if (!right)
        BuildCubeFace(vertices, indices, world.GetBlock(X, Y, Z), new Vector3(X, Y, Z), BlockFaceDirection.XIncreasing, ref offset);
    if (!left)
        BuildCubeFace(vertices, indices, world.GetBlock(X, Y, Z), new Vector3(X, Y, Z), BlockFaceDirection.XDecreasing, ref offset);
}

public void BuildCubeFace(List<VertexPositionTextureLight> vertices, List<short> indices, Block block, Vector3 pos, BlockFaceDirection blockFaceDirection, ref int offset)
{
    Vector3 topLeftFront = new Vector3(0f, 1f, 0f) + pos;
    Vector3 bottomLeftFront = new Vector3(0f, 0f, 0f) + pos;
    Vector3 topRightFront = new Vector3(1f, 1f, 0f) + pos;
    Vector3 bottomRightFront = new Vector3(1f, 0f, 0f) + pos;
    Vector3 topLeftBack = new Vector3(0f, 1f, -1f) + pos;
    Vector3 topRightBack = new Vector3(1f, 1f, -1f) + pos;
    Vector3 bottomLeftBack = new Vector3(0f, 0f, -1f) + pos;
    Vector3 bottomRightBack = new Vector3(1f, 0f, -1f) + pos;

    Vector3 upNormal = new Vector3(0, 1, 0);
    Vector3 downNormal = new Vector3(0, -1, 0);
    Vector3 leftNormal = new Vector3(-1, 0, 0);
    Vector3 rightNormal = new Vector3(1, 0, 0);
    Vector3 backNormal = new Vector3(0, 0, -1);
    Vector3 frontNormal = new Vector3(0, 0, 1);

    int row = (int)block.BlockType / Variables.TILE_ALAIS.NumberOfColumns;
    int column = (int)block.BlockType - row * Variables.TILE_ALAIS.NumberOfColumns;

    float unit = 1.0f / (float)Variables.TILE_ALAIS.NumberOfColumns;

    float x = column * unit;
    float y = row * unit;

    Vector2 topLeft = new Vector2(x, y);
    Vector2 topRight = new Vector2(x + unit, y);
    Vector2 bottomLeft = new Vector2(x, y + unit);
    Vector2 bottomRight = new Vector2(x + unit, y + unit);

    float light = 12;

    switch (blockFaceDirection)
    {
        case BlockFaceDirection.ZIncreasing:
            light = world.GetLight((int)(frontNormal.X + pos.X), (int)(frontNormal.Y + pos.Y), (int)(frontNormal.Z + pos.Z));

            vertices.Add(new VertexPositionTextureLight(bottomLeftFront, frontNormal, bottomLeft, light));
            vertices.Add(new VertexPositionTextureLight(bottomRightFront, frontNormal, bottomRight, light));
            vertices.Add(new VertexPositionTextureLight(topLeftFront, frontNormal, topLeft, light));
            vertices.Add(new VertexPositionTextureLight(topRightFront, frontNormal, topRight, light));
            AddIndices(indices, 0, 2, 3, 3, 1, 0, ref offset);
            break;
        case BlockFaceDirection.ZDecreasing:
            light = world.GetLight((int)(backNormal.X + pos.X), (int)(backNormal.Y + pos.Y), (int)(backNormal.Z + pos.Z));

            vertices.Add(new VertexPositionTextureLight(bottomRightBack, backNormal, bottomLeft, light));
            vertices.Add(new VertexPositionTextureLight(bottomLeftBack, backNormal, bottomRight, light));
            vertices.Add(new VertexPositionTextureLight(topRightBack, backNormal, topLeft, light));
            vertices.Add(new VertexPositionTextureLight(topLeftBack, backNormal, topRight, light));
            AddIndices(indices, 0, 2, 3, 3, 1, 0, ref offset);
            break;
        case BlockFaceDirection.YIncreasing:
            light = world.GetLight((int)(upNormal.X + pos.X), (int)(upNormal.Y + pos.Y), (int)(upNormal.Z + pos.Z));

            vertices.Add(new VertexPositionTextureLight(topLeftFront, upNormal, bottomLeft, light));
            vertices.Add(new VertexPositionTextureLight(topRightFront, upNormal, bottomRight, light));
            vertices.Add(new VertexPositionTextureLight(topLeftBack, upNormal, topLeft, light));
            vertices.Add(new VertexPositionTextureLight(topRightBack, upNormal, topRight, light));
            AddIndices(indices, 0, 2, 3, 3, 1, 0, ref offset);
            break;
        case BlockFaceDirection.YDecreasing:
            light = world.GetLight((int)(downNormal.X + pos.X), (int)(downNormal.Y + pos.Y), (int)(downNormal.Z + pos.Z));

            vertices.Add(new VertexPositionTextureLight(bottomLeftBack, downNormal, bottomLeft, light));
            vertices.Add(new VertexPositionTextureLight(bottomRightBack, downNormal, bottomRight, light));
            vertices.Add(new VertexPositionTextureLight(bottomLeftFront, downNormal, topLeft, light));
            vertices.Add(new VertexPositionTextureLight(bottomRightFront, downNormal, topRight, light));
            AddIndices(indices, 0, 2, 3, 3, 1, 0, ref offset);
            break;
        case BlockFaceDirection.XIncreasing:
            light = world.GetLight((int)(rightNormal.X + pos.X), (int)(rightNormal.Y + pos.Y), (int)(rightNormal.Z + pos.Z));

            vertices.Add(new VertexPositionTextureLight(bottomRightFront, rightNormal, bottomLeft, light));
            vertices.Add(new VertexPositionTextureLight(bottomRightBack, rightNormal, bottomRight, light));
            vertices.Add(new VertexPositionTextureLight(topRightFront, rightNormal, topLeft, light));
            vertices.Add(new VertexPositionTextureLight(topRightBack, rightNormal, topRight, light));
            AddIndices(indices, 0, 2, 3, 3, 1, 0,ref offset);
            break;
        case BlockFaceDirection.XDecreasing:
            light = world.GetLight((int)(leftNormal.X + pos.X), (int)(leftNormal.Y + pos.Y), (int)(leftNormal.Z + pos.Z));

            vertices.Add(new VertexPositionTextureLight(bottomLeftBack, leftNormal, bottomLeft, light));
            vertices.Add(new VertexPositionTextureLight(bottomLeftFront, leftNormal, bottomRight, light));
            vertices.Add(new VertexPositionTextureLight(topLeftBack, leftNormal, topLeft, light));
            vertices.Add(new VertexPositionTextureLight(topLeftFront, leftNormal, topRight, light));
            AddIndices(indices, 0, 2, 3, 3, 1, 0, ref offset);
            break;
    }
}

public void AddIndices(List<short> IndexList, short i0, short i1, short i2, short i3, short i4, short i5, ref int offset)
{
    IndexList.Add((short)(i0 + offset));
    IndexList.Add((short)(i1 + offset));
    IndexList.Add((short)(i2 + offset));
    IndexList.Add((short)(i3 + offset));
    IndexList.Add((short)(i4 + offset));
    IndexList.Add((short)(i5 + offset));

    offset += 4;
}

private void CopyToBuffers(ref VertexBuffer vertexBuffer, ref IndexBuffer indexBuffer, List<VertexPositionTextureLight> vertices, List<short> indices)
{
    vertexBuffer = new VertexBuffer(Variables.GRAPHICS_DEVICE, VertexPositionTextureLight.VertexDeclaration, vertices.Count, BufferUsage.WriteOnly);
    vertexBuffer.SetData(vertices.ToArray());
    indexBuffer = new IndexBuffer(Variables.GRAPHICS_DEVICE, typeof(short), indices.Count, BufferUsage.WriteOnly);
    indexBuffer.SetData(indices.ToArray());
}

public void QueueForBuild(BufferType buffer)
{
    if (buffer == BufferType.All)
    {
        QueueForBuild(BufferType.Solid);
        QueueForBuild(BufferType.Water);
        QueueForBuild(BufferType.Lava);
    }
    else if (!bufferQueued.Contains(buffer))
    {
        bufferQueued.Enqueue(buffer);
    }
}

public void QueueForBuild(Block block)
{
    if (block.BlockType == BlockType.waterStill)
    {
        QueueForBuild(BufferType.Water);
    }
    else if (block.BlockType == BlockType.lavaStill)
    {
        QueueForBuild(BufferType.Lava);
    }
    else
    {
        QueueForBuild(BufferType.Solid);
    }
}

Any ideas? Note also that transparent blocks are either water, glass or air.

\$\endgroup\$
  • \$\begingroup\$ Could you please at least state what method is throwing the exception? \$\endgroup\$ – jdmichal Jan 30 '12 at 4:00
  • 1
    \$\begingroup\$ If the code is not working, this is a question for StackOverflow. \$\endgroup\$ – ANeves Jan 30 '12 at 9:52
1
\$\begingroup\$

Now that there is working code, we can review it. :)

Comments:

  • Class variables should use PascalCase;
  • Local variables should use camelCase;
  • You should avoid having x and X in the same scope, that is really asking for bugs...
  • Taking into consideration BufferType.All and BufferType.None, you should probably look into using the [Flags] attribute, if you are not yet;

Proposed code review of your answer code:

namespace QuarryCraft
{
    public static class Extensions
    {
        public static int GetRow(this BlockType type) {
            int index;
            switch (type) {
                default:
                    throw new NotImplementedException();
            }
            return index / Variables.TILE_ALAIS.NumberOfRows; // You probably had a bug here, you were using Variables.TILE_ALAIS.NumberOfColumns
        }
        public static int GetColumn(this BlockType type) {
            int index;
            switch (type) {
                default:
                    throw new NotImplementedException();
            }
            return index / Variables.TILE_ALAIS.NumberOfColumns;
        }
    }

    public class World
    {
        // Really useful way of acessing!
        public Block this[int x, int y, int z] {
            get {
                throw new NotImplementedException();
            }
            set {
                throw new NotImplementedException();
            }
        }
        // ...
    }

    public class Block
    {
        public BlockType BlockType { get; private set; }
        public bool IsTransparentSolid { get; private set; }
        // ...
    }

    [Flags]
    public enum BufferType
    {
        None = 0,
        Water = 1,
        Solid = 2,
        Air = 4,
        Lava = 10,
        All = 15
    }
    public enum BlockType
    {
        // you had camelCase, should be PascalCase
        None,
        WaterStill,
        LavaStill
    }

    public class Something
    {
        World World;
        // ...

        private void BuildVertexBuffers(BufferType buffer) {
            if (buffer == BufferType.All || buffer == BufferType.None) {
                // I have the feeling you should either throw an exception or return.
                // Use Debug.WriteLine() instead of Console.WriteLine()
                Debug.WriteLine("FAAAAAAAAAAAAAAAAAAAAAAIL!");
            }

            switch (buffer) {
                case BufferType.Water:
                    WaterVertices = new List<VertexPositionTextureLight>();
                    WaterIndexList = new List<short>();
                    OffsetWater = 0;    // PascalCase
                    break;
                case BufferType.Lava:
                    // Nothing // Always explicitly declare when you are doing nothing on purpose. An explanation might be useful too.
                    break;
                default:
                    SolidVertices = new List<VertexPositionTextureLight>();
                    SolidIndexList = new List<short>();
                    OffsetSolid = 0;    // PascalCase
                    break;
            }

            int xOffset = Index.X  // not "index" - class variables should use PascalCase
                                   // We can calculate these in advance, no need to repeat.
                                   * Variables.REGION_SIZE_X;   // I would use Variables.Region.SIZE_X
            int yOffset = Index.Y * Variables.REGION_SIZE_Y;   // I would use Variables.Region.SIZE_Y
            int zOffset = Index.Z * Variables.REGION_SIZE_Z;   // I would use Variables.Region.SIZE_Z
            for (short x = 0; x < Variables.REGION_SIZE_X; x++) {
                for (short y = 0; y < Variables.REGION_SIZE_Y; y++) {
                    for (short z = 0; z < Variables.REGION_SIZE_Z; z++) {
                        int newX = xOffset + x; // Local variables, camelCase; also, using x and X is asking for accidental bugs!
                        int newY = yOffset + y;
                        int newZ = zOffset + z;

                        if (buffer == BufferType.Water && World[newX, newY, newZ].BlockType == BlockType.WaterStill) {
                            BuildCube(buffer, WaterVertices, WaterIndexList, newX, newY, newZ, ref OffsetWater);
                        } else if (buffer == BufferType.Solid && World[newX, newY, newZ].BlockType != BlockType.WaterStill) {
                            BuildCube(buffer, SolidVertices, SolidIndexList, newX, newY, newZ, ref OffsetSolid);
                        }
                    }
                }
            }

            switch (buffer) {
                case BufferType.Water:
                    if (WaterVertices.Count > 0) {
                        CopyToBuffers(ref WaterVertexBuffer, ref WaterIndices, WaterVertices, WaterIndexList);
                    } else {
                        WaterVertexBuffer = null;
                    }
                    break;
                case BufferType.Lava:
                    // Nothing // Always explicitly declare when you are doing nothing on purpose. An explanation might be useful too.
                    break;
                default:
                    if (SolidVertices.Count > 0) {
                        CopyToBuffers(ref SolidVertexBuffer, ref SolidIndices, SolidVertices, SolidIndexList);
                    } else {
                        SolidVertexBuffer = null;
                    }
                    break;
            }
        }

        public void BuildCube(BufferType buffer, List<VertexPositionTextureLight> vertices, List<short> indices, int x, int y, int z, ref int offset) {
            Block target = World[x, y, z];
            if (target.BlockType == BlockType.None)
                return;

            bool above = !World[x, y + 1, z].IsTransparentSolid;
            bool below = !World[x, y - 1, z].IsTransparentSolid;
            bool left  = !World[x - 1, y, z].IsTransparentSolid;
            bool right = !World[x + 1, y, z].IsTransparentSolid;
            bool front = !World[x, y, z + 1].IsTransparentSolid;
            bool back  = !World[x, y, z - 1].IsTransparentSolid;

            bool notVisible = above && below && left && right && front && back;

            if (notVisible)
                return;

            Vector3 vector = new Vector3(x, y, z);
            if (!back)
                BuildCubeFace(vertices, indices, target, vector, BlockFaceDirection.ZDecreasing, ref offset);
            if (!front)
                BuildCubeFace(vertices, indices, target, vector, BlockFaceDirection.ZIncreasing, ref offset);
            if (!above)
                BuildCubeFace(vertices, indices, target, vector, BlockFaceDirection.YIncreasing, ref offset);
            if (!below)
                BuildCubeFace(vertices, indices, target, vector, BlockFaceDirection.YDecreasing, ref offset);
            if (!right)
                BuildCubeFace(vertices, indices, target, vector, BlockFaceDirection.XIncreasing, ref offset);
            if (!left)
                BuildCubeFace(vertices, indices, target, vector, BlockFaceDirection.XDecreasing, ref offset);
        }

        public void BuildCubeFace(List<VertexPositionTextureLight> vertices, List<short> indices, Block block, Vector3 pos, BlockFaceDirection blockFaceDirection, ref int offset) {
            Vector3 topLeftFront = new Vector3(0f, 1f, 0f) + pos;
            Vector3 bottomLeftFront = new Vector3(0f, 0f, 0f) + pos;
            Vector3 topRightFront = new Vector3(1f, 1f, 0f) + pos;
            Vector3 bottomRightFront = new Vector3(1f, 0f, 0f) + pos;
            Vector3 topLeftBack = new Vector3(0f, 1f, -1f) + pos;
            Vector3 topRightBack = new Vector3(1f, 1f, -1f) + pos;
            Vector3 bottomLeftBack = new Vector3(0f, 0f, -1f) + pos;
            Vector3 bottomRightBack = new Vector3(1f, 0f, -1f) + pos;

            Vector3 upNormal = new Vector3(0, 1, 0);
            Vector3 downNormal = new Vector3(0, -1, 0);
            Vector3 leftNormal = new Vector3(-1, 0, 0);
            Vector3 rightNormal = new Vector3(1, 0, 0);
            Vector3 backNormal = new Vector3(0, 0, -1);
            Vector3 frontNormal = new Vector3(0, 0, 1);

            float unit = 1.0f / Variables.TILE_ALAIS.NumberOfColumns;

            float x = unit * block.BlockType.GetColumn();
            float y = unit * block.BlockType.GetRow();

            Vector2 topLeft = new Vector2(x, y);
            Vector2 topRight = new Vector2(x + unit, y);
            Vector2 bottomLeft = new Vector2(x, y + unit);
            Vector2 bottomRight = new Vector2(x + unit, y + unit);

            float light = Variables.Light; // 12

            switch (blockFaceDirection) {
                case BlockFaceDirection.ZIncreasing:
                    light = world.GetLight((int)(frontNormal.X + pos.X), (int)(frontNormal.Y + pos.Y), (int)(frontNormal.Z + pos.Z));

                    vertices.Add(new VertexPositionTextureLight(bottomLeftFront, frontNormal, bottomLeft, light));
                    vertices.Add(new VertexPositionTextureLight(bottomRightFront, frontNormal, bottomRight, light));
                    vertices.Add(new VertexPositionTextureLight(topLeftFront, frontNormal, topLeft, light));
                    vertices.Add(new VertexPositionTextureLight(topRightFront, frontNormal, topRight, light));
                    break;
                case BlockFaceDirection.ZDecreasing:
                    light = world.GetLight((int)(backNormal.X + pos.X), (int)(backNormal.Y + pos.Y), (int)(backNormal.Z + pos.Z));

                    vertices.Add(new VertexPositionTextureLight(bottomRightBack, backNormal, bottomLeft, light));
                    vertices.Add(new VertexPositionTextureLight(bottomLeftBack, backNormal, bottomRight, light));
                    vertices.Add(new VertexPositionTextureLight(topRightBack, backNormal, topLeft, light));
                    vertices.Add(new VertexPositionTextureLight(topLeftBack, backNormal, topRight, light));
                    break;
                case BlockFaceDirection.YIncreasing:
                    light = world.GetLight((int)(upNormal.X + pos.X), (int)(upNormal.Y + pos.Y), (int)(upNormal.Z + pos.Z));

                    vertices.Add(new VertexPositionTextureLight(topLeftFront, upNormal, bottomLeft, light));
                    vertices.Add(new VertexPositionTextureLight(topRightFront, upNormal, bottomRight, light));
                    vertices.Add(new VertexPositionTextureLight(topLeftBack, upNormal, topLeft, light));
                    vertices.Add(new VertexPositionTextureLight(topRightBack, upNormal, topRight, light));
                    break;
                case BlockFaceDirection.YDecreasing:
                    light = world.GetLight((int)(downNormal.X + pos.X), (int)(downNormal.Y + pos.Y), (int)(downNormal.Z + pos.Z));

                    vertices.Add(new VertexPositionTextureLight(bottomLeftBack, downNormal, bottomLeft, light));
                    vertices.Add(new VertexPositionTextureLight(bottomRightBack, downNormal, bottomRight, light));
                    vertices.Add(new VertexPositionTextureLight(bottomLeftFront, downNormal, topLeft, light));
                    vertices.Add(new VertexPositionTextureLight(bottomRightFront, downNormal, topRight, light));
                    break;
                case BlockFaceDirection.XIncreasing:
                    light = world.GetLight((int)(rightNormal.X + pos.X), (int)(rightNormal.Y + pos.Y), (int)(rightNormal.Z + pos.Z));

                    vertices.Add(new VertexPositionTextureLight(bottomRightFront, rightNormal, bottomLeft, light));
                    vertices.Add(new VertexPositionTextureLight(bottomRightBack, rightNormal, bottomRight, light));
                    vertices.Add(new VertexPositionTextureLight(topRightFront, rightNormal, topLeft, light));
                    vertices.Add(new VertexPositionTextureLight(topRightBack, rightNormal, topRight, light));
                    break;
                case BlockFaceDirection.XDecreasing:
                    light = world.GetLight((int)(leftNormal.X + pos.X), (int)(leftNormal.Y + pos.Y), (int)(leftNormal.Z + pos.Z));

                    vertices.Add(new VertexPositionTextureLight(bottomLeftBack, leftNormal, bottomLeft, light));
                    vertices.Add(new VertexPositionTextureLight(bottomLeftFront, leftNormal, bottomRight, light));
                    vertices.Add(new VertexPositionTextureLight(topLeftBack, leftNormal, topLeft, light));
                    vertices.Add(new VertexPositionTextureLight(topLeftFront, leftNormal, topRight, light));
                    break;
            }
            AddIndices(indices, 0, 2, 3, 3, 1, 0, ref offset);
        }

        public void AddIndices(List<short> IndexList, short i0, short i1, short i2, short i3, short i4, short i5, ref int offset) {
            // ...
        }

        private void CopyToBuffers(ref VertexBuffer vertexBuffer, ref IndexBuffer indexBuffer, List<VertexPositionTextureLight> vertices, List<short> indices) {
            //...
        }

        public void QueueForBuild(BufferType buffer) {
            // ...
        }

        public void QueueForBuild(Block block) {
            // ...
        }
    }
}
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.