It sounds like you're taking a very OOP approach to this problem, when really you should be taking a more functional approach (just the approach - we're not going "all-in" here - we're basically just applying functions to buffers).
Instead of a cube class
(reference type) with a constructor that gets "created", simply have a cube struct
(value type) with a very small memory footprint. This could be as simple as an int
that indicates what kind of cube it is. The important thing is to, like an integer, have a "zero" value that represents an empty space.
Then create an array of these. For simplicity you can use a 3D array. Later on you might want to consider a 1D array (slightly faster in .NET) and trying to read through it while touching as little memory as possible. But for now this will do - it is far better than allocating thousands of cube objects flung all over heap memory!
The position of each cube is implicitly defined by its position in the array.
Then, taking a functional approach, you transform that "cube" data into "vertex" data for a given chunk (or the whole world, if it's small enough). A method to do that transformation might have code that looks a little something like this:
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
for(int z = 0; z < depth; z++)
{
if(x-1 >= 0 && cubes[x-1, y, z])
AddFace(x, y, z, Face.Left);
if(x+1 < width && cubes[x+1, y, z])
AddFace(x, y, z, Face.Right);
if(z-1 >= 0 && cubes[x, y, z-1])
AddFace(x, y, z, Face.Back);
if(z+1 < depth && cubes[x, y, z+1])
AddFace(x, y, z, Face.Front);
if(y-1 >= 0 && cubes[x, y-1, z])
AddFace(x, y, z, Face.Bottom);
if(y+1 < depth && cubes[x, y+1, z])
AddFace(x, y, z, Face.Top);
}
}
}
This takes advantage of the fact the cube data is stored in a spatially meaningful way.
I'll leave AddFace
as an exercise. But basically it should append appropriate vertices and indices to a List
of faces for the whole chunk. Which you'd then use to SetData()
to your chunk's VertexBuffer
and IndexBuffer
(via ToArray()
).
(As mentioned in comments in our discussion over here, you can save yourself the copying that ToArray()
does by using an array directly, instead of a List
, and manually managing your count and capacity. Take a look at the code in this answer)