Re: 管理人様にお尋ねしたいこと ( No.1 ) |
- 名前:いっち 日時:2010/11/28 14:15
管理人さんではなくて申し訳ありませんが、一応確認させてください。
ご存知かと思いますが、DXライブラリでデスクトップマスコットのようなものを作成する場合、
通常 SetUseBackBufferTransColorFlag 等を利用するのだと思います(私は作成したことありませんが)。
> ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=1616
SetUseBackBufferTransColorFlag を使用しない理由があるのであれば明らかにしておいたほうが宜しいかと思います。
|
Re: 管理人様にお尋ねしたいこと ( No.2 ) |
- 名前:陽奈 日時:2010/11/28 15:21
> SetUseBackBufferTransColorFlag を使用しない理由があるのであれば明らかにしておいたほうが宜しいかと思います。
すいません、明記しないとちょっとわかりにくりでした
この関数ではウィンドウの境界に半透明の情報を持ったもの、つまり
> ttp://park21.wakwak.com/~ayacy/inasoft/pic/wpt/sample_output2.png
↑このような物を作るには
SetUseBackBufferTransColorFlag では通用しないのでは・・・と思いお尋ねした次第です
あと、私が作ろうとしているデスクトップマスコットなるものは3DではなくApricotのような2Dのもので、そのインターフェイスにあたる部分でこの問題に突き当たっています
|
Re: 管理人様にお尋ねしたいこと ( No.3 ) |
- 名前:いっち 日時:2010/11/28 16:05
> あと、私が作ろうとしているデスクトップマスコットなるものは3DではなくApricotのような2Dのもので、そのインターフェイスにあたる部分でこの問題に突き当たっています
Apricot がどの様な物か存じ上げないのですが、先ほどのスレッドのレス(No.8)にあるサンプル(UpdateLayerdWindow.zip)では、
透過情報付のPNGをデスクトップ背景とのアルファブレンドで描画しています。
ですので、陽奈さんの仰るようなプログラムも作成可能なのではないかと思うのですがどうでしょうか?
※UpdateLayerdWindow.zipに含まれる実行ファイルはビルドが少し古いようなのでリビルドされることをお勧めします。
|
Re: 管理人様にお尋ねしたいこと ( No.4 ) |
- 名前:陽奈 日時:2010/11/28 16:51
> ※UpdateLayerdWindow.zipに含まれる実行ファイルはビルドが少し古いようなのでリビルドされることをお勧めします。
すみません、なぜか私の環境ではリビルドすると
後ろの円が消えてしまいます
さらにいくつかの画像で試した結果
画像を重ねたときのみαブレンドが行われ
デスクトップに直接重ねるときはαブレンドする領域が消えてしまいました
|
Re: 管理人様にお尋ねしたいこと ( No.5 ) |
- 名前:いっち 日時:2010/11/28 17:49
私の環境でもリビルドして実行すると同様の事象となりました。(試さずにリビルドをお勧めしてました。ごめんなさい)
さすがに画像が表示されないのはおかしいと思うので、もう少し調べてみます。
(もうしばらくすると管理人さんから直接回答を頂けるかもしれません)
|
Re: 管理人様にお尋ねしたいこと ( No.6 ) |
- 名前:陽奈 日時:2010/11/28 18:05
少しいろいろ試した結果
// 裏画面の描画結果を透過色つきで画面出力用のソフトウエア画像に転送
BltSoftImageWithTransColor( 0, 0, 640, 480, capsofthandle, 0, 0, screensofthandle, 255, 0, 255, 0 ) ;
// 64ドット右下にずらした位置に同じ画像をアルファ値を考慮した転送
BltSoftImageWithAlphaBlend( 0, 0, 256, 256, softhandle, 64, 64, screensofthandle, 255 ) ;
これらの背後に画像がある状態なら正常にαブレンドが行われ
ない場合にαブレンドが無効になるっと言った結果になりました
先ほどサンプルで画像が消えてしまうといった理由はたぶん画像すべてがアルファ情報を持っているためではないかと思われます
して、この結果からBltSoftImage関連に何かあると思うのですが・・・
|
Re: 管理人様にお尋ねしたいこと ( No.7 ) |
- 名前:いっち 日時:2010/11/28 20:42
だいたい分かりました。
とりあえず AlphaCircle.png を以下のURLのファイルと置き換えてみてください。
> ttp://www1.axfc.net/uploader/Img/so/101442.png
以下に事象の推測です。
おそらく UpdateLayerdWindowForSoftImage の中でアルファチャネルと透過色の両方の透明処理が行われており、
AlphaCircle.png で使用されている色がデフォルトの透過色(黒)のため AlphaCircle.png のすべてが透明として扱われているのだと思います。
DXライブラリでは通常、アルファチャネル付の画像の描画(読み込み)の際は透過色を無視するはずなので、おそらくバグではないかと思います。
|
Re: 管理人様にお尋ねしたいこと ( No.8 ) |
- 名前:陽奈 日時:2010/11/28 21:08
なるほど・・・
確かにほかの色の場合は透過するようですね
ではUpdateLayerdWindowForSoftImageでのαチャンネル付き画像が読み込まれた際の場合分け処理がなされていないというわけですか……?
うーむ
ここはやはり管理人さんにお願いするしかないようですね
|
Re: 管理人様にお尋ねしたいこと ( No.9 ) |
- 名前:陽奈_バグ報告 日時:2010/11/29 19:11
なかなか管理人さんがいらっしゃらないようですが……?
最近多忙と聞いていますが、このスレは流されてしまったのでしょうか
|
Re: 管理人様にお尋ねしたいこと ( No.10 ) |
- 名前:Will 日時:2010/11/30 15:51
管理人さんは多忙な方なのでお返事が付くのは一週間か二週間に一度ぐらいです。
回答が必要なものはどれだけ下がっても忘れず回答してくれますので気長に待ってあげてください。
|
Re: 管理人様にお尋ねしたいこと ( No.11 ) |
- 名前:管理人 日時:2010/12/01 08:37
すみません、毎週、週末にご返信するようにしているのですが、
今回は作業量を見誤って週末内にご返信に必要な作業を終えることができませんでした
SetUseBackBufferTransColorFlag と UpdateLayerdWindowForSoftImage を用いた
半透明ウインドウの表示ですが、何かの対応の過程で
UpdateLayerdWindowForSoftImage の際に
「そのとき SetTransColor で透過色に設定されている色がデスクトップに転送されない」
ようになったため、この仕様変更を行う前に作成したサンプル UpdateLayerdWindow.zip の
プログラムでは半透明の円が消えてしまうことになってしまいました
( デフォルトでは SetTransColor の設定値は 真っ黒( R=0, G=0, B=0 ) なので
UpdateLayerdWindowForSoftImage の際に、真っ黒で不透明度だけ0ではない
黒い円は透過色の判定で透過色として判断されて転送されない )
なので、透過色を R=255 G=0 B=255 などの真っ黒以外にすることで
真っ黒の円が透過色として透過されずに済むので UpdateLayerdWindow,zip の中の実行ファイルと
同じ実行結果を得られるようになります
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int screensofthandle, capsofthandle, softhandle, grhandle ;
int opacity, opacityadd ;
// ウインドウモードで起動
ChangeWindowMode( TRUE );
// ウインドウの透過色モードON
SetUseBackBufferTransColorFlag( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1;
// 画像の読み込み
softhandle = LoadSoftImage( "AlphaCircle.png" );
grhandle = LoadGraph( "Test1.bmp" ) ;
/* SetTransColor を追加 */
// 透過色を設定
SetTransColor( 255, 0, 255 ) ;
// 画面出力用のソフトウエア画像の作成
screensofthandle = MakeARGB8ColorSoftImage( 640, 480 ) ;
// 画面キャプチャ用のソフトウエア画像の作成
capsofthandle = MakeXRGB8ColorSoftImage( 640, 480 ) ;
// 描画先を裏画面に
SetDrawScreen( DX_SCREEN_BACK ) ;
// メインループ(何かキーが押されたらループを抜ける)
opacity = 255 ;
opacityadd = -1 ;
while( ProcessMessage() == 0 )
{
// 透明度を変更
opacity += opacityadd;
if( opacity <= 0 || opacity >= 255 ) opacityadd = -opacityadd;
// 画面をクリア
ClearDrawScreen() ;
// 画像を描画
DrawGraph( 64, 0, grhandle, TRUE ) ;
// 裏画面への描画結果を取得
GetDrawScreenSoftImage( 0, 0, 640, 480, capsofthandle ) ;
// 画面出力用のソフトウエア画像をクリア
FillSoftImage( screensofthandle, 0, 0, 0, 0 ) ;
// 画面出力用のソフトウエア画像の左上端に読み込んだ画像を転送
BltSoftImage( 0, 0, 256, 256, softhandle, 0, 0, screensofthandle ) ;
// 裏画面の描画結果を透過色つきで画面出力用のソフトウエア画像に転送
BltSoftImageWithTransColor( 0, 0, 640, 480, capsofthandle, 0, 0, screensofthandle, 0, 0, 0, 0 ) ;
// 64ドット右下にずらした位置に同じ画像をアルファ値を考慮した転送
BltSoftImageWithAlphaBlend( 0, 0, 256, 256, softhandle, 64, 64, screensofthandle, opacity ) ;
// 画面出力用のソフトウエア画像を使ってウインドウの表示を更新
UpdateLayerdWindowForSoftImage( screensofthandle ) ;
}
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}
ただ、既存のバージョンで試したところ
// 裏画面の描画結果を透過色つきで画面出力用のソフトウエア画像に転送
BltSoftImageWithTransColor( 0, 0, 640, 480, capsofthandle, 0, 0, screensofthandle, 0, 0, 0, 0 ) ;
この関数の中で上位8bitが無効ビットである32bitカラー画像の capsofthandle の無効ビットの部分も含めて
透過色判定を行ってしまっていたため、正常に透過できる場合と透過できない場合が発生していました
( 無効ビットに書き込まれているビットが0以外だと透過色として判定されない )
そのバグを修正したバージョンをアップしましたので、お手数で申し訳ありませんが
こちらのバージョンをお使いの上、前述の SetTransColor の設定を変更する手順も加えてお試しになってみてください m(_ _;m
http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用
http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用
(中身を既存のライブラリのファイルに上書きして、BCCをお使いの
場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)
|
Re: 管理人様にお尋ねしたいこと ( No.12 ) |
- 名前:陽奈_バグ報告 日時:2010/12/01 21:05
お忙しい中対応ありがとうございます!
ちゃんと透過表示されるようになりました
この関数とウィンドウ描画領域の指定などを組み合わせてレスポンスの速いカスタマイズしたウィンドウを作りたいのですが
(Office 2007,2010やApricotなどのインターフェイス)
(高速計算を必要とするソフト)
FPSはあきらめるしかないのでしょうか?
もしよければ、ウィンドウ枠を画像で指定する関数を実装していただけないでしょうか?
インターフェイスを変えられる高速関数があるととても助かります
すみません、出来きたらでもいいのでお願いします
あと、DrawString()系は改行が出来ないということが書いてありましたが、改行可能にしてみました
変なコードがあるかもしれませんが
もし使えるものなら使ってみていただけないでしょうか
void DrawStringEx(int x,int y,char* string,int color)
{
int offset=0;
char temp_c001[2048];
int l=0;
for(int i=0;i<strlen(string)+1;i++)
{
if(string[i]=='\n')
{
temp_c001[i-offset]='\0';
DrawString(x,y,temp_c001,color);
y+=GetFontSize();
offset=i+1;
int k=strlen(temp_c001);
for(int j=0;j<k;j++)
temp_c001[j]='\0';
}
else
{
temp_c001[i-offset]=string[i];
}
if(string[i]=='\0')
{
temp_c001[i-offset]=string[i];
DrawString(x,y,temp_c001,color);
}
}
l=0;
offset=0;
}
void DrawFormatStringEx(int x,int y,int color,char* formatstring , ...)
{
va_list list;
char *p;
char formatstring001[512];
int i=0;
va_start( list, formatstring );
for(p=formatstring; *p; ++p) /* formatの先頭から末尾まで */
{
if( *p != '%' ) /* フォーマット指定子に必ず付く % 以外なら、そのまま出力 */
{
formatstring001[i]=*p;
i++;
continue;
}
++p; /* % だったら、その直後の文字に応じて出力 */
switch( *p )
{
case 'd':
char t[64];
itoa(va_arg(list, int),t,10);
strcpy(formatstring001+i,t);
i+=strlen(t)-1;
strini(t);
break;
case 'c':
formatstring001[i]=va_arg(list, char);
break;
case 's':
char u[64];
strcpy(u,va_arg(list, char *));
strcpy(formatstring001+i,u);
i+=strlen(u)-1;
strini(u);
break;
default:
formatstring001[i]=*p;
break;
}
i++;
}
formatstring001[i]='\0';
i=0;
va_end( list );
int offset=0;
char temp_c001[512];
int l=0;
for(int i=0;i<strlen(formatstring001)+1;i++)
{
if(formatstring001[i]=='\n')
{
temp_c001[i-offset]='\0';
DrawFormatString(x,y,color,temp_c001);
y+=GetFontSize();
offset=i+1;
int k=strlen(temp_c001);
for(int j=0;j<k;j++)
temp_c001[j]='\0';
}
else
{
temp_c001[i-offset]=formatstring001[i];
}
if(formatstring001[i]=='\0')
{
temp_c001[i-offset]=formatstring001[i];
DrawFormatString(x,y,color,temp_c001);
}
}
l=0;
offset=0;
}
void DrawFormatStringToHandleEx(int x,int y,int color,int fonthandle,char* formatstring , ...)
{
va_list list;
char *p;
char formatstring001[512];
int i=0;
va_start( list, formatstring );
for(p=formatstring; *p; ++p) /* formatの先頭から末尾まで */
{
if( *p != '%' ) /* フォーマット指定子に必ず付く % 以外なら、そのまま出力 */
{
formatstring001[i]=*p;
i++;
continue;
}
++p; /* % だったら、その直後の文字に応じて出力 */
switch( *p )
{
case 'd':
char t[64];
itoa(va_arg(list, int),t,10);
strcpy(formatstring001+i,t);
i+=strlen(t)-1;
strini(t);
break;
case 'c':
formatstring001[i]=va_arg(list, char);
break;
case 's':
char u[64];
strcpy(u,va_arg(list, char *));
strcpy(formatstring001+i,u);
i+=strlen(u)-1;
strini(u);
break;
default:
formatstring001[i]=*p;
break;
}
i++;
}
formatstring001[i]='\0';
i=0;
va_end( list );
int offset=0;
char temp_c001[512];
int l=0;
for(int i=0;i<strlen(formatstring001)+1;i++)
{
if(formatstring001[i]=='\n')
{
temp_c001[i-offset]='\0';
DrawFormatStringToHandle(x,y,color,fonthandle,temp_c001);
y+=GetFontSizeToHandle(fonthandle);
offset=i+1;
int k=strlen(temp_c001);
for(int j=0;j<k;j++)
temp_c001[j]='\0';
}
else
{
temp_c001[i-offset]=formatstring001[i];
}
if(formatstring001[i]=='\0')
{
temp_c001[i-offset]=formatstring001[i];
DrawFormatStringToHandle(x,y,color,fonthandle,temp_c001);
}
}
l=0;
offset=0;
}
(ちなみに内部の"%"の場合分けはすべて行っていません……自分が使うものだけ行っています、すみません。もし採用されるようでしたら追加してやってください)
|
Re: 管理人様にお尋ねしたいこと ( No.13 ) |
- 名前:陽奈 日時:2010/12/01 21:06
ユーザー名がバグ報告のままでした……すみません
|
Re: 管理人様にお尋ねしたいこと ( No.14 ) |
- 名前:管理人 日時:2010/12/02 09:49
SetUseBackBufferTransColorFlag と UpdateLayerdWindowForSoftImage を
組み合わせればオリジナルデザインのウインドウのようなものを表示することが
できると思うのですが、それでは駄目なのでしょうか?
FPSについてですが、UpdateLayerdWindowForSoftImage で実現している効果は
DirectX の機能が使えないので、プログラムを最適化したとしてもあと10%くらいしか
高速化することはできないと思います
DrawString に関するご提案ありがとうございます
ただ、すみません、DrawString が改行コードに対応していないのは、意図的にそうしています
改行文字の改行時の下げドット数もそうですが、\t のタブ文字はどれだけスペースを空けるべきか、
\b や \v の挙動など、使用する方によって想定される挙動が違うことが多くなりそうだったので、
それならいっそ、その辺のことは使用する方に任せてしまおう、と思って制御文字には
一切対応しないことにしました
|
Re: 管理人様にお尋ねしたいこと ( No.15 ) |
- 名前:陽奈 日時:2010/12/02 13:11
>FPSについてですが、UpdateLayerdWindowForSoftImage で実現している効果は
>DirectX の機能が使えないので、プログラムを最適化したとしてもあと10%くらいしか
>高速化することはできないと思います
そうなのですか……
すみませんあまり知識がなかったものなので
では組み合わせでやってみたいと思います
>〜一切対応しないことにしました
そういうことだったのですか
過ぎたまねをしてしまいました
どうも解説ありがとうございます
|
Re: 管理人様にお尋ねしたいこと ( No.16 ) |
- 名前:いっち 日時:2010/12/03 23:10
管理人さん>
> UpdateLayerdWindowForSoftImage の際に
> 「そのとき SetTransColor で透過色に設定されている色がデスクトップに転送されない」
> ようになったため、この仕様変更を行う前に作成したサンプル UpdateLayerdWindow.zip の
> プログラムでは半透明の円が消えてしまうことになってしまいました
バグだと言ったのは私の早とちりでした。すみません。
スレッド「デスクトップマスコット」のレス(No.14)にて管理人さんが以下のように仰っていたので、
> ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=1616
> 何故かといいますと、以前まではカラーキー( 特定の色を透過する機能 )を使っていたのですが、
> それだと透過された部分がクリックできてしまうのでαブレンドを使って透過するようにしたからです
透過色を使わずにαブレンドを使用するように機能変更した際に、
透過色を使用していたときのコードが残ったままになってしまい悪さをしているのではないかと思い込んでいました。
(おそらく、上記のレスは本件とはあまり関係なかったのですね)
|
|