Otclient  14/8/2020
texturemanager.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "texturemanager.h"
24 #include "animatedtexture.h"
25 #include "graphics.h"
26 #include "image.h"
27 
29 #include <framework/core/clock.h>
32 
34 
36 {
37  m_emptyTexture = TexturePtr(new Texture);
38 }
39 
41 {
42  if(m_liveReloadEvent) {
43  m_liveReloadEvent->cancel();
44  m_liveReloadEvent = nullptr;
45  }
46  m_textures.clear();
47  m_animatedTextures.clear();
48  m_emptyTexture = nullptr;
49 }
50 
52 {
53  // update only every 16msec, this allows upto 60 fps for animated textures
54  static ticks_t lastUpdate = 0;
55  ticks_t now = g_clock.millis();
56  if(now - lastUpdate < 16)
57  return;
58  lastUpdate = now;
59 
60  for(const AnimatedTexturePtr& animatedTexture : m_animatedTextures)
61  animatedTexture->updateAnimation();
62 }
63 
65 {
66  m_animatedTextures.clear();
67  m_textures.clear();
68 }
69 
71 {
72  if(m_liveReloadEvent)
73  return;
74  m_liveReloadEvent = g_dispatcher.cycleEvent([this] {
75  for(auto& it : m_textures) {
76  const std::string& path = g_resources.guessFilePath(it.first, "png");
77  const TexturePtr& tex = it.second;
78  if(tex->getTime() >= g_resources.getFileTime(path))
79  continue;
80 
81  ImagePtr image = Image::load(path);
82  if(!image)
83  continue;
84  tex->uploadPixels(image, tex->hasMipmaps());
85  tex->setTime(stdext::time());
86  }
87  }, 1000);
88 }
89 
90 TexturePtr TextureManager::getTexture(const std::string& fileName)
91 {
92  TexturePtr texture;
93 
94  // before must resolve filename to full path
95  std::string filePath = g_resources.resolvePath(fileName);
96 
97  // check if the texture is already loaded
98  auto it = m_textures.find(filePath);
99  if(it != m_textures.end()) {
100  texture = it->second;
101  }
102 
103  // texture not found, load it
104  if(!texture) {
105  try {
106  std::string filePathEx = g_resources.guessFilePath(filePath, "png");
107 
108  // load texture file data
109  std::stringstream fin;
110  g_resources.readFileStream(filePathEx, fin);
111  texture = loadTexture(fin);
112  } catch(stdext::exception& e) {
113  g_logger.error(stdext::format("Unable to load texture '%s': %s", fileName, e.what()));
114  texture = g_textures.getEmptyTexture();
115  }
116 
117  if(texture) {
118  texture->setTime(stdext::time());
119  texture->setSmooth(true);
120  m_textures[filePath] = texture;
121  }
122  }
123 
124  return texture;
125 }
126 
127 TexturePtr TextureManager::loadTexture(std::stringstream& file)
128 {
129  TexturePtr texture;
130 
131  apng_data apng;
132  if(load_apng(file, &apng) == 0) {
133  Size imageSize(apng.width, apng.height);
134  if(apng.num_frames > 1) { // animated texture
135  std::vector<ImagePtr> frames;
136  std::vector<int> framesDelay;
137  for(uint i=0;i<apng.num_frames;++i) {
138  uchar *frameData = apng.pdata + ((apng.first_frame+i) * imageSize.area() * apng.bpp);
139  int frameDelay = apng.frames_delay[i];
140 
141  framesDelay.push_back(frameDelay);
142  frames.push_back(ImagePtr(new Image(imageSize, apng.bpp, frameData)));
143  }
144  AnimatedTexturePtr animatedTexture = new AnimatedTexture(imageSize, frames, framesDelay);
145  m_animatedTextures.push_back(animatedTexture);
146  texture = animatedTexture;
147  } else {
148  ImagePtr image = ImagePtr(new Image(imageSize, apng.bpp, apng.pdata));
149  texture = TexturePtr(new Texture(image));
150  }
151  free_apng(&apng);
152  }
153 
154  return texture;
155 }
eventdispatcher.h
graphics.h
TextureManager::init
void init()
Definition: texturemanager.cpp:35
free_apng
void free_apng(struct apng_data *apng)
Definition: apngloader.cpp:1149
animatedtexture.h
Image::load
static ImagePtr load(std::string file)
Definition: image.cpp:39
g_dispatcher
EventDispatcher g_dispatcher
Definition: eventdispatcher.cpp:28
Texture
Definition: texture.h:28
apngloader.h
resourcemanager.h
ResourceManager::resolvePath
std::string resolvePath(const std::string &path)
Definition: resourcemanager.cpp:311
Logger::error
void error(const std::string &what)
Definition: logger.h:54
TextureManager::getEmptyTexture
const TexturePtr & getEmptyTexture()
Definition: texturemanager.h:41
ticks_t
int64 ticks_t
Definition: types.h:43
texturemanager.h
AnimatedTexture
Definition: animatedtexture.h:29
stdext::format
std::string format()
Definition: format.h:82
stdext::time
ticks_t time()
Definition: time.cpp:33
ImagePtr
stdext::shared_object_ptr< Image > ImagePtr
Definition: declarations.h:46
apng_data::height
unsigned int height
Definition: apngloader.h:31
clock.h
apng_data::frames_delay
unsigned short * frames_delay
Definition: apngloader.h:38
ResourceManager::getFileTime
ticks_t getFileTime(const std::string &filename)
Definition: resourcemanager.cpp:366
Image
Definition: image.h:29
g_resources
ResourceManager g_resources
Definition: resourcemanager.cpp:32
EventDispatcher::cycleEvent
ScheduledEventPtr cycleEvent(const std::function< void()> &callback, int delay)
Definition: eventdispatcher.cpp:93
uint
unsigned int uint
Definition: types.h:31
apng_data::bpp
unsigned char bpp
Definition: apngloader.h:34
g_logger
Logger g_logger
Definition: logger.cpp:35
TextureManager::clearCache
void clearCache()
Definition: texturemanager.cpp:64
Texture::setTime
void setTime(ticks_t time)
Definition: texture.h:44
apng_data
Definition: apngloader.h:28
image.h
apng_data::first_frame
unsigned int first_frame
Definition: apngloader.h:32
TexturePtr
stdext::shared_object_ptr< Texture > TexturePtr
Definition: declarations.h:49
TextureManager::getTexture
TexturePtr getTexture(const std::string &fileName)
Definition: texturemanager.cpp:90
apng_data::num_frames
unsigned int num_frames
Definition: apngloader.h:36
TextureManager
Definition: texturemanager.h:29
stdext::exception::what
virtual const char * what() const
Definition: exception.h:37
uchar
unsigned char uchar
Definition: types.h:29
ResourceManager::readFileStream
void readFileStream(const std::string &fileName, std::iostream &out)
Definition: resourcemanager.cpp:173
load_apng
int load_apng(std::stringstream &file, struct apng_data *apng)
Definition: apngloader.cpp:513
stdext::shared_object_ptr
Definition: shared_object.h:39
Texture::setSmooth
virtual void setSmooth(bool smooth)
Definition: texture.cpp:127
Clock::millis
ticks_t millis()
Definition: clock.h:37
TextureManager::liveReload
void liveReload()
Definition: texturemanager.cpp:70
g_textures
TextureManager g_textures
Definition: texturemanager.cpp:33
apng_data::pdata
unsigned char * pdata
Definition: apngloader.h:29
Event::cancel
void cancel()
Definition: event.cpp:49
TextureManager::poll
void poll()
Definition: texturemanager.cpp:51
TSize< int >
g_clock
Clock g_clock
Definition: clock.cpp:25
TextureManager::terminate
void terminate()
Definition: texturemanager.cpp:40
apng_data::width
unsigned int width
Definition: apngloader.h:30
ResourceManager::guessFilePath
std::string guessFilePath(const std::string &filename, const std::string &type)
Definition: resourcemanager.cpp:352
stdext::exception
Definition: exception.h:31