トップページ > 記事閲覧
MakeScreen使用時におけるブレンドモードの指定について
名前:ひろかず 日時: 2020/08/29 21:11

お世話になります。 MakeScreenの正しい使用方法が分からず質問いたします。 これまで、画面の描画は「裏の画面」に直接描画していたのですが、場面によっては拡大などの加工をした上で 表示したくなった為、直接描画をやめてMakeScreenで一時用の画像を作成し、そこに描画するように変更しました。 そうしたところ、直接描画とは表示のされ方が変わってしまいました。 具体的には、半透明の描写が変わってしまいます。 どうしたら、直接描画と同じ描画が出来るようになるのでしょうか? 教えて下さい。 おそらく、ブレンドモードの設定が間違っているのかと思うのですが、解決方法を見つけられませんでした。 「乗算済みアルファのすすめ」を読んだのですが、いまいち理解出来ていない状況です。 以下がテスト用のサンプルプログラムです。 実行するにはテスト用の画像が必要です。 32x32ドットの画像を作成しました。内容はcolor255,255,255で全て塗りつぶし、中心部分を透明度50%にしたアルファチャンネル付きのpng画像です。 ちょうと「乗算済みアルファのすすめ」にある画像に似たものです。 お手数をお掛けしますが「test.png」を自作願います。 #include "DxLib.h" int GrHandle1; int GrHandle2; int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { // ウインドウモードに変更 ChangeWindowMode(TRUE); // DXライブラリの初期化、失敗したら終了 if (DxLib_Init() == -1) return -1; // 描画先グラフィック領域の指定(裏画面) SetDrawScreen(DX_SCREEN_BACK); // 透過情報付きpng画像の読み込み(32x32dot) GrHandle1 = LoadGraph("test.png"); // メインループ while (ProcessMessage() == 0 && ClearDrawScreen() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) { //---------------------------------------------- // ■1.直接描画の場合 // 描画の際のブレンドモードを指定(ノーブレンド) SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 255); // 画像を座標(0,0)に転送(画像の透明度を有効) DrawRectGraph(0, 0, 0, 0, 32, 32, GrHandle1, TRUE, FALSE); //---------------------------------------------- // ■2.MakeScreenに描画の場合 その1(ノーブレンド) // 描画対象にできるグラフィックを作成(アルファチャンネル付き、32x32dot) GrHandle2 = MakeScreen(32, 32, TRUE); // 作成した画像を描画対象にする SetDrawScreen(GrHandle2); // 画像を転送(画像の透明度を有効) DrawGraph(0, 0, GrHandle1, TRUE); // 裏の画面を描画対象にする SetDrawScreen(DX_SCREEN_BACK); // 画像を座標(64,0)に転送(画像の透明度を有効) DrawRectGraph(64, 0, 0, 0, 32, 32, GrHandle2, TRUE, FALSE); //---------------------------------------------- // ■3.MakeScreenに描画の場合 その2(ブレンドモードを乗算済みアルファに変更) // 作成した画像を描画対象にする SetDrawScreen(GrHandle2); // 描画の際のブレンドモードを指定(乗算済みアルファ) SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA, 255); // 画像を転送(画像の透明度を有効) DrawGraph(0, 0, GrHandle1, TRUE); // 裏の画面を描画対象にする SetDrawScreen(DX_SCREEN_BACK); // 画像を座標(128,0)に転送(画像の透明度を有効) DrawRectGraph(128, 0, 0, 0, 32, 32, GrHandle2, TRUE, FALSE); //---------------------------------------------- // 裏画面の内容を表画面に反映 ScreenFlip(); } // DXライブラリ使用の終了処理 DxLib_End(); // 終了 return 0; } 「1.直接描画の場合」は期待通りの描画がされています。中央の半透明部分はcolor128,128,128の灰色で描画されます。 「2.MakeScreenに描画の場合 その1」は直接描画と同じブレンドモードで描画していますが、中央の半透明部分はcolor32,32,32の灰色で描画されます。 「3.MakeScreenに描画の場合 その2」はブレンドモードを乗算済みアルファで描画していますが、中央の半透明部分がcolor255,255,255の白に なってしまいました。 どういった設定をすれば、直接描画と同じ状態になるのでしょうか? 何卒、よろしくお願い申し上げます。
メンテ

