c++ 12bit variable, how can I do this?

落花浮王杯 提交于 2021-02-10 06:21:10

问题


I'm building a voxel engine so I have concerns about memory usage, using 12bit instead of 16bit block ids could save a lot of memory. I have a 3D array of block ids, each id has a static configuration.

I'm not sure what a good way to achieve this would be. Is there a way to just get a block of raw memory and manage it myself and would this be a good idea; are there any problems I might run into? Is there a better way to do this?

I have some experience with c++, but most of my time was spent with Java and c#.

Thanks for reading!


回答1:


It is possible e.g. :-

  • reserve a 8-byte variable (store 5 variables, each 12 bits), or
  • reserve using char[k] that k~ceiling{(12*n)/8.0f}, then use union, etc....

Here is a link (I am the one who ask) that I learn about allocating memory in a chunk.
How to use void* as a single variable holder? (Ex. void* raw=SomeClass() )

However, I moderately disagree of what you are trying to do.

As far I know, the disadvantage of your approach are :-

  • Some bug : It is harder to implement.
  • alignment issue : Performance can be worse.
    See this : Memory alignment : how to use alignof / alignas?

Traditional recommendation : profile it before (prematurely) optimize it.




回答2:


Here are some other ideas:

  • have an 8-bit blockID but have a sectorID for each section, and each section uses it's own "palette" of blockIDs. Basically you could have 128 "common" tiles that can be found anywhere, and 128 zone-specific tiles. This sort of solution can work for many games, especially for mobile platforms, as you can specify a full set of assets and only load in ones referenced in each particular level, according to the "palette" of assets for that level.

And/or an even better idea than scrimping on block types:

  • use an oct-tree for the blocks. An area that's not differentiated would then only have one BlockID for the entire node. Empty space that's been dug out won't have to have many nodes (whenever a block is changed you check it against the higher level to see if it can be merged), which will make up for extra nodes created as areas are opened up.

The theoretical maximum memory for the oct-tree is a little more than for the solid chunk of blockIDs, but actual usage will have large areas which are in fact solids block types (e.g. the air). And rendering an oct-tree is going to be much faster as you can skip any node of empty space much faster than stepping through all tiles to check whether they're empty.

You can make a wrapper so that the oct-tree is interchangeable with your completely defined 3D array of blockIDs to start with, e.g. you can extract a blockID for any node via a function call. Then add in functions to set blockIDs, do the splitting and merging of the nodes as needed.



来源:https://stackoverflow.com/questions/43152077/c-12bit-variable-how-can-i-do-this

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!