ロード中のアニメーション表示
ロード中のアニメーション表示
ふと思った疑問です。
よく市販のPCゲームなどで、ロード中に表示されるアニメーションが、まったく止まらないものがあります。
これは、データをロードしながら画面を更新しているのだ。
と今までは納得していたのですが、最近そうとは思えなくなりました。
まずひとつ、あまりにも画面更新が早く、gifアニメファイルを張っているだけのような気がしてくるのです。
二つ目に、あるゲームのこのロード表示中に Alt+Tab でタスクを切り替えた後、
もう一度切り替えてゲームに戻ってきたときに、
ロード中の画像が表示されなくなっていた(おそらくタスク切り替えでデータが消えた)のです。
つまり、毎フレーム更新していたわけではない、と思えてきたのです。
実際に、このようなゲームではアニメgifファイルのようなもので、実装していたとしたら、
DXライブラリではアニメgifはサポートされていないので、実装不可能でしょうか?
似せるとしたら、やはりひとつひとつのデータを読み込む合間に画面を更新する方法だけでしょうか?
よく市販のPCゲームなどで、ロード中に表示されるアニメーションが、まったく止まらないものがあります。
これは、データをロードしながら画面を更新しているのだ。
と今までは納得していたのですが、最近そうとは思えなくなりました。
まずひとつ、あまりにも画面更新が早く、gifアニメファイルを張っているだけのような気がしてくるのです。
二つ目に、あるゲームのこのロード表示中に Alt+Tab でタスクを切り替えた後、
もう一度切り替えてゲームに戻ってきたときに、
ロード中の画像が表示されなくなっていた(おそらくタスク切り替えでデータが消えた)のです。
つまり、毎フレーム更新していたわけではない、と思えてきたのです。
実際に、このようなゲームではアニメgifファイルのようなもので、実装していたとしたら、
DXライブラリではアニメgifはサポートされていないので、実装不可能でしょうか?
似せるとしたら、やはりひとつひとつのデータを読み込む合間に画面を更新する方法だけでしょうか?
Re:ロード中のアニメーション表示
マルチスレッドを使いたくないならこんな方法もあるのでは?
ということでサクサクっと作ってみました。
簡単なバージョン
http://dixq.net/zip/bbs/SampleLoad.zip
アニメーションも付けられますよということでアニメーションを付けてみたバージョン
http://dixq.net/zip/bbs/SampleLoad2.zip
LoopProcess関数はメイン以外から呼ぶのはちょっと反則な気もしますけど、ここだけ例外扱いで。
エラー処理は別途必要ですね。
まぁ適当に作ったのでいいかどうかはわかりませんけどね^^;
ちなみにScreenFlip関数がある為、どんなに早くロードが終わってもロード関数一つに対して
1/60秒待機してしまいます。
簡単バージョンで画面の書き換えを行わなければScreenFlipを排除することでロードは早くなると思います。
逆にロード関数から処理が帰ってくるまで描画出来ないので、
音楽データなど処理が帰ってくるまでに時間のかかる関数があるとアニメーションがきれいに見えません。
そういうデータは最初にまとめて読み込むなどの工夫が必要かもしれません。
ということでサクサクっと作ってみました。
簡単なバージョン
http://dixq.net/zip/bbs/SampleLoad.zip
アニメーションも付けられますよということでアニメーションを付けてみたバージョン
http://dixq.net/zip/bbs/SampleLoad2.zip
LoopProcess関数はメイン以外から呼ぶのはちょっと反則な気もしますけど、ここだけ例外扱いで。
エラー処理は別途必要ですね。
まぁ適当に作ったのでいいかどうかはわかりませんけどね^^;
ちなみにScreenFlip関数がある為、どんなに早くロードが終わってもロード関数一つに対して
1/60秒待機してしまいます。
簡単バージョンで画面の書き換えを行わなければScreenFlipを排除することでロードは早くなると思います。
逆にロード関数から処理が帰ってくるまで描画出来ないので、
音楽データなど処理が帰ってくるまでに時間のかかる関数があるとアニメーションがきれいに見えません。
そういうデータは最初にまとめて読み込むなどの工夫が必要かもしれません。
Re:ロード中のアニメーション表示
>ScreenFlip関数がある為、どんなに早くロードが終わってもロード関数一つに対して
>1/60秒待機してしまいます
多少画面に線が入るかもしれませんが SetWaitVSyncFlagとか使って
垂直同期待ちをしない、というのも手もありますね。
Re:ロード中のアニメーション表示
違うスレッドでデータを読み出して、パーセントを表す変数を増加させていけば良いかと(排他処理を忘れず)
くわしくは猫でものC言語編を99章辺りから見れば良いと思います。
http://www.kumei.ne.jp/c_lang/intro/no_99.htm
くわしくは猫でものC言語編を99章辺りから見れば良いと思います。
http://www.kumei.ne.jp/c_lang/intro/no_99.htm
Re:ロード中のアニメーション表示
えーと、ちょっとDXライブラリ下のマルチスレッドと、ロード中のアニメーションの方法に
ついて考えてみました。
正しいとは限らないので、何かおかしな点がありましたら指摘して下さい。
一般的にはこの手の処理はマルチスレッドで処理するのが自然ですが、
DXライブラリとマルチスレッドはあまり親和性がよくないように思います
しかもバージョンによって挙動が異なります。
2.25a以前は DXライブラリの大半の関数には異なるスレッドで同時に実行できないよう
排他処理が入っていましたが、2.25b以降は入っておらずマルチスレッド非対応と
なりました。
つまり、2.25a以前は別のスレッドでそのまま LoadGraph関数を呼ぶと
一時的に画面が止まることはあっても動きますが、2.25b以降は危険です。
3.00cで多少改善されたような感じがしますが、タイミングによっては
ロードに失敗するなど、問題があると思われます(あやふや)。
そうなるとどのバージョンでも使える手としては
[color=#d0d0ff" face="sans-serif]
1 別スレッドでファイルをメモリに読み込む。
2 その間メインスレッドでアニメーションをする。
3 別スレッド側で読み込みが終わったらメインスレッドに通知。
4 メインスレッドでメモリからDXライブラリのハンドル化する。[/color]
というのが考えられるのですが、ファイルをメモリに読み込む際に
DXライブラリのファイル読み込み関数が使えるかどうかが微妙です。
非 DXライブラリの読み込み関数を使うのが確実ですが、
そうなるとアーカイブの機能が使えなくなります。
そんなこんなで結局のところ、自前でロードスレッドを用意するのではなく
DXライブラリの機能のロードスレッドを使う方法、
[color=#d0d0ff" face="sans-serif]
1 DXライブラリの非同期読み込み関数を使ってファイルをメモリに読み込む指示を出す。
2 読み込み完了待ちしつつアニメーションを行う
3 読み込みが完了したらメモリから各種 DXライブラリの関数を
使ってハンドル化する[/color]
がベストな気がします。
ついて考えてみました。
正しいとは限らないので、何かおかしな点がありましたら指摘して下さい。
一般的にはこの手の処理はマルチスレッドで処理するのが自然ですが、
DXライブラリとマルチスレッドはあまり親和性がよくないように思います
しかもバージョンによって挙動が異なります。
2.25a以前は DXライブラリの大半の関数には異なるスレッドで同時に実行できないよう
排他処理が入っていましたが、2.25b以降は入っておらずマルチスレッド非対応と
なりました。
つまり、2.25a以前は別のスレッドでそのまま LoadGraph関数を呼ぶと
一時的に画面が止まることはあっても動きますが、2.25b以降は危険です。
3.00cで多少改善されたような感じがしますが、タイミングによっては
ロードに失敗するなど、問題があると思われます(あやふや)。
そうなるとどのバージョンでも使える手としては
[color=#d0d0ff" face="sans-serif]
1 別スレッドでファイルをメモリに読み込む。
2 その間メインスレッドでアニメーションをする。
3 別スレッド側で読み込みが終わったらメインスレッドに通知。
4 メインスレッドでメモリからDXライブラリのハンドル化する。[/color]
というのが考えられるのですが、ファイルをメモリに読み込む際に
DXライブラリのファイル読み込み関数が使えるかどうかが微妙です。
非 DXライブラリの読み込み関数を使うのが確実ですが、
そうなるとアーカイブの機能が使えなくなります。
そんなこんなで結局のところ、自前でロードスレッドを用意するのではなく
DXライブラリの機能のロードスレッドを使う方法、
[color=#d0d0ff" face="sans-serif]
1 DXライブラリの非同期読み込み関数を使ってファイルをメモリに読み込む指示を出す。
2 読み込み完了待ちしつつアニメーションを行う
3 読み込みが完了したらメモリから各種 DXライブラリの関数を
使ってハンドル化する[/color]
がベストな気がします。
Re:ロード中のアニメーション表示
(もう少し聞く事がありそうだったので、解決をOFFにしました。)
>Dixq
サンプルありがとうございます!
チェックさせていただきました。
見たところ、これは「データをロード⇔画面の更新」を繰り返していますよね?
LoadGraphを使っているところから、データひとつひとつの重さが重い場合、待ち時間が発生します。
そうすると、常に動くロード中の表示ができません。
これではだめなのです。
アニメーションの方も同様でした。
それにしても、アニメーション綺麗ですね~!
>lbfuvab
>違うスレッドでデータを読み出して、パーセントを表す変数を増加させていけば良いかと(排他処理を忘れず)
排他処理については、これから調べますが、私も別スレッドから変数を増加させる方法が良いのではないかと。
>Justy
>3.00cで多少改善されたような感じがしますが、タイミングによっては
>ロードに失敗するなど、問題があると思われます(あやふや)。
これが起きるのは困りますね・・・。
>DXライブラリの非同期読み込み関数
申し訳ない、その関数がどれか分からないのですが、具体的に関数名を教えていただけませんか?
>Dixq
サンプルありがとうございます!
チェックさせていただきました。
見たところ、これは「データをロード⇔画面の更新」を繰り返していますよね?
LoadGraphを使っているところから、データひとつひとつの重さが重い場合、待ち時間が発生します。
そうすると、常に動くロード中の表示ができません。
これではだめなのです。
アニメーションの方も同様でした。
それにしても、アニメーション綺麗ですね~!
>lbfuvab
>違うスレッドでデータを読み出して、パーセントを表す変数を増加させていけば良いかと(排他処理を忘れず)
排他処理については、これから調べますが、私も別スレッドから変数を増加させる方法が良いのではないかと。
>Justy
>3.00cで多少改善されたような感じがしますが、タイミングによっては
>ロードに失敗するなど、問題があると思われます(あやふや)。
これが起きるのは困りますね・・・。
>DXライブラリの非同期読み込み関数
申し訳ない、その関数がどれか分からないのですが、具体的に関数名を教えていただけませんか?
Re:ロード中のアニメーション表示
>具体的に関数名を教えていただけませんか
FileRead関数群がそうです。
FileRead_open関数の第二引数で同期するか非同期にするかを指定します。
他にどんな関数があるかはDXライブラリのヘッダファイルを調べてみて下さい。
Re:ロード中のアニメーション表示
横レス失礼します。管理人さんのを見せていただいた(サンプルを)のですが、
外部参照・・・とでて実行できません。(ビルドが失敗します。)なぜでしょう。
外部参照・・・とでて実行できません。(ビルドが失敗します。)なぜでしょう。