トップページ > 記事閲覧
SetDrawBlendModeで、画像のアルファ値のみ張り付けなど
名前:たろう 日時: 2023/10/05 00:41

いつもすみません。たろうです MakeScreenで作ったsc(赤で塗りつぶしています)に画像imの透明部分のみを張り付けたいのですが これは可能でしょうか? つまりimの透明部分の形でscの一部を消す用途で使用したいのですが、 imのr,g,b要素は無視してscのr,g,bを残し、もしscに透明部分があった場合は、scとimの両方の透明部分を生かす感じです。 scと同サイズのimを用意してGraphBlendとDX_GRAPH_BLEND_PMA_RGBA_SELECT_MIXやDX_GRAPH_BLEND_PMA_MULTIPLE_A_ONLY を使えば出来るのですが、すごく大きいscに小さなimの透明部分を貼りたい時は、 この方法だと処理にかなりの無駄が発生してしまうと思うので SetDrawBlendModeのモードで可能であれば行いたいのです。(imの不透明部分を透明部分とする逆バージョンもあると・・・) 可能であればで構いません。 ご検討いただけますでしょうかm(__)m #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ) ; DxLib_Init(); SetUsePremulAlphaConvertLoad(1); SetDrawScreen( DX_SCREEN_BACK ) ; int im = LoadGraph("0001.png"); int sc=MakeScreen(400,400,1); while( ProcessMessage() == 0 ) { ClearDrawScreen(); SetDrawScreen(sc); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA,255); DrawBox(0,0,400,400,GetColor(255,0,0),1); //SetDrawBlendMode(ここです,255); DrawGraph(100,0,im,1); SetDrawScreen(DX_SCREEN_BACK); DrawBox(0,0,1000,1000,GetColor(0,0,100),1); DrawGraph(0,0,sc,1); ScreenFlip(); } DxLib_End() ; return 0 ; } よろしくお願いいたしますm(__)m
メンテ

Page: 1 | 2 | 3 |

Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.11 )
名前:よこ 日時:2023/10/12 21:11

こんにちは 今回追加されたDX_BLENDMODE_DST_RGB_SRC_Aは( No.7 )では DX_GRAPH_BLEND_RGBA_SELECT_MIX, DX_RGBA_SELECT_BLEND_R, DX_RGBA_SELECT_BLEND_G, DX_RGBA_SELECT_BLEND_B, DX_RGBA_SELECT_SRC_A と同じ効果とありますが実際は同じではないです これは誤表記で正しくは DX_GRAPH_BLEND_RGBA_SELECT_MIX, DX_RGBA_SELECT_SRC_R, DX_RGBA_SELECT_SRC_G, DX_RGBA_SELECT_SRC_B, DX_RGBA_SELECT_BLEND_A と同じ効果ですか? そして DX_GRAPH_BLEND_PMA_RGBA_SELECT_MIX, DX_RGBA_SELECT_SRC_R, DX_RGBA_SELECT_SRC_G, DX_RGBA_SELECT_SRC_B, DX_RGBA_SELECT_BLEND_A DX_GRAPH_BLEND_PMA_RGBA_SELECT_MIX, DX_RGBA_SELECT_SRC_R, DX_RGBA_SELECT_SRC_G, DX_RGBA_SELECT_SRC_B, DX_RGBA_SELECT_BLEND_INV_A この二つの処理と同じ効果はブレンドモードの仕組みでは実現出来ないということでしょうか?
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.12 )
名前:よこ 日時:2023/10/12 21:17

少し違う話になるので分けました 重ねての質問で文章も長くなりすみません 急ぎではないので空いている時間に見てもらえれば嬉しいです DX_BLENDMODE_INVDESTCOLORについて教えてください 自分はDX_BLENDMODE_INVDESTCOLORをよく理解出来ていないまま使っているのですが SetDrawScreen( makescreen ); ClearDrawScreen(); SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ); DrawGraph( 0, 0, src, TRUE ); SetDrawBlendMode( DX_BLENDMODE_INVDESTCOLOR, 255 ); DrawBox( 0, 0, 256, 256, GetColor( 255, 255, 255 ), TRUE ); DrawRectGraph( 0, 0, 0, 0, 256, 256, blend, TRUE ); SetDrawScreen( DX_SCREEN_BACK ); ( src=ブレンドさせたい画像, blend=ブレンドに使用したい画像 ) 例えば↑のような処理をすると指定範囲内でblendの透明度に応じてsrcの透明度をクリッピングするのは このブレンドモードの使い方として合っているのでしょうか? DX_BLENDMODE_INVDESTCOLORをクリッピングに利用する場合 blendに描画されている透明度0以外のピクセルのRGB値が全て白(255,255,255)だと問題はないのですが そうではない場合srcにblendのRGB値が混ざってしまうため リアルタイムでblendの内容を変更したいケースが出たときは blendのRGB値を白にする処理も挟まないと求めているクリッピングが出来なくなります DX_BLENDMODE_INVDESTCOLORを使用してもblendのRGB値をsrcに混ぜない方法 あるいはblendの透明度0以外のRGB値を強制的に白として扱うといったことはブレンドモードでは出来ないのでしょうか?
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.13 )
名前:管理人 日時:2023/10/14 02:00

