Radium Engine  1.5.0
TextureManager.cpp
1 #include <Engine/Data/Texture.hpp>
2 #include <Engine/Data/TextureManager.hpp>
3 
4 #include <Core/Utils/Log.hpp>
5 
6 #include <stb/stb_image.h>
7 
8 namespace Ra {
9 namespace Engine {
10 namespace Data {
11 
12 using namespace Core::Utils; // log
13 
14 TextureManager::TextureManager() = default;
15 
16 TextureManager::~TextureManager() {
17  for ( auto& tex : m_textures ) {
18  delete tex.second;
19  }
20  m_textures.clear();
21  m_pendingTextures.clear();
22  m_pendingData.clear();
23 }
24 
25 TextureParameters&
26 TextureManager::addTexture( const std::string& name, uint width, uint height, void* data ) {
27  TextureParameters texData;
28  texData.name = name;
29  texData.width = width;
30  texData.height = height;
31  texData.texels = data;
32 
33  m_pendingTextures[name] = texData;
34 
35  return m_pendingTextures[name];
36 }
37 
39  stbi_set_flip_vertically_on_load( true );
40  int n;
41  unsigned char* data = stbi_load( texParameters.name.c_str(),
42  (int*)( &( texParameters.width ) ),
43  (int*)( &( texParameters.height ) ),
44  &n,
45  0 );
46 
47  if ( !data ) {
48  LOG( logERROR ) << "Something went wrong when loading image \"" << texParameters.name
49  << "\".";
50  texParameters.width = texParameters.height = 0;
51  return;
52  }
53 
54  switch ( n ) {
55  case 1: {
56  texParameters.format = GL_RED;
57  texParameters.internalFormat = GL_R8;
58  } break;
59 
60  case 2: {
61  // suppose it is GL_LUMINANCE_ALPHA
62  texParameters.format = GL_RG;
63  texParameters.internalFormat = GL_RG8;
64  } break;
65 
66  case 3: {
67  texParameters.format = GL_RGB;
68  texParameters.internalFormat = GL_RGB8;
69  } break;
70 
71  case 4: {
72  texParameters.format = GL_RGBA;
73  texParameters.internalFormat = GL_RGBA8;
74  } break;
75  default: {
76  texParameters.format = GL_RGBA;
77  texParameters.internalFormat = GL_RGBA8;
78  } break;
79  }
80 
81  CORE_ASSERT( data, "Data is null" );
82  texParameters.texels = data;
83  texParameters.type = GL_UNSIGNED_BYTE;
84 }
85 
86 Texture* TextureManager::loadTexture( const TextureParameters& texParameters, bool linearize ) {
87  TextureParameters texParams = texParameters;
88  // TODO : allow to keep texels in texture parameters with automatic lifetime management.
89  bool mustFreeTexels = false;
90  if ( texParams.texels == nullptr ) {
91  loadTextureImage( texParams );
92  mustFreeTexels = true;
93  }
94  auto ret = new Texture( texParams );
95  ret->initializeGL( linearize );
96 
97  if ( mustFreeTexels ) {
98  stbi_image_free( ret->getParameters().texels );
99  ret->getParameters().texels = nullptr;
100  }
101  return ret;
102 }
103 
105  bool linearize ) {
106  {
107  // Is texture in the manager ?
108  auto it = m_textures.find( texParameters.name );
109  if ( it != m_textures.end() ) { return it->second; }
110  }
111  {
112  // Is texture pending but registered in the manager
113  auto it = m_pendingTextures.find( texParameters.name );
114  if ( it != m_pendingTextures.end() ) {
115  auto pendingParams = it->second;
116  auto ret = loadTexture( pendingParams, linearize );
117  m_textures[pendingParams.name] = ret;
118  m_pendingTextures.erase( it );
119  return ret;
120  }
121  }
122  // Texture is not in the manager, add it
123  auto ret = loadTexture( texParameters, linearize );
124 
125  m_textures[texParameters.name] = ret;
126  return ret;
127 }
128 
129 void TextureManager::deleteTexture( const std::string& filename ) {
130  auto it = m_textures.find( filename );
131 
132  if ( it != m_textures.end() ) {
133  delete it->second;
134  m_textures.erase( it );
135  }
136 }
137 
139  deleteTexture( texture->getName() );
140 }
141 
142 void TextureManager::updateTextureContent( const std::string& texture, void* content ) {
143  CORE_ASSERT( m_textures.find( texture ) != m_textures.end(),
144  "Trying to update non existing texture" );
145  m_pendingData[texture] = content;
146 }
147 
149  if ( m_pendingData.empty() ) { return; }
150 
151  for ( auto& data : m_pendingData ) {
152  LOG( logINFO ) << "TextureManager::updateTextures \"" << data.first << "\".";
153  m_textures[data.first]->updateData( data.second );
154  }
155  m_pendingData.clear();
156 }
157 
158 } // namespace Data
159 } // namespace Engine
160 } // namespace Ra
TextureParameters & addTexture(const std::string &name, uint width, uint height, void *data)
Texture * loadTexture(const TextureParameters &texParameters, bool linearize=false)
Texture * getOrLoadTexture(const TextureParameters &texParameters, bool linearize=false)
void deleteTexture(const std::string &filename)
void loadTextureImage(TextureParameters &texParameters)
void updateTextureContent(const std::string &texture, void *content)
std::string getName() const
Definition: Texture.hpp:151
Definition: Cage.cpp:3
size_t height
height of the texture (t dimension)
Definition: Texture.hpp:50
GLenum format
Format of the external data.
Definition: Texture.hpp:54
size_t width
width of the texture (s dimension)
Definition: Texture.hpp:48
GLenum type
Type of the components in external data.
Definition: Texture.hpp:58
GLenum internalFormat
OpenGL internal format (WARNING, for Integer textures, must be GL_XXX_INTEGER)
Definition: Texture.hpp:56
std::string name
Name of the texture.
Definition: Texture.hpp:44