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