> これは誤表記で正しくは > DX_GRAPH_BLEND_RGBA_SELECT_MIX, > DX_RGBA_SELECT_SRC_R, DX_RGBA_SELECT_SRC_G, DX_RGBA_SELECT_SRC_B, DX_RGBA_SELECT_BLEND_A > と同じ効果ですか? GraphBlendBlt の場合は出力先を指定できるので SRC と BLEND のどちらが書き込み元、書き込み先、というのが特に無いので SRC を書き込み元、BLEND を書き込み先のつもりで表記しましたが、 GraphBlend の場合は出力先が SRC のハンドルになるので、 SRC を書き込み先、BLEND を書き込みも元となるわけですね… その場合は確かにこちらが正しい表記になりますね (・・ > そして > DX_GRAPH_BLEND_PMA_RGBA_SELECT_MIX, > DX_RGBA_SELECT_SRC_R, DX_RGBA_SELECT_SRC_G, DX_RGBA_SELECT_SRC_B, DX_RGBA_SELECT_BLEND_A >  > DX_GRAPH_BLEND_PMA_RGBA_SELECT_MIX, > DX_RGBA_SELECT_SRC_R, DX_RGBA_SELECT_SRC_G, DX_RGBA_SELECT_SRC_B, DX_RGBA_SELECT_BLEND_INV_A >  > この二つの処理と同じ効果はブレンドモードの仕組みでは実現出来ないということでしょうか? DX_RGBA_SELECT_SRC_R, DX_RGBA_SELECT_SRC_G, DX_RGBA_SELECT_SRC_B, DX_RGBA_SELECT_BLEND_A は今回追加した DX_BLENDMODE_DST_RGB_SRC_A で実現できています DX_RGBA_SELECT_SRC_R, DX_RGBA_SELECT_SRC_G, DX_RGBA_SELECT_SRC_B, DX_RGBA_SELECT_BLEND_INV_A こちらも( DX_BLENDMODE_DST_RGB_SRC_A よりも作業量が多いので少し時間がかかりますが )ブレンドモードの仕組みで実現できます > 例えば↑のような処理をすると指定範囲内でblendの透明度に応じてsrcの透明度をクリッピングするのは > このブレンドモードの使い方として合っているのでしょうか? なかなか興味深い使い方をされていますが よこさんの意図通りの結果が得られているのでしたら 使い方として問題ないと思います ただ、すみません、こちらのコードでどのようにクリッピングを行うのかちょっとイメージが出来ないので よろしければもう少し詳しくご説明頂けないでしょうか? m(_ _;m ( src や blend の画像の内容は実際にはどのようなものなのか等 ) > DX_BLENDMODE_INVDESTCOLORを使用してもblendのRGB値をsrcに混ぜない方法 RGB の値は一切変えずに A の値だけを変えるブレンドモードということでしょうか? DX_BLENDMODE_INVDESTCOLOR の A にのみ影響を与えるブレンドモードでしたら追加可能です > あるいはblendの透明度0以外のRGB値を強制的に白として扱うといったことはブレンドモードでは出来ないのでしょうか? DX_BLENDMODE_INVDESTCOLOR の RGB を白で固定するブレンドモードでしたら追加可能です
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.14 )
名前:よこ 日時:2023/10/14 20:56

DX_BLENDMODE_INVDESTCOLORによるクリッピングはDX_GRAPH_BLEND_PMA_MULTIPLE_A_ONLYと似た結果になりました で、DX_BLENDMODE_INVDESTCOLORでクリッピングをする部分だけのテストプログラムを作成したのですが そのためにコードを整理してついでにGraphBlendと比較をしたら普通にGraphBlendを使用したほうがちょっと速くなりました 多分整理前はGraphBlendの引数にブレンド画像としてLoadGraphで読み込んだ画像をそのまま指定していたからだと思います (どちらにしても誤差程度なのですが) なのでその上で何か要望を出すのは申し訳ないのですが DX_BLENDMODE_INVDESTCOLORのモードの追加をお願いしてもよろしいでしょうか? A値のみモードと白固定モードはどちらをお願いするか少し迷ったのですが A値のみモードのほうがモードとして自然かと思うのでDX_BLENDMODE_INVDESTCOLORのA値のみモードの追加をお願いします
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.15 )
名前:管理人 日時:2023/10/15 07:57

