xoreos  0.0.5
textureman.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include "src/common/scopedptr.h"
26 #include "src/common/util.h"
27 #include "src/common/error.h"
28 #include "src/common/uuid.h"
29 
32 
34 
35 #include "src/graphics/graphics.h"
36 
37 #include "src/events/requests.h"
38 
40 
41 namespace Graphics {
42 
43 namespace Aurora {
44 
45 static GLenum kTextureUnit[] = {
46  GL_TEXTURE0_ARB,
47  GL_TEXTURE1_ARB,
48  GL_TEXTURE2_ARB,
49  GL_TEXTURE3_ARB,
50  GL_TEXTURE4_ARB,
51  GL_TEXTURE5_ARB,
52  GL_TEXTURE6_ARB,
53  GL_TEXTURE7_ARB,
54  GL_TEXTURE8_ARB,
55  GL_TEXTURE9_ARB,
56  GL_TEXTURE10_ARB,
57  GL_TEXTURE11_ARB,
58  GL_TEXTURE12_ARB,
59  GL_TEXTURE13_ARB,
60  GL_TEXTURE14_ARB,
61  GL_TEXTURE15_ARB,
62  GL_TEXTURE16_ARB,
63  GL_TEXTURE17_ARB,
64  GL_TEXTURE18_ARB,
65  GL_TEXTURE19_ARB,
66  GL_TEXTURE20_ARB,
67  GL_TEXTURE21_ARB,
68  GL_TEXTURE22_ARB,
69  GL_TEXTURE23_ARB,
70  GL_TEXTURE24_ARB,
71  GL_TEXTURE25_ARB,
72  GL_TEXTURE26_ARB,
73  GL_TEXTURE27_ARB,
74  GL_TEXTURE28_ARB,
75  GL_TEXTURE29_ARB,
76  GL_TEXTURE30_ARB,
77  GL_TEXTURE31_ARB
78 };
79 
80 static const size_t kTextureUnitCount = ARRAYSIZE(kTextureUnit);
81 
82 
83 TextureManager::TextureManager() : _deswizzleSBM(false), _recordNewTextures(false) {
84 }
85 
87  clear();
88 }
89 
92 
93  _bogusTextures.clear();
94 
95  for (TextureMap::iterator t = _textures.begin(); t != _textures.end(); ++t)
96  delete t->second;
97  _textures.clear();
98 
99  _deswizzleSBM = false;
100 
101  _recordNewTextures = false;
102  _newTextureNames.clear();
103 }
104 
107 
108  _bogusTextures.insert(name);
109 }
110 
111 void TextureManager::setDeswizzleSBM(bool deswizzle) {
112  _deswizzleSBM = deswizzle;
113 }
114 
117 
118  if (_bogusTextures.find(name) != _bogusTextures.end())
119  return true;
120  if (_textures.find(name) != _textures.end())
121  return true;
122 
123  return false;
124 }
125 
128 
129  if (_bogusTextures.find(name) != _bogusTextures.end()) {
130  delete texture;
131  return TextureHandle();
132  }
133 
134  if (name.empty())
136 
137  Common::ScopedPtr<ManagedTexture> managedTexture(new ManagedTexture(texture));
138 
139  std::pair<TextureMap::iterator, bool> result = _textures.insert(std::make_pair(name, managedTexture.get()));
140  if (!result.second)
141  throw Common::Exception("Texture \"%s\" already exists", name.c_str());
142 
143  managedTexture.release();
144  TextureMap::iterator textureIterator = result.first;
145 
146  if (_recordNewTextures)
147  _newTextureNames.push_back(name);
148 
149  return TextureHandle(textureIterator);
150 }
151 
154 
155  if (_bogusTextures.find(name) != _bogusTextures.end())
156  return TextureHandle();
157 
158  TextureMap::iterator texture = _textures.find(name);
159  if (texture == _textures.end()) {
160  std::pair<TextureMap::iterator, bool> result;
161 
162  ManagedTexture *managedTexture = new ManagedTexture(Texture::create(name, _deswizzleSBM));
163 
164  if (managedTexture->texture->isDynamic())
165  name = name + "#" + Common::generateIDRandomString();
166 
167  result = _textures.insert(std::make_pair(name, managedTexture));
168 
169  texture = result.first;
170  }
171 
172  if (_recordNewTextures)
173  _newTextureNames.push_back(name);
174 
175  return TextureHandle(texture);
176 }
177 
180 
181  if (_bogusTextures.find(name) != _bogusTextures.end())
182  return TextureHandle();
183 
184  TextureMap::iterator texture = _textures.find(name);
185  if (texture != _textures.end())
186  return TextureHandle(texture);
187 
188  return TextureHandle();
189 }
190 
193 
194  _newTextureNames.clear();
195  _recordNewTextures = true;
196 }
197 
198 void TextureManager::stopRecordNewTextures(std::list<Common::UString> &newTextures) {
200 
201  _newTextureNames.swap(newTextures);
202 
203  _newTextureNames.clear();
204  _recordNewTextures = false;
205 }
206 
209 
210  texture._empty = from._empty;
211  texture._it = from._it;
212 
213  if (!texture._empty)
214  texture._it->second->referenceCount++;
215 }
216 
219 
220  if (!texture._empty && (texture._it != _textures.end())) {
221  if (--texture._it->second->referenceCount == 0) {
222  delete texture._it->second;
223  _textures.erase(texture._it);
224  }
225  }
226 
227  texture._empty = true;
228  texture._it = _textures.end();
229 }
230 
233 
234  GfxMan.lockFrame();
235 
236  for (TextureMap::iterator texture = _textures.begin(); texture != _textures.end(); ++texture) {
237  try {
238  texture->second->texture->reload();
239  } catch (...) {
240  Common::exceptionDispatcherWarning("Failed reloading texture \"%s\"", texture->first.c_str());
241  }
242  }
243 
244  RequestMan.sync();
245  GfxMan.unlockFrame();
246 }
247 
249  for (size_t i = 0; i < kTextureUnitCount; i++) {
250  activeTexture(i);
251 
252  glDisable(GL_TEXTURE_2D);
253  glDisable(GL_TEXTURE_CUBE_MAP);
254 
255  glDisable(GL_TEXTURE_GEN_S);
256  glDisable(GL_TEXTURE_GEN_T);
257  glDisable(GL_TEXTURE_GEN_R);
258  }
259 
260  activeTexture(0);
261  glEnable(GL_TEXTURE_2D);
262  glBindTexture(GL_TEXTURE_2D, 0);
263 }
264 
266  glBindTexture(GL_TEXTURE_2D, 0);
267 
268  glEnable(GL_TEXTURE_2D);
269  glDisable(GL_TEXTURE_CUBE_MAP);
270 
271  glDisable(GL_TEXTURE_GEN_S);
272  glDisable(GL_TEXTURE_GEN_T);
273  glDisable(GL_TEXTURE_GEN_R);
274 }
275 
276 void TextureManager::set(const TextureHandle &handle, TextureMode mode) {
277  if (handle.empty()) {
278  set();
279  return;
280  }
281 
282  TextureID id = handle._it->second->texture->getID();
283  if (id == 0)
284  warning("Empty texture ID for texture \"%s\"", handle._it->first.c_str());
285 
286  if (handle._it->second->texture->getImage().isCubeMap()) {
287  glBindTexture(GL_TEXTURE_CUBE_MAP, id);
288 
289  glDisable(GL_TEXTURE_2D);
290  glEnable(GL_TEXTURE_CUBE_MAP);
291  } else {
292  glBindTexture(GL_TEXTURE_2D, id);
293 
294  glDisable(GL_TEXTURE_CUBE_MAP);
295  glEnable(GL_TEXTURE_2D);
296  }
297 
298  switch (mode) {
300  if (handle._it->second->texture->getImage().isCubeMap()) {
301  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
302  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
303  glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
304 
305  glEnable(GL_TEXTURE_GEN_S);
306  glEnable(GL_TEXTURE_GEN_T);
307  glEnable(GL_TEXTURE_GEN_R);
308  } else {
309  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
310  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
311 
312  glEnable(GL_TEXTURE_GEN_S);
313  glEnable(GL_TEXTURE_GEN_T);
314  }
315 
316  break;
317 
318  case kModeDiffuse:
319  default:
320  glDisable(GL_TEXTURE_GEN_S);
321  glDisable(GL_TEXTURE_GEN_T);
322  glDisable(GL_TEXTURE_GEN_R);
323  break;
324  }
325 }
326 
328  if ((n >= GfxMan.getMultipleTextureCount()) || (n >= ARRAYSIZE(kTextureUnit)))
329  return;
330 
331  glActiveTextureARB(kTextureUnit[n]);
332 }
333 
334 } // End of namespace Aurora
335 
336 } // End of namespace Graphics
TextureHandle getIfExist(const Common::UString &name)
Retrieve this named texture, returning an empty handle if it&#39;s not managed.
Definition: textureman.cpp:178
void assign(TextureHandle &texture, const TextureHandle &from)
Definition: textureman.cpp:207
Generic image decoder interface.
Inter-thread request events.
The global graphics manager.
bool hasTexture(const Common::UString &name)
Does this named managed texture exist?
Definition: textureman.cpp:115
A class holding an UTF-8 string.
Definition: ustring.h:48
PointerType release()
Returns the plain pointer value and releases ScopedPtr.
Definition: scopedptr.h:103
static GLenum kTextureUnit[]
Definition: textureman.cpp:45
The global Aurora texture manager.
Definition: textureman.h:43
void release(TextureHandle &texture)
Definition: textureman.cpp:217
static Texture * create(const Common::UString &name, bool deswizzle=false)
Create a texture from this image resource.
Definition: texture.cpp:323
The Aurora texture manager.
Utility functions for generating unique IDs.
#define ARRAYSIZE(x)
Macro which determines the number of entries in a fixed size array.
Definition: util.h:131
void startRecordNewTextures()
Start recording all names of newly created textures.
Definition: textureman.cpp:191
GLuint TextureID
Definition: types.h:45
A simple scoped smart pointer template.
void exceptionDispatcherWarning(const char *s,...)
Exception dispatcher that prints the exception as a warning, and adds another reason on top...
Definition: error.cpp:158
void clear()
Remove and delete all managed textures.
Definition: textureman.cpp:90
Basic exceptions to throw.
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
std::set< Common::UString > _bogusTextures
Definition: textureman.h:109
Utility templates and functions.
void setDeswizzleSBM(bool deswizzle)
Do we need to deswizzle SBM images?
Definition: textureman.cpp:111
TextureHandle get(Common::UString name)
Retrieve this named texture, loading it if it&#39;s not yet managed.
Definition: textureman.cpp:152
static const size_t kTextureUnitCount
Definition: textureman.cpp:80
#define DECLARE_SINGLETON(T)
Note that you need to use this macro from the global namespace.
Definition: singleton.h:122
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
A managed texture, storing how often it&#39;s referenced.
Definition: texturehandle.h:40
StackException Exception
Definition: error.h:59
void reset()
Completely reset the texture rendering.
Definition: textureman.cpp:248
A scoped plain pointer, allowing pointer-y access and normal deletion.
Definition: scopedptr.h:120
void warning(const char *s,...)
Definition: util.cpp:33
TextureMode
The mode/usage of a specific texture.
Definition: textureman.h:46
TextureHandle add(Texture *texture, Common::UString name="")
Add this texture to the TextureManager.
Definition: textureman.cpp:126
Convenience class that locks a mutex on creation and unlocks it on destruction.
Definition: mutex.h:71
virtual bool isDynamic() const
Is this a dynamic texture, or a shared static one?
Definition: texture.cpp:91
PointerType get() const
Returns the plain pointer value.
Definition: scopedptr.h:96
A texture as used in the Aurora engines.
void addBogusTexture(const Common::UString &name)
Add the name of a texture that doesn&#39;t really exist.
Definition: textureman.cpp:105
std::list< Common::UString > _newTextureNames
Definition: textureman.h:114
void set()
Reset the current texture unit to an empty texture.
Definition: textureman.cpp:265
#define RequestMan
Shortcut for accessing the request manager.
Definition: requests.h:127
void activeTexture(size_t n)
Set this texture unit as the current one.
Definition: textureman.cpp:327
UString generateIDRandomString()
Definition: uuid.cpp:37
TextureMap::iterator _it
Definition: texturehandle.h:68
void stopRecordNewTextures(std::list< Common::UString > &newTextures)
Stop the recording of texture names, and return a list of previously recorded names.
Definition: textureman.cpp:198
A handle to a texture.
Definition: texturehandle.h:51
#define GfxMan
Shortcut for accessing the graphics manager.
Definition: graphics.h:299
void reloadAll()
Reload and rebuild all managed textures, if possible.
Definition: textureman.cpp:231