トップページ > 記事閲覧
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.31 )
名前:管理人 日時:2023/10/25 09:33

ご返信が大変遅くなっていてすみません 今週の平日はかなり忙しくちょっと検証用のプログラムを組んだりする余裕が無いので、 申し訳ありませんが週末までお待ちください m(_ _;m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.32 )
名前:たろう 日時:2023/10/25 20:44

ご対応いただけるだけで、大変感謝しておりますm(__)m お手すきの時でよろしくお願いいたしますm(__)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.33 )
名前:管理人 日時:2023/10/29 09:10

大変お待たせしました m(_ _;m > @ > 下記テストにて、試していただくと分かるのですが > ビルの右端or下端にはみ出すように血を貼ると、 > 画像端が限界になるようで、結果的に血が縦長や横長になってしまいます。 > これは困るので、修正可能でしょうか? GraphBlendRectBlt2 の SrcX1, SrcY1, SrcX2, SrcY2 は描画範囲ではなく BlendX1, BlendY1, BlendX2, BlendY2 とブレンドしたい範囲を指定する必要が ありますので、ブレンドしたい範囲が画像からはみ出てしまう場合は 座標を補正して画像内を指すようにする必要があります if(MOUo==1) の中を以下のようにすることで正常な結果を得られるようになりますので よろしければお試しください m(_ _)m if(MOUo==1) { int SrcX1, SrcY1, SrcX2, SrcY2; int BldX1, BldY1, BldX2, BldY2; int DstX, DstY; SrcX1 = MOUx - 血w / 2; SrcY1 = MOUy - 血h / 2; SrcX2 = MOUx + 血w / 2; SrcY2 = MOUy + 血h / 2; BldX1 = 0; BldY1 = 0; BldX2 = 血w; BldY2 = 血h; DstX = MOUx - 血w / 2; DstY = MOUy - 血h / 2; if( SrcX1 < 0 ) { BldX1 += -SrcX1; SrcX1 = 0; DstX = 0; } if( SrcX2 > 家w ) { BldX2 -= SrcX2 - 家w; SrcX2 = 家w; } if( SrcY1 < 0 ) { BldY1 += -SrcY1; SrcY1 = 0; DstY = 0; } if( SrcY2 > 家h ) { BldY2 -= SrcY2 - 家h; SrcY2 = 家h; } GraphBlendRectBlt2(家,血,家, SrcX1, SrcY1, SrcX2, SrcY2, //Src BldX1, BldY1, BldX2, BldY2, //Blend DstX, DstY, //Dest 255,DX_GRAPH_BLEND_PMA_MASK ); } > A > >一度作成したら削除はされずそのまま次の GraphBlend でも > >使用されます > という件ですが、私の使い方では、例えばどんどん湧き出す「敵」があって > その敵が作り出されるたびMakeScreenで画像(仮にA)を作ります(死んだら画像も削除します) > 「一度作成したら削除はされずそのまま次の〜」という画像(仮にB)については > この敵が生み出されるたび作り出される画像(A)が削除されるときに(B)も解放される > という認識であっているでしょうか?Aが削除されても残り続けるBだとしたら > やはりメモリが大変なことになりそうです。 > ※あほな質問だったらすみませんm(__)m ブレンド処理に使用される一時的な画像は、DestGrHandle などで指定されたグラフィックハンドル専用の ものではなく、同じサイズの画像が GraphBlend で使用された場合は、その画像に対しても 同じ『一時的な画像』が使用されますので、GraphBlend に使用するグラフィックハンドルの数だけ 『一時的な画像』が作成されるわけではありませんのでご安心ください m(_ _)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.34 )
名前:たろう 日時:2023/10/30 10:08

いつもありがとうございます。 Aの件、安心いたしました、ありがとうございますm(__)m @の件ですが、 BlendがSrcを、マイナス座標側にはみ出すときはBlend側の座標をいじる 必要がないので、できればプラス側にはみ出す場合もこの仕様のほうが うれしいのですが、これは問題があるのでしょうか? すみません、あほなことを言っているかもしれません 間違っていたらごめんなさいm(__)m よろしくお願いいたします
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.35 )
名前:管理人 日時:2023/10/30 12:14

> @の件ですが、 > BlendがSrcを、マイナス座標側にはみ出すときはBlend側の座標をいじる > 必要がないので、できればプラス側にはみ出す場合もこの仕様のほうが > うれしいのですが、これは問題があるのでしょうか? すみません、仰りたいことが分かるようで分からないような… な状態です もう少し詳しくご説明頂けないでしょうか? m(_ _;m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.36 )
名前:たろう 日時:2023/10/30 12:37

すみません、書き方が悪かったかもしれませんし 単に私が何かを間違っている可能性もありますm(__)m つまり No.30のプログラムをそのまま実行していただくと ビルの左側や上側にはみだすように血を貼っても、血が縦長(横長)にならないのですが ビルの右側や下側にはみ出すように血を貼ると、血が縦長(横長)になるのですが この左側や上側にはみ出して貼った時の様に 右側や下側にはみ出しても、血が縦長(横長)にならないように なると嬉しい・・・という事です。 もちろんご提示いただいた方法は 十分満足すべきものなので、 もし可能であればという程度の事なのですが m(__)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.37 )
名前:管理人 日時:2023/10/30 18:40

詳しいご説明ありがとうございます、理解できました GraphBlendRectBlt2 の処理を確認したところ、GraphBlendRectBlt2 は後から追加した関数なので BlendX2 と BlendY2 に関しては SrcX2 や SrcY2 が右端や下端から指定座標がはみ出ていても クリップ処理を行っていませんでした BlendX2 と BlendY2 についてもクリップ処理を行うようにしたところ、No.33 のような 自前でクリップ処理を行わなくても正常なブレンド結果が得られるようになりました よろしければその変更を行ったこちらのバージョンをお試しください 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.38 )
名前:たろう(解決) 日時:2023/10/30 19:47