Page: 1 |

Re: MakeScreen使用時におけるブレンドモードの指定について ( No.1 )
名前:kanamaru 日時:2020/08/29 22:18

間違ってたらすいません。 プログラム見て思ったんですけど、 DrawGraphとDrawRectGraphで二回ブレンドが適用されてるのかもしれません。 DrawRectGraphはブレンドが適用されてる関数の中にはないですけど。 (管理人さん、DrawRectGraphでもブレンド適用されるならリファレンスに追加しておいてください) 試しにMakeScreen使ってる版のDrawRectGraphの前にSetDrawBlendModeにDX_BLENDMODE_NOBLEND指定したのを追加してみたらどうなりますか? こちらでも試したいですがαチャンネルがある画像を作成できる環境が無いのです。 ただ上記が原因だとすると一個おかしなことがたぶん起きてるんです。 ノーブレンドの時は問題ないはず。なのに気のせいか色の変化的に不透明度が二回計算されてるような気がします。 計算あってるかわからないけど50%の50%は25%、実際、128から32って四分の一になってますし。
メンテ
Re: MakeScreen使用時におけるブレンドモードの指定について ( No.2 )
名前:ひろかず 日時:2020/08/30 06:11

>kanamaru さん ご返信頂き、誠に有り難うございます。 >試しにMakeScreen使ってる版のDrawRectGraphの前にSetDrawBlendModeにDX_BLENDMODE_NOBLEND指定したのを追加してみたらどうなりますか? ご指摘頂きました件について、試してみました。 「3.MakeScreenに描画の場合 その2」に、DrawRectGraphの直前に // 描画の際のブレンドモードを指定(ノーブレンド) SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 255); を追加しました。 そうした結果、中央の半透明部分はcolor160,160,160の灰色で描画されました。 やはり、直接描画とは違った結果になります。 何卒、よろしくお願い申し上げます。
メンテ
Re: MakeScreen使用時におけるブレンドモードの指定について ( No.3 )
名前:ひろかず(解決) 日時:2020/08/30 07:54

すみません。 その後、色々と試してみました。 MakeScreenの画像を初期化していないのに気づきました。 「3.MakeScreenに描画の場合 その2」のSetDrawScreenの後に、 // 画像を初期化する ClearDrawScreen(); をさらに追加しました。 これで、直接描画と同じ結果になりました。 有り難うございました。
メンテ
Re: MakeScreen使用時におけるブレンドモードの指定について ( No.4 )
名前:ひろかず 日時:2020/08/30 08:41

