Advertisement
Geometrian

Aegle Buffer Prototype

Sep 24th, 2018
288
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.68 KB | None | 0 0
  1. #define AEGLE_BUFFER_ALIGNPAD 256
  2.  
  3.  
  4. //Encapsulates a buffer.
  5. //  Note: untyped for ease-of-use (no need to specify types when handling).  To set/get typed data,
  6. //  construct `BufferView<...>` instances.
  7. class Buffer final {
  8.     public:
  9.         uint8_t* backing;
  10.     private:
  11.         size_t _size_max;
  12.     public:
  13.         size_t size;
  14.  
  15.     public:
  16.         Buffer();
  17.         explicit Buffer(size_t size);
  18.         explicit Buffer(Buffer const& other);
  19.         ~Buffer();
  20.  
  21.         void resize(size_t size);
  22. };
  23.  
  24. //Encapsulates typed views of a `Buffer`.
  25. //  Exposes an "array-of-structures" representation, regardless of whether the underlying data looks
  26. //  like that.  Surprisingly, with good compilers, this has no runtime cost.
  27. #define AEGLE_BUFFER_INDEXING_METHODS(PREFIX,ASSERT)\
  28.     private:\
  29.         /*E.g. `resolution[0]*(resolution[1]*(resolution[2]*index[0] + index[1]) + index[2]) + index[3]`*/\
  30.                                        PREFIX size_t _convert_to_index_helper(size_t inner, size_t index                   ) const { return resolution[0]*inner+index; }\
  31.         template <typename... size_ts> PREFIX size_t _convert_to_index_helper(size_t inner, size_t index,size_ts... indices) const { return _convert_to_index_helper( resolution[sizeof...(indices)]*inner+index, indices... ); }\
  32.         template <typename... size_ts> PREFIX size_t _convert_to_index(size_ts... indices) const { ASSERT return _convert_to_index_helper(indices...); }\
  33.     public:\
  34.         template <bool b=!type_elem::CONST_ACCESS,typename=typename std::enable_if_t<b>                     > type_elem       operator()(size_t     index  )       { return type_elem(buffer,                  index      ); }\
  35.                                                                                                               type_elem const operator()(size_t     index  ) const { return type_elem(buffer,                  index      ); }\
  36.         template <bool b=!type_elem::CONST_ACCESS,typename=typename std::enable_if_t<b>, typename... size_ts> type_elem       operator()(size_ts... indices)       { return type_elem(buffer,_convert_to_index(indices...)); }\
  37.         template <                                                                       typename... size_ts> type_elem const operator()(size_ts... indices) const { return type_elem(buffer,_convert_to_index(indices...)); }
  38. template <class type_elem, size_t... reses> class BufferView            final {
  39.     public:
  40.         std::add_const_if_t<Buffer,type_elem::CONST_ACCESS>*const buffer;
  41.  
  42.         enum : size_t { DIMENSIONS=sizeof...(reses) };
  43.         enum class ORDERING { LINEAR, Z_FRACTAL };
  44.  
  45.         size_t const resolution[sizeof...(reses)] = { reses... };
  46.  
  47.     public:
  48.         explicit BufferView(std::add_const_if_t<Buffer,type_elem::CONST_ACCESS>* buffer) : buffer(buffer) {}
  49.         ~BufferView() = default;
  50.  
  51.         constexpr size_t get_length() const {
  52.             size_t length = resolution[0];
  53.             for (size_t i=1;i<sizeof...(reses);++i) length*=resolution[i];
  54.             return length;
  55.         }
  56.  
  57.         template <bool b=!type_elem::CONST_ACCESS,typename=typename std::enable_if_t<b>>
  58.         void resize_backing() { buffer->resize(get_length()*type_elem::SIZE); }
  59.  
  60.         AEGLE_BUFFER_INDEXING_METHODS(constexpr,static_assert(sizeof...(size_ts)==DIMENSIONS,"Invalid number of indices!");)
  61. };
  62. template <class type_elem                 > class BufferView<type_elem> final {
  63.     public:
  64.         std::add_const_if_t<Buffer,type_elem::CONST_ACCESS>*const buffer;
  65.  
  66.         enum class ORDERING { LINEAR, Z_FRACTAL };
  67.  
  68.         size_t const*const resolution;
  69.  
  70.     public:
  71.         BufferView(std::add_const_if_t<Buffer,type_elem::CONST_ACCESS>* buffer, size_t const reses[]) : buffer(buffer), resolution(reses) {}
  72.         ~BufferView() = default;
  73.  
  74.         size_t get_length(size_t dimensions) const {
  75.             size_t length = resolution[0];
  76.             for (size_t i=1;i<dimensions;++i) length*=resolution[i];
  77.             return length;
  78.         }
  79.  
  80.         template <bool b=!type_elem::CONST_ACCESS,typename=typename std::enable_if_t<b>>
  81.         void resize_backing(size_t dimensions) { buffer->resize(get_length(dimensions)*type_elem::SIZE); }
  82.  
  83.         AEGLE_BUFFER_INDEXING_METHODS(NOTHING,NOTHING)
  84. };
  85.  
  86. template <typename type, bool const_access> class BufferAccessor;
  87. template <typename type                   > class BufferAccessor<type,false> final {
  88.     public:
  89.         type* ptr;
  90.  
  91.     public:
  92.         explicit BufferAccessor(type* ptr) : ptr(ptr) {}
  93.         ~BufferAccessor() = default;
  94.  
  95.         operator type      &()       { return *ptr; }
  96.         operator type const&() const { return *ptr; }
  97.         template <typename type_other> type& operator=(type_other const& other) { return static_cast<type&>(*this)=other; }
  98. };
  99. template <typename type                   > class BufferAccessor<type,true > final {
  100.     public:
  101.         type const* ptr;
  102.  
  103.     public:
  104.         explicit BufferAccessor(type const* ptr) : ptr(ptr) {}
  105.         ~BufferAccessor() = default;
  106.  
  107.         operator type const&() const { return *ptr; }
  108. };
  109.  
  110. template <bool const_access> class BufferElemXYZ final {
  111.     public:
  112.         enum : size_t { SIZE=3*sizeof(float) };
  113.         enum : bool { CONST_ACCESS=const_access };
  114.         BufferAccessor<float,const_access> x, y, z;
  115.  
  116.     public:
  117.         explicit BufferElemXYZ(float* ptr) : x(ptr), y(ptr+1), z(ptr+2) {}
  118.         BufferElemXYZ(Buffer const* parent, size_t index) : BufferElemXYZ(reinterpret_cast<float*>(parent->backing)+index) {}
  119.         ~BufferElemXYZ() = default;
  120. };
  121. template <bool const_access> class BufferElemRGB final {
  122.     public:
  123.         enum : size_t { SIZE=3*sizeof(float) };
  124.         enum : bool { CONST_ACCESS=const_access };
  125.         BufferAccessor<float,const_access> r, g, b;
  126.  
  127.     public:
  128.         explicit BufferElemRGB(float* ptr) : r(ptr), g(ptr+1), b(ptr+2) {}
  129.         BufferElemRGB(Buffer const* parent, size_t index) : BufferElemRGB(reinterpret_cast<float*>(parent->backing)+index) {}
  130.         ~BufferElemRGB() = default;
  131. };
  132. template <bool const_access> class BufferElemPlanarRGB final {
  133.     public:
  134.         enum : size_t { SIZE=3*sizeof(float) };
  135.         enum : bool { CONST_ACCESS=const_access };
  136.         BufferAccessor<float,const_access> r, g, b;
  137.  
  138.     public:
  139.         BufferElemPlanarRGB(float*__restrict ptr_r, float*__restrict ptr_g, float*__restrict ptr_b) : r(ptr_r), g(ptr_g), b(ptr_b) {}
  140.         BufferElemPlanarRGB(Buffer const* parent, size_t index) : BufferElemPlanarRGB(
  141.             reinterpret_cast<float*>(parent->backing)+index,
  142.             reinterpret_cast<float*>(parent->backing)+index+  sizeof(float)*parent->length,
  143.             reinterpret_cast<float*>(parent->backing)+index+2*sizeof(float)*parent->length
  144.         ) {}
  145.         ~BufferElemPlanarRGB() = default;
  146. };
  147. template <bool const_access> class BufferElemVert final {
  148.     public:
  149.         enum : size_t { SIZE=BufferElemXYZ<const_access>::SIZE+BufferElemPlanarRGB<const_access>::SIZE };
  150.         enum : bool { CONST_ACCESS=const_access };
  151.         BufferElemXYZ<const_access> vert;
  152.         BufferElemPlanarRGB<const_access> color;
  153.  
  154.     public:
  155.         explicit BufferElemVert(
  156.             float*__restrict ptr_v,
  157.             float*__restrict ptr_col_r, float*__restrict ptr_col_g, float*__restrict ptr_col_b
  158.         ) :
  159.             vert(ptr_v),
  160.             color(ptr_col_r,ptr_col_g,ptr_col_b)
  161.         {}
  162.         template <size_t... reses> BufferElemVert(Buffer const* parent, size_t index) : BufferElemVert(
  163.             reinterpret_cast<float*>(parent->data)+index,
  164.             reinterpret_cast<float*>(parent->data)+index+ 3   *sizeof(float)*parent->length,
  165.             reinterpret_cast<float*>(parent->data)+index+(3+1)*sizeof(float)*parent->length,
  166.             reinterpret_cast<float*>(parent->data)+index+(3+2)*sizeof(float)*parent->length
  167.         ) {}
  168.         ~BufferElemVert() = default;
  169. };
  170.  
  171. Buffer* foo() {
  172.     Buffer* buffer = _new Buffer;
  173.  
  174.     BufferView<BufferElemVert<false>,32,32,32> view(buffer);
  175.     view.resize_backing();
  176.  
  177.     return buffer;
  178. }
  179. Buffer* bar() {
  180.     Buffer* buffer = _new Buffer;
  181.  
  182.     Ash::LA::Vec2zu res(800,600);
  183.     BufferView<BufferElemVert<false>> view(buffer,res[0]);
  184.     view.resize_backing(2);
  185.  
  186.     return buffer;
  187. }
  188. float bar(Buffer const& buf) {
  189.     BufferView<BufferElemVert<true>,32,32,32> view(&buf);
  190.     //view(6,7,11).color.g = 6.0f;
  191.     return view(6,7,11).color.g;
  192. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement