A 2D tile-based sandbox game.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #include "TileAtlas.h"
  2. #include <iostream>
  3. #include <vector>
  4. #include <SDL_opengles2.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <swan-common/constants.h>
  8. namespace Cygnet {
  9. struct AtlasState {
  10. size_t tilesPerLine;
  11. size_t width = 0;
  12. size_t height = 0;
  13. std::vector<unsigned char> data;
  14. };
  15. TileAtlas::TileAtlas(): state_(std::make_unique<AtlasState>()) {
  16. GLint size;
  17. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size);
  18. state_->tilesPerLine = size / SwanCommon::TILE_SIZE;
  19. }
  20. TileAtlas::~TileAtlas() = default;
  21. void TileAtlas::addTile(size_t tileId, const void *data, size_t len) {
  22. size_t rows = len / (SwanCommon::TILE_SIZE * 4);
  23. const unsigned char *bytes = (const unsigned char *)data;
  24. size_t x = tileId % state_->tilesPerLine;
  25. size_t y = tileId / state_->tilesPerLine;
  26. if (y >= state_->tilesPerLine) {
  27. std::cerr << "Cygnet: Warning: Tile ID " << tileId << " too big for texture atlas\n";
  28. return;
  29. }
  30. if (state_->width <= x) {
  31. state_->width = x + 1;
  32. }
  33. if (state_->height <= y) {
  34. state_->height = y + 1;
  35. }
  36. size_t tileImgSize = SwanCommon::TILE_SIZE * SwanCommon::TILE_SIZE * 4;
  37. size_t requiredSize = (x + 1) * (y + 1) * tileImgSize;
  38. state_->data.resize(requiredSize);
  39. for (size_t ty = 0; ty < rows; ++ty) {
  40. unsigned char *dest = state_->data.data() +
  41. ((y + ty) * state_->width * SwanCommon::TILE_SIZE * 4) +
  42. (x * SwanCommon::TILE_SIZE * 4);
  43. const unsigned char *src = bytes + ty * SwanCommon::TILE_SIZE * 4;
  44. memcpy(dest, src, SwanCommon::TILE_SIZE * 4);
  45. }
  46. }
  47. }