いつもありがとうございます。 先ほど、期待通りの動作を確認させていただきました。 DX_BLENDMODE_PMA_MUL_Aと DX_GRAPH_BLEND_PMA_MASKという とても便利な機能を追加していただいて 次に作るゲームから、かなり作業が楽になりそうで 本当にうれしいです。 またお手数をおかけしてしまいましたm(__)m ありがとうございましたm(__)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.39 )
名前:たろう 日時:2023/10/31 18:02

また蒸し返しで、すみませんm(__)m 早速本格的に取り入れようと色々試していましたところ 貼る血のサイズを倍にして貼ると 家からはみ出して貼った場合に、おかしな膨らみ方をしてしまう事が分かりました。 説明しにくいのですが、下のプログラムで ビルから上下左右どちらでもよいのではみ出して血(2倍)を クリックで貼ると、その様子が分かりやすいです 血をそのままの大きさで貼ると問題ありませんがSrcX(Y)1(2)の範囲を広げる事で 血を拡大して貼ろうとすると、ビルからはみ出したときにおかしなことになるようです。 これは修正可能でしょうか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); float sz=2;//血のサイズ(※倍率) 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*sz,MOUy-血h/2*sz,MOUx+血w/2*sz,MOUy+血h/2*sz,//Src 0,0,血w,血h, //Blend MOUx-血w/2*sz,MOUy-血h/2*sz, //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 ; }
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.40 )
名前:管理人 日時:2023/11/01 00:43

なるほど、確かに現在のクリッピング処理は Src と Blend が同じ倍率であることを前提としているので 上手く動作しないと思います というわけで、Src と Blend の倍率が異なる場合でも正常に動作するようにしてみましたので、 よろしければお試しください 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.41 )
名前:たろう(解決) 日時:2023/11/01 06:17

ありがとうございましたm(__)m 先ほど、期待通りの動作を確認させていただきました。 何度もお手数をおかけしてしてすみませんm(__)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.42 )
名前:たろう 日時:2023/11/02 09:07

