Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# Sprite.cpp

Go to the documentation of this file.

    00001 //------------------------------------------------------------------------------
    00002 // Lamp : Open source game middleware
    00003 // Copyright (C) 2004  Junpei Ohtani ( Email : junpee@users.sourceforge.jp )
    00004 //
    00005 // This library is free software; you can redistribute it and/or
    00006 // modify it under the terms of the GNU Lesser General Public
    00007 // License as published by the Free Software Foundation; either
    00008 // version 2.1 of the License, or (at your option) any later version.
    00009 //
    00010 // This library is distributed in the hope that it will be useful,
    00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013 // Lesser General Public License for more details.
    00014 //
    00015 // You should have received a copy of the GNU Lesser General Public
    00016 // License along with this library; if not, write to the Free Software
    00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00018 //------------------------------------------------------------------------------
    00019
    00020 /** @file
    00021  * スプライト実装
    00022  * @author Junpee
    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 == &copy){ 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     // UVの算出
    00100     TexCoord2 minUV(imageRectangle_.x, imageRectangle_.y);
    00101     TexCoord2 maxUV(imageRectangle_.x + imageRectangle_.width,
    00102         imageRectangle_.y + imageRectangle_.height);
    00103
    00104     // 半ピクセルずらし
    00105     // 半ピクセルを出すにはUV範囲、スプライトサイズが必要
    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     // Xアライン
    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     // Yアライン
    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 } // End of namespace Lamp
    00220 //------------------------------------------------------------------------------