« Flashのレイヤーへの描画 | メイン | アニメーション »

2007年08月30日

グラフィックライブラリ:: 関数オブジェクトと値のバインド

    

ピクセルを処理する関数オブジェクトは、アルファブレンド以外にも多数ある。
テンプレートを使用して、最適化によってインライン展開される恩恵を受けるためには、画像コピーメソッド呼び出し時点で静的に型が決定される必要がある。
この事からブレンド方法を値で指定して画像のコピーを行おうとした場合、素直に実装すると if ~ else、もしくは switch ~ case が多数表れることになってしまう。
そして、そのコードは単純に関数オブジェクトの型が違うだけで、他はまったく同じ事の繰り返しになってしまう。
とりあえずは、switch ~ case で書いたが、出来ればこれを避けたい。

まず思い浮かんだのは、テンプレートメタプログラミング。
テンプレートを使って出来そうな気がする。
Modern C++ Design を読みながら考える。
可能そうだ。
ファクトリーの Create を Copy メソッドに置き換えたようなものを作れば、値と型を関連付けられ、値によって関数オブジェクトの型が静的に決定され、画像のコピーが実行できる。
難点は、ソースコードが読み辛いこと。
この方法でも良かったのだが、もっと手軽な方法の方がいいなぁと考えていて気付いた。
マクロでやればいいんじゃないのかと。
例えば以下のような感じ。

#define VALUE2TYPE_FUNC_CALL( VAL, TYPE ) \
case VAL: \
{ \
  TYPE func(val); \
  image_copy(destBmp, destRect, srcBmp, srcRect, func, mask ); \
  break; \
}

switch( op )
{
  VALUE2TYPE_FUNC_CALL( DT_AlphaBlend, COperationAlphaBlend ) // アルファブレンド - 通常
  VALUE2TYPE_FUNC_CALL( DT_AddBlend, COperationAddBlend ) // 覆い焼き(リニア)
  VALUE2TYPE_FUNC_CALL( DT_SubBlend, COperationSubBlend ) // 焼き込み(リニア)
  VALUE2TYPE_FUNC_CALL( DT_MulBlend, COperationMulBlend ) // 乗算
  VALUE2TYPE_FUNC_CALL( DT_ScreenBlend, COperationScreenBlend ) // スクリーン
  VALUE2TYPE_FUNC_CALL( DT_OverlayBlend, COperationOverlayBlend ) // オーバーレイ
  VALUE2TYPE_FUNC_CALL( DT_HardLightBlend, COperationHardLightBlend ) // ハードライト
  VALUE2TYPE_FUNC_CALL( DT_SoftLightBlend, COperationSoftLightBlend ) // ソフトライト
  VALUE2TYPE_FUNC_CALL( DT_ColorDodgeBlend, COperationColorDodgeBlend ) // 覆い焼きカラー
  VALUE2TYPE_FUNC_CALL( DT_ColorBurnBlend, COperationColorBurnBlend ) // 焼き込みカラー
  VALUE2TYPE_FUNC_CALL( DT_LightenBlend, COperationLightenBlend ) // 比較(明)
  VALUE2TYPE_FUNC_CALL( DT_DarkenBlend, COperationDarkenBlend ) // 比較(暗)
  VALUE2TYPE_FUNC_CALL( DT_DiffBlend, COperationDiffBlend ) // 差の絶対値
  VALUE2TYPE_FUNC_CALL( DT_ExclusionBlend, COperationExclusionBlend ) // 除外
}

テンプレートを駆使するよりは遥かにわかりやすいし、それほど冗長でもない。
型の安全性などの面では劣るかもしれないが、これで十分な気がする。
でも、普通初めにこの方法を思い浮かべるよなぁと思う。
テンプレートにばかり目が行き過ぎていたか。



投稿者 Takenori : 2007年08月30日 15:17




comments powered by Disqus
Total : Today : Yesterday : なかのひと