何度も申し訳ございません。 その後、色々と試したのですが、問題が解決していませんでした。 最初に貼り付けましたプログラムは色々と間違いがありましたので、修正しました。 以下が修正したプログラムとなります。 テストに使用する画像もアップロードさせて頂きました。 ttp://s.kota2.net/1598744046.png ※「test.png」の名前で保存してください。 #include "DxLib.h" int GrHandle1; int GrHandle2; int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { // ウインドウモードに変更 ChangeWindowMode(TRUE); // DXライブラリの初期化、失敗したら終了 if (DxLib_Init() == -1) return -1; // 描画先グラフィック領域の指定(裏画面) SetDrawScreen(DX_SCREEN_BACK); // 透過情報付きpng画像の読み込み(64x32dot) GrHandle1 = LoadGraph("test.png"); // 描画対象にできるグラフィックを作成(アルファチャンネル付き、32x32dot) GrHandle2 = MakeScreen(32, 32, TRUE); // メインループ while (ProcessMessage() == 0 && ClearDrawScreen() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) { //---------------------------------------------- // ■1.直接描画の場合 // 描画の際のブレンドモードを指定(ノーブレンド) SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 255); // 白の画像を座標(0,0)に転送(画像の透明度を有効) DrawRectGraph(0, 0, 0, 0, 32, 32, GrHandle1, TRUE, FALSE); // 赤の画像を座標(0,0)に転送(画像の透明度を有効) DrawRectGraph(0, 0, 32, 0, 32, 32, GrHandle1, TRUE, FALSE); //---------------------------------------------- // ■2.MakeScreenに描画の場合 その2(ブレンドモードを乗算済みアルファに変更) // MakeScreenで作成した画像を描画対象にする SetDrawScreen(GrHandle2); // MakeScreenの画像を初期化する ClearDrawScreen(); // 描画の際のブレンドモードを指定(乗算済みアルファ) SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA, 255); // 白の画像をMakeScreenで作成した画像に転送(画像の透明度を有効) DrawRectGraph(0, 0, 0, 0, 32, 32, GrHandle1, TRUE, FALSE); // 赤の画像をMakeScreenで作成した画像に転送(画像の透明度を有効) DrawRectGraph(0, 0, 32, 0, 32, 32, GrHandle1, TRUE, FALSE); // 裏の画面を描画対象にする SetDrawScreen(DX_SCREEN_BACK); // 描画の際のブレンドモードを指定(ノーブレンド) SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 255); // 画像を座標(96,0)に転送(画像の透明度を有効) DrawRectGraph(96, 0, 0, 0, 32, 32, GrHandle2, TRUE, FALSE); //---------------------------------------------- // 裏画面の内容を表画面に反映 ScreenFlip(); } // DXライブラリ使用の終了処理 DxLib_End(); // 終了 return 0; } どういう方法を取れば直接描画と同じ結果になるのでしょうか? 以上、何卒よろしくお願い申し上げます。
メンテ
Re: MakeScreen使用時におけるブレンドモードの指定について ( No.5 )
名前:管理人 日時:2020/08/31 02:10

載せていただいたプログラムを以下のように変更したら、正常な描画結果が得られました #include "DxLib.h" int GrHandle1; int GrHandle1PMA; int GrHandle2; int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) { // ウインドウモードに変更 ChangeWindowMode(TRUE); // DXライブラリの初期化、失敗したら終了 if (DxLib_Init() == -1) return -1; // 描画先グラフィック領域の指定(裏画面) SetDrawScreen(DX_SCREEN_BACK); // 透過情報付きpng画像の読み込み(64x32dot) GrHandle1 = LoadGraph("test.png"); // 通常のアルファチャンネル付き画像を、乗算済みアルファの画像に変換しながら読み込む設定を ON にする SetUsePremulAlphaConvertLoad( TRUE ) ; // 乗算済みアルファに変換したpng画像の読み込み GrHandle1PMA = LoadGraph("test.png"); // 描画対象にできるグラフィックを作成(アルファチャンネル付き、32x32dot) GrHandle2 = MakeScreen(32, 32, TRUE); // メインループ while (ProcessMessage() == 0 && ClearDrawScreen() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) { //---------------------------------------------- // ■1.直接描画の場合 // 描画の際のブレンドモードを指定(ノーブレンド) SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 255); // 白の画像を座標(0,0)に転送(画像の透明度を有効) DrawRectGraph(0, 0, 0, 0, 32, 32, GrHandle1, TRUE, FALSE); // 赤の画像を座標(0,0)に転送(画像の透明度を有効) DrawRectGraph(0, 0, 32, 0, 32, 32, GrHandle1, TRUE, FALSE); //---------------------------------------------- // ■2.MakeScreenに描画の場合 その2(ブレンドモードを乗算済みアルファに変更) // MakeScreenで作成した画像を描画対象にする SetDrawScreen(GrHandle2); // MakeScreenの画像を初期化する ClearDrawScreen(); // 描画の際のブレンドモードを指定(乗算済みアルファ) SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA, 255); // 白の画像をMakeScreenで作成した画像に転送(画像の透明度を有効) DrawRectGraph(0, 0, 0, 0, 32, 32, GrHandle1PMA, TRUE, FALSE); // 赤の画像をMakeScreenで作成した画像に転送(画像の透明度を有効) DrawRectGraph(0, 0, 32, 0, 32, 32, GrHandle1PMA, TRUE, FALSE); // 裏の画面を描画対象にする SetDrawScreen(DX_SCREEN_BACK); // 描画の際のブレンドモードを指定(ノーブレンド) SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA, 255); // 画像を座標(96,0)に転送(画像の透明度を有効) DrawRectGraph(96, 0, 0, 0, 32, 32, GrHandle2, TRUE, FALSE); //---------------------------------------------- // 裏画面の内容を表画面に反映 ScreenFlip(); } // DXライブラリ使用の終了処理 DxLib_End(); // 終了 return 0; } 『乗算済みアルファ』の設定( DX_BLENDMODE_PMA_ALPHA )で描画する画像は、乗算済みアルファの画像である 必要がありますので、LoadGraph で読み込む前に SetUsePremulAlphaConvertLoad( TRUE ) ; を実行して、 『通常のアルファチャンネル付きの画像』を『乗算済みアルファの画像』に変換する必要があります ( なので、GrHandle1 とは別に GrHandle1PMA という変数に読み込んでいます ) あと、最後に裏画面に GrHandle2 を描画する際も『乗算済みアルファ』の設定( DX_BLENDMODE_PMA_ALPHA )で 描画する必要があります( GrHandle2 は『乗算済みアルファの画像』となっているので… ) よろしければお試しください m(_ _)m
メンテ
Re: MakeScreen使用時におけるブレンドモードの指定について ( No.6 )
名前:ひろかず(解決) 日時:2020/08/31 20:42