> A値のみモードのほうがモードとして自然かと思うのでDX_BLENDMODE_INVDESTCOLORのA値のみモードの追加をお願いします 了解しました DX_BLENDMODE_INVDESTCOLOR_A という DX_BLENDMODE_INVDESTCOLOR の A値のみのブレンドモードを追加したバージョンを アップしましたので、よろしければお試しください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 11.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい)
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.16 )
名前:よこ 日時:2023/10/15 13:21

一緒にDX_BLENDMODE_MUL_Aも追加されていて DX_BLENDMODE_INVDESTCOLORではなくDX_BLENDMODE_MULを使うことでも同じ効果になることに気付きました DrawBoxを挟まなくてよくなるのでこっちのほうがいいですね勉強になりました そして試した結果ですがblendに半透明部分があると意図しない表示になりました #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int src; int blend[ 4 ]; int dest1[ 4 ]; int dest2[ 4 ]; int flg = FALSE; ChangeWindowMode( TRUE ); SetGraphMode( 800, 600, 32 ); if( DxLib_Init() == -1 )return -1; src = MakeScreen( 128, 128, TRUE ); for( int i = 0; i < 4; ++i ) blend[ i ] = MakeScreen( 128, 128, TRUE ); for( int i = 0; i < 4; ++i ) dest1[ i ] = MakeScreen( 128, 128, TRUE ); for( int i = 0; i < 4; ++i ) dest2[ i ] = MakeScreen( 128, 128, TRUE ); // src SetDrawScreen( src ); ClearDrawScreen(); SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ); DrawBox( 0, 0, 64, 64, GetColor( 255, 255, 0 ), TRUE ); DrawBox( 78, 0, 128, 50, GetColor( 255, 0, 255 ), TRUE ); DrawBox( 0, 78, 64, 128, GetColor( 0, 255, 0 ), TRUE ); DrawBox( 78, 78, 128, 128, GetColor( 0, 255, 255 ), TRUE ); // blend1 SetDrawScreen( blend[ 0 ] ); ClearDrawScreen(); SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ); DrawCircle( 64, 64, 50, GetColor( 255, 255, 255 ), TRUE ); // blend2 GraphFilterBlt( blend[ 0 ], blend[ 1 ], DX_GRAPH_FILTER_GAUSS, 16, 1000 ); // blend3 SetDrawScreen( blend[ 2 ] ); ClearDrawScreen(); SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ); DrawCircle( 64, 64, 50, GetColor( 255, 0, 0 ), TRUE ); // blend4 GraphFilterBlt( blend[ 2 ], blend[ 3 ], DX_GRAPH_FILTER_GAUSS, 16, 1000 ); while( ProcessMessage() == 0 ) { if( CheckHitKey( KEY_INPUT_A ) == 1 )flg = FALSE; else if( CheckHitKey( KEY_INPUT_S ) == 1 )flg = TRUE; // DX_BLENDMODE_MUL // DX_BLENDMODE_INVDESTCOLOR for( int i = 0; i < 4; ++i ) { SetDrawScreen( dest1[ i ] ); ClearDrawScreen(); SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ); DrawGraph( 0, 0, src, TRUE ); if( flg == FALSE )SetDrawBlendMode( DX_BLENDMODE_MUL, 255 ); else { SetDrawBlendMode( DX_BLENDMODE_INVDESTCOLOR, 255 ); DrawBox( 0, 0, 128, 128, GetColor( 255, 255, 255 ), TRUE ); } DrawGraph( 0, 0, blend[ i ], TRUE ); } // DX_BLENDMODE_MUL_A // DX_BLENDMODE_INVDESTCOLOR_A for( int i = 0; i < 4; ++i ) { SetDrawScreen( dest2[ i ] ); ClearDrawScreen(); SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ); DrawGraph( 0, 0, src, TRUE ); if( flg == FALSE )SetDrawBlendMode( DX_BLENDMODE_MUL_A, 255 ); else { SetDrawBlendMode( DX_BLENDMODE_INVDESTCOLOR_A, 255 ); DrawBox( 0, 0, 128, 128, GetColor( 255, 255, 255 ), TRUE ); } DrawGraph( 0, 0, blend[ i ], TRUE ); } // 裏画面に描画 SetDrawScreen( DX_SCREEN_BACK ); SetDrawBlendMode( DX_BLENDMODE_PMA_ALPHA, 255 ); DrawBox( 0, 0, 1000, 800, GetColor( 100, 100, 100 ), TRUE ); DrawString( 10, 10, TEXT( "src" ), GetColor( 255, 255, 255 ) ); DrawGraph( 10, 30, src, TRUE ); DrawBox( 10, 30, 10 + 128, 30 + 128, GetColor( 0, 0, 0 ), FALSE ); for( int i = 0; i < 4; ++i ) { DrawFormatString( 148 + 138 * i, 10, GetColor( 255, 255, 255 ), TEXT( "blend%d" ), i + 1 ); DrawGraph( 148 + 138 * i, 30, blend[ i ], TRUE ); DrawBox( 148 + 138 * i, 30, 148 + 138 * i + 128, 30 + 128, GetColor( 0, 0, 0 ), FALSE ); } if( flg == FALSE )DrawString( 10, 178, TEXT( "DX_BLENDMODE_MUL" ), GetColor( 255, 255, 255 ) ); else DrawString( 10, 178, TEXT( "DX_BLENDMODE_INVDESTCOLOR" ), GetColor( 255, 255, 255 ) ); for( int i = 0; i < 4; ++i ) { DrawFormatString( 148 + 138 * i, 198, GetColor( 255, 255, 255 ), TEXT( "src + blend%d" ), i + 1 ); DrawGraph( 148 + 138 * i, 218, dest1[ i ], TRUE ); DrawBox( 148 + 138 * i, 218, 148 + 138 * i + 128, 218 + 128, GetColor( 0, 0, 0 ), FALSE ); } if( flg == FALSE )DrawString( 10, 366, TEXT( "DX_BLENDMODE_MUL_A" ), GetColor( 255, 255, 255 ) ); else DrawString( 10, 366, TEXT( "DX_BLENDMODE_INVDESTCOLOR_A" ), GetColor( 255, 255, 255 ) ); for( int i = 0; i < 4; ++i ) { DrawFormatString( 148 + 138 * i, 386, GetColor( 255, 255, 255 ), TEXT( "src + blend%d" ), i + 1 ); DrawGraph( 148 + 138 * i, 406, dest2[ i ], TRUE ); DrawBox( 148 + 138 * i, 406, 148 + 138 * i + 128, 406 + 128, GetColor( 0, 0, 0 ), FALSE ); } DrawString( 10, 560, TEXT( "[ A ] キーで MUL に変更, [ S ]キーで INVDESTCOLOR に変更" ), GetColor( 255, 255, 255 ) ); ScreenFlip(); } DxLib_End(); return 0; } DX_BLENDMODE_MULやDX_BLENDMODE_INVDESTCOLORを使用している場合にはこの表示にならないのですが RGB値を反映させない+半透明も正常に処理するといういいとこどりは出来ないでしょうか? しつこくてすみません
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.17 )
名前:管理人 日時:2023/10/15 19:30

