トップページ > 過去ログ > 記事閲覧
デスクトップマスコット
名前:だみあん 日時: 2010/02/09 02:01

3Dモデルを使用した デスクトップマスコットを作ろうとおもっているのですが いろいろと調べてみたところ DiectXの描画内容をレイヤーウィンドウに表示する際に DiectXで使用するバックバッファのデバイスコンテキストを取得して、 Presentを行わずに、ウィンドウのDCとコンパチブルなDIBビットマップを作成し DiectXのバックバッファの内容をそこにBitBltで転送する・・・という 方法を取る。 というところまでは調べたのですが そのためにまず Direct3D オブジェクトの作成時に D_D3DPRESENTFLAG_LOCKABLE_BACKBUFFER バックバッファをロック出来るようにするかというフラグ を付加してバックバッファのデバイスコンテキストを取得できるようになくてはならないようで。 Dxlibのソースを見たところ DxGraphics2.cpp 3030 param.Flags = GRH.MultiSampleType == D_D3DMULTISAMPLE_NONE ? D_D3DPRESENTFLAG_LOCKABLE_BACKBUFFER/* D_D3DPRESENTFLAG_DEVICECLIP */ : 0 ; 該当部分はここのようなのですが MultiSampleTypeというのがよくわからない為、 もともと現状でフラグがどういう値になってるのか判りませんでした・・・。 とはいえ、Dxライブラリ自体がもともとPresentを行うのがデフォなので ライブラリ自体を改造しないと実現できそうもないのでどうにもならないのですがw というわけで、そのような用途 (デスクトップ上に、3Dモデルを表示する) につかえる機能を追加していただけないでしょうか。 基本的には描画周りの変更のみというかんじなので 音声だしたり通信機能を使ったりと Dxライブラリの資源がそのまま使えるので 実現するとうれしいのですが・・・。

Page: 1 |

Re: デスクトップマスコット ( No.1 )
名前:管理人 日時:2010/02/15 00:11

ご要望了解しました 機能としては、ウインドウモードのウインドウ部分とウインドウのクライアント領域の 背景色の部分が透過するようなものでよろしいでしょうか?
Re: デスクトップマスコット ( No.2 )
名前:だみあん 日時:2010/02/15 05:21

