///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004-2007 by The Allacrost Project
// All Rights Reserved
//
// This code is licensed under the GNU GPL version 2. It is free software
// and you may modify it and/or redistribute it under the terms of this license.
// See http://www.gnu.org/copyleft/gpl.html for details.
///////////////////////////////////////////////////////////////////////////////
/** ****************************************************************************
*** \file image.h
*** \author Tyler Olsen, roots@allacrost.org
*** \brief Source file for image classes
***
*** This file contains several classes that represent images loaded into the
*** engine. The public classes used outside of the video engine are:
***
*** - ImageDescriptor is an abstract base class for other images. This
*** type is used to allow containers to create multiple derived image classes.
*** It also contains a number of static functions for general image operation
*** code.
***
*** - StillImage is a single non-animated image and is what the user
*** will utilize most of the time.
***
*** - AnimatedImage is an animated image that contains multiple frames,
*** where a frame is a StillImage object along with timing information.
***
*** - AnimationFrame is a single frame of animation. It consists of a
*** StillImage, and how long the frame should be displayed in the animation.
*** This class is contained in the private_video namespace and is not a part
*** of the image manipulation API.
***
*** - CompositeImage is an image formed by piecing together multiple
*** StillImage objects. The image elements in a composite image may or may
*** not overlap one another
***
*** \note A multi image is nothing more than a single image file which
*** contains multiple adjacent sub-images within it. For example, a tileset file
*** contains numerous tile images. All sub-images are required to have the same
*** dimensions in a multi image file. Multi images are never explicitly contained
*** in any way by the video engine -- rather, these multi images are loaded into
*** memory and then the sub-images are split up into separate StillImage objects.
*** ***************************************************************************/
#ifndef __IMAGE_HEADER__
#define __IMAGE_HEADER__
#include "defs.h"
#include "utils.h"
#include "image_base.h"
#include "color.h"
#include "texture.h"
namespace hoa_video {
/** ****************************************************************************
*** \brief An abstract base class for all public API image classes
***
*** This class also contains several static functions for performing image
*** operations which do not operate on a single instance of a derived
*** ImageDescriptor object. For example, functions which load a single image
*** file into multiple StillImage objects.
***
*** \note A multi image is defined as a single image file which contains
*** several images in a grid format that we wish to extract as seperate image
*** entities. This is used, for example, to hold multiple tile images in a large
*** tileset file, or multiple animation frames stored in a single image file.
*** All individual image elements in a multi image are required to be the same
*** size.
***
*** \note The copy constructor and copy assignement operator ensure that the
*** reference to the texture being used is updated appropriately. The
*** derived classes should not require the implementation of a copy constructor
*** or assignment operator, at least not for the purposes of proper reference
*** counting.
***
*** \note If the destructor finds that the image texture has no more references
*** after it decrements the reference counter, it will mark it as free on the
*** image texture's texture sheet. However it will not attempt to remove
*** it from any container in the TextureManager class, so that is up to the
*** destructors of the derived classes to implement.
*** ***************************************************************************/
class ImageDescriptor {
friend class GameVideo;
public:
ImageDescriptor();
virtual ~ImageDescriptor();
ImageDescriptor(const ImageDescriptor& copy);
ImageDescriptor& operator=(const ImageDescriptor& copy);
//! \brief Clears all data retained by the object (color, width, height, etc.)
virtual void Clear() = 0;
/** \brief Draws the image to the display buffer
*** The location and orientation of the drawn image is dependent upon the current cursor position
*** and context (draw flags) set in the GameVideo class.
**/
virtual void Draw() const = 0;
/** \brief Draws a color modulated version of the image to the display buffer
*** \param draw_color The color to modulate the image by
**/
virtual void Draw(const Color& draw_color) const = 0;
//! \name Class Member Access Functions
//@{
//! \brief Returns the image width
virtual float GetWidth() const
{ return _width; }
//! \brief Returns image height
virtual float GetHeight() const
{ return _height; }
//! \brief Returns true if the image is grayscale.
bool IsGrayScale() const
{ return _grayscale; }
virtual void EnableGrayScale() = 0;
virtual void DisableGrayScale() = 0;
/** \brief Enables or disables the image's static property
*** \param is_static If true, the image will be made static
**/
virtual void SetStatic(bool is_static) = 0;
/** \brief Sets the image's width, expressed as coordinate system units
*** \param width The desired width of the image
**/
virtual void SetWidth(float width) = 0;
/** \brief Sets the image's height, expressed as coordinate system units
*** \param height The desired height of the image
**/
virtual void SetHeight(float height) = 0;
/** \brief Sets the image's dimensions, expressed as coordinate system units
*** \param width The desired width of the image
*** \param height The desired height of the image
**/
virtual void SetDimensions(float width, float height) = 0;
/** \brief Sets the UV coordinates for the image
*** \param u1 First u coordinate
*** \param v1 First v coordinate
*** \param u2 Second u coordinate
*** \param v2 Second v coordinate
***
*** This method rarely needs to be called, as the default UV coordinates suffice
*** for nearly all images.
**/
virtual void SetUVCoordinates(float u1, float v1, float u2, float v2)
{ _u1 = u1; _v1 = v1; _u2 = u2; _v2 = v2; }
/** \brief Sets the image's four vertices to a single color
*** \param color The desired color of all image vertices
**/
virtual void SetColor(const Color& color);
/** \brief Sets the image's vertex colors
*** \param tl The top left vertex color
*** \param tr The top right vertex color
*** \param bl The bottom left vertex color
*** \param br The bottom right vertex color
**/
virtual void SetVertexColors(const Color& tl, const Color& tr, const Color& bl, const Color& br);
//@}
/** \name Static Image Manipulation Functions
*** This series of static functions provide additional image mainpulation that does not operate
*** on a single instance of a derived image type.
**/
//@{
/** \brief Retrieves various properties about an image file
*** \param filename The name of the image file (.png or .jpg) to retrieve the properties of
*** \param rows The number of rows of pixels in the image
*** \param cols The number of columns of pixels in the image
*** \param bpp The number of bits per pixel of the image
*** \throw Exception If any of the properties are not retrieved successfully
**/
static void GetImageInfo(const std::string& filename, uint32& rows, uint32& cols, uint32& bpp) throw(hoa_utils::Exception);
/** \brief Loads a multi image into a vector of StillImage objects
*** \param images Reference to the vector of StillImages to be loaded with elements from the multi image
*** \param filename The name of the multi image file to load the image data from
*** \param elem_width The width of each sub-image element, in pixels
*** \param elem_height The height of each sub-image element, in pixels
*** \return True upon successful loading, false if there was an error
***
*** This function determines the image elements to extract from the multi image by the width and height
*** of each element (in pixels) specified in the function arguments. Upon success, the size of the images
*** reference vector will always be equal to the area of the multi image divided by the area of each
*** element image.
*** \note All image elements within the multi image should be of the same size
*/
static bool LoadMultiImageFromElementSize(std::vector& images, const std::string& filename,
const uint32 elem_width, const uint32 elem_height);
/** \brief Loads a multi image into a vector of StillImage objects
*** \param images Reference to the vector of StillImages to be loaded with elements from the multi image
*** \param filename The name of the multi image file to load the image data from
*** \param grid_rows The number of rows of image elements contained in the multi image
*** \param grid_cols The number of columns of image elements contained in the multi image
*** \return True upon successful loading, false if there was an error
***
*** This function determines the image elements to extract from dividing the multi image into a number
*** of rows and columns, as given through the function's arguments. Upon success, the size of the images
*** reference vector will always be equal to grid_rows * grid_cols.
*** \note All image elements within the multi image should be of the same size
**/
static bool LoadMultiImageFromElementGrid(std::vector& images, const std::string& filename,
const uint32 grid_rows, const uint32 grid_cols);
/** \brief Saves a vector of images into a single image file (a multi image)
*** \param images A reference to the vector of StillImage pointers to save into a multi image
*** \param filename The name of the multi image file to write (.png of .jpg extension required)
*** \param grid_rows The number of rows of sub-images in the MultiImage.
*** \param grid_cols Number of columns of sub-images in the MultiImage.
*** \return True upon successful loading, false if there was an error
*** \note All images within the images vector should be of the same size
**/
static bool SaveMultiImage(const std::vector& images, const std::string& filename,
const uint32 grid_rows, const uint32 grid_cols);
//@}
//! \brief A debug function which prints the image's information to the screen
void DEBUG_PrintInfo();
protected:
/** \brief A pointer to the texture used by the image
*** The purpose of this member is for the ImageDescriptor class to be able to manage
**/
private_video::BaseTexture* _texture;
//! \brief The width and height of the image, in coordinate system units.
float _width, _height;
/** \brief The texture coordinates for the image
*** (u1, v1) represents the upper-left corner while (u2, v2) represents the bottom-right corner. These coordinates
*** are typically (0.0f, 0.0f), (1.0f, 1.0f) and do not need to be modified except in special cases.
**/
float _u1, _v1, _u2, _v2;
//! \brief Holds the color of the upper left, upper right, lower left, and lower right vertices, respectively.
Color _color[4];
//! \brief True indicates to perform blending with this image
bool _blend;
//! \brief Set to true if all vertices are the same color
bool _unichrome_vertices;
//! \brief Indicates whether the image being loaded should be loaded into a non-volatile area of texture memory.
bool _is_static;
//! \brief True if this image is grayscale.
bool _grayscale;
/** \brief Removes a reference to _texture, and frees or deletes it if it has no remaining references
***
*** This method will set _texture to NULL before returning. If your derived class has a duplicate texture
*** pointer (ie, ImageTexture pointer for StillImage class), you should make sure to set that member to
*** NULL as well.
**/
void _RemoveTextureReference();
/** \brief A draw helper function which adjusts the draw orientation (translation and scaling)
***
*** \note This method modifies the draw cursor position and does not restore it before finishing. Therefore
*** under most circumstances, you will want to call VideoManager->PushState()/PopState(), or
*** glPushMatrix()/glPopMatrix() before and after calling this function. The latter is preferred due to the
*** lower cost of the call, but some circumstances may require using the former when more state information
*** needs to be retained.
**/
void _DrawOrientation() const;
/** \brief Draws the OpenGL texture referred to by the object on the screen
*** \param draw_color A non-NULL pointer to an array of four valid Color objects
***
*** This method is typically a helper method to other draw calls in some way. It assumes that
*** all of the appropriate transformation, scaling, and other image property opertaions have been
*** completed prior to the calling of this function. The draw_color argument is usually nothing
*** more than a pointer to the _color member of this very class, but in certain cases like during
*** a screen fade these colors may differ.
**/
void _DrawTexture(const Color* draw_color) const;
private:
/** \brief Retrieves various properties about a PNG image file
*** \param filename The name of the PNG image file to retrieve the properties of
*** \param rows The number of rows of pixels in the image
*** \param cols The number of columns of pixels in the image
*** \param bpp The number of bits per pixel of the image
*** \throw Exception If any of the properties are not retrieved successfully
**/
static void _GetPngImageInfo(const std::string& filename, uint32& rows, uint32& cols, uint32& bpp) throw(hoa_utils::Exception);
/** \brief Retrieves various properties about a JPG image file
*** \param filename The name of the JPG image file to retrieve the properties of
*** \param rows The number of rows of pixels in the image
*** \param cols The number of columns of pixels in the image
*** \param bpp The number of bits per pixel of the image
*** \throw Exception If any of the properties are not retrieved successfully
**/
static void _GetJpgImageInfo(const std::string& filename, uint32& rows, uint32& cols, uint32& bpp) throw(hoa_utils::Exception);
/** \brief A helper function to the public LoadMultiImage* calls
*** \param images Reference to the vector of StillImages to be loaded
*** \param filename The name of the multi image file to read
*** \param grid_rows The number of rows of image elements in the multi image
*** \param grid_cols The number of columns of image elements in the multi image
*** \return True if the image file was loaded and parsed successfully, false if there was an error.
**/
static bool _LoadMultiImage(std::vector& images, const std::string& filename,
const uint32 grid_rows, const uint32 grid_cols);
}; // class ImageDescriptor
/** ****************************************************************************
*** \brief Represents a simple still image
***
*** This is the most frequently used image construct of the video engine. Objects
*** of this class are used in the construction of some of the more advanced image
*** classes.
*** ***************************************************************************/
class StillImage : public ImageDescriptor {
friend class GameVideo;
friend class ImageDescriptor;
friend class AnimatedImage;
friend class CompositeImage;
friend class TextureController;
friend class private_video::ParticleSystem;
public:
//! \brief Supply the constructor with "true" if you want this to represent a grayscale image
StillImage(const bool grayscale = false);
~StillImage();
//! \brief Resets the image's properties and removes any references to image data that it maintains
void Clear();
/** \brief Loads a single image file to be represented by the class object
*** \param filename The filename of the image to load (should have a .png or .jpg extension)
*** \return True if the image was successfully loaded and is now represented by this object
***
*** \note Invoking this function will clear all image elements currently used by this class.
*** \note Passing in an emptry string for filename is a special case, and will construct
*** a colored quad for the image procedurally. It is not an error to pass an empty string to
*** the function.
**/
bool Load(const std::string& filename);
bool Load(const std::string& filename, float width, float height)
{ SetDimensions(width, height); return Load(filename); }
//! \brief Draws the image to the screen
void Draw() const;
/** \brief Draws a color-modulated version of the image
*** \param draw_color The color to modulate the image by
**/
void Draw(const Color& draw_color) const;
/** \brief Saves the image to a file
*** \param filename The filename of the image to save (should have a .png or .jpg extension)
*** \return True if the image was successfully saved to a file
***
*** \note The image being saved should contain only one image element. Support for saving of
*** composite (multi-element) images is not yet supported
**/
bool Save(const std::string& filename) const;
//! \brief Enables grayscaling for the image then reloads it
void EnableGrayScale();
//! \brief Disables grayscaling for the image then reloads it
void DisableGrayScale();
//! \name Class Member Access Functions
//@{
//! \brief Returns the filename string for the image
const std::string& GetFilename() const
{ return _filename; }
/** \brief Returns the color of a particular vertex
*** \param c The Color object to place the color in.
*** \param index The vertex index of the color to fetch
*** \note If an invalid index value is used, the function will return with no warning.
**/
void GetVertexColor(Color& c, uint8 index)
{ if (index > 3) return; else c = _color[index]; }
/** \brief Sets width of the image
*** \param width Width of the image
**/
void SetWidth(float width)
{ _width = width; }
/** \brief Sets height of the image
*** \param height Height of the image
**/
void SetHeight(float height)
{ _height = height; }
/** \brief Sets the dimensions of the image for a desired coordinate system
*** \param width The width of the image
*** \param height The height of the image
**/
void SetDimensions(float width, float height)
{ SetWidth(width); SetHeight(height); }
/** \brief Sets image to static/animated
*** \param is_static Flag indicating whether the image should be made static or not
**/
void SetStatic(bool is_static)
{ _is_static = is_static; }
//@}
protected:
/** \brief The name of the image file from which this image was created
*** This member is only valid for StillImage objects which had their Load() function
*** invoked successfully and have no additional elements. This member will be set to
*** the empty string otherwise.
**/
std::string _filename;
//! \brief The texture image that is referenced by this element
private_video::ImageTexture* _image_texture;
}; // class StillImage : public ImageDescriptor
namespace private_video {
/** ****************************************************************************
*** \brief Represents a single frame in an animation
*** ***************************************************************************/
class AnimationFrame {
public:
//! \brief The amount of time to display this frame, in milliseconds
uint32 frame_time;
//! \brief The StillImage used for this frame in the animation
StillImage image;
}; // class AnimationFrame
/** ****************************************************************************
*** \brief Represents a single element in a composite image
*** ***************************************************************************/
class ImageElement {
public:
ImageElement() :
x_offset(0.0f), y_offset(0.0f) {}
ImageElement(const StillImage& img, float x, float y) :
image(img), x_offset(x), y_offset(y) {}
//! \brief The singular image that represents this element
StillImage image;
//! \brief X and y draw position offsets of this element
float x_offset, y_offset;
}; // class ImageElement
} // namespace private_video
/** ****************************************************************************
*** \brief Represents an animated image with both frames and timing information
***
*** Animated images are really nothing more than a series of individual still
*** images and timing information for each frame. This class assumes that
*** all frame images are the same size, so you should not attempt to use
*** this class if your frames are of different sizes. If you wish to use different
*** sized frame images in an animation, you'll need to implement the code
*** to do so yourself.
*** ***************************************************************************/
class AnimatedImage : public ImageDescriptor {
friend class GameVideo;
public:
//! \brief Supply the constructor with "true" if you want this to represent a grayscale image.
AnimatedImage(bool grayscale = false);
//! \brief A constructor which also sets the image's dimensions
AnimatedImage(float width, float height, bool grayscale = false);
//! \brief Resets the image's properties and removes any references to image data that it maintains
void Clear();
/** \brief Loads an AnimatedImage by opening a multi image file
*** \param filename The name of the file to load, which should end in a .png or .jpg extension
*** \param timings A vector reference which holds the timing information for each animation frame
*** \param frame_width The width (in pixels) of each frame in the multi image file
*** \param frame_height The height (in pixels) of each frame in the multi image file
*** \param trim The number of frame images to "ignore" from the multi image (default == 0)
*** \return True if the animation was successfully constructed from the loaded multi image
***
*** The trim factor must be less than the total number of frames that are stored in the multi image.
*** The size of the timings vector must be at least (# of frames in multi image - trim). It may
*** be larger than this, but the rest of the elements beyond the minimum size will be ignored.
**/
bool LoadFromFrameSize(const std::string& filename, const std::vector& timings, const uint32 frame_width, const uint32 frame_height, const uint32 trim = 0);
/** \brief Loads an AnimatedImage from a multi image file
*** \param filename The name of the file to load, which should end in a .png or .jpg extension
*** \param timings A vector reference which holds the timing information for each animation frame
*** \param frame_rows The number of rows of frame images in the image file
*** \param frame_cols The number of columns of frame images in the image file
*** \param trim The number of frame images to "ignore" from the multi image (default == 0)
*** \return True if the animation was successfully constructed from the loaded multi image
***
*** The trim factor is useful for indicating if any of the final frames in a multi image
*** contain no relevant image data that we are interested in. For example, if we have a
*** multi image with 2 rows and 4 columns of frames, but only the first 6 frames (the entire
*** top row, and the left-most two frames in the bottom row) are valid, we would set the trim
*** factor to two. Obviously, trim must be less than frame_rows * frame_cols, otherwise we
*** can't load even a single frame.
***
*** The timings vector must have a minimum size of (frame_rows * frame_cols - trim) so that each
*** frame we will add has a timing value associated with it. The timings vector may be larger
*** than this minimum size, but only the first (frame_rows * frame_cols - trim) elements will
*** be used, and the rest of the vector ignored.
**/
bool LoadFromFrameGrid(const std::string& filename, const std::vector& timings, const uint32 frame_rows, const uint32 frame_cols, const uint32 trim = 0);
//! \brief Draws the current frame image to the screen
void Draw() const;
/** \brief Draws the current frame image which is modulated by a color
*** \param draw_color The color to modulate the image by
**/
void Draw(const Color& draw_color) const;
/** \brief Saves all frame images into a single file (a multi image file)
*** \param filename The filename of the image to save (should have a .png or .jpg extension)
*** \param grid_rows The number of grid rows to save in the multi image
*** \param grid_cols The number of grid columns to save in the multi image
*** \return True if all frames were successfully saved to a file
***
*** This function
***
*** \note No frame images should contain more than one image element. Support for saving of
*** composite (multi-element) images is not yet supported.
**/
bool Save(const std::string& filename, const uint32 grid_rows = 0, const uint32 grid_cols = 0) const;
//! \brief Enables grayscale for all image frames
void EnableGrayScale();
//! \brief Disables grayscale for all image frames
void DisableGrayScale();
//! \brief Resets the animation's frame, counter, and looping.
void ResetAnimation()
{ _frame_index = 0; _frame_counter = 0; _loop_counter = 0; _loops_finished = false; }
/** \brief Called every frame to update the animation's current frame
*** This will automatically synchronize the animation to VIDEO_ANIMATION_FRAME_PERIOD,
*** i.e. 30 frames per second. If you want to update the frames yourself using some custom
*** algorithm, then use the SetFrame() method instead of calling this function
***
*** \note This method will do nothing if there are no frames contained in the animation,
*** or if the _loops_finished member is set to true.
**/
void Update();
/** \brief Adds an animation frame using the filename of the image to add.
*** \param frame The filename of the frame image to add.
*** \param frame_time The number of milliseconds that this animation should last for
*** \return True on success, false on failure.
***
*** This is perhaps a more convenient way to add frames, but this makes it impossible
*** to control the image properties such as vertex colors, and size. If you use this function,
*** the width and height will be the pixel width/height of the image itself. This is not what
*** you always will want. For example, if your coordinate system is in terms of 32x32 pixel
*** tiles, then a tile image would have a width and height of 1, not 32.
**/
bool AddFrame(const std::string& frame, uint32 frame_time);
/** \brief Adds an animation frame by using an existing static image.
*** \param frame The still image to use as the frame image.
*** \param frame_time The amount of millseconds to display the frame.
*** \return True on success, false on failure.
***
*** The frame argument should have at least one element prepared. Passing a StillImage
*** that does not contain any image data will result in failure for this call.
**/
bool AddFrame(const StillImage& frame, uint32 frame_time);
//! \name Class Member Access Functions
//@{
//! \brief Returns the number of frames in this animation
uint32 GetNumFrames() const
{ return _frames.size(); }
//! \brief Retuns a pointer to the StillImage representing the current frame
StillImage* GetCurrentFrame() const
{ return const_cast(&(_frames[_frame_index].image)); }
//! \brief Returns the index number of the current frame in the animation.
uint32 GetCurrentFrameIndex() const
{ return _frame_index; }
/** \brief Returns a pointer to the StillImage at a specified frame.
*** \param index index of the frame you want
*** \return A pointer to the image at that index, or NULL if the index parameter was invalid
***
*** Using this function is dangerous since it provides direct access to an image frame.
*** If you find yourself in constant need of using this function, think twice about
*** what you are doing.
**/
StillImage* GetFrame(uint32 index) const
{ if (index >= _frames.size()) return NULL; else return const_cast(&(_frames[index].image)); }
//! \brief Returns the number of milliseconds that the current frame has been shown for.
uint32 GetTimeProgress() const
{ return _frame_counter; }
/** \brief Returns the percentage of timing complete for the current frame being shown.
*** \return A float from 0.0f to 1.0f, indicate how much of its allotted time this frame has spent
*** \note The divide by 0.0f case is not checked for here, so this function could potentially throw
*** a divide by zero exception at run-time.
**/
float GetPercentProgress() const
{ return static_cast(_frame_counter) / _frames[_frame_index].frame_time; }
//! \brief Returns true if the loops have finished, false otherwise
bool IsLoopsFinished() const
{ return _loops_finished; }
/** \brief Sets all animation frames to be a certain width
*** \param width Width to set each frame (in coordinate system units)
**/
void SetWidth(float width);
/** \brief Sets all animation frames to be a certain height
*** \param height Height to set each frame (in coordinate system units)
**/
void SetHeight(float height);
/** \brief Sets all animation frames to be a certain width and height
*** \param width Width to set each frame (in coordinate system units)
*** \param height Height to set each frame (in coordinate system units)
**/
void SetDimensions(float width, float height);
void SetUVCoordinates(float u1, float v1, float u2, float v2)
{}
/** \brief Sets the static member for all animation frame images
*** \param is_static Flag indicating whether the image will be static or not.
*** \note If the frames are already loaded, it doesn't bother to try to unload them
*** and then reload them again statically.
**/
void SetStatic(bool is_static)
{ _is_static = is_static; }
/** \brief sets All frames to be of a certain color (all vertices are set to the same color)
*** \param color Color of the 4 vertices
**/
void SetColor(const Color &color);
/** \brief sets all frames to have the specified vertex colors
*** \param tl The top left vertex color
*** \param tr The top right vertex color
*** \param bl The bottom left vertex color
*** \param br The bottom right vertex color
**/
void SetVertexColors(const Color &tl, const Color &tr, const Color &bl, const Color &br);
/** \brief Sets the current frame index of the animation.
*** \param index The index of the frame to access
*** \note Passing in an invalid value for the index will not change the current frame
**/
void SetFrameIndex(const uint32 index)
{ if (index > _frames.size()) return; _frame_index = index; _frame_counter = 0; }
/** \brief Sets the number of milliseconds that the current frame has been shown for.
*** \param time The time to set the frame counter
*** \note This does not set the frame timer for the current frame
**/
void SetTimeProgress(uint32 time)
{ _frame_counter = time; }
/** \brief Set the number of loops for the animation.
*** A value less than zero indicates to loop forever. Zero indicates do not loop: just run the
*** animation from beginning to end and stop.
*** \param loops Number of loops for the animation
**/
void SetNumberLoops(int32 loops)
{ _number_loops = loops; if (_loop_counter >= _number_loops && _number_loops >= 0) _loops_finished = true; }
/** \brief Set the current number of loops that the animation has completed.
*** \param loops The urrent loop count
**/
void SetLoopCounter(int32 loops)
{ _loop_counter = loops; if (_loop_counter >= _number_loops && _number_loops >= 0) _loops_finished = true; }
/** \brief Effectively stops the animation in its track if this member is set to true.
*** \param loops True to stop the looping process. Setting it to false will restart the loop counter
**/
void SetLoopsFinished(bool loops)
{ _loops_finished = loops; if (loops == false) _loop_counter = 0; }
//@}
private:
//! \brief The index of which animation frame to display.
uint32 _frame_index;
//! \brief Counts how long each frame has been shown for.
uint32 _frame_counter;
/** \brief The number of times to loop the animation frames.
*** A negative value indicates to loop forever, which is the default.
**/
int32 _number_loops;
//! \brief Counts the number of loops remaining for the animation.
int32 _loop_counter;
/** \brief Set to true when the loop counter has expired.
*** This member will remain eternally false if the looping is set to infinite mode.
**/
bool _loops_finished;
//! \brief The vector of animation frames (contains both images and timing)
std::vector _frames;
}; // class AnimatedImage : public ImageDescriptor
/** ****************************************************************************
*** \brief Represents a composite image created from multiple image elements
***
*** A composite image is created by taking multiple StillImage objects and
*** "stitching" them together to represent a singular image object. Each image
*** element has x and y offsets that determine where the image is located in
*** the composite image. A good example usage of this class can be found in the
*** MenuWindow class, where a window is represented as a composite image and
*** created by attaching multiple border images together to create the window.
***
*** \note Because this class references other StillImage objects, it's _texture
*** member is always NULL, since the class itself does not make use of any
*** textures.
*** ***************************************************************************/
class CompositeImage : public ImageDescriptor {
public:
CompositeImage()
{}
~CompositeImage()
{}
//! \brief Removes all image elements held by this class
void Clear();
/** \brief Draws the image to the display buffer
*** The location and orientation of the drawn image is dependent upon the current cursor position
*** and context (draw flags) set in the GameVideo class.
**/
void Draw() const;
/** \brief Draws a color modulated version of the image to the display buffer
*** \param draw_color The color to modulate the image by
**/
void Draw(const Color& draw_color) const;
/** \brief Sets the static member for all future element images
*** \param is_static Flag indicating whether the image will be static or not
*** \note If the elements are already loaded, it doesn't bother to try to unload them
*** and then reload them again statically.
**/
void SetStatic(bool is_static)
{ _is_static = is_static; }
/** \brief Sets the image's width, expressed as coordinate system units
*** \param width The desired width of the image
**/
void SetWidth(float width);
/** \brief Sets the image's height, expressed as coordinate system units
*** \param height The desired height of the image
**/
void SetHeight(float height);
/** \brief Sets the image's dimensions, expressed as coordinate system units
*** \param width The desired width of the image
*** \param height The desired height of the image
**/
void SetDimensions(float width, float height)
{ SetWidth(width); SetHeight(height); }
void EnableGrayScale()
{}
void DisableGrayScale()
{}
void SetUVCoordinates(float u1, float v1, float u2, float v2)
{}
/** \brief Sets the image's four vertices to a single color
*** \param color The desired color of all image vertices
**/
void SetColor(const Color& color);
/** \brief Sets the image's vertex colors
*** \param tl The top left vertex color
*** \param tr The top right vertex color
*** \param bl The bottom left vertex color
*** \param br The bottom right vertex color
**/
void SetVertexColors(const Color& tl, const Color& tr, const Color& bl, const Color& br);
/** \brief Adds a new image element to the composite image
*** \param img The image to add to the composite image.
*** \param x_offset The x offset of the composite image.
*** \param y_offset The y offset of the composite image.
*** \param u1 The upper-left u coordinate for the image. The default is 0.0f.
*** \param v1 The upper-left v coordinate for the image. The default is 0.0f.
*** \param u2 The lower-right u coordinate for the image. The default is 1.0f.
*** \param v2 The lower-right v coordinate for the image. The default is 1.0f.
***
*** Starting with a newly created StillImage, call AddImage(), for all of the images you wish
*** to add, along with the x and y offsets that they should be positioned at. The u1, v1, u2, v2
*** coordinates tell which portion of the image to use (usually 0.0f, 0.0f, 1.0f, 1.0f)
**/
void AddImage(const StillImage& img, float x_offset, float y_offset, float u1 = 0.0f, float v1 = 0.0f,
float u2 = 1.0f, float v2 = 1.0f);
/** \brief Creates a single composite image from a 2D array of like-sized images
*** \param tiles A 1D vector of StillImage objects that will be used to construct the composite image
*** \param indeces A 2D vector in row-column order (e.g. indices[y][x]) with indeces into the tiles vector
***
*** This method is useful for constructing variable-sized objects within a map from multiple smaller tile
*** images. The StillImage object that this method is invoked upon will be cleared prior to constructing
*** the composite image.
***
*** \note This should be obvious, but don't include "this" StillImage object inside the tiles argument vector
*** \note All StillImages in the tiles vector should have the same dimensions
*** \note Every vector row in indeces must be the same size
*** \note Every index element (indices[y][x]) should range from 0 to tiles.size() - 1
**/
// void ConstructCompositeImage(const std::vector& tiles, const std::vector >& indeces);
private:
//! \brief A container for each element in the composite image
std::vector _elements;
}; // class CompositeImage : public ImageDescriptor
} // namespace hoa_video
#endif // __IMAGE_HEADER__