トップページ > 過去ログ > 記事閲覧
SetDrawBlendModeで透明処理ができない?
名前:orca 日時: 2008/05/06 13:22

はじめまして、よろしくお願いします。 アルファ付きの画像を読み込んで表示するプログラムで、SetDrawBlendModeにDX_BLENDMODE_MULやDX_BLENDMODE_INVDESTCOLORを指定すると 本来透明になる部分が黒く表示されてしまいます。 DX_BLENDMODE_ADDやDX_BLENDMODE_ALPHAだと正常に透明部分が処理されるので、これはバグなんでしょうか?

Page: 1 |

Re: SetDrawBlendModeで透明処理ができない? ( No.1 )
名前:管理人 日時:2008/05/06 23:42

すいません、仕様となります。 DX_BLENDMODE_MUL は描画先画像の色に描画画像の色を乗算するため、描画画像のアルファ値は使用されません。 DX_BLENDMODE_INVDESTCOLOR は描画画像の色に描画先画像の色を反転したものを乗算する為、やはり描画画像のアルファ値は使用されません。 計算自体は以下のようになっています。 描画元のアルファ値は ALPHA,ADD,SUB にのみ使用されています。 DX_BLENDMODE_NOBLEND 描画後の色 = Src * 1.0 + Dest * 0.0 DX_BLENDMODE_ALPHA 描画後の色 = Src * SrcAlpha + Dest * InvSrcAlpha DX_BLENDMODE_ADD 描画後の色 = Src * SrcAlpha + Dest * 1.0 DX_BLENDMODE_SUB 描画後の色 = -Src * SrcAlpha + Dest * 1.0 DX_BLENDMODE_MUL 描画後の色 = Src * 0.0 + Dest * Src DX_BLENDMODE_DESTCOLOR 描画後の色 = Src * 0.0 + Dest * 1.0 DX_BLENDMODE_INVDESTCOLOR 描画後の色 = Src * InvDestColor + Dest * 0.0 Src :描画元のRGB値(0〜255 で 0.0〜1.0 と考える) SrcAlpha :描画元のアルファ値(0〜255 で 0.0〜1.0 と考える) InvSrcAlpha :描画元のアルファ値を反転( 1.0 - SrcAlpha )したもの Dest :描画先のRGB値(0〜255 で 0.0〜1.0 と考える) InvDestColor:描画先のRGB値を反転( 1.0 - Dest )したもの(RGB各要素単位) 因みに DX_BLENDMODE_SUB は計算的には上記の通りですが、DirectX7 の Direct3D には 直に減算する機能が無いので、実際は3回の計算を行って減算を実現しています。
Re: SetDrawBlendModeで透明処理ができない? ( No.2 )
名前:orca 日時:2008/05/07 14:00

お返事ありがとうございます。 DirectXの仕様だったんですね。 合成処理について良く理解していなかったようですみません。 とりあえず、以下のような方法でやりたいことはできました。 描画可能なグラフィックを作成して白で塗りつぶす。 そこに、描画したい画像を描画する。 描画先を元に戻して作成した画像を使って乗算合成する。 ところで、ググって少し調べてみたんですが、上記のような処理はテクスチャステージで事前に処理しておくこともできるんでしょうか? 参考URL ttp://d.hatena.ne.jp/Ko-Ta/20080219 可能ならば不透明度を考慮した乗算処理としてDXライブラリに実装して頂けるとありがたいです。 それと、できれば描画元を反転するINVSRCCOLORのような合成も欲しいです。
Re: SetDrawBlendModeで透明処理ができない? ( No.3 )
名前:管理人 日時:2008/05/11 00:10

仰られたような処理は、描画したい画像の透過部分を最初から白にしておくことで 描画可能なグラフィックに一度描くことなく実現可能だと思います。 透明度を考慮した乗算処理は描画先の画像を別の画像に退避しておき、普通に 乗算描画した結果と退避した画像を描画したい画像のアルファ値でブレンドする、 ということが必要になる為、テクスチャステージでは実現することは出来ません。 描画元を反転する機能は実現可能ですが、乗算と同じく透明度を考慮した描画は できませんがそれでも宜しいでしょうか?
Re: SetDrawBlendModeで透明処理ができない? ( No.4 )
名前:orca 日時:2008/05/13 02:42

