1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2010 by The Allacrost Project
3 //                         All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software
6 // and you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ///////////////////////////////////////////////////////////////////////////////
9 
10 /** ****************************************************************************
11 *** \file    image.h
12 *** \author  Tyler Olsen, roots@allacrost.org
13 *** \brief   Source file for image classes
14 ***
15 *** This file contains several classes that represent images loaded into the
16 *** engine. The public classes used outside of the video engine are:
17 ***
18 *** - <b>ImageDescriptor</b> is an abstract base class for other images. This
19 *** type is used to allow containers to create multiple derived image classes.
20 *** It also contains a number of static functions for general image operation
21 *** code.
22 ***
23 *** - <b>StillImage</b> is a single non-animated image and is what the user
24 *** will utilize most of the time.
25 ***
26 *** - <b>AnimatedImage</b> is an animated image that contains multiple frames,
27 *** where a frame is a StillImage object along with timing information.
28 ***
29 *** - <b>AnimationFrame</b> is a single frame of animation. It consists of a
30 *** StillImage, and how long the frame should be displayed in the animation.
31 *** This class is contained in the private_video namespace and is not a part
32 *** of the image manipulation API.
33 ***
34 *** - <b>CompositeImage</b> is an image formed by piecing together multiple
35 *** StillImage objects. The image elements in a composite image may or may
36 *** not overlap one another
37 ***
38 *** \note A <b>multi image</b> is nothing more than a single image file which
39 *** contains multiple adjacent sub-images within it. For example, a tileset file
40 *** contains numerous tile images. All sub-images are required to have the same
41 *** dimensions in a multi image file. Multi images are never explicitly contained
42 *** in any way by the video engine -- rather, these multi images are loaded into
43 *** memory and then the sub-images are split up into separate StillImage objects.
44 *** ***************************************************************************/
45 
46 #ifndef __IMAGE_HEADER__
47 #define __IMAGE_HEADER__
48 
49 #include "defs.h"
50 #include "utils.h"
51 
52 #include "image_base.h"
53 #include "color.h"
54 #include "texture.h"
55 
56 namespace hoa_video {
57 
58 /** ****************************************************************************
59 *** \brief An abstract base class for all public API image classes
60 ***
61 *** This class also contains several static functions for performing image
62 *** operations which do not operate on a single instance of a derived
63 *** ImageDescriptor object. For example, functions which load a single image
64 *** file into multiple StillImage objects.
65 ***
66 *** \note A <b>multi image</b> is defined as a single image file which contains
67 *** several images in a grid format that we wish to extract as seperate image
68 *** entities. This is used, for example, to hold multiple tile images in a large
69 *** tileset file, or multiple animation frames stored in a single image file.
70 *** All individual image elements in a multi image are required to be the same
71 *** size.
72 ***
73 *** \note The copy constructor and copy assignement operator ensure that the
74 *** reference to the texture being used is updated appropriately. The
75 *** derived classes should not require the implementation of a copy constructor
76 *** or assignment operator, at least not for the purposes of proper reference
77 *** counting.
78 ***
79 *** \note If the destructor finds that the image texture has no more references
80 *** after it decrements the reference counter, it will mark it as free on the
81 *** image texture's texture sheet. However it will <b>not</b> attempt to remove
82 *** it from any container in the TextureManager class, so that is up to the
83 *** destructors of the derived classes to implement.
84 *** ***************************************************************************/
85 class ImageDescriptor {
86 	friend class VideoEngine;
87 
88 public:
89 	ImageDescriptor();
90 
91 	virtual ~ImageDescriptor();
92 
93 	ImageDescriptor(const ImageDescriptor& copy);
94 
95 	ImageDescriptor& operator=(const ImageDescriptor& copy);
96 
97 	//! \brief Clears all data retained by the object (color, width, height, etc.)
98 	virtual void Clear() = 0;
99 
100 	/** \brief Draws the image to the display buffer
101 	*** The location and orientation of the drawn image is dependent upon the current cursor position
102 	*** and context (draw flags) set in the VideoEngine class.
103 	**/
104 	virtual void Draw() const = 0;
105 
106 	/** \brief Draws a color modulated version of the image to the display buffer
107 	*** \param draw_color The color to modulate the image by
108 	**/
109 	virtual void Draw(const Color& draw_color) const = 0;
110 
111 	//! \name Class Member Access Functions
112 	//@{
113 	//! \brief Returns the image width
GetWidth()114 	virtual float GetWidth() const
115 		{ return _width; }
116 
117 	//! \brief Returns image height
GetHeight()118 	virtual float GetHeight() const
119 		{ return _height; }
120 
121 	//! \brief Returns true if the image is grayscale.
IsGrayScale()122 	bool IsGrayScale() const
123 		{ return _grayscale; }
124 
125 	virtual void EnableGrayScale() = 0;
126 
127 	virtual void DisableGrayScale() = 0;
128 
129 	/** \brief Enables or disables the image's static property
130 	*** \param is_static If true, the image will be made static
131 	**/
132 	virtual void SetStatic(bool is_static) = 0;
133 
134 	/** \brief Sets the image's width, expressed as coordinate system units
135 	*** \param width The desired width of the image
136 	**/
137 	virtual void SetWidth(float width) = 0;
138 
139 	/** \brief Sets the image's height, expressed as coordinate system units
140 	*** \param height The desired height of the image
141 	**/
142 	virtual void SetHeight(float height) = 0;
143 
144 	/** \brief Sets the image's dimensions, expressed as coordinate system units
145 	*** \param width The desired width of the image
146 	*** \param height The desired height of the image
147 	**/
148 	virtual void SetDimensions(float width, float height) = 0;
149 
150 	/** \brief Sets the UV coordinates for the image
151 	*** \param u1 First u coordinate
152 	*** \param v1 First v coordinate
153 	*** \param u2 Second u coordinate
154 	*** \param v2 Second v coordinate
155 	***
156 	*** This method rarely needs to be called, as the default UV coordinates suffice
157 	*** for nearly all images.
158 	**/
SetUVCoordinates(float u1,float v1,float u2,float v2)159 	virtual void SetUVCoordinates(float u1, float v1, float u2, float v2)
160 		{ _u1 = u1; _v1 = v1; _u2 = u2; _v2 = v2; }
161 
162 	/** \brief Sets the image's four vertices to a single color
163 	*** \param color The desired color of all image vertices
164 	**/
165 	virtual void SetColor(const Color& color);
166 
167 	/** \brief Sets the image's vertex colors
168 	*** \param tl The top left vertex color
169 	*** \param tr The top right vertex color
170 	*** \param bl The bottom left vertex color
171 	*** \param br The bottom right vertex color
172 	**/
173 	virtual void SetVertexColors(const Color& tl, const Color& tr, const Color& bl, const Color& br);
174 	//@}
175 
176 	/** \name Static Image Manipulation Functions
177 	*** This series of static functions provide additional image mainpulation that does not operate
178 	*** on a single instance of a derived image type.
179 	**/
180 	//@{
181 	/** \brief Retrieves various properties about an image file
182 	*** \param filename The name of the image file (.png or .jpg) to retrieve the properties of
183 	*** \param rows The number of rows of pixels in the image
184 	*** \param cols The number of columns of pixels in the image
185 	*** \param bpp The number of bits per pixel of the image
186 	*** \throw Exception If any of the properties are not retrieved successfully
187 	**/
188 	static void GetImageInfo(const std::string& filename, uint32& rows, uint32& cols, uint32& bpp) throw(hoa_utils::Exception);
189 
190 	/** \brief Loads a multi image into a vector of StillImage objects
191 	*** \param images Reference to the vector of StillImages to be loaded with elements from the multi image
192 	*** \param filename The name of the multi image file to load the image data from
193 	*** \param elem_width The width of each sub-image element, in pixels
194 	*** \param elem_height The  height of each sub-image element, in pixels
195 	*** \return True upon successful loading, false if there was an error
196 	***
197 	*** This function determines the image elements to extract from the multi image by the width and height
198 	*** of each element (in pixels) specified in the function arguments. Upon success, the size of the images
199 	*** reference vector will always be equal to the area of the multi image divided by the area of each
200 	*** element image.
201 	*** \note All image elements within the multi image should be of the same size
202 	 */
203 	static bool LoadMultiImageFromElementSize(std::vector<StillImage>& images, const std::string& filename,
204 		const uint32 elem_width, const uint32 elem_height);
205 
206 	/** \brief Loads a multi image into a vector of StillImage objects
207 	*** \param images Reference to the vector of StillImages to be loaded with elements from the multi image
208 	*** \param filename The name of the multi image file to load the image data from
209 	*** \param grid_rows The number of rows of image elements contained in the multi image
210 	*** \param grid_cols The number of columns of image elements contained in the multi image
211 	*** \return True upon successful loading, false if there was an error
212 	***
213 	*** This function determines the image elements to extract from dividing the multi image into a number
214 	*** of rows and columns, as given through the function's arguments. Upon success, the size of the images
215 	*** reference vector will always be equal to grid_rows * grid_cols.
216 	*** \note All image elements within the multi image should be of the same size
217 	**/
218 	static bool LoadMultiImageFromElementGrid(std::vector<StillImage>& images, const std::string& filename,
219 		const uint32 grid_rows, const uint32 grid_cols);
220 
221 	/** \brief Saves a vector of images into a single image file (a multi image)
222 	*** \param images A reference to the vector of StillImage pointers to save into a multi image
223 	*** \param filename The name of the multi image file to write (.png of .jpg extension required)
224 	*** \param grid_rows The number of rows of sub-images in the MultiImage.
225 	*** \param grid_cols Number of columns of sub-images in the MultiImage.
226 	*** \return True upon successful loading, false if there was an error
227 	*** \note All images within the images vector should be of the same size
228 	**/
229 	static bool SaveMultiImage(const std::vector<StillImage*>& images, const std::string& filename,
230 		const uint32 grid_rows, const uint32 grid_cols);
231 	//@}
232 
233 	//! \brief A debug function which prints the image's information to the screen
234 	void DEBUG_PrintInfo();
235 
236 protected:
237 	/** \brief A pointer to the texture used by the image
238 	*** The purpose of this member is for the ImageDescriptor class to be able to manage
239 	**/
240 	private_video::BaseTexture* _texture;
241 
242 	//! \brief The width and height of the image, in coordinate system units.
243 	float _width, _height;
244 
245 	/** \brief The texture coordinates for the image
246 	*** (u1, v1) represents the upper-left corner while (u2, v2) represents the bottom-right corner. These coordinates
247 	*** are typically (0.0f, 0.0f), (1.0f, 1.0f) and do not need to be modified except in special cases.
248 	**/
249 	float _u1, _v1, _u2, _v2;
250 
251     //! \brief Holds the color of the upper left, upper right, lower left, and lower right vertices, respectively.
252 	Color _color[4];
253 
254 	//! \brief True indicates to perform blending with this image
255 	bool _blend;
256 
257 	//! \brief Set to true if all vertices are the same color
258 	bool _unichrome_vertices;
259 
260 	//! \brief Indicates whether the image being loaded should be loaded into a non-volatile area of texture memory.
261 	bool  _is_static;
262 
263 	//! \brief True if this image is grayscale.
264 	bool _grayscale;
265 
266 	/** \brief Removes a reference to _texture, and frees or deletes it if it has no remaining references
267 	***
268 	*** This method will set _texture to NULL before returning. If your derived class has a duplicate texture
269 	*** pointer (ie, ImageTexture pointer for StillImage class), you should make sure to set that member to
270 	*** NULL as well.
271 	**/
272 	void _RemoveTextureReference();
273 
274 	/** \brief A draw helper function which adjusts the draw orientation (translation and scaling)
275 	***
276 	*** \note This method modifies the draw cursor position and does not restore it before finishing. Therefore
277 	*** under most circumstances, you will want to call VideoManager->PushState()/PopState(), or
278 	*** glPushMatrix()/glPopMatrix() before and after calling this function. The latter is preferred due to the
279 	*** lower cost of the call, but some circumstances may require using the former when more state information
280 	*** needs to be retained.
281 	**/
282 	void _DrawOrientation() const;
283 
284 	/** \brief Draws the OpenGL texture referred to by the object on the screen
285 	*** \param draw_color A non-NULL pointer to an array of four valid Color objects
286 	***
287 	*** This method is typically a helper method to other draw calls in some way. It assumes that
288 	*** all of the appropriate transformation, scaling, and other image property opertaions have been
289 	*** completed prior to the calling of this function. The draw_color argument is usually nothing
290 	*** more than a pointer to the _color member of this very class, but in certain cases like during
291 	*** a screen fade these colors may differ.
292 	**/
293 	void _DrawTexture(const Color* draw_color) const;
294 
295 private:
296 	/** \brief Retrieves various properties about a PNG image file
297 	*** \param filename The name of the PNG image file to retrieve the properties of
298 	*** \param rows The number of rows of pixels in the image
299 	*** \param cols The number of columns of pixels in the image
300 	*** \param bpp The number of bits per pixel of the image
301 	*** \throw Exception If any of the properties are not retrieved successfully
302 	**/
303 	static void _GetPngImageInfo(const std::string& filename, uint32& rows, uint32& cols, uint32& bpp) throw(hoa_utils::Exception);
304 
305 	/** \brief Retrieves various properties about a JPG image file
306 	*** \param filename The name of the JPG image file to retrieve the properties of
307 	*** \param rows The number of rows of pixels in the image
308 	*** \param cols The number of columns of pixels in the image
309 	*** \param bpp The number of bits per pixel of the image
310 	*** \throw Exception If any of the properties are not retrieved successfully
311 	**/
312 	static void _GetJpgImageInfo(const std::string& filename, uint32& rows, uint32& cols, uint32& bpp) throw(hoa_utils::Exception);
313 
314 	/** \brief A helper function to the public LoadMultiImage* calls
315 	*** \param images Reference to the vector of StillImages to be loaded
316 	*** \param filename The name of the multi image file to read
317 	*** \param grid_rows The number of rows of image elements in the multi image
318 	*** \param grid_cols The number of columns of image elements in the multi image
319 	*** \return True if the image file was loaded and parsed successfully, false if there was an error.
320 	**/
321 	static bool _LoadMultiImage(std::vector<StillImage>& images, const std::string& filename,
322 		const uint32 grid_rows, const uint32 grid_cols);
323 }; // class ImageDescriptor
324 
325 
326 /** ****************************************************************************
327 *** \brief Represents a simple still image
328 ***
329 *** This is the most frequently used image construct of the video engine. Objects
330 *** of this class are used in the construction of some of the more advanced image
331 *** classes.
332 *** ***************************************************************************/
333 class StillImage : public ImageDescriptor {
334 	friend class VideoEngine;
335 	friend class ImageDescriptor;
336 	friend class AnimatedImage;
337 	friend class CompositeImage;
338 	friend class TextureController;
339 	friend class private_video::ParticleSystem;
340 
341 public:
342 	//! \brief Supply the constructor with "true" if you want this to represent a grayscale image
343 	StillImage(const bool grayscale = false);
344 
345 	~StillImage();
346 
347 	//! \brief Resets the image's properties and removes any references to image data that it maintains
348 	void Clear();
349 
350 	/** \brief Loads a single image file to be represented by the class object
351 	*** \param filename The filename of the image to load (should have a .png or .jpg extension)
352 	*** \return True if the image was successfully loaded and is now represented by this object
353 	***
354 	*** \note Invoking this function will clear all image elements currently used by this class.
355 	*** \note Passing in an emptry string for filename is a special case, and will construct
356 	*** a colored quad for the image procedurally. It is not an error to pass an empty string to
357 	*** the function.
358 	**/
359 	bool Load(const std::string& filename);
360 
Load(const std::string & filename,float width,float height)361 	bool Load(const std::string& filename, float width, float height)
362 		{ SetDimensions(width, height); return Load(filename); }
363 
364 	//! \brief Draws the image to the screen
365 	void Draw() const;
366 
367 	/** \brief Draws a color-modulated version of the image
368 	*** \param draw_color The color to modulate the image by
369 	**/
370 	void Draw(const Color& draw_color) const;
371 
372 	/** \brief Saves the image to a file
373 	*** \param filename The filename of the image to save (should have a .png or .jpg extension)
374 	*** \return True if the image was successfully saved to a file
375 	***
376 	*** \note The image being saved should contain only one image element. Support for saving of
377 	*** composite (multi-element) images is not yet supported
378 	**/
379 	bool Save(const std::string& filename) const;
380 
381 	//! \brief Enables grayscaling for the image then reloads it
382 	void EnableGrayScale();
383 
384 	//! \brief Disables grayscaling for the image then reloads it
385 	void DisableGrayScale();
386 
387 	//! \name Class Member Access Functions
388 	//@{
389 	//! \brief Returns the filename string for the image
GetFilename()390 	const std::string& GetFilename() const
391 		{ return _filename; }
392 
393 	/** \brief Returns the color of a particular vertex
394 	*** \param c The Color object to place the color in.
395 	*** \param index The vertex index of the color to fetch
396 	*** \note If an invalid index value is used, the function will return with no warning.
397 	**/
GetVertexColor(Color & c,uint8 index)398 	void GetVertexColor(Color& c, uint8 index)
399 		{ if (index > 3) return; else c = _color[index]; }
400 
401 	/** \brief Sets width of the image
402 	*** \param width Width of the image
403 	**/
SetWidth(float width)404 	void SetWidth(float width)
405 		{ _width = width; }
406 
407 	/** \brief Sets height of the image
408 	*** \param height Height of the image
409 	**/
SetHeight(float height)410 	void SetHeight(float height)
411 		{ _height = height; }
412 
413 	/** \brief Sets the dimensions of the image for a desired coordinate system
414 	*** \param width The width of the image
415 	*** \param height The height of the image
416 	**/
SetDimensions(float width,float height)417 	void SetDimensions(float width, float height)
418 		{ SetWidth(width); SetHeight(height); }
419 
420 	/** \brief Sets image to static/animated
421 	***	\param is_static Flag indicating whether the image should be made static or not
422 	**/
SetStatic(bool is_static)423 	void SetStatic(bool is_static)
424 		{ _is_static = is_static; }
425 	//@}
426 
427 protected:
428 	/** \brief The name of the image file from which this image was created
429 	*** This member is only valid for StillImage objects which had their Load() function
430 	*** invoked successfully and have no additional elements. This member will be set to
431 	*** the empty string otherwise.
432 	**/
433 	std::string _filename;
434 
435 	//! \brief The texture image that is referenced by this element
436 	private_video::ImageTexture* _image_texture;
437 }; // class StillImage : public ImageDescriptor
438 
439 
440 
441 namespace private_video {
442 
443 /** ****************************************************************************
444 *** \brief Represents a single frame in an animation
445 *** ***************************************************************************/
446 class AnimationFrame {
447 public:
448 	//! \brief The amount of time to display this frame, in milliseconds
449 	uint32 frame_time;
450 
451 	//! \brief The StillImage used for this frame in the animation
452 	StillImage image;
453 }; // class AnimationFrame
454 
455 
456 /** ****************************************************************************
457 *** \brief Represents a single element in a composite image
458 *** ***************************************************************************/
459 class ImageElement {
460 public:
ImageElement()461 	ImageElement() :
462 		x_offset(0.0f), y_offset(0.0f) {}
463 
ImageElement(const StillImage & img,float x,float y)464 	ImageElement(const StillImage& img, float x, float y) :
465 		image(img), x_offset(x), y_offset(y) {}
466 
467 	//! \brief The singular image that represents this element
468 	StillImage image;
469 
470 	//! \brief X and y draw position offsets of this element
471 	float x_offset, y_offset;
472 }; // class ImageElement
473 
474 } // namespace private_video
475 
476 
477 /** ****************************************************************************
478 *** \brief Represents an animated image with both frames and timing information
479 ***
480 *** Animated images are really nothing more than a series of individual still
481 *** images and timing information for each frame. This class assumes that
482 *** all frame images are the same size, so you should not attempt to use
483 *** this class if your frames are of different sizes. If you wish to use different
484 *** sized frame images in an animation, you'll need to implement the code
485 *** to do so yourself.
486 *** ***************************************************************************/
487 class AnimatedImage : public ImageDescriptor {
488 	friend class VideoEngine;
489 
490 public:
491 	//! \brief Supply the constructor with "true" if you want this to represent a grayscale image.
492 	AnimatedImage(bool grayscale = false);
493 
494 	//! \brief A constructor which also sets the image's dimensions
495 	AnimatedImage(float width, float height, bool grayscale = false);
496 
497 	//! \brief Resets the image's properties and removes any references to image data that it maintains
498 	void Clear();
499 
500 	/** \brief Loads an AnimatedImage by opening a multi image file
501 	*** \param filename The name of the file to load, which should end in a .png or .jpg extension
502 	*** \param timings A vector reference which holds the timing information for each animation frame
503 	*** \param frame_width The width (in pixels) of each frame in the multi image file
504 	*** \param frame_height The height (in pixels) of each frame in the multi image file
505 	*** \param trim The number of frame images to "ignore" from the multi image (default == 0)
506 	*** \return True if the animation was successfully constructed from the loaded multi image
507 	***
508 	*** The trim factor must be less than the total number of frames that are stored in the multi image.
509 	*** The size of the timings vector must be at least (# of frames in multi image - trim). It may
510 	*** be larger than this, but the rest of the elements beyond the minimum size will be ignored.
511 	**/
512 	bool LoadFromFrameSize(const std::string& filename, const std::vector<uint32>& timings, const uint32 frame_width, const uint32 frame_height, const uint32 trim = 0);
513 
514 	/** \brief Loads an AnimatedImage from a multi image file
515 	*** \param filename The name of the file to load, which should end in a .png or .jpg extension
516 	*** \param timings A vector reference which holds the timing information for each animation frame
517 	*** \param frame_rows The number of rows of frame images in the image file
518 	*** \param frame_cols The number of columns of frame images in the image file
519 	*** \param trim The number of frame images to "ignore" from the multi image (default == 0)
520 	*** \return True if the animation was successfully constructed from the loaded multi image
521 	***
522 	*** The trim factor is useful for indicating if any of the final frames in a multi image
523 	*** contain no relevant image data that we are interested in. For example, if we have a
524 	*** multi image with 2 rows and 4 columns of frames, but only the first 6 frames (the entire
525 	*** top row, and the left-most two frames in the bottom row) are valid, we would set the trim
526 	*** factor to two. Obviously, trim must be less than frame_rows * frame_cols, otherwise we
527 	*** can't load even a single frame.
528 	***
529 	*** The timings vector must have a minimum size of (frame_rows * frame_cols - trim) so that each
530 	*** frame we will add has a timing value associated with it. The timings vector may be larger
531 	*** than this minimum size, but only the first (frame_rows * frame_cols - trim) elements will
532 	*** be used, and the rest of the vector ignored.
533 	**/
534 	bool LoadFromFrameGrid(const std::string& filename, const std::vector<uint32>& timings, const uint32 frame_rows, const uint32 frame_cols, const uint32 trim = 0);
535 
536 	//! \brief Draws the current frame image to the screen
537 	void Draw() const;
538 
539 	/** \brief Draws the current frame image which is modulated by a color
540 	*** \param draw_color The color to modulate the image by
541 	**/
542 	void Draw(const Color& draw_color) const;
543 
544 	/** \brief Saves all frame images into a single file (a multi image file)
545 	*** \param filename The filename of the image to save (should have a .png or .jpg extension)
546 	*** \param grid_rows The number of grid rows to save in the multi image
547 	*** \param grid_cols The number of grid columns to save in the multi image
548 	*** \return True if all frames were successfully saved to a file
549 	***
550 	*** This function
551 	***
552 	*** \note No frame images should contain more than one image element. Support for saving of
553 	*** composite (multi-element) images is not yet supported.
554 	**/
555 	bool Save(const std::string& filename, const uint32 grid_rows = 0, const uint32 grid_cols = 0) const;
556 
557 	//! \brief Enables grayscale for all image frames
558 	void EnableGrayScale();
559 
560 	//! \brief Disables grayscale for all image frames
561 	void DisableGrayScale();
562 
563 	//! \brief Resets the animation's frame, counter, and looping.
ResetAnimation()564 	void ResetAnimation()
565 		{ _frame_index = 0; _frame_counter = 0; _loop_counter = 0; _loops_finished = false; }
566 
567 	/** \brief Called every frame to update the animation's current frame
568 	*** This will automatically synchronize the animation to VIDEO_ANIMATION_FRAME_PERIOD,
569 	*** i.e. 30 frames per second. If you want to update the frames yourself using some custom
570 	*** algorithm, then use the SetFrame() method instead of calling this function
571 	***
572 	*** \note This method will do nothing if there are no frames contained in the animation,
573 	*** or if the _loops_finished member is set to true.
574 	**/
575 	void Update();
576 
577 	/** \brief Adds an animation frame using the filename of the image to add.
578 	*** \param frame The filename of the frame image to add.
579 	*** \param frame_time The number of milliseconds that this animation should last for
580 	*** \return True on success, false on failure.
581 	***
582 	*** This is perhaps a more convenient way to add frames, <b>but</b> this makes it impossible
583 	*** to control the image properties such as vertex colors, and size. If you use this function,
584 	*** the width and height will be the pixel width/height of the image itself. This is not what
585 	*** you always will want. For example, if your coordinate system is in terms of 32x32 pixel
586 	*** tiles, then a tile image would have a width and height of 1, not 32.
587 	**/
588 	bool AddFrame(const std::string& frame, uint32 frame_time);
589 
590 	/** \brief Adds an animation frame by using an existing static image.
591 	*** \param frame The still image to use as the frame image.
592 	*** \param frame_time The amount of millseconds to display the frame.
593 	*** \return True on success, false on failure.
594 	***
595 	*** The frame argument should have at least one element prepared. Passing a StillImage
596 	*** that does not contain any image data will result in failure for this call.
597 	**/
598 	bool AddFrame(const StillImage& frame, uint32 frame_time);
599 
600 	//! \name Class Member Access Functions
601 	//@{
602 	//! \brief Returns the number of frames in this animation
GetNumFrames()603 	uint32 GetNumFrames() const
604 		{ return _frames.size(); }
605 
606 	//! \brief Retuns a pointer to the StillImage representing the current frame
GetCurrentFrame()607 	StillImage* GetCurrentFrame() const
608 		{ return const_cast<StillImage*>(&(_frames[_frame_index].image)); }
609 
610 	//! \brief Returns the index number of the current frame in the animation.
GetCurrentFrameIndex()611 	uint32 GetCurrentFrameIndex() const
612 		{ return _frame_index; }
613 
614 	/** \brief Returns a pointer to the StillImage at a specified frame.
615 	*** \param index index of the frame you want
616 	*** \return A pointer to the image at that index, or NULL if the index parameter was invalid
617 	***
618 	*** Using this function is dangerous since it provides direct access to an image frame.
619 	*** If you find yourself in constant need of using this function, think twice about
620 	*** what you are doing.
621 	**/
GetFrame(uint32 index)622 	StillImage* GetFrame(uint32 index) const
623 		{ if (index >= _frames.size()) return NULL; else return const_cast<StillImage*>(&(_frames[index].image)); }
624 
625 	//! \brief Returns the number of milliseconds that the current frame has been shown for.
GetTimeProgress()626 	uint32 GetTimeProgress() const
627 		{ return _frame_counter; }
628 
629 	/** \brief Returns the percentage of timing complete for the current frame being shown.
630 	*** \return A float from 0.0f to 1.0f, indicate how much of its allotted time this frame has spent
631 	*** \note The divide by 0.0f case is not checked for here, so this function could potentially throw
632 	*** a divide by zero exception at run-time.
633 	**/
GetPercentProgress()634 	float GetPercentProgress() const
635 		{ return static_cast<float>(_frame_counter) / _frames[_frame_index].frame_time; }
636 
637 	//! \brief Returns true if the loops have finished, false otherwise
IsLoopsFinished()638 	bool IsLoopsFinished() const
639 		{ return _loops_finished; }
640 
641 	/** \brief Sets all animation frames to be a certain width
642 	*** \param width Width to set each frame (in coordinate system units)
643 	**/
644 	void SetWidth(float width);
645 
646 	/** \brief Sets all animation frames to be a certain height
647 	*** \param height Height to set each frame (in coordinate system units)
648 	**/
649 	void SetHeight(float height);
650 
651 	/** \brief Sets all animation frames to be a certain width and height
652 	*** \param width Width to set each frame (in coordinate system units)
653 	*** \param height Height to set each frame (in coordinate system units)
654 	**/
655 	void SetDimensions(float width, float height);
656 
SetUVCoordinates(float u1,float v1,float u2,float v2)657 	void SetUVCoordinates(float u1, float v1, float u2, float v2)
658 		{}
659 
660 	/** \brief Sets the static member for all animation frame images
661 	*** \param is_static Flag indicating whether the image will be static or not.
662 	*** \note If the frames are already loaded, it doesn't bother to try to unload them
663 	*** and then reload them again statically.
664 	**/
SetStatic(bool is_static)665 	void SetStatic(bool is_static)
666 		{ _is_static = is_static; }
667 
668 	/** \brief sets All frames to be of a certain color (all vertices are set to the same color)
669 	*** \param color Color of the 4 vertices
670 	**/
671 	void SetColor(const Color &color);
672 
673 	/** \brief sets all frames to have the specified vertex colors
674 	*** \param tl The top left vertex color
675 	*** \param tr The top right vertex color
676 	*** \param bl The bottom left vertex color
677 	*** \param br The bottom right vertex color
678 	**/
679 	void SetVertexColors(const Color &tl, const Color &tr, const Color &bl, const Color &br);
680 
681 	/** \brief Sets the current frame index of the animation.
682 	*** \param index The index of the frame to access
683 	*** \note Passing in an invalid value for the index will not change the current frame
684 	**/
SetFrameIndex(const uint32 index)685 	void SetFrameIndex(const uint32 index)
686 		{ if (index > _frames.size()) return; _frame_index = index; _frame_counter = 0; }
687 
688 	/** \brief Sets the number of milliseconds that the current frame has been shown for.
689 	*** \param time The time to set the frame counter
690 	*** \note This does not set the frame timer for the current frame
691 	**/
SetTimeProgress(uint32 time)692 	void SetTimeProgress(uint32 time)
693 		{ _frame_counter = time; }
694 
695 	/** \brief Set the number of loops for the animation.
696 	*** A value less than zero indicates to loop forever. Zero indicates do not loop: just run the
697 	*** animation from beginning to end and stop.
698 	***	\param loops Number of loops for the animation
699 	**/
SetNumberLoops(int32 loops)700 	void SetNumberLoops(int32 loops)
701 		{ _number_loops = loops; if (_loop_counter >= _number_loops && _number_loops >= 0) _loops_finished = true; }
702 
703 	/** \brief Set the current number of loops that the animation has completed.
704 	*** \param loops The urrent loop count
705 	**/
SetLoopCounter(int32 loops)706 	void SetLoopCounter(int32 loops)
707 		{ _loop_counter = loops; if (_loop_counter >= _number_loops && _number_loops >= 0) _loops_finished = true; }
708 
709 	/** \brief Effectively stops the animation in its track if this member is set to true.
710 	*** \param loops True to stop the looping process. Setting it to false will restart the loop counter
711 	**/
SetLoopsFinished(bool loops)712 	void SetLoopsFinished(bool loops)
713 		{ _loops_finished = loops; if (loops == false) _loop_counter = 0; }
714 	//@}
715 
716 private:
717 	//! \brief The index of which animation frame to display.
718 	uint32 _frame_index;
719 
720     //! \brief Counts how long each frame has been shown for.
721 	uint32 _frame_counter;
722 
723 	/** \brief The number of times to loop the animation frames.
724 	*** A negative value indicates to loop forever, which is the default.
725 	**/
726 	int32 _number_loops;
727 
728 	//! \brief Counts the number of loops remaining for the animation.
729 	int32 _loop_counter;
730 
731 	/** \brief Set to true when the loop counter has expired.
732 	*** This member will remain eternally false if the looping is set to infinite mode.
733 	**/
734 	bool _loops_finished;
735 
736 	//! \brief The vector of animation frames (contains both images and timing)
737 	std::vector<private_video::AnimationFrame> _frames;
738 }; // class AnimatedImage : public ImageDescriptor
739 
740 
741 /** ****************************************************************************
742 *** \brief Represents a composite image created from multiple image elements
743 ***
744 *** A composite image is created by taking multiple StillImage objects and
745 *** "stitching" them together to represent a singular image object. Each image
746 *** element has x and y offsets that determine where the image is located in
747 *** the composite image. A good example usage of this class can be found in the
748 *** MenuWindow class, where a window is represented as a composite image and
749 *** created by attaching multiple border images together to create the window.
750 ***
751 *** \note Because this class references other StillImage objects, it's _texture
752 *** member is always NULL, since the class itself does not make use of any
753 *** textures.
754 *** ***************************************************************************/
755 class CompositeImage : public ImageDescriptor {
756 public:
CompositeImage()757 	CompositeImage()
758 		{}
759 
~CompositeImage()760 	~CompositeImage()
761 		{}
762 
763 	//! \brief Removes all image elements held by this class
764 	void Clear();
765 
766 	/** \brief Draws the image to the display buffer
767 	*** The location and orientation of the drawn image is dependent upon the current cursor position
768 	*** and context (draw flags) set in the VideoEngine class.
769 	**/
770 	void Draw() const;
771 
772 	/** \brief Draws a color modulated version of the image to the display buffer
773 	*** \param draw_color The color to modulate the image by
774 	**/
775 	void Draw(const Color& draw_color) const;
776 
777 	/** \brief Sets the static member for all future element images
778 	*** \param is_static Flag indicating whether the image will be static or not
779 	*** \note If the elements are already loaded, it doesn't bother to try to unload them
780 	*** and then reload them again statically.
781 	**/
SetStatic(bool is_static)782 	void SetStatic(bool is_static)
783 		{ _is_static = is_static; }
784 
785 	/** \brief Sets the image's width, expressed as coordinate system units
786 	*** \param width The desired width of the image
787 	**/
788 	void SetWidth(float width);
789 
790 	/** \brief Sets the image's height, expressed as coordinate system units
791 	*** \param height The desired height of the image
792 	**/
793 	void SetHeight(float height);
794 
795 	/** \brief Sets the image's dimensions, expressed as coordinate system units
796 	*** \param width The desired width of the image
797 	*** \param height The desired height of the image
798 	**/
SetDimensions(float width,float height)799 	void SetDimensions(float width, float height)
800 		{ SetWidth(width); SetHeight(height); }
801 
EnableGrayScale()802 	void EnableGrayScale()
803 		{}
804 
DisableGrayScale()805 	void DisableGrayScale()
806 		{}
807 
SetUVCoordinates(float u1,float v1,float u2,float v2)808 	void SetUVCoordinates(float u1, float v1, float u2, float v2)
809 		{}
810 
811 	/** \brief Sets the image's four vertices to a single color
812 	*** \param color The desired color of all image vertices
813 	**/
814 	void SetColor(const Color& color);
815 
816 	/** \brief Sets the image's vertex colors
817 	*** \param tl The top left vertex color
818 	*** \param tr The top right vertex color
819 	*** \param bl The bottom left vertex color
820 	*** \param br The bottom right vertex color
821 	**/
822 	void SetVertexColors(const Color& tl, const Color& tr, const Color& bl, const Color& br);
823 
824 	/** \brief Adds a new image element to the composite image
825 	*** \param img The image to add to the composite image.
826 	*** \param x_offset The x offset of the composite image.
827 	*** \param y_offset The y offset of the composite image.
828 	*** \param u1 The upper-left u coordinate for the image. The default is 0.0f.
829 	*** \param v1 The upper-left v coordinate for the image. The default is 0.0f.
830 	*** \param u2 The lower-right u coordinate for the image. The default is 1.0f.
831 	*** \param v2 The lower-right v coordinate for the image. The default is 1.0f.
832 	***
833 	*** Starting with a newly created StillImage, call AddImage(), for all of the images you wish
834 	*** to add, along with the x and y offsets that they should be positioned at. The u1, v1, u2, v2
835 	*** coordinates tell which portion of the image to use (usually 0.0f, 0.0f, 1.0f, 1.0f)
836 	**/
837 	void AddImage(const StillImage& img, float x_offset, float y_offset, float u1 = 0.0f, float v1 = 0.0f,
838 		float u2 = 1.0f, float v2 = 1.0f);
839 
840 	/** \brief Creates a single composite image from a 2D array of like-sized images
841 	*** \param tiles A 1D vector of StillImage objects that will be used to construct the composite image
842 	*** \param indeces A 2D vector in row-column order (e.g. indices[y][x]) with indeces into the tiles vector
843 	***
844 	*** This method is useful for constructing variable-sized objects within a map from multiple smaller tile
845 	*** images. The StillImage object that this method is invoked upon will be cleared prior to constructing
846 	*** the composite image.
847 	***
848 	*** \note This should be obvious, but don't include "this" StillImage object inside the tiles argument vector
849 	*** \note All StillImages in the tiles vector should have the same dimensions
850 	*** \note Every vector row in indeces must be the same size
851 	*** \note Every index element (indices[y][x]) should range from 0 to tiles.size() - 1
852 	**/
853 // 	void ConstructCompositeImage(const std::vector<ImageElement>& tiles, const std::vector<std::vector<uint32> >& indeces);
854 
855 private:
856 	//! \brief A container for each element in the composite image
857 	std::vector<private_video::ImageElement> _elements;
858 }; // class CompositeImage : public ImageDescriptor
859 
860 }  // namespace hoa_video
861 
862 #endif // __IMAGE_HEADER__
863