>機能としては、ウインドウモードのウインドウ部分とウインドウのクライアント領域の >背景色の部分が透過するようなものでよろしいでしょうか? ずばりそのような物を追加していただけると嬉しいです。 よろしくお願いします(ぺこり
Re: デスクトップマスコット ( No.3 )
名前:Masao 日時:2010/02/15 09:44

まさか実現する方向にいくとは。 待望の機能です! ちょっと期待してみます(笑
Re: デスクトップマスコット ( No.4 )
名前:管理人 日時:2010/03/05 23:35

すいません、遅くなりました orz ウインドウモードの透過色部分が透過する機能を作りましたので、よろしければお試し下さい http://homepage2.nifty.com/natupaji/DxLib/DxLibDotNet.zip // C#用 http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい) 追加した関数は以下の関数です // バックバッファの透過色の部分を透過させるかどうかを設定する( TRUE:透過させる FALSE:透過させない ) int SetUseBackBufferTransColorFlag( int Flag ) ; DxLib_Init の前でこの関数に TRUE を渡して呼べば、ウインドウの透過色の部分が透過されます、 透過色については SetTransColor で設定してください( こちらは DxLib_Init の後に呼んでください ) ついでに、ウインドウの枠やメニュー部分なども透過されてしまいます・・・ もし不都合がありましたら対応します
Re: デスクトップマスコット ( No.5 )
名前:だみあん 日時:2010/03/06 22:08

機能追加、ありがとうございました。 DXライブラリの機能をそのまま生かせるので ありがたいです。 いまのところ、用途的にはばっちりな感じで満足しております。 とりあえず試してみたところ、一点、不具合のような物が見つかりましたので 報告させていただきます。 アプリケーション起動中 タスクバーをクリック(もしくは右クリックメニューから最小化)してから 元に戻すと、ウィンドウの表示位置がずれてしまう様です。 移動距離的に、メニューバーのサイズ分、下にずれてしまっている模様です。
Re: デスクトップマスコット ( No.6 )
名前:Masao 日時:2010/03/09 07:11

似たような問題をこちらでも発見しました。 よければ対応してください。 ウィンドウ上クリックしたらドラッグできるような機能をつけようと思ったのですが、どうやら SetWindowPosition関数を毎フレーム呼び出すと、 ウィンドウが振動するみたいです。 あと、ここからはよかったらの提案なんですが、 ウィンドウ自体の透明値を再現可能でしたらご検討していただけないでしょうか? (たとえばα値のあるpngを描画すると、α値を維持したような状態でデスクトップにかさなる。現状では背景色とブレンドされるため、α値が0以外のところはかならず描画される。) でも、いままでこれを実現しているデスクトップマスコットをみたことがないので、難しいようならば結構です。
Re: デスクトップマスコット ( No.7 )
名前:Masao 日時:2010/03/09 07:27

なんどもすいません。 もうひとつ問題がありました。 透明色をしろにするのは SetBackgroundColor(255, 255, 255) ; DxLib_Init( ); SetTransColor(255,255,255); これでできたんですが、 SetBackgroundColor(255, 0, 0) ; DxLib_Init( ); SetTransColor(255,0,0); こうすると、思っていた結果を得られませんでした。 具体的には、赤く塗りつぶされたところが、まったく透明化しませんでした。 コーディングの問題でしょうか?ご確認お願いします。 (なお赤でなくても、白と黒以外ならおきるみたいです。)
Re: デスクトップマスコット ( No.8 )
名前:管理人 日時:

> だみあんさん ご報告ありがとうございます 修正したものをアップしましたので、もし不都合がありましたらこちらをお使い下さい m(_ _)m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい) > Masaoさん Masaoさんもよろしければ上記修正バージョンをダウンロードしてください ウインドウが振動する原因の一つを修正してあります ただ、バグとは別にマウスカーソルの座標を GetMousePoint で取得しますと、 GetMousePoint はメインウインドウのクライアント領域の左上端を原点とした値を返してきますので、 SetWindowPosition でメインウインドウの位置を変更してしまうと GetMousePoint で取得できるマウスの 位置も変わってしまい、結果として GetMousePoint で得られる位置の差分値を使ってウインドウをドラッグ できるような機能を作ろうとすると上手くいきません なので、GetMousePoint の代わりに、Win32 API の GetCursorPos をお使い下さい、この API はデスクトップの 左上端を原点としたマウスカーソルの位置を得られる API ですので、SetWindowPosition の設定値で値が変化 することはありませんので・・・ POINT MousePos ; GetCursorPos( &MousePos ) ; MousePos.x // x座標 MousePos.y // y座標 あと、SetTransColor( 255,255,255 ) ; 以外を設定した際に正しく透過されないバグも修正しておきました > ウィンドウ自体の透明値を再現可能でしたらご検討していただけないでしょうか? やっぱりやりたいですよね 可能といえば可能ですが、その処理を実現しつつハードウエアでの高速描画をしようとすると最低でもシェーダーモデル2.0の ピクセルシェーダーが使えないといけないので、動作環境のことを考えるとソフトウエア描画をする必要があります ( 裏画面のピクセルフォーマットにαチャンネルがあれば、描画した際のα値を裏画面のαチャンネルに 保存すれば良いだけ、というように簡単に実現できそうに思えますが、描画先のピクセルのα値が
( No.0以外の際の
色の合成処理の関係で実際はそうはいかないんです( 描画する画像同士が重なることが無い前提でしたら簡単ですが・・・ ) )

というわけで、ソフトウエア画像に機能追加をして最低限の描画結果のα値を使った透明表示を実現してみた
サンプルをアップしましたので、よろしければご覧になってみてください

https://dxlib.xsrv.jp/file/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( 255, 0, 255 ) ;
SetBackgroundColor( 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, 4 )
名前: 日時:

( No.80, 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, 255, 0, 255, 0 ) ;

// 64ドット右下にずらした位置に同じ画像をアルファ値を考慮した転送
BltSoftImageWithAlphaBlend( 0, 0, 256, 256, softhandle, 64, 64, screensofthandle, opacity ) ;

// 画面出力用のソフトウエア画像を使ってウインドウの表示を更新
UpdateLayerdWindowForSoftImage( screensofthandle ) ;
}

