texture.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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 "scope_guard/scope_guard.hpp"
  9. #include <string>
  10. #include <unordered_map>
  11. #pragma clang diagnostic push
  12. #pragma clang diagnostic ignored "-Wcomma"
  13. #define STB_IMAGE_IMPLEMENTATION
  14. #include "stb/stb_image.h"
  15. #pragma clang diagnostic pop
  16. unsigned char * stbi_load(char const *, int *, int *, int *, int);
  17. void stbi_image_free(void *);
  18. template <typename T, typename Key = std::string> class private_factory {
  19. public:
  20. using key_t = Key;
  21. template <typename... Args> static T create(key_t const & key) {
  22. auto found = instances.find(key);
  23. if (found == instances.end()) {
  24. found = instances.emplace(key, T::create(key)).first;
  25. }
  26. return found->second;
  27. }
  28. private:
  29. static std::unordered_map<key_t, T> instances;
  30. };
  31. namespace graphics { namespace detail { namespace texture {
  32. struct format {};
  33. std::unordered_map<std::string, ::graphics::texture> g_textures;
  34. unsigned int init(format = {}, math::vec2i = {}, unsigned char * = {}) {
  35. throw; // TODO implement
  36. }
  37. }}}
  38. namespace graphics {
  39. texture texture::create(std::string const & imagefile) {
  40. using detail::texture::g_textures;
  41. auto found = g_textures.find(imagefile);
  42. if (found != g_textures.end()) { return found->second; }
  43. int components = 0;
  44. math::vec2i size;
  45. unsigned char * data =
  46. stbi_load(imagefile.c_str(), &size.x(), &size.y(), &components, 0);
  47. scope(exit) { stbi_image_free(data); };
  48. texture tex{detail::texture::init({}, size, data), size};
  49. return g_textures.emplace(imagefile, std::move(tex)).first->second;
  50. }
  51. texture texture::create(unsigned char * data, math::vec2i size) {
  52. return {detail::texture::init({}, size, data), size};
  53. }
  54. texture::texture(unsigned int id, math::vec2i sz)
  55. : identity<graphics::texture>(id), size(sz) {}
  56. }