また蒸し返しですみませんm(__)m メモリが増え続けないかどうかを一応検証しようと 下記のプログラムを書いたのですが、タスクマネージャーで確認すると ずっとメモリ使用量が増え続けてしまうようです。 色々な血と家を作っては消ししながら GraphBlendRectBlt2でブレンドしあう というものです。 if(time%2==1&&MOUo==0)の部分をif(1)にすると (むしろ負荷が上がりそうなのに)大丈夫だったりするので 謎な部分もあります。 どういう可能性が考えられるでしょうか? よろしくお願いいたしますm(__)m #include "DxLib.h" //DX_GRAPH_BLEND_PMA_MASK int 血,血w,血h; void MAKE血() { //端が半透明な「血」を作る DeleteGraph(血);int w=100+GetRand(50),h=100+GetRand(50); 血=MakeScreen(w,h,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); GetGraphSize(血,&血w,&血h); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA ,255); SetDrawScreen(DX_SCREEN_BACK); } int 家,家w,家h; void MAKE家() { //半透明の窓や透明部分のある「家」を作る DeleteGraph(家);int w=200+GetRand(50),h=200+GetRand(50); 家=MakeScreen(w,h,1); SetDrawScreen(家);ClearDrawScreen(); DrawBox(10,10,w,h,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);}} GetGraphSize(家,&家w,&家h); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA ,255); SetDrawScreen(DX_SCREEN_BACK); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ) ; DxLib_Init(); SetUsePremulAlphaConvertLoad(1); MAKE血(); MAKE家(); float sz=2;//血のサイズ(※倍率) int time=0; 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; time++;MOUx=GetRand(100);MOUy=GetRand(100); if(time%2==1&&MOUo==0) { MAKE血(); MAKE家(); GraphBlendRectBlt2(家,血,家, MOUx-血w/2*sz,MOUy-血h/2*sz,MOUx+血w/2*sz,MOUy+血h/2*sz,//Src 0,0,血w,血h, //Blend MOUx-血w/2*sz,MOUy-血h/2*sz, //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 ; }
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.43 )
名前:管理人 日時:2023/11/04 01:35

> メモリが増え続けないかどうかを一応検証しようと > 下記のプログラムを書いたのですが、タスクマネージャーで確認すると > ずっとメモリ使用量が増え続けてしまうようです。 手元でも使用メモリが増え続けるのを確認しました ただ、色々試してみたのですが、原因は分かりませんでした MakeScreen を一度だけにして DeleteGraph を呼ばないようにしたところ使用メモリが増えなくなったのですが、 GraphFilter内で行っているポリゴン描画を行わないようにしても使用メモリが増えなくなったりと、 何処が根本の原因なのかが分かりませんでした… Direct3D 関係のオブジェクトの開放忘れ等の箇所が無いか確認したのですが、そのような箇所も無く… Direct3D 11 に問題がある可能性も考えにくいので、本当に謎です… Direct3D 9 を使用するようにした場合は使用メモリが増えることはありませんでしたので、 もし Direct3D 9 でも問題がありませんでしたら DxLib_Init の呼び出しの前に SetUseDirect3DVersion( DX_DIRECT3D_9EX ); という記述を増やして、Direct3D 9 を使用するようにしてください m(_ _;m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.44 )
名前:たろう 日時:2023/11/04 11:23

いつもありがとうございます DX_DIRECT3D_9EXはデバイスロストしやすかったりで困るので 色々試したのですが、そもそもGraphBlendを使わなくても 下のプログラムでメモリが増え続けるようです。 原因はMakeScreenかSetDrawScreen にあると思うのですが、何かわかりませんでしょうか? ちなみにですが以下の4つのうちどれか(一つでも)をするとメモリ増え続けなくなります ・「これです@」のSetDrawScreen(DX_SCREEN_BACK);をコメントアウトする (※No.42のプログラムもMAKE血()内のSetDrawScreen(DX_SCREEN_BACK);を削除するとメモリ増えなくなります) ・「これですA」の行とその下の行を取り換えてIM2のサイズのバリエーションを減らす ・if(i%2==1)をif(1)に変える ・「これですB」のDrawBoxをコメントアウトする(※IM2へのDrawBoxは消してもメモリ増え続けます) お忙しいところスミマセン、 よろしくお願いいたしますm(__)m ------------------------------------------- #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ) ; DxLib_Init(); int i=0,IM1=-1,IM2=-1; while( ProcessMessage() == 0 ) { i++; if(i%2==1) { DeleteGraph(IM1); IM1=MakeScreen(100,100,1); SetDrawScreen(IM1); DrawBox(0,0,10,10,GetColor(0,0,0),1);//これですB SetDrawScreen(DX_SCREEN_BACK);//これです@ DeleteGraph(IM2); //int w=200+GetRand(5)*10,h=200+GetRand(5)*10;//これですA int w=200+GetRand(50),h=200+GetRand(50); IM2=MakeScreen(w,h,1); SetDrawScreen(IM2); DrawBox(0,0,10,10,GetColor(0,0,0),1); SetDrawScreen(DX_SCREEN_BACK); } DrawGraph(100,100,IM2,1); ScreenFlip(); } DxLib_End() ; return 0 ; }
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.45 )
名前:管理人 日時:2023/11/05 10:24