// DXライブラリの後始末
DxLib_End();

// ソフトの終了
return 0;
}

今回追加した関数は以下の3つです

// ソフトウエアで扱うイメージを透過色処理付きで転送する
int BltSoftImageWithTransColor( int SrcX, int SrcY, int SrcSizeX, int SrcSizeY, int SrcSIHandle, int DestX, int DestY, int DestSIHandle, int Tr, int Tg, int Tb, int Ta ) ;

// ソフトウエアで扱うイメージをアルファ値のブレンドを考慮した上で転送する( Opacity は透明度 : 0( 完全透明 ) 〜 255( 完全不透明 ) )( 出力先が ARGB8 形式以外の場合はエラーになります )
int BltSoftImageWithAlphaBlend( int SrcX, int SrcY, int SrcSizeX, int SrcSizeY, int SrcSIHandle, int DestX, int DestY, int DestSIHandle, int Opacity ) ;

// ソフトウエアで扱うイメージを使用して UpdateLayerdWindow を行う( イメージはウインドウのクライアント領域と同じサイズである必要があります )
int UpdateLayerdWindowForSoftImage( int SIHandle ) ;

関数名と注釈でなんとなく機能は想像できますよね・・・?
因みに UpdateLayerdWindowForSoftImage を使用してウインドウの表示を更新する場合は ScreenFlip 関数は使用しません

あと、上記サンプルでは通常の描画処理の結果とソフトウエア画像を使っての描画( というか転送 )を同時に使用していますが、
これは通 )
名前: 日時:

2010/03/15 23:45 ( No.常の描画処理と今回追加した機能を一緒に使いたい場合はどうすればいいのか分かるようにするために敢えてそうした
だけで、通常の描画処理が必要が無い場合は通常の描画処理を一切使わずに済ますこともできます

もうひとつ、UpdateLayerdWindowForSoftImage や BltSoftImageWithAlphaBlend は非常に重い処理ですので、これらを使用する場合は
60FPS(秒間60コマ)とかは考えない方が良いです、まあ、デスクトップマスコットですから10FPSくらい確保できれば十分ですよね?(汗)

というわけで、α値を考慮した描画処理は今のところ画像等倍単純転送だけですが、これだけでは足りますでしょうか? )
名前:61.124.50.106 日時:   <7WzPDYntfKD0Q>

Re: デスクトップマスコット ( No.9 )
名前:Masao 日時:

GetMousePoint について、助言ありがとうございます <(_ _)> ウィンドウのドラッグについては、だいたいうまくできました。 ただ、SetWindowPositin を呼んでいる間、クライアントウィンドウのサイズが伸びているようです。 この現象が発生するサンプルプログラムがこちらです。 ウィンドウ右下に注目してみてください。 よろしければこちらの対応もよろしくお願いいたします。 #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ); SetUseBackBufferTransColorFlag(TRUE); SetDrawScreen(DX_SCREEN_BACK); if ( DxLib_Init( ) == -1 ) return -1; while ( ProcessMessage( ) == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0) { ClearDrawScreen(); DrawBox(0,0,640,480,GetColor(255,0,0),TRUE); static int count = 0;//フレーム数 count++; if(count%10 < 5)//5フレーム毎に、SetWindowPisitionを呼ぶか呼ばないか変化する。 SetWindowPosition(count%100,100);//x座標はフレーム数だけ上昇するが、100フレームごとにx=0 へリセットする。 ScreenFlip( ); } DxLib_End( ); return 0; } >SetTransColor( 255,255,255 ) ; 以外を設定した際に正しく透過されないバグも修正しておきました 対応ありがとうございます。修正されていたのを確認しました。 >というわけで、α値を考慮した描画処理は今のところ画像等倍単純転送だけですが、これだけでは足りますでしょうか? ウィンドウの透明化機能もありがとうございます! 画像等倍転送だけで、十分やりたいことができています。 ありがとうございました。 それから、もうひとつお願いがあります。 今回の修正後、どうやら透明化されたところをクリックした場合も、 GetMouseInput(); が反応するようになったみたいです。 修正前は、透明化された部分をクリックした場合、後ろにあったタスクがクリックされたんですが、それができなくなってしまいます。 こちらも
2010/03/17 05:07 ( No.、よろしければ対応お願いします。 )
名前:99.7.249.183 日時:   <nfhiKdzm6GKUY>