透明度を考慮した乗算はテクスチャステージで実現できないとのことですが、 DX9SDKで試してみたところ以下のようなコードで出来ました。 D3DCOLOR Factor = 0xFFFFFFFF; // 白 g_pd3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR, Factor ); // 定数テクスチャを設定 g_pd3dDevice->SetTexture( 0, g_pTexture ); g_pd3dDevice->SetTexture( 1, NULL ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); // テクスチャステージ1で白テクスチャと合成 g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT); g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR); // 定数テクスチャを使用 g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA); g_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT); g_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE ); // 乗算ブレンド g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR); g_pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); DX9SDK付属のチュートリアルの5番で確認しました。 自分でDXライブラリに実装してみようと思ったのですが、ちょっと構造が複雑で良く分からないでいます。 やはり不可能と仰られたのはDXライブラリで使用しているDirectXのバージョンによるものなのでしょうか?
Re: SetDrawBlendModeで透明処理ができない? ( No.5 )
名前:Will 日時:2008/05/13 09:42

DXライブライリは2D特化ライブラリなのでDirectX7がベースです。
Re: SetDrawBlendModeで透明処理ができない? ( No.6 )
名前:管理人 日時:2008/05/18 12:42

透明な部分ほど白に近づける。 なるほど!確かにそうすることで乗算の効果を抑えることができますね。 アルファブレンドの概念にとらわれていました。申し訳ありません。m(_ _;m 早速実装してみましたので、宜しければお使いください。 http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe //VC用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe //BCC用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい) 今回追加したブレンドモードは以下の二つです。 (乗算ブレンドは今までの仕様で実装されている方もいらっしゃると 思いますので、互換性を考えて新しくモードを追加するという形にしました) DX_BLENDMODE_MULA : 不透明度考慮付き乗算描画 DX_BLENDMODE_INVSRC : 描画元反転描画 どちらも SetDrawBlendMode の第二引数である Pal はブレンド値となっています。 ( 0に近くなるほど透明で、255に近づくほど不透明 ) DX_BLENDMODE_INVSRC については No.3 の書き込みで透明度を考慮することは できませんと書きましたが、テクスチャステージの機能を見直したところ 可能であることがわかりました。こちらも失礼致しました。m(_ _;m > やはり不可能と仰られたのはDXライブラリで使用しているDirectXのバージョンによるものなのでしょうか?  思い付かなかっただけでした。orz
Re: SetDrawBlendModeで透明処理ができない? ( No.7 )
名前:orca 日時:2008/05/18 20:33

>管理人様 お忙しい所対応して頂きありがとうございました。 おかげで目的の事ができました。 殆どDirectXの知識0でしたが2,3日頑張って調べた甲斐がありましたw テクスチャステージで事前に処理する事で色々な事ができるみたいですね。 今回、自分で調べた事で色々勉強になりました。 描画元反転も不透明度処理されているのを確認しました。 が、描画先反転と整合性をとる為に DX_BLENDMODE_INVDESTCOLOR // 不透明度無し DX_BLENDMODE_INVSRC // 不透明度無し DX_BLENDMODE_INVDESTCOLORA // 不透明度あり DX_BLENDMODE_INVSRCA // 不透明度あり のような形で分けたら如何かなと思いました。 それと、差し支えなければ今回修正された部分のみソースも公開して頂けるとありがたいです。 修正前との差分を見れば、多分自分でも実装できるようになると思いますので。
Re: SetDrawBlendModeで透明処理ができない? ( No.8 )
名前:orca 日時:2008/05/23 12:30

なんとか自分で実装することに成功しました! 減算と同じ要領で別テーブル用意すればできそうだなって所までは分かっていたのですが、何故かうまくいかない。。 そこで、デバッグしながら値を一つ一つ調べていくとアルファオペレーションとカラーオペレーションの値が逆になってましたw もっと早くに気付けていたら・・・orz 実装は、上記の通りテクスチャファクタを定数テクスチャとして使用してるんですが、この値はブレンド画像の アルファブレンディングに使用されているようなので、この値を使用するのはあまり宜しくないでしょうか? DX9だとD3DTSS_CONSTANTなんてのがあるみたいですが、DX7だとないようですね。。 すみません、まだソース全部理解できていないのでおかしな事言ってるかも知れません、 宜しければ管理人様の実装方法など解説頂けると幸いです。
Re: SetDrawBlendModeで透明処理ができない? ( No.9 )
名前:管理人 日時:2008/05/26 00:21

ご返答が遅くなり申し訳ありません。 最新版のソースは DxLibVCTest.exe 等をアップするときに一緒に、 必ず以下のパスにアップしていますので、もしご興味がありましたら ご覧になってみて下さい。m(_ _)m http://homepage2.nifty.com/natupaji/DxLib/DxLibMakeTest.exe //ソース 実装方法につきましては、Dx3D.cpp 内のテーブル( __TexStageStateTable )の 次元数を増やすことで対応しています。 ブレンド画像を使用した場合は定数値が足りなくなるので今のところ アルファブレンド処理付き乗算描画とソース画像反転描画ではブレンド画像を 使用することは出来ません。(D3DTSS_CONSTANT 良いですねぇ・・・)  一応DX7でも真っ白の1x1のテクスチャをセットして定数テクスチャの様に 使用することで D3DTSS_CONSTANT の代用はできるのですが、この場合頂点 データのUV座標も増やさなければならないので大改造が必要です。なので 今のところ手を付けていません。(汗) DX_BLENDMODE_INVDESTCOLORA 等のご意見ありがとうございます。 DX_BLENDMODE_INVDESTCOLOR 等の設定は非公開だったのであまり 考えていませんでしたが、公開するのも良いかもしれませんね・・・
Re: SetDrawBlendModeで透明処理ができない? ( No.10 )
名前:orca 日時:2008/05/27 00:15

実装方法の解説して頂きありがとうございます。 ソースもRC版のような形で同時にアップされてたんですね知らなかったです。早速落して読ませて頂きました。 ブレンド画像はやはり同時にはできないんですね… でも、同時に使う場面はあまりなさそうなので特に問題はないかもしれないですね D3DTSS_CONSTANT の代用はちょっと大変そうですね; あれから、自分で色々なブレンド方法を実装してみたりしましたが、不透明度を考慮するとなるとなかなか難しいものです そもそも、画像の合成処理についてまだ良く理解してない部分があるからかもしれませんが・・・ この辺はDXライブラリとは別の問題なので自分で頑張ってみようと思います。 管理人様には色々教えて頂いてありがとうございました。 また、ライブラリの事で分からない事があれば質問させて頂くかと思います。
Re: SetDrawBlendModeで透明処理ができない? ( No.11 )
名前:憂煉 日時:2008/10/23 21:00

DirectX7の環境を持っていないので実際に利用できるかわからないのですが… DirectX9だとテクスチャステージで色の反転ができるのでDX_BLENDMODE_INVSRCをDX_BLENDMODE_ALPHAに統合できないかなと思いました。 lpD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT); //このようにD3DTA_COMPLEMENTを追加する。 それと、テクスチャステージは古いチップセットだと0番と1番までしか使えない(Intelの810系とか)のでその場合のエラー出力なんかがあるといいと思います。
ちょっと追加説明 ( No.12 )
名前:憂煉 日時:2008/10/23 21:35

えーと、微妙に説明不足だった気がしたのですが記事メンテパスを入れ忘れたので連投します。 D3DTA_COMPLEMENTを使うとテクスチャステージの項自体を反転する処理になるので、反転に一つ費やしていたテクスチャステージが不要になり、後の演算もAlphaの場合と同様になるので楽かなと 古いチップセットがどうの〜 のソースはこちらです。DirectX8〜9のデータなのですが、たぶん同じだと思います。 ttp://www.netsphere.jp/dxinfo/
Re: SetDrawBlendModeで透明処理ができない? ( No.13 )
名前:管理人 日時:2008/10/25 17:17

ご情報ありがとうございます D3DTA_COMPLEMENT ! こんな便利なものがあったんですね、DirectX7 でも使用可能だったので 早速組み込みました ( ログ出力も追加しました ) 憂煉さんには必要ないかもしれませんが、一応こちらにアップしました http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe //VC用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe //BCC用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)

Page: 1 |