追記 ( No.1 ) |
- 名前:SweetBlack 日時:2007/01/17 17:52
追記です。
MakeGraphとGetDrawScreenGraphで作成した画像も
復帰されていないような気がします。
これについては詳しく調べておりませんが、一応。
|
Re: タスク切換時の画像復帰 ( No.2 ) |
- 名前:管理人 日時:2007/01/19 13:28
SweetBlackさんどうも、DXライブラリの管理人です。
フルスクリーンモードで起動している際に「ALT+TAB」で
デスクトップ画面に戻る等の画面モード変更が発生した場合
MakeGraph や CreateGraphFromMem で作成した画像の内容が
無くなるのは仕様です。
LoadGraph で読み込んだ画像は再度フルスクリーンになった
際に自動的に読み直されるので何もしなくてもそのまま使い
続けることが出来ますが、MakeGraph や CreateGraphFromMem
等で作成した画像は SetRestoreShredPoint 関数で登録できる、
画像復元用のコールバック関数で読み込み直す必要があります。
// グラフィック復元関数の登録
int SetRestoreShredPoint( void (*ShredPoint)( void ) ) ;
(関数名がヘンですが気にしないで下さい・・・)
この関数で登録できるコールバック関数は、フルスクリーンに
再び画面モードが変更された際に呼ばれますので、この関数の中で、
作成された全ての画像のデータを ReLoadGraph や
ReCreateGraphFromMem や GetDrawScreenGraph 等を使用して
再度画像を読み込み直すということをします。
(デフォルトでは LoadGraph や LoadDivGraph で作成された
画像のみファイルから読み込み直すということをしています
(CreateGraphFromMem や GetDrawScreenGraph で読み込まれた
画像は、既にメモリ上や画面上から無くなっている可能性が
高いので自動で再読み込み処理を行うことが出来ないのです))
サンプル:
画像復元用関数の LoadImage 関数を SetRestoreShredPoint 関数
で登録して、フルスクリーンに戻って来たときに呼ばれるように
しています。
#include "DxLib.h"
#include <stdio.h>
int GraphHandle;
// 画像読み込み関数
void LoadImage( void )
{
void *Buffer;
int BufferSize;
FILE *fp;
// 画像ハンドルを全て削除する
InitGraph();
// 画像ファイルをメモリに読み込む
fp = fopen( "test1.bmp", "rb" );
fseek( fp, 0L, SEEK_END );
BufferSize = ftell( fp );
fseek( fp, 0L, SEEK_SET );
Buffer = malloc( BufferSize );
fread( Buffer, BufferSize, 1, fp );
fclose( fp );
// メモリに読み込んだ画像データでハンドルを作成する
GraphHandle = CreateGraphFromMem( Buffer, BufferSize );
// メモリに読み込んだ画像データを解放する
free( Buffer );
}
// WinMain 関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1;
// 画像の復帰関数を登録する
SetRestoreShredPoint( LoadImage );
// 画像を読み込む
LoadImage();
// 描画先を裏画面にする
SetDrawScreen( DX_SCREEN_BACK );
// メインループ(ESCキーが押されたらループを抜ける)
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
{
// 画面のクリア
ClearDrawScreen();
// 画像の描画
DrawGraph( 0, 0, GraphHandle, TRUE );
// 裏画面の内容を表画面に反映
ScreenFlip();
}
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}
上記の例では最初の画像の読み込み関数と、復帰用の関数を同じ
関数で行えるように、関数の最初で InitGraph で全ての画像ハンドルを
削除しています。
|
Re: タスク切換時の画像復帰 ( No.3 ) |
- 名前:SweetBlack 日時:2007/01/19 22:55
管理人様、お返事ありがとうございます。
つまり、今現在どの画像が読み込まれているかを
管理しておいて、読み直すという事ですね。
アドバイスありがとうございます。
現在の私のやり方でGetDrawScreenGraphの画像を
復元させるのはかなりホネ(というか不可能)ですが
ちょっと考えてみます。
|
Re: タスク切換時の画像復帰 ( No.4 ) |
- 名前:SweetBlack 日時:2007/01/20 21:59
教えていただいた方法だと
今までは自動的に復元されていた画像まで
すべて手動で復元しなくてはならないので、
全てのシーンで「現在利用している画像」を
チェックしておき、それを復元しなくては
ならないようで、変更量が凄くて挫折しそうです……。
すみません、愚痴です。
|
Re: タスク切換時の画像復帰 ( No.5 ) |
- 名前:管理人 日時:2007/01/21 04:31
すみません、この仕様はリファレンスに載せておくべきでした。
|
Re: タスク切換時の画像復帰 ( No.6 ) |
- 名前:SweetBlack 日時:2007/01/22 14:43
たびたびすみません。
また質問させてください。
「ALT+TAB」でタスク切り替えする時、
小さなウィンドウが出てきて、処理を選びますよね?
この時に、実行中のプログラム以外に処理を移してから
再度、「ALT+TAB」で処理を戻した場合は問題ないのですが、
「ALT」を押しっぱなしにしたまま、「TAB」をトントンと
押していき、ぐるっと一周させてから、
「実行中のプログラム」に戻して処理を続けさせた場合、
画面に何も表示されなくなってしまいます。
グラフィックデータが消えたとかじゃないようです。
文字すら表示されません。
(再度、別のアプリケーションに処理を移してから
戻すと、ちゃんと表示されるようになる)
管理人さまが提示してくださったサンプルで試しても
同様の現象が起きました。
これは環境のせいでしょうか?
私の環境を次の通りです。
Windows2000
AMD Athlon 64 Processor 3000+ 1.8GHz
DirectX 9.0c
NVIDIA GeForce 6600 GT
|
Re: タスク切換時の画像復帰 ( No.7 ) |
- 名前:SweetBlack 日時:2007/01/22 14:46
書き忘れましたが、使用ソフトはBCCです。
|
Re: タスク切換時の画像復帰 ( No.8 ) |
- 名前:管理人 日時:2007/01/23 11:50
SweetBlackさんどうも、DXライブラリの管理人です。
不具合のご報告有難うございます、ライブラリの問題です。
ALT+TABのタスク選択で再び元々実行しているタスクを選択する
というのは試していませんでした。
修正したバージョンをアップしましたので、宜しければ
お使い下さい。m(_ _)m
http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe //VC用
http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe //BCC用
(中身を既存のライブラリのファイルに上書きして、BCCをお使いの
場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)
|
Re: タスク切換時の画像復帰 ( No.9 ) |
- 名前:SweetBlack 日時:2007/01/24 23:30
管理人様。
早速の対応ありがとうございます。
ちゃんと動作する事を確認いたしました。
大元の変更の方もなんとか目処が立ちました。
まだいくつか問題が残ってますが
(この仕様だとGetDrawScreenGraphの使い道が無いのではないか? とか、
タスク切り替えの際に、タイミング次第では強制終了してしまう?
WaitVSync等を上手く配置すると落ちる確率が減る? 等)
一応は先に進めそうです。
ありがとうございました。
|
Re: タスク切換時の画像復帰 ( No.10 ) |
- 名前:niwa 日時:2007/01/26 22:27
横からですが、報告です。
>タスク切り替えの際に、タイミング次第では強制終了してしまう?
こちらでは、'06夏頃のは大丈夫で2.22dから落ちます。
logを見ると復帰後に画像データを読み込んだあと、
また同じデータを読み込んで落ちているようです。
|
Re: タスク切換時の画像復帰 ( No.11 ) |
- 名前:管理人 日時:2007/01/29 13:12
SweetBlackさん、niwaさんどうも、DXライブラリの管理人です。
不具合のご報告有難うございます。
タスク切り替え時に強制終了してしまう現象ですが、私の環境で
簡易的なテストプログラムを実行した限りでは発生しませんでした。
何か条件があると思うのですが、とりあえず niwaさんのお書き込みにある
> logを見ると復帰後に画像データを読み込んだあと、
> また同じデータを読み込んで落ちているようです。
という部分が気になりましたので、同じデータを読み込んで
しまっている箇所を修正してみました。
これで正常に動作するかどうかは分かりませんが、宜しければ
お試しになってみてください。m(_ _)m
http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe //VC用
http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe //BCC用
(中身を既存のライブラリのファイルに上書きして、BCCをお使いの
場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)
|
Re: タスク切換時の画像復帰 ( No.12 ) |
- 名前:SweetBlack 日時:2007/01/29 15:02
管理人様、niwa様、色々とありがとうございます。
さて、強制終了の件ですが、新たに頂いた分でも
やはり発生しました。
※これがniwa様のおっしゃる現象と同じものか
どうかは、解りません。念の為。
私は上のほうで
「WaitVSync等を上手く配置すると落ちる確率が減る?」
と書きましたように、特定の条件下では発生しやすい
ような気がしましたので、わざとそういうサンプルを
作ってみました。
上のほうの記事(bQ)で管理人様が提示してくださったサンプルに手を加えたものです。
//--------------------------------ここから
#include "DxLib.h"
#include <stdio.h>
int GraphHandle;
// 画像読み込み関数
void LoadImage( void )
{
void *Buffer;
int BufferSize;
FILE *fp;
// 画像ハンドルを全て削除する
InitGraph();
// 画像ファイルをメモリに読み込む
fp = fopen( "test1.bmp", "rb" );
fseek( fp, 0L, SEEK_END );
BufferSize = ftell( fp );
fseek( fp, 0L, SEEK_SET );
Buffer = malloc( BufferSize );
fread( Buffer, BufferSize, 1, fp );
fclose( fp );
// メモリに読み込んだ画像データでハンドルを作成する
GraphHandle = CreateGraphFromMem( Buffer, BufferSize );
// メモリに読み込んだ画像データを解放する
free( Buffer );
}
// WinMain 関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1;
// 画像の復帰関数を登録する
SetRestoreShredPoint( LoadImage );
// 画像を読み込む
LoadImage();
// 描画先を裏画面にする
SetDrawScreen( DX_SCREEN_BACK );
// 画面のクリア
ClearDrawScreen();
// 画像の描画
DrawGraph( 0, 0, GraphHandle, TRUE );
// 裏画面の内容を表画面に反映
ScreenFlip();
// メインループ(ESCキーが押されたらループを抜ける)
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
{
}
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}
//--------------------------------ここまで
これだと当然画面の復帰は行われませんが、実験はできました。
タスクを別の処理に切り替え、再び戻す、を何度か繰り返すと落ちます。
私の環境ではほぼ2回目までには落ちました。
念の為に以下にログも記しておきます。
//---------------------------ここから
15:システムの情報を出力します
15: DXライブラリ Ver2.22e
15: OS Windows2000 ( Build 2195 Service Pack 4 )
115: CPU動作速度:大体1.46GHz
116: MMX命令を使用します
117: CPUベンダ:AuthenticAMD
121: CPU名:AMD Athlon(tm) 64 Processor 3000+
122:COMの初期化... 成功しました
125:メモリ総量:2047.23MB 空きメモリ領域:1705.73MB
126:タイマーの精度を検査します
127:精度結果 更新回数 マルチメディアタイマー:0 パフォーマンスカウンター:60
128:パフォーマンスカウンターを使用します タイマー分解能 : 3579.545000 KHz
128:ソフトの二重起動検査... 二重起動はされていませんでした
130:ウインドウクラスを登録します... 登録に成功しました
132:フルスクリーンモード用のウインドウを作成します
145:カーソルを不可視にしました
146:IMEを無効にしました
347:DirectInput関係初期化処理
348: DirectInput7 の取得中... 成功
360: 引き続き初期化処理... 初期化成功
362: ジョイパッドの初期化...
369: 入力装置を見つけました
372: デバイスの登録名:Rumble Pad
373: デバイスの製品登録名:Rumble Pad
374: 周期的エフェクトの作成に失敗しました。
375: ジョイパッドの追加は正常に終了しました
376: ジョイパッドの初期化は正常に終了しました
377: マウスデバイスの初期化... 初期化成功
379: キーボードデバイスの初期化... 初期化成功
382:DirectInput 関連の初期化は正常に終了しました
383:DirectSound の初期化を行います
384:DirectSound インターフェースの取得を行います.... 成功
387:引き続きインターフェースの初期化処理... 成功
461: DirectSound デバイスを列挙します
463: モジュール名: ドライバ記述:プライマリ サウンド ドライバ
464: モジュール名: ctaud2k.sys ドライバ記述:SB Live! オーディオ [A000]
465: 最大サンプリングレート:192.00KHz 最小サンプリングレート:4.00KHz
466: 総サウンドメモリ領域:0.00KB 空きサウンドメモリ領域:0.00KB
468: 利用可能サンプリング精度
469: プライマリ 16bit = OK 8bit = OK
470: セカンダリ 16bit = OK 8bit = OK
471: 利用可能チャンネル
472: プライマリ MONO = OK STEREO = OK
473: セカンダリ MONO = OK STEREO = OK
475:DirectSound の初期化は正常に終了しました
476:DirectDraw 関連の初期化を行います
477: DirectDraw オブジェクトの取得を行います.... 成功
481: 引き続き初期化処理... 初期化に成功しました
485: ビデオカードの情報
486: 画面モード変更処理を開始します
547: ウインドウスタイルをフルスクリーンモード用に変更します... 完了
552: 画面モードの変更処理を開始します 640 x 480 16 bit
553: 画面解像度を変更します... 成功しました
692: 画面モードの変更は正常に終了しました
699: カラー情報
703: A:00000000 B:0000f800 G:000007e0 B:0000001f
718: 出力画面用の DirectDrawSurface を作成します
913: 各スクリーンメモリの配置位置
918: PrimaryBuffer : VIDEOMEMORY
924: BaskBuffer : VIDEOMEMORY
927: 出力画面用の DirectDrawSurface の作成は正常に終了しました
937: Direct3D 関連の初期化を行います
949: Direct3Dオブジェクトを取得します
1240: Direct3Dオブジェクトを取得しました
1242: 3Dデバイスを作成します... 3Dデバイスの作成に成功しました
1247: テクスチャ最大幅:4096 最小幅:1
1249: 描画制限: D_D3DPTEXTURECAPS_POW2 = 0 D_D3DPTEXTURECAPS_SQUAREONLY = 0
1250: テクスチャピクセルフォーマット
1250: 通常グラフィック用
1252: BIT:16 RED:5 GREEN:6 BLUE:5
1253: RED:00f800 GREEN:0007e0 BLUE:00001f
1254: BIT:32 RED:8 GREEN:8 BLUE:8
1255: RED:ff0000 GREEN:00ff00 BLUE:0000ff
1257: アルファチャンネル付きグラフィック用
1258: BIT:16 ALPHA:4 RED:4 GREEN:4 BLUE:4
1259: ALPHA:0000f000 RED:00000f00 GREEN:000000f0 BLUE:0000000f
1261: BIT:32 ALPHA:8 RED:8 GREEN:8 BLUE:8
1262: ALPHA:ff000000 RED:00ff0000 GREEN:0000ff00 BLUE:000000ff
1263: Direct3D 関連の初期化は正常に終了しました
1265: グラフィック管理系の初期化を行います
1267: 3Dグラフィック描画機能を使用します
1268: フォントの初期化を行います
1272: フォントの初期化は正常に終了しました
1274: グラフィック管理系の初期化は正常に終了しました
1333: サーフェス間転送には BltFast を使用します
1334: BitBlt:29696μs BltFast:25088μs
1335: スキャンラインの数:480
1465: 1フレーム当たりの時間は 17 msecです
1466: Tri00:17 msec
1468: Tri01:16 msec
1469: Tri02:17 msec
1471: Tri03:16 msec
1473: 画面モード変更処理は正常に終了しました
1482: オーバーレイサーフェスを使用します UYVY
1483: DirectDraw 関連の初期化は正常に終了しました
1498: 文字コードバッファの初期化を行います... 完了しました
7349: Direct3Dデバイスを削除しました
7351: Direct3Dオブジェクトを解放します
7352: Direct3Dオブジェクトを解放しました
7354: メインサーフェスを破棄をします... 完了しました
7355: DirectInput 関連の終了処理... 完了
7357: DirectDrawオブジェクトを解放します
7361: DirectDrawオブジェクトを解放しました
7363: DirectDraw オブジェクトの取得を行います.... 成功
7366: 引き続き初期化処理... 初期化に成功しました
7370: ビデオカードの情報
7371: 画面モードの変更処理を開始します 640 x 480 16 bit
7373: 画面解像度を変更します... 成功しました
7513: 画面モードの変更は正常に終了しました
7519: 画面モードの変更処理を開始します 640 x 480 16 bit
7526: 画面解像度を変更します... 成功しました
7618: 画面モードの変更は正常に終了しました
7619: 出力画面用の DirectDrawSurface を作成します
7668: 各スクリーンメモリの配置位置
7676: PrimaryBuffer : VIDEOMEMORY
7682: BaskBuffer : VIDEOMEMORY
7698: 出力画面用の DirectDrawSurface の作成は正常に終了しました
7746: Direct3Dオブジェクトを取得します
7747: Direct3Dオブジェクトは正常に取得されました
7749: 3Dデバイスを作成します... 3Dデバイスの作成に成功しました
7763: DirectInput関係初期化処理
7764: DirectInput7 の取得中... 成功
7767: 引き続き初期化処理... 初期化成功
8029: ジョイパッドの初期化...
8036: 入力装置を見つけました
8039: デバイスの登録名:Rumble Pad
8041: デバイスの製品登録名:Rumble Pad
8041: 周期的エフェクトの作成に失敗しました。
8043: ジョイパッドの追加は正常に終了しました
8045: ジョイパッドの初期化は正常に終了しました
8046: マウスデバイスの初期化... 初期化成功
8050: キーボードデバイスの初期化... 初期化成功
8053: DirectInput 関連の初期化は正常に終了しました
14916: Direct3Dデバイスを削除しました
14917: Direct3Dオブジェクトを解放します
14919: Direct3Dオブジェクトを解放しました
14921: メインサーフェスを破棄をします... 完了しました
14922: DirectInput 関連の終了処理... 完了
14924: DirectDrawオブジェクトを解放します
14928: DirectDrawオブジェクトを解放しました
14930: DirectDraw オブジェクトの取得を行います.... 成功
14933: 引き続き初期化処理... 初期化に成功しました
14936: ビデオカードの情報
14938: 画面モードの変更処理を開始します 640 x 480 16 bit
14939: 画面解像度を変更します... 成功しました
15080: 画面モードの変更は正常に終了しました
15085: 画面モードの変更処理を開始します 640 x 480 16 bit
15090: 画面解像度を変更します... 成功しました
15183: 画面モードの変更は正常に終了しました
15184: 出力画面用の DirectDrawSurface を作成します
15224: 各スクリーンメモリの配置位置
15235: PrimaryBuffer : VIDEOMEMORY
15239: BaskBuffer : VIDEOMEMORY
15253: 出力画面用の DirectDrawSurface の作成は正常に終了しました
15301: Direct3Dオブジェクトを取得します
15307: Direct3Dオブジェクトは正常に取得されました
15309: 3Dデバイスを作成します... 3Dデバイスの作成に成功しました
|
Re: タスク切換時の画像復帰 ( No.13 ) |
- 名前:niwa 日時:2007/01/29 23:59
動作報告です。
>logを見ると復帰後に画像データを読み込んだあと、
>また同じデータを読み込んで落ちているようです。
何回か試しましたが、今の所落ちる事はありません。
SweetBlack様のテストプログラムでも落ちません。
(Ver2.22fでは落ちました)
ただVC上から実行した時はタスクを切り替えても
画面が戻らない為リセットする必要があります。
あとログのVerを見ると2.22eになっています。
こちらでは2.23なので旨くlibが更新出来ていないのでは?
|
Re: タスク切換時の画像復帰 ( No.14 ) |
- 名前:SweetBlack 日時:2007/01/30 00:34
>あとログのVerを見ると2.22eになっています。
ご指摘ありがとうございます。
テストプログラムの方の更新を忘れていました。
ただし、やはり2.23に更新しても落ちました。
となると私の環境のせいなのでしょうか……?
|
Re: タスク切換時の画像復帰 ( No.15 ) |
- 名前:管理人 日時:2007/01/30 13:16
SweetBlackさん、niwaさんどうも、DXライブラリの管理人です。
動作テストをして頂き有難うございます。
その後 SweetBlackさんがご掲載して下さったテストプログラムを
実行したところ、私の環境でも同様の強制終了現象が発生しました。
ソフトが非アクティブになった時にはDXライブラリ中の様々な
箇所に仕掛けてある非アクティブチェックプログラムでプログラムが
一時停止するようになっているのですが、丁度 CheckHitKey 関数の中に
仕掛けてあるチェックプログラムで一時停止した場合のみ復帰時に
不正なメモリアクセスが発生するようになっていました。
修正したバージョンをアップしましたので、何度も申し訳ありませんが
宜しければお試しになってみてください。m(_ _)m
http://homepage2.nifty.com/natupaji/DxLib/DxLibVCTest.exe //VC用
http://homepage2.nifty.com/natupaji/DxLib/DxLibBCCTest.exe //BCC用
(中身を既存のライブラリのファイルに上書きして、BCCをお使いの
場合は『再構築』、VCをお使いの場合は『リビルド』をして下さい)
|