トップページ > 記事閲覧
文字色の反転
名前:s8079 日時: 2017/05/27 10:14

いつもお世話になっております。 今回は文字色の反転をしたいのですが,方法が分かりません。 一般的にはセンシルバッファと呼ばれる技術を使うそうですが,そういった類いの関数はあるのでしょうか。 マスクやブレンドをうまく使えばできるような気がしないこともないですが,そのあたりの熟練度が低いため困っております。 文字色の反転というのはリンク先の画像ようなもののことです。 illustrator-ok.com/main_bbs/img/154x320x20276.jpg.pagespeed.ic.VQqe0GiA_0.jpg
メンテ

Page: 1 |

Re: 文字色の反転 ( No.1 )
名前:管理人 日時:2017/05/27 23:20

文字色の反転、というより箱と重なっている文字の部分を白色にする、という感じですよね?( 白の文字を反転したら黒なので ) センシルバッファという言葉で検索しても何も引っかからなかったので、何か別の名称の誤りでしょうか? ともあれ、お察しの通りブレンドで表現することができます( マスクを使用する必要はありません ) 載せていただいたURLの画像のような表現をするプログラムを組んでみましたので、よろしければご覧ください m(_ _)m #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int BoxMaskScreen ; int StringMaskScreen ; int BoxStringMixMaskScreen ; int FontHandle ; ChangeWindowMode( TRUE ) ; SetGraphMode( 316, 654, 32 ) ; // ライブラリ初期化 if( DxLib_Init() == -1 ) return 0 ; // 箱マスク画面の作成 BoxMaskScreen = MakeScreen( 316, 654, TRUE ) ; // 文字マスク画面の作成 StringMaskScreen = MakeScreen( 316, 654, TRUE ) ; // 箱マスクと文字マスクを合成した結果を出力する画面の作成 BoxStringMixMaskScreen = MakeScreen( 316, 654, TRUE ) ; // 縦書き用のフォントハンドルを作成 FontHandle = CreateFontToHandle( "@MS 明朝", 100, 16, DX_FONTTYPE_ANTIALIASING_4X4 ) ; // 箱マスク画面に箱を白色で描画 SetDrawScreen( BoxMaskScreen ) ; ClearDrawScreen() ; DrawBox( 31, 18, 148, 133, GetColor( 255,255,255 ), TRUE ) ; DrawBox( 149, 134, 266, 250, GetColor( 255,255,255 ), TRUE ) ; DrawBox( 31, 251, 148, 366, GetColor( 255,255,255 ), TRUE ) ; DrawBox( 149, 367, 266, 482, GetColor( 255,255,255 ), TRUE ) ; DrawBox( 31, 483, 148, 599, GetColor( 255,255,255 ), TRUE ) ; // 文字マスク画面に文字を白色で描画 SetDrawScreen( StringMaskScreen ) ; ClearDrawScreen() ; DrawVStringToHandle( 95, 60, "あいうえお", GetColor( 255,255,255 ), FontHandle ) ; // 箱マスク画面と文字マスク画面を合成 // ( どちらの画面でも透明ではない部分を抜き出し ) GraphBlendBlt( BoxMaskScreen, StringMaskScreen, BoxStringMixMaskScreen, 255, DX_GRAPH_BLEND_MULTIPLE_A_ONLY ) ; // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // 画面全体を真っ白に塗りつぶす DrawBox( 0, 0, 316, 654, GetColor( 255,255,255 ), TRUE ) ; // 箱マスク画面を赤色で描画 SetDrawBright( 153, 52, 0 ) ; DrawGraph( 0, 0, BoxMaskScreen, TRUE ) ; SetDrawBright( 255,255,255 ) ; // 赤色の文字を描画 DrawVStringToHandle( 95, 60, "あいうえお", GetColor( 153, 52, 0 ), FontHandle ) ; // 箱マスク画面と文字マスク画面の重なっている部分を白色で描画 DrawGraph( 0, 0, BoxStringMixMaskScreen, TRUE ) ; // 裏画面の内容を表画面に反映 ScreenFlip(); while( ProcessMessage() == 0 ) { Sleep( 1 ) ; } //終了 DxLib_End(); return 0 ; } 手順としては   1. 箱の部分だけの画像を作成   2. 文字の部分だけの画像を作成   3. 箱と文字が重なっている部分を抽出   4. 裏画面を真っ白にする   5. 裏画面に赤色で四角形と文字を描画する   6. 裏画面に 3 で抽出した『箱と文字が重なっている部分』を白で描画する となっています、箱と文字が重なっている部分を抽出しているのがポイントです
メンテ
Re: 文字色の反転 ( No.2 )
名前:N 日時:2017/05/28 13:11

