CSurfaceInfo




CSurfaceInfoは、サーフェースの情報を示すための構造体です。
サーフェースのサイズ、メモリへのポインタ、ピッチ(次のラインまでのバイト数)、種類が格納されています。

※ yaneSDK2ndのCPlaneInfoに対応するものです。

このCSurfaceInfo自体が、Bltter(転送系関数)と、Effecter(エフェクト系関数)、Morpher(モーフィング転送系関数)を持っています。

list-1
    LRESULT GeneralBlt(EBltType type,const CSurfaceInfo*pSrc,const CBltInfo* pInfo,DWORD*pAdditionalParameter=NULL);
    LRESULT GeneralEffect(EEffectType type,LPCRECT prc=NULL,DWORD*pAdditionalParameter=NULL);
    LRESULT GeneralMorph(EBltType type,const CSurfaceInfo*pSrc,const CMorphInfo* pInfo,DWORD*pAdditionalParameter=NULL);


CSurfaceInfoに対して、これらのメソッドを呼び出した場合は、ISurfaceLockerによって、サーフェースをLockして、転送を開始します。メモリを直接いじるため、ハードウェアのアクセラレーションには頼れませんが、転送はすべてfunctorを利用して書かれているのでそれなりに速いです。

枠-1 注意
    デバッグモードでビルドすると、functorがinline展開されないため、
    関数呼び出しのオーバーヘッドがあって、ずいぶん遅いです。
    リリースモードを用い、かつinline展開するオプションをつけて
    コンパイルすることを忘れないでください。
    (ディフォルトでついているはずですが.)


ただ、これらのBltterは、汎用的すぎて使いにくい部分があるので、ISurfaceのほうには、yaneSDK2ndのCFastPlaneに有ったような転送関数も実装してあります。GeneralBlt等の使いかたについては、これらの関数の実装を見ると良いでしょう。

枠-2 転送系関数(一例)
    /// 抜き色無し転送
    LRESULT BltFast(const ISurface*pSrc,int x=0,int y=0,LPCSIZE pDstSize=NULL,
        LPCRECT pSrcRect=NULL,LPCRECT   pDstClip=NULL,int nBasePoint=0);

    /// 加色合成(抜き色なし)
    /// パラメータの意味は、Bltと同じ
    LRESULT AddColorBltFast(const ISurface*pSrc,int x=0,int y=0,LPCSIZE pDstSize=NULL,
        LPCRECT  pSrcRect=NULL,LPCRECT  pDstClip=NULL,int nBasePoint=0);

    /// 加色合成(抜き色あり)
    /// パラメータの意味は、Bltと同じ
    LRESULT AddColorBlt(const ISurface*pSrc,int x=0,int y=0,LPCSIZE pDstSize=NULL,
        LPCRECT pSrcRect=NULL,LPCRECT   pDstClip=NULL,int nBasePoint=0);

    /// 減色合成(抜き色なし)
    /// パラメータの意味は、Bltと同じ
    LRESULT SubColorBltFast(const ISurface*pSrc,int x=0,int y=0,LPCSIZE pDstSize=NULL,
        LPCRECT pSrcRect=NULL,LPCRECT   pDstClip=NULL,int nBasePoint=0);

    /// 減色合成(抜き色あり)
    /// パラメータの意味は、Bltと同じ
    LRESULT SubColorBlt(const ISurface*pSrc,int x=0,int y=0,LPCSIZE pDstSize=NULL,
        LPCRECT  pSrcRect=NULL,LPCRECT  pDstClip=NULL,int nBasePoint=0);


また、Bltter系の関数の命名規則は、以下のものに従います。

list-2
        Bltterの命名規則:
            (この規則は、CSurfaceInfo::EBltTypeの命名規則にも共通)

        例)
            MorphBltAlphaFastFade
            (1)   (2) (3) (4) (5)

        例)
            MorphBltAlphaFastFade
            (1)   (2) (3) (4) (5)

            BlendConstBltFast
            (6)  (7)  (1) (4)

            (1)...Morph...モーフィング系であることを意味する
            (2)...Blt.....転送関数であることを意味する
            (3)...Alpha...転送元がalphaサーフェースであることを意味する
                    これがついていない場合、alphaサーフェースを
                    サポートしているかどうかは、そのメソッドによる
            (4)...Fast....抜き色は無視されることを意味する
            (5)...Fade....転送のときにフェード率を指定できることを意味する
                フェード率(減衰率)は、BYTE(0-255)で指定し、
                255を指定すれば100%(減衰無し),0を指定すれば0%
                (このとき、転送元は黒として扱われる)
            (6)...Blend...ブレンド系転送であることを意味する。
                    転送先のピクセルとブレンドする(混ぜ合わせる)
                    たとえば64(=25%なぜなら255×25%=64)を指定すれば、
                    転送元25%と転送先75%の比率でブレンドされる。
            (7)...Const...ブレンドの比率が固定であることを意味する
                    ブレンド比率は、BYTE(0-255)をふたつとる。
                    そのふたつをα1,α2とすれば、
                    転送先 = 転送元×α1+転送先×α2
                となる。ただし、α1+α2≦255でなくてはならない


また、色はISurfaceRGBという構造体で指定します。これは、実際は

枠-3
    /// ISurfaceRGBはDWORDっちゅーことで
    typedef DWORD ISurfaceRGB;


とtypedefされているだけです。上位から、A,R,G,Bの順に8ビットずつになっています。すなわち、ARGB8888です。

ISurfaceのメソッドで

枠-4
    static inline ISurfaceRGB makeRGB(DWORD r,DWORD g,DWORD b,DWORD a=0);

というのがあるので、色の生成には、これを用いると良いでしょう。

CSurfaceInfoの面白いところは、転送元、転送先のCSurfaceInfo*さえあれば、さまざまな転送が出来る、ということです。ユーザー側で独自に用意したサーフェースであっても、CSurfaceInfoの初期化メソッド

枠-5
    void    Init(void* lpSurfacePtr,LONG lPitch,const SIZE &size
        ,int nSurfaceType = 0) {
        m_lpSurface = lpSurfacePtr; m_lPitch = lPitch; m_size = size,
        m_bInit = true, m_nSurfaceType = nSurfaceType;
    }
    /**
        ここで与えるものは、以下のもの。(あとでも個別に設定できる)
        さらに、lock〜unlockに際して、さらに処理が必要ならば
        SetLockerで、それを設定すること。
    
        lpSurfacePtr    :   サーフェースのイメージへのポインタ
            サーフェースのイメージの左上の座標のメモリアドレス
        lPitch          :   1ラインのバイト数
        size            :   Surfaceのサイズ
        nSurfaceType    :   サーフェースの種類

        0:  未調査(OnChangeSurfaceがまだ呼び出されていない)
        1:  不明(以下の以外)

        //  通常のサーフェース
        2:  8bpp
        3:  16(RGB565)
        4:  16(RGB555)
        5:  24(RGB888)
        6:  24(BGR888)
        7:  32(XRGB8888)
        8:  32(XBGR8888)

        //  αサーフェース
        10: 16+a4(ARGB4565)
        11: 16+a4(ARGB4555)
        12: 32(ARGB8888)
        13: 32(ABGR8888)
    */


さえ呼び出せば、立派なCSurfaceInfoであり、CSurfaceのBltter等を利用できるようになるということです。

通例、ISurfaceを用いれば事足りるため、実際にCSurfaceInfoを用いる機会は少ないかも知れませんが、異なるサーフェースクラス間(例:CFastPlaneとCDIBitmap)で転送したい場合など、このCSurfaceInfoを取得して転送することになるので、知っておいて損は無いでしょう。