Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TextureManager.h
Go to the documentation of this file.
1 /* Copyright (C) 2013 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_TEXTUREMANAGER
19 #define INCLUDED_TEXTUREMANAGER
20 
21 #include "Texture.h"
22 
23 #include "lib/ogl.h"
24 #include "lib/file/vfs/vfs.h"
25 #include "lib/res/handle.h"
26 
27 #include <boost/weak_ptr.hpp>
28 
29 class CTextureProperties;
31 
32 /**
33  * Texture manager with asynchronous loading and automatic DDS conversion/compression.
34  *
35  * Input textures can be any format. They will be converted to DDS using settings defined
36  * in files named "texture.xml", in the same directory as the texture and in its parent
37  * directories. See CTextureConverter for the XML syntax. The DDS file will be cached
38  * for faster loading in the future.
39  *
40  * Typically the graphics code will initialise many textures at the start of the game,
41  * mostly for off-screen objects, by calling CreateTexture().
42  * Loading texture data may be very slow (especially if it needs to be converted
43  * to DDS), and we don't want the game to become unresponsive.
44  * CreateTexture therefore returns an object immediately, without loading the
45  * texture. If the object is never used then the data will never be loaded.
46  *
47  * Typically, the renderer will call CTexture::Bind() when it wants to use the
48  * texture. This will trigger the loading of the texture data. If it can be loaded
49  * quickly (i.e. there is already a cached DDS version), then it will be loaded before
50  * the function returns, and the texture can be rendered as normal.
51  *
52  * If loading will take a long time, then Bind() binds a default placeholder texture
53  * and starts loading the texture in the background. It will use the correct texture
54  * when the renderer next calls Bind() after the load has finished.
55  *
56  * It is also possible to prefetch textures which are not being rendered yet, but
57  * are expected to be rendered soon (e.g. for off-screen terrain tiles).
58  * These will be loaded in the background, when there are no higher-priority textures
59  * to load.
60  *
61  * The same texture file can be safely loaded multiple times with different GL parameters
62  * (but this should be avoided whenever possible, as it wastes VRAM).
63  *
64  * For release packages, DDS files can be precached by appending ".dds" to their name,
65  * which will be used instead of doing runtime conversion. This means most players should
66  * never experience the slow asynchronous conversion behaviour.
67  * These cache files will typically be packed into an archive for faster loading;
68  * if no archive cache is available then the source file will be converted and stored
69  * as a loose cache file on the user's disk.
70  */
72 {
74 
75 public:
76  /**
77  * Construct texture manager. vfs must be the VFS instance used for all textures
78  * loaded from this object.
79  * highQuality is slower and intended for batch-conversion modes.
80  * disableGL is intended for tests, and will disable all GL uploads.
81  */
82  CTextureManager(PIVFS vfs, bool highQuality, bool disableGL);
83 
85 
86  /**
87  * Create a texture with the given GL properties.
88  * The texture data will not be loaded immediately.
89  */
91 
92  /**
93  * Returns a magenta texture. Use this for highlighting errors
94  * (e.g. missing terrain textures).
95  */
97 
98  /**
99  * Work on asynchronous texture loading operations, if any.
100  * Returns true if it did any work.
101  * The caller should typically loop this per frame until it returns
102  * false or exceeds the allocated time for this frame.
103  */
104  bool MakeProgress();
105 
106  /**
107  * Synchronously converts and compresses and saves the texture,
108  * and returns the output path (minus a "cache/" prefix). This
109  * is intended for pre-caching textures in release archives.
110  * @return true on success
111  */
112  bool GenerateCachedTexture(const VfsPath& path, VfsPath& outputPath);
113 
114 private:
116 };
117 
118 /**
119  * Represents the filename and GL parameters of a texture,
120  * for passing to CTextureManager::CreateTexture.
121  */
123 {
124  friend class CTextureManagerImpl;
125  friend struct TextureCacheCmp;
126  friend struct TPequal_to;
127  friend struct TPhash;
128 
129 public:
130  /**
131  * Use the given texture name, and default GL parameters.
132  */
133  explicit CTextureProperties(const VfsPath& path) :
134  m_Path(path), m_Filter(GL_LINEAR_MIPMAP_LINEAR),
135  m_WrapS(GL_REPEAT), m_WrapT(GL_REPEAT), m_Aniso(1.0f)
136  {
137  }
138 
139  /**
140  * Set min/mag filter mode (typically GL_LINEAR_MIPMAP_LINEAR, GL_NEAREST, etc).
141  */
142  void SetFilter(GLint filter) { m_Filter = filter; }
143 
144  /**
145  * Set wrapping mode (typically GL_REPEAT, GL_CLAMP_TO_EDGE, etc).
146  */
147  void SetWrap(GLint wrap) { m_WrapS = wrap; m_WrapT = wrap; }
148 
149  /**
150  * Set wrapping mode (typically GL_REPEAT, GL_CLAMP_TO_EDGE, etc),
151  * separately for S and T.
152  */
153  void SetWrap(GLint wrap_s, GLint wrap_t) { m_WrapS = wrap_s; m_WrapT = wrap_t; }
154 
155  /**
156  * Set maximum anisotropy value. Must be >= 1.0. Should be a power of 2.
157  */
158  void SetMaxAnisotropy(float aniso) { m_Aniso = aniso; }
159 
160  // TODO: rather than this static definition of texture properties
161  // (especially anisotropy), maybe we want something that can be more
162  // easily tweaked in an Options menu? e.g. the caller just specifies
163  // "terrain texture mode" and we combine it with the user's options.
164  // That'd let us dynamically change texture properties easily.
165  //
166  // enum EQualityMode
167  // {
168  // NONE,
169  // TERRAIN,
170  // MODEL,
171  // GUI
172  // }
173  // void SetQuality(EQualityMode mode, float anisotropy, float lodbias, int reducemipmaps, ...);
174  //
175  // or something a bit like that.
176 
177 private:
179  GLint m_Filter;
180  GLint m_WrapS;
181  GLint m_WrapT;
182  float m_Aniso;
183 };
184 
185 /**
186  * Represents a texture object.
187  * The texture data may or may not have been loaded yet.
188  * Before it has been loaded, all operations will act on a default
189  * 1x1-pixel grey texture instead.
190  */
191 class CTexture
192 {
193  friend class CTextureManagerImpl;
194  friend struct TextureCacheCmp;
195  friend struct TPequal_to;
196  friend struct TPhash;
197 
198  // Only the texture manager can create these
199  explicit CTexture(Handle handle, const CTextureProperties& props, CTextureManagerImpl* textureManager);
200 
202 
203 public:
204 
205  ~CTexture();
206 
207  /**
208  * Returns the width (in pixels) of the current texture.
209  */
210  size_t GetWidth() const;
211 
212  /**
213  * Returns the height (in pixels) of the current texture.
214  */
215  size_t GetHeight() const;
216 
217  /**
218  * Returns whether the current texture has an alpha channel.
219  */
220  bool HasAlpha() const;
221 
222  /**
223  * Returns the ARGB value of the lowest mipmap level (i.e. the
224  * average of the whole texture).
225  * Returns 0 if the texture has no mipmaps.
226  */
227  u32 GetBaseColour() const;
228 
229  /**
230  * Bind the texture to the given GL texture unit.
231  * If the texture data hasn't been loaded yet, this may wait a short while to
232  * load it. If loading takes too long then it will return sooner and the data will
233  * be loaded in a background thread, so this does not guarantee the texture really
234  * will be loaded.
235  */
236  void Bind(size_t unit = 0);
237 
238  /**
239  * Returns a ogl_tex handle, for later binding. See comments from Bind().
240  */
241  Handle GetHandle();
242 
243  /**
244  * Attempt to load the texture data quickly, as with Bind().
245  * Returns whether the texture data is currently loaded.
246  */
247  bool TryLoad();
248 
249  /**
250  * Returns whether the texture data is currently loaded.
251  */
252  bool IsLoaded();
253 
254  /**
255  * Activate the prefetching optimisation for this texture.
256  * Use this if it is likely the texture will be needed in the near future.
257  * It will be loaded in the background so that it is likely to be ready when
258  * it is used by Bind().
259  */
260  void Prefetch();
261 
262 private:
263  /**
264  * Replace the Handle stored by this object.
265  * If takeOwnership is true, it will not increment the Handle's reference count.
266  */
267  void SetHandle(Handle handle, bool takeOwnership = false);
268 
270 
273 
274  enum {
275  UNLOADED, // loading has not started
276  PREFETCH_NEEDS_LOADING, // was prefetched; currently waiting to try loading from cache
277  PREFETCH_NEEDS_CONVERTING, // was prefetched; currently waiting to be sent to the texture converter
278  PREFETCH_IS_CONVERTING, // was prefetched; currently being processed by the texture converter
279  HIGH_NEEDS_CONVERTING, // high-priority; currently waiting to be sent to the texture converter
280  HIGH_IS_CONVERTING, // high-priority; currently being processed by the texture converter
281  LOADED // loading has completed (successfully or not)
282  } m_State;
283 
285 
286  // Self-reference to let us recover the CTexturePtr for this object.
287  // (weak pointer to avoid cycles)
288  boost::weak_ptr<CTexture> m_Self;
289 };
290 
291 #endif // INCLUDED_TEXTUREMANAGER
friend struct TextureCacheCmp
u32 m_BaseColour
bool GenerateCachedTexture(const VfsPath &path, VfsPath &outputPath)
Synchronously converts and compresses and saves the texture, and returns the output path (minus a &quot;ca...
CTexturePtr CreateTexture(const CTextureProperties &props)
Create a texture with the given GL properties.
void Prefetch()
Activate the prefetching optimisation for this texture.
Handle m_Handle
CTexture(Handle handle, const CTextureProperties &props, CTextureManagerImpl *textureManager)
shared_ptr< IVFS > PIVFS
Definition: vfs.h:226
Represents the filename and GL parameters of a texture, for passing to CTextureManager::CreateTexture...
const CTextureProperties m_Properties
NONCOPYABLE(CTextureManager)
bool IsLoaded()
Returns whether the texture data is currently loaded.
CTextureManagerImpl * m_TextureManager
boost::weak_ptr< CTexture > m_Self
size_t GetWidth() const
Returns the width (in pixels) of the current texture.
Texture manager with asynchronous loading and automatic DDS conversion/compression.
void SetWrap(GLint wrap_s, GLint wrap_t)
Set wrapping mode (typically GL_REPEAT, GL_CLAMP_TO_EDGE, etc), separately for S and T...
bool MakeProgress()
Work on asynchronous texture loading operations, if any.
CTextureManager(PIVFS vfs, bool highQuality, bool disableGL)
Construct texture manager.
u32 GetBaseColour() const
Returns the ARGB value of the lowest mipmap level (i.e.
void SetFilter(GLint filter)
Set min/mag filter mode (typically GL_LINEAR_MIPMAP_LINEAR, GL_NEAREST, etc).
Definition: path.h:75
bool HasAlpha() const
Returns whether the current texture has an alpha channel.
NONCOPYABLE(CTexture)
Represents a texture object.
size_t GetHeight() const
Returns the height (in pixels) of the current texture.
CTextureProperties(const VfsPath &path)
Use the given texture name, and default GL parameters.
Handle GetHandle()
Returns a ogl_tex handle, for later binding.
CTextureManagerImpl * m
i64 Handle
`handle&#39; representing a reference to a resource (sound, texture, etc.)
Definition: handle.h:41
void SetMaxAnisotropy(float aniso)
Set maximum anisotropy value.
CTexturePtr GetErrorTexture()
Returns a magenta texture.
#define u32
Definition: types.h:41
void SetHandle(Handle handle, bool takeOwnership=false)
Replace the Handle stored by this object.
bool TryLoad()
Attempt to load the texture data quickly, as with Bind().
enum CTexture::@17 m_State
void Bind(size_t unit=0)
Bind the texture to the given GL texture unit.
static Handle handle(size_t idx, u64 tag)
Definition: h_mgr.cpp:121
void SetWrap(GLint wrap)
Set wrapping mode (typically GL_REPEAT, GL_CLAMP_TO_EDGE, etc).
friend struct TextureCacheCmp
shared_ptr< CTexture > CTexturePtr
Definition: Texture.h:22