すみません、今回追加した DX_BLENDMODE_INVDESTCOLOR_A と DX_BLENDMODE_MUL_A は 乗算済みアルファには対応していません 乗算済みアルファはその名の通り『RGB の値は A の値で乗算済みである』画像のことなので、 今回追加したような『RGB の値は変わらない』ブレンドモードで、A の値だけが変化してしまうと 『乗算済みアルファとして正しくない( A の値に対応した RGB の値ではない )画像』となってしまい、 今回のよこさんが載せてくださったプログラムの実行結果のようになります なので DX_BLENDMODE_PMA_INVDESTCOLOR_A や DX_BLENDMODE_PMA_MUL_A のような 乗算済みアルファに対応( A の値の変化に応じて RGB の値も変化する )した DX_BLENDMODE_INVDESTCOLOR_A や DX_BLENDMODE_MUL_A を追加する必要があります というわけで DX_BLENDMODE_PMA_INVDESTCOLOR_A と DX_BLENDMODE_PMA_MUL_A を追加してみましたので よろしければこちらをダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 11.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) 載せていただいたプログラムの中の DX_BLENDMODE_INVDESTCOLOR_A と DX_BLENDMODE_MUL_A の部分を DX_BLENDMODE_PMA_INVDESTCOLOR_A や DX_BLENDMODE_PMA_MUL_A に 置き換えていただければ正常な描画結果が得られます
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.18 )
名前:よこ(解決) 日時:2023/10/15 20:46

