mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-21 01:25:32 -04:00
a8559bfbbc
* 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
214 lines
7.1 KiB
C++
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
|
|
};
|