この程度であれば、描画対象スクリーンを使うと煩雑になるので、マスクを使ってしまえばいいのではないでしょうか? 以下のような手順にすれば、描画対象を作らずとも、裏画面とマスクのみで完結するかと思われます。  背景部分の市松模様を描画  マスクを設定し、文字部分のみ描画できるようにする  逆位置の市松模様を描画
メンテ
Re: 文字色の反転 ( No.3 )
名前:s8079 日時:2017/05/28 15:58

なるほど。 丁寧な説明ありがとうございます。 あと,「センシル」ではなく,「ステンシル」です。 間違えました。
メンテ
Re: 文字色の反転 ( No.4 )
名前:管理人 日時:2017/05/28 20:24

> あと,「センシル」ではなく,「ステンシル」です。 > 間違えました。 承知しました > Nさん DXライブラリのマスク処理は重いのと、マスクの画像を用意してサーバーにアップするのを 避けたかったので GraphBlend を使用する方法にしました
メンテ
Re: 文字色の反転 ( No.5 )
名前:s8079 日時:2017/05/29 02:24

少し話題が変わってしまいますが, MakeScreen関数で作成したグラフィックはDeleteGraph関数で削除しなくても大丈夫なのでしょうか。 while( ProcessMessage() == 0 ) { int MaskScreen = MakeScreen( 316, 654, TRUE ) ; } 上記のようなプログラムを書くとメモリの使用率が大変なことになるのですが… あと,CreateGraphFromSoftImage関数も大変なことになります。
メンテ
Re: 文字色の反転 ( No.6 )
名前:N 日時:2017/05/29 04:23

MakeScreenで作成するスクリーンは画像をロードする時と同じように、予めループの外で作成しておいて、ハンドルを変数に保存しておくのが通常かと思われます。 毎フレーム作って消しては重そうですが、、、どうなんでしょう
メンテ
Re: 文字色の反転 ( No.7 )
名前:yumetodo 日時:2017/05/29 13:52

スクリーンの作成がそんなにコストがかかるという認識はしていなかったんですがどうなんでしょうか・・・(メモリー使用量はともかく)
メンテ
Re: 文字色の反転 ( No.8 )
名前:管理人 日時:2017/05/30 01:59

> MakeScreen関数で作成したグラフィックはDeleteGraph関数で削除しなくても大丈夫なのでしょうか。 お察しの通り、削除しないと駄目です すみません、サンプルでは削除していませんでした… ただ、Nさんが仰られていますように、作業で使用する画像はメインループが始まる前に MakeScreen で作成しておいて、 ソフトを終了する際に DeleteGraph で削除する、というのが一般的な方法です 処理を行う対象となる画像のサイズが毎回異なる、という場合でしたらメインループ内で MakeScreen → 描画処理 → DeleteGraph という形で毎フレーム作成と削除を行うしかありませんが、 メインループの前に一回だけ MakeScreen する場合よりは負荷が大きくなります > yumetodoさん 手元のPCで MakeScreen( 1024, 1024 ); と DeleteGraph を 100回繰り返したところ 6ms 掛かりました 今回の処理は1回で 3つの作業用スクリーンが必要なので、今回の処理を33回実行すると MakeScreen + DeleteGraph だけで 6ms となります 多用しなければ問題がある程の負荷ではありませんが、全く気にしなくて良い程軽いというわけでもなさそうです
メンテ
Re: 文字色の反転 ( No.9 )
名前:s8079 日時:2017/05/30 16:24