迅速なご対応ありがとうございます 求めていたクリッピングがブレンドモードでも実現出来ました この度は何度もご対応していただき本当にありがとうございました!
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.19 )
名前:管理人(解決) 日時:2023/10/16 00:09

> よこさん 問題なく乗算済みα用のブレンドモードが動作したようで何よりです! > たろうさん すみません、No.7 で『描画先と描画元のaのみを合成する機能( DX_GRAPH_BLEND_PMA_MULTIPLE_A_ONLY に相当する機能 )』は ブレンドモードの仕組みでは実現できないとお伝えしましたが、その後改めて確認した所 ブレンドモードでも DX_GRAPH_BLEND_PMA_MULTIPLE_A_ONLY に相当する機能が可能である事が分かりました m(_ _;m こちらの暫定最新バージョンに含まれている DX_BLENDMODE_PMA_MUL_A というブレンドモードが 『描画先と描画元のaのみを合成する機能』となっていますので、よろしければお試しください m(_ _;m ( GraphBlendRectBlt + DX_GRAPH_BLEND_PMA_MULTIPLE_A_ONLY を使用するより若干高速に処理できると思います ) https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 11.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) 因みに当初実現が出来ないと思ったのは 書き込まれるα = 書き込み先α + 書き込み元α ↑ こちらのブレンド処理の式の『+』が掛かれている部分の演算子として『×』を指定できないから、だったのですが、 そこ以外の設定の変更によって 書き込まれるα = ( 書き込み先α × 書き込み元α ) + ( 書き込み元α × 0 ) ↑ このように『+』はそのままで、『書き込み先α』に『書き込み元α』を乗算できることが 後から分かったからでした m(_ _;m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.20 )
名前:たろう 日時:2023/10/16 14:23

いつもありがとうございます。 まさかの大逆転で、機能を追加していただいて本当にありがとうございますm(__)m よこさんにも感謝いたしますm(__)m 色々確認しましたが、DX_BLENDMODE_PMA_MUL_Aで期待通りの動作が得られました。 すみません、たぶん似た処理で、実現可能だと思うのですが。 追加でかさねて図々しくすみませんm(__)m 下にテストプログラムを用意しました。 「ここです」の部分になりますm(__)m 「家」のアルファ値だけをのこして「血」を描画するというものです 例えばキャラが傷ついたときに血の画像を頭からはみ出さないように貼る時や ビルに爆発で煤がつくというような場面で使う処理です GraphBlendで実行する場合まず「ビルに血を貼る」そして「ビルの形にくりぬく」という 手順になるので、もしSetDrawBlendModeでできれば簡単かつ誰にでも理解しやすい形で 出来ると思います もちろんGraphBlendで出来る処理なので、作業が大変だったり、 難しいようでしたら却下で構いません なんどもすみません、ご検討いただければありがたいです よろしくお願いいたしますm(__)m ----------------------------------------------------------------- #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ) ; DxLib_Init(); SetUsePremulAlphaConvertLoad(1); //端が半透明な「血」を作る int 血=MakeScreen(100,100,1); SetDrawScreen(血);ClearDrawScreen(); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA,125);DrawBox(10,10,90,90,GetColor(255,0,0),1); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA,255);DrawBox(20,20,80,80,GetColor(255,0,0),1); //半透明の窓や透明部分のある「家」を作る int 家=MakeScreen(400,400,1); SetDrawScreen(家);ClearDrawScreen(); DrawBox(100,100,300,300,GetColor(200,200,200),1); SetDrawBlendMode(DX_BLENDMODE_PMA_MUL_A ,100); for(int i1=0;i1<6;i1++){for(int i2=0;i2<6;i2++){DrawBox(115+(i1*30),115+(i2*30),135+(i1*30),135+(i2*30),GetColor(200,200,200),1);}} //家に血を貼り付ける(ただし壁がない部分には貼らず、窓の部分は半透明のまま貼る) SetDrawBlendMode(ここです,255); DrawRotaGraph2(90,90,50,50,1.5,0.5,血,1); //DX_SCREEN_BACKに戻す SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA,255); SetDrawScreen(DX_SCREEN_BACK); while( ProcessMessage() == 0 ) { ClearDrawScreen(); DrawBox(0,0,1000,1000,GetColor(0,0,100),1); DrawGraph(0,0,家,1); ScreenFlip(); } DxLib_End() ; return 0 ; }
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.21 )
名前:管理人 日時:2023/10/17 00:36