ご返信頂き、誠に有り難うございます。 修正して頂きましたプログラムで正常に動作する事を確認いたしました。 感謝申し上げます。有り難うございました。 画像ファイルを読み込む際に「SetUsePremulAlphaConvertLoad( TRUE ) ;」を記述して「乗算済みアルファの画像」に変換する必要があるのですね。 今一度、「乗算済みアルファのすすめ」を読み直して、上記の記載があることに気づきました。 大変お手数をお掛けしました。申し訳ございません。 以下、別件のお話になります。 プログラミングの際には、いつも「関数リファレンスページ」をありがたく利用させて頂いております。 その中で幾つかリンクミスを見つけました。 些末な事ではございますが、修正して頂けますと大変助かります。 ■リンク修正を要するページ ttps://dxlib.xsrv.jp/function/dxfunc_graph1.html 1「DrawPixel」のリンク間違い(1箇所) 誤 ttps://dxlib.xsrv.jp/function/dxfunc_graph1.html#R2N4 正 ttps://dxlib.xsrv.jp/function/dxfunc_graph0.html#R2N5 2「DrawCircle」のリンク間違い(1箇所) 誤 ttps://dxlib.xsrv.jp/function/dxfunc_graph1.html#R2N3 正 ttps://dxlib.xsrv.jp/function/dxfunc_graph0.html#R2N3 3「DrawLine」のリンク間違い(1箇所) 誤 ttps://dxlib.xsrv.jp/function/dxfunc_graph1.html#R2N1 正 ttps://dxlib.xsrv.jp/function/dxfunc_graph0.html#R2N1 4「DrawBox」のリンク間違い(4箇所) 誤 ttps://dxlib.xsrv.jp/function/dxfunc_graph1.html#R2N2 正 ttps://dxlib.xsrv.jp/function/dxfunc_graph0.html#R2N2 何卒、よろしくお願い申し上げます。
メンテ
Re: MakeScreen使用時におけるブレンドモードの指定について ( No.7 )
名前:管理人(解決) 日時:2020/09/01 00:23

リンクミスのご報告ありがとうございます 修正しました m(_ _)m
メンテ

Page: 1 |

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

   クッキー保存