Files
GDevelop/Core/GDCore/Project/ImageManager.cpp
T
Florian Rival a8559bfbbc Add clang-format to format (C++) source files automatically (#491)
* Update all CMakeLists of extensions to use clang-format
* Run clang-format on all Extensions
* Update GDCore CMakeLists.txt to add clang-format
* Run clang-format on GDCore files
* Update GDJS and GDCpp CMakeLists.txt to add clang-format
* Run clang-format on GDCpp and GDJS files
2018-05-09 15:57:38 -07:00

214 lines
7.1 KiB
C++

/*
* GDevelop Core
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
* reserved. This project is released under the MIT License.
*/
#include "GDCore/Project/ImageManager.h"
#include <SFML/OpenGL.hpp>
#include "GDCore/Project/ResourcesLoader.h"
#include "GDCore/Project/ResourcesManager.h"
#include "GDCore/Tools/InvalidImage.h"
#if !defined(ANDROID) && !defined(MACOS)
#include <GL/glu.h>
#endif
#undef LoadImage // thx windows.h
namespace gd {
ImageManager::ImageManager() : resourcesManager(NULL) {
#if !defined(EMSCRIPTEN)
badTexture = std::make_shared<SFMLTextureWrapper>();
badTexture->texture.loadFromMemory(gd::InvalidImageData,
sizeof(gd::InvalidImageData));
badTexture->texture.setSmooth(false);
badTexture->image = badTexture->texture.copyToImage();
#endif
}
std::shared_ptr<SFMLTextureWrapper> ImageManager::GetSFMLTexture(
const gd::String& name) const {
if (!resourcesManager) {
std::cout << "ImageManager has no ResourcesManager associated with.";
return badTexture;
}
if (alreadyLoadedImages.find(name) != alreadyLoadedImages.end() &&
!alreadyLoadedImages.find(name)->second.expired())
return alreadyLoadedImages.find(name)->second.lock();
std::cout << "ImageManager: Loading " << name << ".";
// Load only an image when necessary
try {
ImageResource& image =
dynamic_cast<ImageResource&>(resourcesManager->GetResource(name));
auto texture = std::make_shared<SFMLTextureWrapper>();
ResourcesLoader::Get()->LoadSFMLImage(image.GetFile(), texture->image);
texture->texture.loadFromImage(texture->image);
texture->texture.setSmooth(image.smooth);
alreadyLoadedImages[name] = texture;
#if defined(GD_IDE_ONLY)
if (preventUnloading)
unloadingPreventer.push_back(
texture); // If unload prevention is activated, add the image to the
// list dedicated to prevent images from being unloaded.
#endif
return texture;
} catch (...) {
}
std::cout << " Resource not found." << std::endl;
return badTexture;
}
bool ImageManager::HasLoadedSFMLTexture(const gd::String& name) const {
if (alreadyLoadedImages.find(name) != alreadyLoadedImages.end() &&
!alreadyLoadedImages.find(name)->second.expired())
return true;
return false;
}
void ImageManager::SetSFMLTextureAsPermanentlyLoaded(
const gd::String& name,
std::shared_ptr<SFMLTextureWrapper>& texture) const {
if (alreadyLoadedImages.find(name) == alreadyLoadedImages.end() ||
alreadyLoadedImages.find(name)->second.expired())
alreadyLoadedImages[name] = texture;
if (permanentlyLoadedImages.find(name) == permanentlyLoadedImages.end())
permanentlyLoadedImages[name] = texture;
}
void ImageManager::ReloadImage(const gd::String& name) const {
if (!resourcesManager) {
std::cout << "ImageManager has no ResourcesManager associated with.";
return;
}
// Verify if image is in memory. If not, it will be automatically reloaded
// when necessary.
if (alreadyLoadedImages.find(name) == alreadyLoadedImages.end() ||
alreadyLoadedImages.find(name)->second.expired())
return;
// Image still in memory, get it and update it.
std::shared_ptr<SFMLTextureWrapper> oldTexture =
alreadyLoadedImages.find(name)->second.lock();
try {
ImageResource& image =
dynamic_cast<ImageResource&>(resourcesManager->GetResource(name));
std::cout << "ImageManager: Reload " << name << std::endl;
ResourcesLoader::Get()->LoadSFMLImage(image.GetFile(), oldTexture->image);
oldTexture->texture.loadFromImage(oldTexture->image);
oldTexture->texture.setSmooth(image.smooth);
return;
} catch (...) { /*The ressource is not an image*/
}
// Image not present anymore in image list.
std::cout << "ImageManager: " << name << " is not available anymore."
<< std::endl;
*oldTexture = *badTexture;
}
std::shared_ptr<OpenGLTextureWrapper> ImageManager::GetOpenGLTexture(
const gd::String& name) const {
if (alreadyLoadedOpenGLTextures.find(name) !=
alreadyLoadedOpenGLTextures.end() &&
!alreadyLoadedOpenGLTextures.find(name)->second.expired())
return alreadyLoadedOpenGLTextures.find(name)->second.lock();
std::cout << "Load OpenGL Texture" << name << std::endl;
std::shared_ptr<OpenGLTextureWrapper> texture =
std::make_shared<OpenGLTextureWrapper>(GetSFMLTexture(name));
alreadyLoadedOpenGLTextures[name] = texture;
return texture;
}
void ImageManager::LoadPermanentImages() {
if (!resourcesManager) {
std::cout << "ImageManager has no ResourcesManager associated with.";
return;
}
// Create a new list of permanently loaded images but do not delete now the
// old list so as not to unload images that could be still present.
std::map<gd::String, std::shared_ptr<SFMLTextureWrapper> >
newPermanentlyLoadedImages;
std::vector<gd::String> resources = resourcesManager->GetAllResourceNames();
for (std::size_t i = 0; i < resources.size(); i++) {
try {
ImageResource& image = dynamic_cast<ImageResource&>(
resourcesManager->GetResource(resources[i]));
if (image.alwaysLoaded)
newPermanentlyLoadedImages[image.GetName()] =
GetSFMLTexture(image.GetName());
} catch (...) { /*The resource is not an image, we don't care about it.*/
}
}
permanentlyLoadedImages = newPermanentlyLoadedImages;
}
#if defined(GD_IDE_ONLY)
void ImageManager::PreventImagesUnloading() {
preventUnloading = true;
for (auto it = alreadyLoadedImages.begin(); it != alreadyLoadedImages.end();
++it) {
std::shared_ptr<SFMLTextureWrapper> image = (it->second).lock();
if (image != std::shared_ptr<SFMLTextureWrapper>())
unloadingPreventer.push_back(image);
}
}
void ImageManager::EnableImagesUnloading() {
preventUnloading = false;
unloadingPreventer
.clear(); // Images which are not used anymore will thus be destroyed (As
// no shared pointer will be pointing to them).
}
#endif
} // namespace gd
SFMLTextureWrapper::SFMLTextureWrapper(const sf::Texture& texture_)
: texture(texture_), image(texture.copyToImage()) {}
SFMLTextureWrapper::SFMLTextureWrapper() {}
SFMLTextureWrapper::~SFMLTextureWrapper() {}
OpenGLTextureWrapper::OpenGLTextureWrapper(
std::shared_ptr<SFMLTextureWrapper> sfmlTexture_) {
sfmlTexture = sfmlTexture_;
#if !defined(ANDROID) // TODO: OpenGL
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, sfmlTexture->image.getSize().x,
// sfmlTexture->image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE,
// sfmlTexture->image.getPixelsPtr()); glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(
GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
#endif
}
OpenGLTextureWrapper::~OpenGLTextureWrapper() {
#if !defined(ANDROID) // TODO: OpenGL
glDeleteTextures(1, &texture);
#endif
};