DX_BLENDMODE_PMA_MUL_A が正常に動作したようで何よりです > GraphBlendで実行する場合まず「ビルに血を貼る」そして「ビルの形にくりぬく」という > 手順になるので、もしSetDrawBlendModeでできれば簡単かつ誰にでも理解しやすい形で > 出来ると思います 処理の内容としてはたろうさんのご説明の通り 1.ビル(書き込み先) に 血(書き込み元) をアルファブレンドで描画 2.ビル(書き込み先) に 変更前ビル(書き込み元) をα値だけ乗算描画 という処理になると思うのですが、残念ながらこの2つの処理を 1回のブレンドモードで実現するのは(見落としていたブレンド処理の仕様を使用したとしても)無理です 恐らく最初に DX_BLENDMODE_PMA_ALPHA で「ビルに血を貼る」をしたあと、 書き込まれる前のビルの画像を使用して DX_BLENDMODE_PMA_MUL_A でビルを書き込めば 「ビルの形にくりぬく」が出来るので、GraphBlend で行う場合と同じ効果が得られるのではないかと思います ただ、GraphBlend に新たなブレンド機能として追加する場合は 1回の GraphBlend で 「ビルに血を貼る」「ビルの形にくりぬく」を実現するものを追加することができると思います なので、よろしければ現状で 「ビルに血を貼る」「ビルの形にくりぬく」を実行するために 使用している GraphBlend のブレンド機能を教えて頂けないでしょうか? m(_ _)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.22 )
名前:たろう 日時:2023/10/17 02:10

ご返信ありがとうございます。 ブレンドモードで実現するのは難しい件、了解いたしました。 DX_BLENDMODE_PMA_MUL_Aだけで、すごく助かりますので 本来満足すべきところ、余計な下心を出してしまいましたm(__)m 現在GraphBlendで貼って抜く作業は まずビル画像の透明部分を白、不透明部分を黒にしたマスク用画像を GraphBlend(マスク,ビル,255,DX_GRAPH_BLEND_PMA_RGBA_SELECT_MIX,DX_RGBA_SELECT_BLEND_INV_A,DX_RGBA_SELECT_BLEND_INV_A,DX_RGBA_SELECT_BLEND_INV_A,DX_RGBA_SELECT_SRC_INV_A); で作り、事前に用意しておいて、 そのうえで普通にビルに血をアルファブレンドで描画。 その血のはみ出したビルの画像を、上で用意したマスク画像で下の様に型抜きしています GraphBlend(ビル,マスク,255,DX_GRAPH_BLEND_PMA_RGBA_SELECT_MIX,DX_RGBA_SELECT_SRC_R,DX_RGBA_SELECT_SRC_G,DX_RGBA_SELECT_SRC_B,DX_RGBA_SELECT_BLEND_INV_R); 1回のGraphBlendで実現という事は、マスク用画像はいらなくなるという事でしょうか? また、GraphBlendで行う場合、血を貼る位置や大きさは、GraphBlendRectBltの範囲指定で行い、 血を貼る角度の変更は不可で、貼る時の濃さについてはBlendRatioで設定…という事になるでしょうか? マスク用画像を用意する必要がなくなるのであればうれしいのですが そうでなければデメリットもあるので、追加なしで大丈夫です。 いつもほんとうにすみませんm(__)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.23 )
名前:管理人 日時:2023/10/18 00:24

ご返答ありがとうございます > 1回のGraphBlendで実現という事は、マスク用画像はいらなくなるという事でしょうか? はい、仮に実装する場合はマスク用画像は不要になります > また、GraphBlendで行う場合、血を貼る位置や大きさは、GraphBlendRectBltの範囲指定で行い、 > 血を貼る角度の変更は不可で、貼る時の濃さについてはBlendRatioで設定…という事になるでしょうか? >  > マスク用画像を用意する必要がなくなるのであればうれしいのですが > そうでなければデメリットもあるので、追加なしで大丈夫です。 回転角度や濃さも全て引数で渡すようにすることは可能ですが、煩雑になり過ぎるかもしれません ( また、回転の中心座標も引数で渡す形になると更に煩雑に… ) GraphBlend に渡す引数が物凄く多くなると思いますが、どうしましょう? (・・;
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.24 )
名前:たろう 日時:2023/10/18 03:18

