Duckdoom5
Duckdoom5

Reputation: 764

c++ Memory reduction with arrays

I'm creating a block based game and I would like to improve on its memory usage. I'm currently creating blocks with a sizeof() 8. And I can't reduce its size.

Block:

...
bool front, back, left, right, top, bottom;//If the face is active, true

BYTE blockType;
BYTE data;

I came up with a solution but I have no idea how to properly implement it because I'm quite new to c++. The solution: All air blocks are exactly equal but each take up 8 bytes of memory. If I could set all air blocks, pointing to the same piece of memory, this should (I guess) be using less memory. (unless the pointer address takes up 8 bytes ?)

Currently my array looks like this:

Chunk:

Block*** m_pBlocks;

Chunk::Chunk()
{
    m_pBlocks = new Block**[CHUNK_SIZE];
    for(int x = 0; x < CHUNK_SIZE; x++){
        m_pBlocks[x] = new Block*[CHUNK_HEIGHT];
        for(int y = 0; y < CHUNK_HEIGHT; y++){
            m_pBlocks[x][y] = new Block[CHUNK_SIZE];
        }
    }
}

I know you can't make these point to null or point to something else so how should I do this?

Upvotes: 0

Views: 258

Answers (2)

Surt
Surt

Reputation: 16099

Using bitfields to reduce the size of Block.

class Block {
  // bit fields, reduce 6 bytes to 1
  unsigned char front:1, back:1, left:1, right:1, top:1, bottom:1;//If the face is active, true

  BYTE blockType;
  BYTE data;
  // optional alignment to size 4.
  // BYTE pad;
};

Block m_pBlocks[32][64][32]; // 32*64*32=64K * sizeof(Block)=256K that is a lot.

And yes, using a pointer that is 8 bytes is not really a save.

But there are several methods that helps save more, if you have a hightmap everything above the hight map is air! so you only need a 2d array to check that, where the elements are the hight. All air voxels below the hightmap must be defined along with the other none-air elements.

Other data structures are often more space effective like Octree or Sparse voxel octree.

Upvotes: 1

dau_sama
dau_sama

Reputation: 4357

if you don't need to modify those blocks, you could create a lookup map. please, do not use new, and avoid pointers as much as you can.

bool lookup[CHUNK_SIZE][CHUNK_HEIGHT];

Chunk::Chunk()
{
    for(int x = 0; x < CHUNK_SIZE; x++)
      for(int y = 0; y < CHUNK_HEIGHT; y++)
        lookup[x][y] = true;
}

now you can just query the lookup table to see if you have that particular block set. Moreover you now have all those values close together, which is beneficial for performance.

Upvotes: 1

Related Questions