SpriteSet.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #ifndef GRAPHICS_SPRITESET_H
  2. #define GRAPHICS_SPRITESET_H
  3. #include <cstdlib>
  4. #include <functional>
  5. #include <vector>
  6. class SpriteSet final {
  7. private:
  8. struct Page {
  9. unsigned previousIndex, nextIndex;
  10. unsigned firstShelfIndex;
  11. unsigned textureId;
  12. unsigned firstDirtyY, pastLastDirtyY, firstDirtyX, pastLastDirtyX;
  13. std::unique_ptr<std::vector<unsigned char>> textureData;
  14. };
  15. struct Shelf {
  16. unsigned pageIndex;
  17. unsigned y, height;
  18. unsigned previousIndex, nextIndex;
  19. unsigned firstSlotIndex, firstFreeSlotIndex;
  20. bool allocated;
  21. };
  22. struct Slot {
  23. unsigned shelfIndex;
  24. unsigned textureId;
  25. unsigned x, y, width, height, actualWidth;
  26. unsigned previousIndex, nextIndex;
  27. unsigned previousFreeIndex, nextFreeIndex;
  28. unsigned epoch;
  29. bool allocated;
  30. };
  31. unsigned bytesPerPixel, pageSize, spritePadding;
  32. std::vector<Page> pagePool{1 << 3};
  33. std::vector<Shelf> shelfPool{1 << 8};
  34. std::vector<Slot> slotPool{1 << 10};
  35. unsigned
  36. pageCount = 0, firstPageIndex = -1, lastPageIndex = 0,
  37. nextFreeShelfIndex = 0, nextFreeSlotIndex = 0;
  38. unsigned firstPageAllocatedPixels = 0;
  39. unsigned currentEpoch = 0;
  40. unsigned allocate(unsigned width, unsigned height);
  41. unsigned tryAllocateInPage(unsigned pageIndex, unsigned width, unsigned height);
  42. unsigned remove(unsigned slotIndex);
  43. public:
  44. struct Handle {
  45. unsigned slotIndex;
  46. unsigned epoch;
  47. };
  48. struct SpriteData {
  49. unsigned textureId, x, y, width, height;
  50. };
  51. std::function<void(unsigned)> removalCallback;
  52. std::function<void(unsigned, Handle)> migrationCallback;
  53. SpriteSet(unsigned bytesPerPixel, unsigned pageSize, unsigned spritePadding);
  54. void tick();
  55. Handle add(const unsigned width, const unsigned height, const unsigned char *const data) {
  56. return add(width, height, data, width);
  57. }
  58. Handle add(unsigned width, unsigned height, const unsigned char *data, unsigned rowStride);
  59. void remove(Handle handle);
  60. SpriteData get(Handle handle) const;
  61. std::vector<const unsigned char*> getTextures() const;
  62. void dump(std::vector<SpriteData> &sprites) const;
  63. };
  64. #endif // GRAPHICS_SPRITESET_H