いつもありがとうございます。 マスク用画像が不要になると 私の場合ほとんどの画像のマスク用画像を用意しているので めちゃくちゃうれしいです。 @すみません、前にもお聞きしたかもしれませんが GraphBlendRectBltのDestGrHandleはSrcGrHandleと同じものを指定しても問題なかったでしょうか? (※SrcGrHandleに影響を及ぼしたいだけなのでDestGrHandleは不要なため。また、 内部的に別画像が生み出されたりしているとメモリがどんどん増えて困るので) AやはりGraphBlendRectBltの範囲指定で貼る位置と大きさを決める事になるでしょうか? そうであれば、例えばSrcX1の数値は-10などを指定したり、SrcX2はSrcGrHandleの画像の横幅を 大きく超える座標を指定したりなど、そういった使い方も可能でしょうか? (※SrcGrHandleの端をはみ出す形でBlendGrHandleの画像を貼るケースがあるので) もし上記二つが可能であれば 引数が増えても、それ用の関数を挟んで使うので大丈夫ですし ものすごくありがたいです また、汚れや血を貼りたいだけなので、 位置、大きさ、濃さ、が自由に設定できれば 私の場合、回転はあっても無くても大丈夫です。 あとPMA版でお願いいたします…m(__)m お手数をおかけいたしますm(__)m 作業的に大変なようでしたら却下でも大丈夫ですm(__)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.25 )
名前:管理人 日時:2023/10/20 13:32

ご返信が遅くなり申し訳ありません > @すみません、前にもお聞きしたかもしれませんが > GraphBlendRectBltのDestGrHandleはSrcGrHandleと同じものを指定しても問題なかったでしょうか? 問題ありませんが、処理速度は遅くなります ( SrcGrHandle と BlendGrHandle のブレンドした結果を一時的なグラフィックハンドルに出力した後、 一時的なグラフィックハンドルの内容を SrcGrHandle に転送することになるので… ) > AやはりGraphBlendRectBltの範囲指定で貼る位置と大きさを決める事になるでしょうか? > そうであれば、例えばSrcX1の数値は-10などを指定したり、SrcX2はSrcGrHandleの画像の横幅を > 大きく超える座標を指定したりなど、そういった使い方も可能でしょうか? GraphBlendRectBlt2 を使用すると Blend側も左上座標と右下座標を指定することが出来るので、 それで拡大して合成も可能かもしれません とりあえず今までのブレンド機能と同じように実装してみますので、その上で現状の 座標指定の機能ではAの部分が意図した通りに実行できないということでしたら 改めてその後追加で機能を実装する形にさせてください m(_ _)m > また、汚れや血を貼りたいだけなので、 > 位置、大きさ、濃さ、が自由に設定できれば > 私の場合、回転はあっても無くても大丈夫です。 了解です 回転を追加するとかなり複雑になりそうなので、今回は回転は無しで実装したいと思います > あとPMA版でお願いいたします…m(__)m 了解です 通常版とPMA版どちらも追加します 週末に作業しますので、数日ほどお待ち下さい m(_ _)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.26 )
名前:たろう 日時:2023/10/20 14:06

ご返信ありがとうございます。 すみません、作業を始めていただいてしまう前に 取り急ぎ質問を、失礼しますm(__)m > SrcGrHandle と BlendGrHandle のブレンドした結果を一時的なグラフィックハンドルに出力した後、 > 一時的なグラフィックハンドルの内容を SrcGrHandle に転送することになるので という事は、おそらく・・・ ブレンドする瞬間に、 SrcGrHandle(ビル)のコピーをMakescreenで一時的に作って(コピー) そのうえでBlendGrHandle(血)をビルに貼って ビルと血を合成したものをコピーで型抜きし、コピーを削除する ・・・というのと、速度的にあまり変わらないのではないでしょうか? もしそうであれば、私は独自の関数を間に挟んで使用するつもりなので 合成前にコピーをする処理をその独自の関数に含めてしまえばいいわけですから 機能追加していただかなくても大丈夫だったりします・・・ 色々とすみませんm(__)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.27 )
名前:管理人 日時:2023/10/21 05:49

> ブレンドする瞬間に、 > SrcGrHandle(ビル)のコピーをMakescreenで一時的に作って(コピー) 一時的なグラフィックハンドルは GraphBlend を実行する度に MakeScreen で作成すると 速度が遅くなってしまうので、一度作成したら削除はされずそのまま次の GraphBlend でも 使用されますので、毎回 MakeScreen → DeleteGraph が実行されるわけではありません > そのうえでBlendGrHandle(血)をビルに貼って > ビルと血を合成したものをコピーで型抜きし、コピーを削除する > ・・・というのと、速度的にあまり変わらないのではないでしょうか? こちらの部分は処理負荷的には if( 初回かどうか ) { 一時的なグラフィックハンドル = MakeScreen(); } SetDrawScreen( 一時的なグラフィックハンドル ); SetDrawBlendMode( 合成するブレンドモード(仮定) ); DrawGraph( SrcGrHandle と BlendGrHandle を合成して描画する処理(仮定) ); SetDrawScreen( SrcGrHandle ); DrawGraph( 一時的なグラフィックハンドル ); SetDrawScreen( 元の描画先 ); ↑ こちらのような処理と同等になります
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.28 )
名前:たろう 日時:2023/10/21 07:55

