ウィモバの日々

Windowsをモバイルする…それがウィモバ(仮)。手のひら端末が好きです

C#でのGDI描画実験。TransparentBltの透過色は?

いっせきもどき(仮)を開発している中での気づきのメモ。

相変わらず互換性を気にするあまり、C#の標準描画機能であるGDI+で描画を行っていたんだけども・・・
開発用のWinXPPen4 3.4GHzだと60FPSでも問題なく表示されていたんだけど、AtomEeePCデュアルコアの2GHzくらいのPCで実行してみたところコマ落ちしまくりで見るに耐えない事になってしまった。

30Fpsに落としてみたらそれなりに表示できていたんだけども、せっかくなので色々調べてみたらC#で使っているGDI+はGDIより遅いという事が分かった。

という事で下記のサイト様を参考に、自分でも描画ベンチを作って確かめてみた。
http://blog.livedoor.jp/moepk/archives/675684.html
http://blog.livedoor.jp/moepk/archives/676205.html

■PC環境:WinXP 3.4GHz メモリ2GB
ビットマップ画像(320x240)をPaint()イベント内で1000回描画
A:DrawImage関数(C#標準関数)
B:BitBlt関数(Win32API)・ハンドルの取得〜解放を毎回行う
C:Bitblt関数(Win32API)・ハンドルは保持したまま描画だけを行う
D:TransparentBlt関数(Win32API)・Cと同じく描画だけを行う

上記の設定で複数回繰り返した結果、一番多い値です。
A:812ms
B:1766ms
C:234ms
D:328ms

ということで、Win32APIを直叩きしたBitblt(C)のほうがDrawImage(A)よりも優秀だと判明した。
ただBを見る限り、ハンドルは保持したままでないと、毎回取得&解放してるとかえって遅くなる模様。
そしてGDIとGDI+を同時には使えないみたいので、描画部分に関してはもう全部API直叩きでやっちゃおうかな!というノリに。

透過色を設定して描画できるTransparentBltもなかなかのスコアなので
そのまま使えそうかな、と思ったんだけど、透過色を試していたら
黒色しか設定できない?ような不具合?らしきものが・・・
透過色を常に黒にしていれば問題なさそうだけども。
これについてはまた調べてみようと思う。


■2012/1/13追記
TransparentBltについては、透過色の設定の仕方が悪かっただけみたい。
僕の頭が不具合だった><
GDI+のBitmap型インスタンスからGetPixelでColorを取得して数値型に変換〜というやり方でやってたんだけども、それでは駄目だった。
ビットマップから取得したGraphicsを、Win32APIでGetHdcしたデバイスコンテキストをWin32APIのGetPixelして取得した色を透過色にしたら上手くいったよ!
もう描画は全部Win32APIでするしかねぇ!


せっかくなのでベンチに使ったソフトを置いておく。
http://island.geocities.jp/flcl_ride_on_shooting_star/soft/CSharpDrawBench.zip