yaneSDK3rdの拡張
自分は、やねさんの公開しているライブラリ、yaneSDK3rdを使ってゲームを作っています。
しかし、このライブラリだけでは足りない機能とかもあるので、自分の場合は、yaneSDK3rdに依存した自分のライブラリを作って、自分のゲームを、その自分のライブラリに依存させて作ります。
そうすればyaneSDK3rdを使いつつ、欲しい機能がある場合、自分のライブラリに追加すれば、自分の思うままにプログラムが組めます。
で、yaneSDK3rdのISurfaceには、四角形描画をする、JAVAで言うところの、drawRectのような関数がないことに気づいたんですよ。
ということで、自分のライブラリにdrawRectを追加することにしたのですが、これがなかなかしんどかったです。
プログラムの量が多かったからではなくて、yaneSDK3rdの描画部分がなかなか理解できなかったからです(;´Д`)
そもそも、yaneSDK3rdの描画部分は、(自分的には)かなりでかいです。
というのも、画像の種類(RGB888とかBGR565とか)を意識しなくても組めるようにするために、全ての組み合わせの描画について定義しなくてはならなくなってしまったからです(それでもfunctorを使ってかなり小さくはなっていると思いますが……)。
つまり、自分がこの描画部分を拡張しようと思うのであれば、これらを全て理解した上で、全ての組み合わせに対しての描画を定義しないといけないのです。
まあ、今回は、drawRectというルーチンで、しかも、使用するサーフェスは、転送先のサーフェスだけなので、組み合わせは(今のところ)10種類だけです。
で、あとは、メンバ関数テンプレートを使用して、1つの転送ルーチンで解決します。
class CYaneDrawHelper{ public: static LRESULT drawRect(ISurface* pDst, int x, int y, int w, int h, int c){ CSurfaceInfo* pInfo = pDst->GetSurfaceInfo(); CFastPlaneRGB888 color; color.SetRGB((DWORD)(c&0x00ffffff)); switch(pInfo->GetSurfaceType()){ case 3: //RGB565 return innerDrawRect(CFastPlaneRGB565(), pInfo, x, y, w, h, color); case 4: //RGB555 return innerDrawRect(CFastPlaneRGB555(), pInfo, x, y, w, h, color); case 5: //RGB888 return innerDrawRect(CFastPlaneRGB888(), pInfo, x, y, w, h, color); //以下同じように書いていく } } private: template<class DstClass> static LRESULT innerDrawRect(DstClass dstType, CSurfaceInfo* pInfo, int x, int y, int w, int h CFastPlaneRGB888 color){ //ここにdrawRectの転送ルーチンを書いていく } };
第一引数で、テンプレートを実体化させてやって、そこに転送ルーチンを書いています。
しかも、RGB888→XRGB8888への変換子とかがきちんと定義されているので、同じルーチンでも正常に動作します。
普通に考えると、10種類のinnerDrawRectが必要なはずなのに、これだけで全ての組み合わせの転送ルーチンが出来るのですから、yaneSDK3rdってやっぱり(・∀・)イイ!!ですね。
……そういえば、ふと思ったのですが、メンバ関数テンプレートって、
innerDrawRect<CFastPlaneRGB565>(pInfo, x, y, w, h, color);
なんでこうやって使えないんですかね?
こうすれば、メンバ関数を実体化するためだけにあるダミー変数を、わざわざ用意しなくてもすむんですけどねぇ……。