mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-23 10:35:35 -04:00
211 lines
7.2 KiB
C++
211 lines
7.2 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 "GDCore/Project/ResourcesManager.h"
|
|
#include "GDCore/Project/ResourcesLoader.h"
|
|
#include "GDCore/Tools/InvalidImage.h"
|
|
#include "GDCore/Project/ResourcesManager.h"
|
|
#include <SFML/OpenGL.hpp>
|
|
#if !defined(ANDROID)
|
|
#include <GL/glu.h>
|
|
#endif
|
|
#undef LoadImage //thx windows.h
|
|
|
|
namespace gd
|
|
{
|
|
|
|
ImageManager::ImageManager() :
|
|
resourcesManager(NULL)
|
|
{
|
|
#if !defined(EMSCRIPTEN)
|
|
badTexture = std::shared_ptr<SFMLTextureWrapper>(new 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));
|
|
|
|
std::shared_ptr<SFMLTextureWrapper> texture(new SFMLTextureWrapper(ResourcesLoader::Get()->LoadSFMLTexture( image.GetFile() )));
|
|
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;
|
|
|
|
oldTexture->texture = ResourcesLoader::Get()->LoadSFMLTexture( image.GetFile() );
|
|
oldTexture->texture.setSmooth(image.smooth);
|
|
oldTexture->image = oldTexture->texture.copyToImage();
|
|
|
|
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::shared_ptr<OpenGLTextureWrapper>(new 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->GetAllResourcesList();
|
|
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
|
|
|
|
}
|
|
|
|
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);
|
|
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, sfmlTexture->image.getSize().x, sfmlTexture->image.getSize().y, GL_RGBA, GL_UNSIGNED_BYTE, sfmlTexture->image.getPixelsPtr());
|
|
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
|
|
};
|