00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Graphics2D/Sprite/Sprite.h"
00027 #include "Graphics2D/Renderer/SpriteRenderState.h"
00028 #include "Graphics2D/Sprite/SpritePictureRGBA8.h"
00029 #include "Graphics2D/Sprite/SpritePictureRGB8.h"
00030 #include "Core/InputOutput/FilePath.h"
00031 #include "Core/Codec/Tga/TargaLoader.h"
00032
00033 namespace Lamp{
00034
00035
00036
00037
00038
00039 Sprite::Sprite() : SpriteRequest(), picture_(NULL),
00040 rectangle_(RectangleF::zero), imageRectangle_(RectangleF::unit),
00041 align_(alignNone), fit_(fitNone), enabled_(true){
00042 }
00043
00044
00045 Sprite::Sprite(const Sprite& copy) : SpriteRequest(copy), picture_(NULL),
00046 rectangle_(copy.rectangle_), imageRectangle_(copy.imageRectangle_),
00047 align_(copy.align_), fit_(copy.fit_), enabled_(copy.enabled_){
00048
00049 setPicture(copy.picture_);
00050 }
00051
00052
00053 Sprite& Sprite::operator =(const Sprite& copy){
00054
00055 if(this == ©){ return *this; }
00056
00057 SpriteRequest::operator =(copy);
00058
00059 setPicture(copy.picture_);
00060
00061 rectangle_ = copy.rectangle_;
00062 imageRectangle_ = copy.imageRectangle_;
00063 align_ = copy.align_;
00064 fit_ = copy.fit_;
00065 enabled_ = copy.enabled_;
00066 return *this;
00067 }
00068
00069
00070 Sprite::~Sprite(){
00071
00072 setPicture(NULL);
00073 }
00074
00075
00076
00077
00078 void Sprite::render(SpriteRenderState* renderState){
00079
00080 if(!enabled_){ return; }
00081
00082
00083 RectangleF rectangle(rectangle_);
00084 const DimensionF& renderTargetSize = renderState->getRenderTargetSize();
00085
00086 if(fit_ != fitNone){
00087 rectangle = applyFit(rectangle, renderTargetSize);
00088 }
00089
00090 if(align_ != alignNone){
00091 rectangle = applyAlign(rectangle, renderTargetSize);
00092 }
00093
00094
00095 Point2f minPosition(rectangle.x, rectangle.y);
00096 Point2f maxPosition(rectangle.x + rectangle.width,
00097 rectangle.y + rectangle.height);
00098
00099
00100 TexCoord2 minUV(imageRectangle_.x, imageRectangle_.y);
00101 TexCoord2 maxUV(imageRectangle_.x + imageRectangle_.width,
00102 imageRectangle_.y + imageRectangle_.height);
00103
00104
00105
00106
00107 TexCoord2 halfPixel(
00108 (imageRectangle_.width) * 0.5f / rectangle.width,
00109 (imageRectangle_.height) * 0.5f / rectangle.height);
00110 minUV += halfPixel;
00111 maxUV += halfPixel;
00112
00113
00114 renderState->request(picture_, minPosition, maxPosition, minUV, maxUV);
00115 }
00116
00117
00118 RectangleF Sprite::applyFit(const RectangleF& rectangle,
00119 const DimensionF& renderTargetSize){
00120 RectangleF result(rectangle);
00121 if((fit_ == fitScreen) || (fit_ == fitScreenWidth)){
00122 result.width = renderTargetSize.width;
00123 }
00124 if((fit_ == fitScreen) || (fit_ == fitScreenHeight)){
00125 result.height = renderTargetSize.height;
00126 }
00127
00128 return result;
00129 }
00130
00131
00132 RectangleF Sprite::applyAlign(const RectangleF& rectangle,
00133 const DimensionF& renderTargetSize){
00134 RectangleF result(rectangle);
00135
00136 if((align_ == alignTop) || (align_ == alignCenter) ||
00137 (align_ == alignBottom)){
00138 result.x += (renderTargetSize.width - rectangle.width) * 0.5f;
00139 }else if((align_ == alignTopRight) || (align_ == alignRight) ||
00140 (align_ == alignBottomRight)){
00141 result.x += renderTargetSize.width - rectangle.width;
00142 }
00143
00144
00145 if((align_ == alignLeft) || (align_ == alignCenter) ||
00146 (align_ == alignRight)){
00147 result.y += (renderTargetSize.height - rectangle.height) * 0.5f;
00148 }else if((align_ == alignBottomLeft) || (align_ == alignBottom) ||
00149 (align_ == alignBottomRight)){
00150 result.y += renderTargetSize.height - rectangle.height;
00151 }
00152 return result;
00153 }
00154
00155
00156
00157
00158 bool Sprite::loadPicture(const String& fileName){
00159
00160 SpritePicture* picture;
00161
00162 FilePath filePath(fileName);
00163 if(!filePath.existFile()){ return false; }
00164
00165 String extension = filePath.getExtension();
00166 if(extension == "tga"){
00167 TargaLoader loader(filePath.getPath());
00168 loader.loadHeader();
00169 if(loader.hasAlpha()){
00170 SpritePictureRGBA8* pictureRGBA8 = new SpritePictureRGBA8();
00171 pictureRGBA8->setSize(loader.getSize());
00172 loader.loadImage(pictureRGBA8->getImageBuffer());
00173 picture = pictureRGBA8;
00174 }else{
00175 SpritePictureRGB8* pictureRGB8 = new SpritePictureRGB8();
00176 pictureRGB8->setSize(loader.getSize());
00177 loader.loadImage(pictureRGB8->getImageBuffer());
00178 picture = pictureRGB8;
00179 }
00180 }else{
00181 return false;
00182 }
00183
00184 setPicture(picture);
00185 return true;
00186 }
00187
00188
00189 void Sprite::setPicture(SpritePicture* picture){
00190
00191 if(picture_ != NULL){
00192 if(picture_->removeReference() == 0){ SafeDelete(picture_); }
00193 }
00194
00195 picture_ = picture;
00196 if(picture != NULL){ picture_->addReference(); }
00197 }
00198
00199
00200
00201
00202 void Sprite::setAnimation(const DimensionI& animationDivision,
00203 int animation, const RectangleF& imageRectangle){
00204 int animationCount = animationDivision.width * animationDivision.height;
00205 Assert((animation >= 0) && (animation < animationCount));
00206 int xIndex = animation % animationDivision.width;
00207 int yIndex = animation / animationDivision.width;
00208 float xScale = imageRectangle.width / animationDivision.width;
00209 float yScale = imageRectangle.height / animationDivision.height;
00210
00211 RectangleF result;
00212 result.x = imageRectangle.x + xIndex * xScale;
00213 result.y = imageRectangle.y + yIndex * yScale;
00214 result.width = xScale;
00215 result.height = yScale;
00216 setImageRectangle(result);
00217 }
00218
00219 }
00220