ご返信いただきありがとうございます。 各グラフィックハンドルごと、 初回以降はGraphBlendで追加していただく やり方のほうが処理が少ないという事でしょうか それであれば大変ありがたいです。 結局お願いすることになるのは心苦しいですが それでは是非追加をお願いいたしますm(__)m 本格的に使わせていただこうと思っているのは 来月以降なので、まったく急いでいませんので お手すきの時で大丈夫です なにとぞよろしくお願いいたしますm(__)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.29 )
名前:管理人 日時:2023/10/21 18:34

了解しました 早速実装してみましたので、よろしければこちらの機能追加版をダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 11.3 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) 以下のブレンドタイプを追加しました DX_GRAPH_BLEND_MASK DX_GRAPH_BLEND_PMA_MASK どちらも『SrcGrHandle に BlendGrHandle をアルファブレンドした上で、SrcGrHandle の A は維持する』 というものになっています( DX_GRAPH_BLEND_PMA_MASK は乗算済みα用 ) よろしければたろうさんの意図したブレンド結果になるか試してみてください m(_ _)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.30 )
名前:たろう 日時:2023/10/22 20:17

いつもありがとうございます。 新機能を使用させていただきましたm(__)m そのうえで、質問を二つ失礼いたしますm(__)m @ 下記テストにて、試していただくと分かるのですが ビルの右端or下端にはみ出すように血を貼ると、 画像端が限界になるようで、結果的に血が縦長や横長になってしまいます。 これは困るので、修正可能でしょうか? A >一度作成したら削除はされずそのまま次の GraphBlend でも >使用されます という件ですが、私の使い方では、例えばどんどん湧き出す「敵」があって その敵が作り出されるたびMakeScreenで画像(仮にA)を作ります(死んだら画像も削除します) 「一度作成したら削除はされずそのまま次の〜」という画像(仮にB)については この敵が生み出されるたび作り出される画像(A)が削除されるときに(B)も解放される という認識であっているでしょうか?Aが削除されても残り続けるBだとしたら やはりメモリが大変なことになりそうです。 ※あほな質問だったらすみませんm(__)m よろしくお願いいたしますm(__)m #include "DxLib.h" //DX_GRAPH_BLEND_PMA_MASK int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ) ; DxLib_Init(); SetUsePremulAlphaConvertLoad(1); //端が半透明な「血」を作る int 血=MakeScreen(100,100,1); SetDrawScreen(血);ClearDrawScreen(); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA,125);DrawBox(10,10,90,90,GetColor(255,0,0),1); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA,255);DrawBox(20,20,80,80,GetColor(255,0,0),1); int 血w,血h; GetGraphSize(血,&血w,&血h); //半透明の窓や透明部分のある「家」を作る int 家=MakeScreen(300,300,1); SetDrawScreen(家);ClearDrawScreen(); DrawBox(10,10,300,300,GetColor(200,200,200),1); SetDrawBlendMode(DX_BLENDMODE_PMA_MUL_A ,100); for(int i1=0;i1<9;i1++){for(int i2=0;i2<9;i2++){DrawBox(25+(i1*30),25+(i2*30),45+(i1*30),45+(i2*30),GetColor(200,200,200),1);}} int 家w,家h; GetGraphSize(家,&家w,&家h); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA ,255); SetDrawScreen(DX_SCREEN_BACK); while( ProcessMessage() == 0 ) { static int MOUo=0,MOUx,MOUy; int m=GetMouseInput();if((m&MOUSE_INPUT_LEFT)!=0){MOUo++;}else{MOUo=0;} GetMousePoint(&MOUx,&MOUy); MOUx-=100;MOUy-=100; if(MOUo==1) { GraphBlendRectBlt2(家,血,家, MOUx-血w/2,MOUy-血h/2,MOUx+血w/2,MOUy+血h/2,//Src 0,0,血w,血h, //Blend MOUx-血w/2,MOUy-血h/2, //Dest 255,DX_GRAPH_BLEND_PMA_MASK ); } ClearDrawScreen(); DrawBox(0,0,1000,1000,GetColor(0,0,100),1); DrawGraph(100,100,家,1); ScreenFlip(); } DxLib_End() ; return 0 ; }
メンテ

Page: 1 | 2 | 3 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存