No.44 で載せていただいたプログラムについては、100MBほどまでメモリ使用量が増えますが、 それ以上は増えないようです DxLib_Init の前に SetWaitVSyncFlag( FALSE ) ; を記述して、VSYNC待ちをしないで超高速でメインループを回すと簡単に確認できますので よろしければお試しください m(_ _)m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.46 )
名前:たろう 日時:2023/11/05 11:56

いつもご返信ありがとうございます SetWaitVSyncFlag( FALSE ) ;について知りませんでした。 便利な機能をありがとうございますm(__)m それで色々試しましたところ、No.42のプログラムも、 下の様にしたら100MBほどで上昇が止まりました。 GraphBlendRectBlt2のDestGrHandleにSrcGrHandleと同じものを指定しないように 新たに「家2」を追加してそこに入れる形に改造したものですが すると100MBほどで上昇が止まりました。 この結果から DestGrHandleにSrcGrHandleと同じものを入れた場合に発生するという事だとすると GraphBlendのようにGraphBlendRectBlt2もBlt無しバージョンを追加していただくのは難しいでしょうか? もしくは内部的には同じだったりで、その方法では改善しないという事になりますでしょうか? 何度もスミマセンm(__)m ----------------------------------------------------------------- #include "DxLib.h" //DX_GRAPH_BLEND_PMA_MASK int 血,血w,血h; void MAKE血() { //端が半透明な「血」を作る DeleteGraph(血);int w=100+GetRand(50),h=100+GetRand(50); 血=MakeScreen(w,h,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); GetGraphSize(血,&血w,&血h); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA ,255); SetDrawScreen(DX_SCREEN_BACK); } int 家,家w,家h; void MAKE家() { //半透明の窓や透明部分のある「家」を作る DeleteGraph(家);int w=200+GetRand(50),h=200+GetRand(50); 家=MakeScreen(w,h,1); SetDrawScreen(家);ClearDrawScreen(); DrawBox(10,10,w,h,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);}} GetGraphSize(家,&家w,&家h); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA ,255); SetDrawScreen(DX_SCREEN_BACK); } int 家2,家2w,家2h; void MAKE家2() { //半透明の窓や透明部分のある「家」を作る DeleteGraph(家2);int w=200+GetRand(50),h=200+GetRand(50); 家2=MakeScreen(w,h,1); SetDrawScreen(家2);ClearDrawScreen(); DrawBox(10,10,w,h,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);}} GetGraphSize(家2,&家2w,&家2h); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA ,255); SetDrawScreen(DX_SCREEN_BACK); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ) ;SetWaitVSyncFlag( FALSE ) ; DxLib_Init(); SetUsePremulAlphaConvertLoad(1); MAKE血(); MAKE家();MAKE家2(); float sz=2;//血のサイズ(※倍率) int time=0; 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; time++;MOUx=GetRand(100);MOUy=GetRand(100); if(time%2==1&&MOUo==0) { MAKE血(); MAKE家();MAKE家2(); GraphBlendRectBlt2(家,血,家2, MOUx-血w/2*sz,MOUy-血h/2*sz,MOUx+血w/2*sz,MOUy+血h/2*sz,//Src 0,0,血w,血h, //Blend MOUx-血w/2*sz,MOUy-血h/2*sz, //Dest 255,DX_GRAPH_BLEND_PMA_MASK ); } ClearDrawScreen(); DrawBox(0,0,1000,1000,GetColor(0,0,100),1); DrawGraph(100,100,家2,1); ScreenFlip(); } DxLib_End() ; return 0 ; }
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.47 )
名前:管理人 日時:2023/11/05 13:04

> もしくは内部的には同じだったりで、その方法では改善しないという事になりますでしょうか? はい、GraphBlend は内部では int W, H ; GetGraphSize( GrHandle, &W, &H ) ; GraphBlendRectBlt2( GrHandle, BlendGrHandle, GrHandle, 0, 0, W, H, 0, 0, W, H, 0, 0, BlendRatio, ... と同じ処理を行っています
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.48 )
名前:たろう 日時:2023/11/05 17:05