関数リファレンスページに記載されているサンプルも修正していただいた方がよいかと思います。 どうやら,グラフィックハンドルに関してのみ削除を忘れておられるようです。(MakeScreen,MakeGraph等) 一度ご確認ください。
メンテ
Re: 文字色の反転 ( No.10 )
名前:管理人 日時:2017/05/30 23:12

ご指摘ありがとうございます、修正します DxLib_End を実行すると自動的にグラフィックハンドルが削除されるので、サンプルのように一度だけ使用して すぐにプログラムが終了する場合は問題は発生しないので、サンプルプログラムが間違っている、というわけではないのですが、 確かに DeleteGraph が殆ど使用されていないと削除しなくても良いかのように感じてしまう可能性が高いですね… MakeScreen, MakeGraph に限らず、LoadGraph や LoadDivGraph なども含めると修正の対象となるサンプルが大量にあるので、 少しづつ進めていこうと思います
メンテ
Re: 文字色の反転 ( No.11 )
名前:yumetodo 日時:2017/05/31 00:12

そういえばハンドルの数って何個まで作れるんでしょう?まさか0〜INT_MAXではないでしょうし
メンテ
Re: 文字色の反転 ( No.12 )
名前:管理人 日時:2017/05/31 01:02

> s8079さん DeleteGraph, DeleteSoundMem, DeleteMask, MV1DeleteModel などの、読み込み関数と対になる 削除関数の呼び出しをリファレンスのサンプルに追加しました( 思ったより早く終わりました ) > yumetodoさん 作成できるハンドルの上限は DxLib.h に記載されていて、このような感じです #define MAX_IMAGE_NUM (32768) // 同時に持てるグラフィックハンドルの最大数 #define MAX_SHADOWMAP_NUM (8192) // シャドウマップデータの最大数 #define MAX_SOFTIMAGE_NUM (8192) // 同時に持てるソフトイメージハンドルの最大数 #define MAX_SOUND_NUM (32768) // 同時に持てるサウンドハンドルの最大数 #define MAX_SOFTSOUND_NUM (8192) // 同時に持てるソフトウエアサウンドハンドルの最大数 #define MAX_MUSIC_NUM (256) // 同時に持てるミュージックハンドルの最大数 #define MAX_MOVIE_NUM (100) // 同時に持てるムービーハンドルの最大数 #define MAX_MASK_NUM (512) // 同時に持てるマスクハンドルの最大数 #define MAX_FONT_NUM (40) // 同時に持てるフォントハンドルの最大数 #define MAX_INPUT_NUM (256) // 同時に持てる文字列入力ハンドルの最大数 #define MAX_SOCKET_NUM (8192) // 同時に持てる通信ハンドルの最大数 #define MAX_LIGHT_NUM (4096) // 同時に持てるライトハンドルの最大数 #define MAX_SHADER_NUM (4096) // 同時に持てるシェーダーハンドルの最大数 #define MAX_CONSTANT_BUFFER_NUM (8192) // 同時に持てる定数バッファハンドルの最大数 #define MAX_MODEL_BASE_NUM (32768) // 同時に持てる3Dモデル基本データハンドルの最大数 #define MAX_MODEL_NUM (32768) // 同時に持てる3Dモデルデータハンドルの最大数 #define MAX_VERTEX_BUFFER_NUM (16384) // 同時に持てる頂点バッファハンドルの最大数 #define MAX_INDEX_BUFFER_NUM (16384) // 同時に持てるインデックスバッファの最大数 #define MAX_FILE_NUM (32768) // 同時に持てるファイルハンドルの最大数 かつては処理もメモリ使用量も多かったのでフォントハンドルは 40個が上限となっていますが、 思えば今ならもっと多くても良いですね…
メンテ

Page: 1 |

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

   クッキー保存