Re: デスクトップマスコット ( No.10 )
名前:管理人 日時:2010/03/22 01:36

ご報告ありがとうございます、ウインドウが伸びる現象を確認して、修正しました よろしければこちらをお試し下さい m(_ _)m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい) 透明な部分もクリックできてしまうという現象は私の環境( Windows7+64bit )では確認できませんでした 因みにメインウインドウの背後にあるウインドウをクリックできるようにするには該当するピクセルを完全に透明にしないといけないのですが Masaoさんのお手元では完全に透明になっている部分(ピクセル)をクリックしてもDXライブラリのウインドウをクリックしたことになってしまうのでしょうか?
Re: デスクトップマスコット ( No.11 )
名前:Masao 日時:2010/03/22 02:44

ウィンドウがのびる現象が修正されていました。 ありがとうございます。 >Masaoさんのお手元では完全に透明になっている部分(ピクセル)をクリックしてもDXライブラリのウインドウをクリックしたことになってしまうのでしょうか? はい、そうです。 SetBackgroundColor(255, 255, 0) ; if ( DxLib_Init( ) == -1 ) return -1; SetTransColor(255,255,0); このようにすると発生するみたいです。 こちらがサンプルになります。 #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { ChangeWindowMode( TRUE ); SetUseBackBufferTransColorFlag(TRUE); SetDrawScreen(DX_SCREEN_BACK); SetBackgroundColor(255, 255, 0) ; if ( DxLib_Init( ) == -1 ) return -1; SetTransColor(255,255,0); while ( ProcessMessage( ) == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0) { ClearDrawScreen(); DrawBox(0,0,640,480,GetColor(255,0,0),TRUE); DrawBox(100,100,200,200,GetColor(255,255,0),TRUE); if(GetMouseInput() & MOUSE_INPUT_LEFT){ DrawString(0,0,"MOUSE_LEFT",GetColor(0,0,0)); } ScreenFlip( ); } DxLib_End( ); return 0; }
Re: デスクトップマスコット ( No.12 )
名前:管理人 日時:2010/03/22 04:22

すいません、Masaoさんのテストプログラムで私の環境でも再現しました orz ( UpdateLayerdWindowForSoftImage でのみテストしていました ) にしても、見た目は透過しているのにクリックできるという謎現象ですね・・・仕様の見落としがあるのかもしれません・・・ とりあえず、UpdateLayerdWindowForSoftImage で正常に動作している方法と同じ方法を使って 正常に動作するように修正したものをアップしましたので、よろしければお試し下さい m(_ _;m http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe // VisualC++ 用 http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe // BorlandC++ 用 (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)
Re: デスクトップマスコット ( No.13 )
名前:Masao 日時:2010/03/22 08:59

なおってました。 対応ありがとうございます。 ほんのちょっと気になるのは、3.01a から 3.02a に更新して、fps が 30前後から15 前後に落ちてしまった気がする点です。 3.01aのを上書きしてしまったので正確に検証ができませんが・・・>< DXライブラリ3.01aを、もう一度いただけないでしょうか?

Page: 1 |