ありがとうございますm(__)m またいろいろ試したのですが、 GraphBlendRectBlt2をGraphBlendに取り換えて 他のブレンド(DX_GRAPH_BLEND_PMA_MULTIPLE_A_ONLYなど)を使っても 同じ問題が発生することを確認しました。 下のプログラムの様に MakeScreenで血と家を作ってから、ScreenFlip();を1回挟んで GraphBlendRectBlt2をするとメモリが増え続ける事は無くなるようです。 DirectX側の問題で発生している不具合かもしれませんが、これは例えば DXライブラリ側でメモリの増加を回避するヒントになりませんでしょうか? ※とりあえずは、MakeScreenしたターンにGraphBlendをしないようにすることで、 回避できそうなので、他に方法がなければそれで気を付けて使っていくようにします お手数をおかけいたします、 よろしくお願いいたしますm(__)m --------------------------------------------------------- #include "DxLib.h" int 血,血w,血h; void MAKE血() { //端が半透明な「血」を作る DeleteGraph(血);int w=100+GetRand(50),h=100+GetRand(50); 血=MakeScreen(w,h,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); GetGraphSize(血,&血w,&血h); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA ,255); SetDrawScreen(DX_SCREEN_BACK); } int 家,家w,家h; void MAKE家() { //半透明の窓や透明部分のある「家」を作る DeleteGraph(家);int w=200+GetRand(50),h=200+GetRand(50); 家=MakeScreen(w,h,1); SetDrawScreen(家);ClearDrawScreen(); DrawBox(10,10,w,h,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);}} GetGraphSize(家,&家w,&家h); SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA ,255); SetDrawScreen(DX_SCREEN_BACK); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ) ;SetWaitVSyncFlag( FALSE ) ; DxLib_Init(); SetUsePremulAlphaConvertLoad(1); //for(int i=0;i<100;i++){MAKE血(); MAKE家();} float sz=2;//血のサイズ(※倍率) int time=0; 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; time++;MOUx=GetRand(100);MOUy=GetRand(100); if(time%2==1){MAKE血(); MAKE家();}ScreenFlip(); if(time%2==1&&MOUo==0) { GraphBlendRectBlt2(家,血,家, MOUx-血w/2*sz,MOUy-血h/2*sz,MOUx+血w/2*sz,MOUy+血h/2*sz,//Src 0,0,血w,血h, //Blend MOUx-血w/2*sz,MOUy-血h/2*sz, //Dest 255,DX_GRAPH_BLEND_PMA_MASK ); } ClearDrawScreen(); DrawBox(0,0,1000,1000,GetColor(0,0,100),1); DrawGraph(100,100,家,1); } DxLib_End() ; return 0 ; }
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.49 )
名前:管理人 日時:2023/11/05 23:57

> DirectX側の問題で発生している不具合かもしれませんが、これは例えば > DXライブラリ側でメモリの増加を回避するヒントになりませんでしょうか? 公式の仕様・資料に載っていない DirectX 内部の処理を推測していい感じに動作するように 敢えて捻った処理を行う、ということをしても、グラフィックデバイスのドライバが変わっただけで その効果が失われたり、OSのバージョンが変わると逆効果になってしまったりするので、基本的に 『行儀の良い使い方をして少し変なことが起こっても、下手に捻った処理はしないようにする』のが 正解だったりします なので、申し訳ありませんが > ※とりあえずは、MakeScreenしたターンにGraphBlendをしないようにすることで、 > 回避できそうなので、他に方法がなければそれで気を付けて使っていくようにします ↑ こちらの対処方で凌いで頂ければと思います m(_ _;m
メンテ
Re: SetDrawBlendModeで、画像のアルファ値のみ張り付けなど ( No.50 )
名前:たろう(解決) 日時:2023/11/06 00:53

いつもありがとうございます 勉強になりますm(__)m 近頃完成させたゲームはMakeScreenとGraphBlendをしまくっていますが、 メモリが増大することはないので、 たぶんよほど無茶をしなければ何とかなるのだと思います。 そのうえで、MakeScreenしたターンにGraphBlendをしないように 気を付けてやっていこうと思いますm(__)m 長々と失礼いたしましたm(__)m
メンテ

Page: 1 | 2 | 3 |

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

   クッキー保存