BARE2D
ResourceManager.cpp
Go to the documentation of this file.
1 #include "ResourceManager.hpp"
2 
3 #include <string>
4 #include <vector>
5 
6 #include "BAREErrors.hpp"
7 #include "GLContextManager.hpp"
8 #include "IOManager.hpp"
9 #include "PicoPNG.hpp"
10 
11 namespace BARE2D {
12 
15 Cache<std::string, Texture>* ResourceManager::m_textures = new Cache<std::string, Texture>();
16 Cache<std::string, MutableTexture>* ResourceManager::m_mutableTextures = new Cache<std::string, MutableTexture>();
17 Cache<std::string, Sound>* ResourceManager::m_sounds = new Cache<std::string, Sound>();
18 Cache<std::string, Music>* ResourceManager::m_music = new Cache<std::string, Music>();
19 Cache<std::string, LuaScript>* ResourceManager::m_scripts = new Cache<std::string, LuaScript>();
20 Cache<std::string, Font>* ResourceManager::m_fonts = new Cache<std::string, Font>();
21 
23 {
24  ShaderProgram newProgram;
25 
26  newProgram.compileShaders((m_assetsPathPrefix + vertShaderSource).c_str(),
28 
29  return newProgram;
30 }
31 
33 {
34  ShaderProgram newProgram;
35 
36  newProgram.compileShadersFromSource(vertShaderSource.c_str(), fragShaderSource.c_str());
37 
38  return newProgram;
39 }
40 
41 Texture ResourceManager::loadTexture(std::string& texturePath)
42 {
43  std::string fullPath = m_assetsPathPrefix + m_texturePathPrefix + texturePath;
44 
45  {
46  // First, check that it doesn't already exist.
47  Texture* cached = m_textures->findItem(fullPath);
48 
49  if(cached)
50  return *cached;
51  }
52 
53  // So, it's not in the cache if we're still here. Load it from a file, create it in the cache, and add it.
54  // Creates it in the cache and returns a pointer.
55  Texture* loadedTex = m_textures->createItem(fullPath);
56  loadedTex->filepath = fullPath;
57  {
58  // Load raw data from the file
59  std::vector<unsigned char> fileData;
60  bool good = IOManager::readFileToBuffer(fullPath, fileData);
61 
62  // Check for errors
63  if(!good)
64  {
66  return *loadedTex;
67  }
68 
69  // Decode the raw information into texture data (thanks PicoPNG!)
70  std::vector<unsigned char> textureData;
71  unsigned long width, height;
72  int errCode = decodePNG(textureData, width, height, &(fileData[0]), fileData.size());
73  loadedTex->width = width;
74  loadedTex->height = height;
75 
76  // Check if pico broke
77  if(errCode != 0)
78  {
80  return *loadedTex;
81  }
82 
83  // Our data is good, so actually generate the texture, etc.
84  glGenTextures((GLsizei)1, &(loadedTex->id));
85 
86  // Bind the texture object
87  GLContextManager::getContext()->bindTexture(GL_TEXTURE_2D, loadedTex->id);
88 
89  // Upload pixel data
90  glTexImage2D(GL_TEXTURE_2D, (GLint)0, GL_RGBA, (GLsizei)loadedTex->width, (GLsizei)loadedTex->height, (GLint)0,
91  GL_RGBA, GL_UNSIGNED_BYTE, &(textureData[0]));
92 
93  // Set some basic parameters
94  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
95  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
96  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
97  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
98 
99  // Generate mipmaps
100  glGenerateTextureMipmap(loadedTex->id);
101 
102  // Finally, unbind the texture.
103  GLContextManager::getContext()->bindTexture(GL_TEXTURE_2D, 0);
104  }
105 
106  // Now that we know our texture definitely exists, we just return an instance of it!
107  return *loadedTex;
108 }
109 
111  unsigned int width,
112  unsigned int height,
113  GLenum minMagFilter /* = GL_LINEAR*/,
114  unsigned int channels /* = 4*/,
115  GLenum format /* = GL_RGBA*/)
116 {
117  // First, check if there's already a texture by this name:
118  MutableTexture* tex = loadMutableTexture(textureName);
119 
120  // If we don't already have one generated, we need to do so:
121  if(!tex)
122  {
123  tex = m_mutableTextures->createItem(textureName);
124  glGenTextures(1, &(tex->id));
125  }
126 
127  // Now that we have a texture, we need to set some parameters
128  // First, BARE parameters.
129  tex->width = width;
130  tex->height = height;
131  tex->filepath = textureName;
132  tex->channels = channels;
133  tex->format = format;
134 
135  // Now for OpenGL parameters.
136  GLContextManager::getContext()->bindTexture(GL_TEXTURE_2D, tex->id);
137 
138  // Specify it as a texture
139  glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, nullptr);
140 
141  // Will never want wrapping hopefully.
142  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
143  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
144 
145  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, minMagFilter);
146  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minMagFilter);
147 
148  GLContextManager::getContext()->bindTexture(GL_TEXTURE_2D, 0);
149 
150  return tex;
151 }
152 
154 {
155  // Find it in the cache. If none exists, return nullptr, not a new one.
156  MutableTexture* tex = m_mutableTextures->findItem(textureName);
157 
158  return tex;
159 }
160 
161 Sound ResourceManager::loadSound(std::string& soundPath)
162 {
163  std::string fullPath = m_assetsPathPrefix + soundPath;
164 
165  Sound* searched = m_sounds->findItem(fullPath);
166  if(searched)
167  {
168  return *searched; // We've already got it in the cache
169  }
170 
171  // Cache doesn't have it. Load it.
172  Mix_Chunk* chunk = Mix_LoadWAV(fullPath.c_str());
173  if(!chunk)
174  {
175  // There's been an error!
176  throwFatalError(BAREError::SDL_MIXER_LOAD_FAILURE, "Failed to load sound: " + std::string(Mix_GetError()));
177  }
178 
179  // Create a new one in the cache.
180  Sound* created = m_sounds->createItem(fullPath);
181  created->chunk = chunk;
182 
183  return *created;
184 }
185 
186 Music ResourceManager::loadMusic(std::string& musicPath)
187 {
188  std::string fullPath = m_assetsPathPrefix + musicPath;
189 
190  Music* searched = m_music->findItem(fullPath);
191  if(searched)
192  {
193  return *searched; // We've already got it in the cache
194  }
195 
196  // Cache doesn't have it. Load it.
197  Mix_Music* musicChunk = Mix_LoadMUS(fullPath.c_str());
198  if(!musicChunk)
199  {
200  // There's been an error!
201  throwFatalError(BAREError::SDL_MIXER_LOAD_FAILURE, "Failed to load music: " + std::string(Mix_GetError()));
202  }
203 
204  // Create a new one in the cache.
205  Music* created = m_music->createItem(fullPath);
206  created->music = musicChunk;
207 
208  return *created;
209 }
210 
211 LuaScript ResourceManager::loadScript(std::string& scriptPath)
212 {
213  if(scriptPath == "")
214  return LuaScript();
215 
216  std::string fullPath = m_assetsPathPrefix + scriptPath;
217 
218  // Make sure we don't already have it loaded
219  LuaScript* searched = m_scripts->findItem(fullPath);
220  if(searched)
221  {
222  return *searched;
223  }
224 
225  // Just needs to load text from a script file and put it into a LuaScript object, then put that into the cache.
226  // Load it!
227  std::string scriptSource = "";
228  if(!IOManager::readFileToBuffer(fullPath.c_str(), scriptSource))
229  {
230  // There was a problem reading, return an uninited script
231  return LuaScript();
232  }
233 
234  // Put it in the cache!
235  LuaScript* script = m_scripts->createItem(fullPath);
236  // and actually give it data lol.
237  script->m_script = scriptSource;
238  script->m_path = fullPath;
239  script->inited = true;
240 
241  return *script;
242 }
243 
244 LuaScript ResourceManager::loadScriptFromSource(std::string& scriptSource, std::string name)
245 {
246  // Make sure we don't already have it loaded
247  LuaScript* searched = m_scripts->findItem(name);
248  if(searched)
249  {
250  return *searched;
251  }
252 
253  // Put it in the cache!
254  LuaScript* script = m_scripts->createItem(name);
255  // and actually give it data lol.
256  script->m_script = scriptSource;
257  script->m_path = "NO_PATH";
258  script->inited = true;
259 
260  return *script;
261 }
262 
263 Font ResourceManager::loadFont(std::string& fontPath, int size)
264 {
265  std::string path = m_assetsPathPrefix + fontPath + std::to_string(size);
266 
267  // Check we haven't cached it
268  {
269  Font* cached = m_fonts->findItem(path);
270 
271  if(cached)
272  return *cached;
273  }
274 
275  // We don't already have it. Time to create it!
276  Font* font = m_fonts->createItem(path);
277 
278  font->init((m_assetsPathPrefix + fontPath).c_str(), size);
279 
280  return *font;
281 }
282 
284 {
285  m_textures->clear();
286  m_mutableTextures->clear();
287  m_sounds->clear();
288  m_scripts->clear();
289  m_fonts->clear();
290 
291  Logger::getInstance()->log("Cleared all caches.");
292 }
293 
294 void ResourceManager::setAssetsPathPrefix(std::string prefix)
295 {
296  m_assetsPathPrefix = prefix;
297 }
298 
300 {
301  return m_assetsPathPrefix;
302 }
303 
305 {
306  m_texturePathPrefix = prefix;
307 }
308 
309 } // namespace BARE2D
BARE2D::ResourceManager::setAssetsPathPrefix
static void setAssetsPathPrefix(std::string prefix)
Changes the prefix that will be prepended to all paths when resources are loaded.
Definition: ResourceManager.cpp:294
BARE2D::Font
Essentially just a wrapper for the SDL TTF_Font type.
Definition: Font.hpp:29
BARE2D::Sound
Definition: Sound.hpp:7
BARE2D::LuaScript::m_script
std::string m_script
Definition: LuaScript.hpp:20
BARE2D::ResourceManager::m_scripts
static Cache< std::string, LuaScript > * m_scripts
Definition: ResourceManager.hpp:137
BARE2D
Definition: App.cpp:13
BARE2D::Logger::getInstance
static Logger * getInstance()
Definition: Logger.cpp:34
BARE2D::ResourceManager::m_sounds
static Cache< std::string, Sound > * m_sounds
Definition: ResourceManager.hpp:135
BARE2D::decodePNG
int decodePNG(std::vector< unsigned char > &out_image, unsigned long &image_width, unsigned long &image_height, const unsigned char *in_png, std::size_t in_size, bool convert_to_rgba32)
Definition: PicoPNG.cpp:28
vertShaderSource
const char * vertShaderSource
Definition: DebugRenderer.cpp:16
BARE2D::GLContext::bindTexture
void bindTexture(GLenum target, GLenum texture)
Binds a texture to target in the currently active texture slot.
Definition: GLContextManager.cpp:22
BARE2D::ResourceManager::m_textures
static Cache< std::string, Texture > * m_textures
Definition: ResourceManager.hpp:133
BARE2D::ResourceManager::m_assetsPathPrefix
static std::string m_assetsPathPrefix
Definition: ResourceManager.hpp:130
BARE2D::Music
Definition: Music.hpp:7
BARE2D::Texture::height
int height
Definition: Texture.hpp:17
BARE2D::Texture
The texture struct holds very basic stuff - the filepath, width, height, and ID,.
Definition: Texture.hpp:13
BARE2D::ResourceManager::loadSound
static Sound loadSound(std::string &soundPath)
Loads a sound from the filepath given from the cache or from the file if the cache doesn't contain it...
Definition: ResourceManager.cpp:161
BARE2D::ResourceManager::createMutableTexture
static MutableTexture * createMutableTexture(std::string &textureName, unsigned int width, unsigned int height, GLenum minMagFilter=GL_LINEAR, unsigned int channels=4, GLenum format=GL_RGBA)
Creates a new mutable texture, or replaces one that exists with a new texture.
Definition: ResourceManager.cpp:110
BARE2D::ResourceManager::loadShadersFromSource
static ShaderProgram loadShadersFromSource(std::string &vertShaderSource, std::string &fragShaderSource)
Loads some shaders from their source. Does not cache.
Definition: ResourceManager.cpp:32
PicoPNG.hpp
ResourceManager.hpp
BARE2D::MutableTexture::channels
unsigned int channels
Definition: MutableTexture.hpp:37
BARE2D::Logger::log
void log(std::string message, bool important=false)
Logs a message to a file and the terminal.
Definition: Logger.cpp:42
BARE2D::ResourceManager::clearCaches
static void clearCaches()
Clears the various caches. This is useful for debugging.
Definition: ResourceManager.cpp:283
BARE2D::Texture::filepath
std::string filepath
Definition: Texture.hpp:14
BARE2D::LuaScript
Definition: LuaScript.hpp:14
BARE2D::Texture::width
int width
Definition: Texture.hpp:16
BARE2D::ShaderProgram::compileShaders
void compileShaders(const char *vertexShaderPath, const char *fragmentShaderPath)
Compiles the shaders. Does not link them.
Definition: ShaderProgram.cpp:23
BARE2D::ResourceManager::loadScript
static LuaScript loadScript(std::string &scriptPath)
Loads a script from the filepath given from the cache or from the file if it's not already in the cac...
Definition: ResourceManager.cpp:211
BARE2D::MutableTexture
A child of Texture which allows (and gives helpful functions for) mutation.
Definition: MutableTexture.hpp:13
fragShaderSource
const char * fragShaderSource
Definition: DebugRenderer.cpp:7
BARE2D::ResourceManager::loadMutableTexture
static MutableTexture * loadMutableTexture(std::string &textureName)
Gets a texture from the cache, or creates a new, empty texture.
Definition: ResourceManager.cpp:153
BAREErrors.hpp
GLContextManager.hpp
BARE2D::MutableTexture::format
GLenum format
Definition: MutableTexture.hpp:36
BARE2D::BAREError::TEXTURE_FAILURE
@ TEXTURE_FAILURE
BARE2D::ResourceManager::m_mutableTextures
static Cache< std::string, MutableTexture > * m_mutableTextures
Definition: ResourceManager.hpp:134
BARE2D::LuaScript::inited
bool inited
Definition: LuaScript.hpp:23
BARE2D::ResourceManager::loadShaders
static ShaderProgram loadShaders(std::string &vertShaderPath, std::string &fragShaderPath)
Loads some shaders. Combines both to give a full shader program. Does not cache.
Definition: ResourceManager.cpp:22
BARE2D::IOManager::readFileToBuffer
static bool readFileToBuffer(std::string &filepath, std::vector< T > &buf, std::ios_base::openmode mode=std::ios::binary)
Loads a file into a buffer.
BARE2D::ResourceManager::m_music
static Cache< std::string, Music > * m_music
Definition: ResourceManager.hpp:136
BARE2D::LuaScript::m_path
std::string m_path
Definition: LuaScript.hpp:21
BARE2D::ResourceManager::loadTexture
static Texture loadTexture(std::string &texturePath)
Loads a texture if it isn't already in the cache.
Definition: ResourceManager.cpp:41
BARE2D::Sound::chunk
Mix_Chunk * chunk
Definition: Sound.hpp:8
BARE2D::ShaderProgram
The ShaderProgram is a GLSL program which combines two shaders - the vertex shader and the fragment s...
Definition: ShaderProgram.hpp:14
BARE2D::ResourceManager::getAssetsPathPrefix
static std::string getAssetsPathPrefix()
Returns the assets path prefix. Pretty simple.
Definition: ResourceManager.cpp:299
BARE2D::ResourceManager::loadScriptFromSource
static LuaScript loadScriptFromSource(std::string &scriptSource, std::string name)
Creates and caches a script from the given source code.
Definition: ResourceManager.cpp:244
BARE2D::ResourceManager::loadMusic
static Music loadMusic(std::string &musicPath)
Loads some music from the filepath given from the cache or from the file if the cache doesn't contain...
Definition: ResourceManager.cpp:186
BARE2D::BAREError::SDL_MIXER_LOAD_FAILURE
@ SDL_MIXER_LOAD_FAILURE
BARE2D::Texture::id
GLuint id
Definition: Texture.hpp:15
BARE2D::GLContextManager::getContext
static GLContext * getContext()
Definition: GLContextManager.cpp:44
BARE2D::ResourceManager::setTexturePathPrefix
static void setTexturePathPrefix(std::string prefix)
Changes the prefix that will be prepended to all texture paths when they're loaded.
Definition: ResourceManager.cpp:304
BARE2D::ResourceManager::m_texturePathPrefix
static std::string m_texturePathPrefix
Definition: ResourceManager.hpp:131
BARE2D::ResourceManager::loadFont
static Font loadFont(std::string &fontPath, int size)
Loads a font to the cache.
Definition: ResourceManager.cpp:263
IOManager.hpp
BARE2D::Music::music
Mix_Music * music
Definition: Music.hpp:8
BARE2D::Font::init
void init(const char *fontFile, int size)
Creates font resources.
Definition: Font.cpp:30
BARE2D::throwFatalError
void throwFatalError(BAREError err, std::string message)
Throws an error (fatal). Also calls displayErrors and exits the program.
Definition: BAREErrors.cpp:178
BARE2D::ShaderProgram::compileShadersFromSource
void compileShadersFromSource(const char *vertexSource, const char *fragmentSource)
Similar to compileShaders, this just compiles the shaders.
Definition: ShaderProgram.cpp:38
BARE2D::ResourceManager::m_fonts
static Cache< std::string, Font > * m_fonts
Definition: ResourceManager.hpp:138