texture.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. //
  2. // texture.cpp
  3. // graphics
  4. //
  5. // Created by Sam Jaffe on 7/5/16.
  6. //
  7. #include "game/graphics/texture.hpp"
  8. #include <unordered_map>
  9. #include "scope_guard/scope_guard.hpp"
  10. #pragma clang diagnostic push
  11. #pragma clang diagnostic ignored "-Wcomma"
  12. #define STB_IMAGE_IMPLEMENTATION
  13. #include "stb/stb_image.h"
  14. #pragma clang diagnostic pop
  15. #include "game/util/hash.hpp"
  16. #include "helper.hpp"
  17. unsigned char * stbi_load(char const *, int *, int *, int *, int);
  18. void stbi_image_free(void *);
  19. using namespace graphics;
  20. namespace {
  21. std::unordered_map<std::string, flyweight<texture>> g_textures;
  22. }
  23. static textures::format format(int comps) {
  24. switch (comps) {
  25. case 3:
  26. return textures::format::RGB;
  27. case 4:
  28. return textures::format::RGBA;
  29. default:
  30. throw;
  31. }
  32. }
  33. flyweight<texture> texture::create(std::string const & imagefile) {
  34. auto found = g_textures.find(imagefile);
  35. if (found != g_textures.end()) { return found->second; }
  36. int components = 0;
  37. math::vec2i size;
  38. unsigned char * data =
  39. stbi_load(imagefile.c_str(), &size.x(), &size.y(), &components, 0);
  40. scope(exit) { stbi_image_free(data); };
  41. auto id = textures::init(format(components), size, data);
  42. flyweight<texture> fly{id, {id, size}};
  43. return g_textures.emplace(imagefile, fly).first->second;
  44. }
  45. texture texture::create(char const * data, math::vec2i size) {
  46. return {textures::init(format(4), size, data), size};
  47. }
  48. texture::texture(unsigned int id, math::vec2i sz)
  49. : identity<texture>(id), size(sz) {}
  50. texture const texture::WHITE = texture::create("\xFF\xFF\xFF\xFF", {{1, 1}});
  51. texture const texture::DARK_YELLOW =
  52. texture::create("\x80\x80\x00\xFF", {{1, 1}});
  53. texture const texture::LIGHT_BLUE =
  54. texture::create("\x80\x80\xFF\xFF", {{1, 1}});