XE4で垂直同期で処理をするには?

解決


べなりあ  2013-05-31 21:35:59  No: 44592

はじめまして。Delphiでゲーム作りを始めたのですが、躓いてしまったので質問させていただきます。

現在、60FPSで画面更新、及び処理を行うようなアクションゲームを作っていて、
単純に1秒間に60回処理するようにタイマを回していたのですが、
タイマ処理では実際の画面更新との関係でコマ落ちが結構な頻度で発生してしまっています。
具体的には、1フレームだけ表示したい画像が、表示されたりされなかったりしています。

DirectXを使用して垂直同期が実現出来るかなと思ったのですが、
DirectX関連のライブラリ等を探すと古いものしか見つからず、
XE4で使えるような資料を見つけることが出来ませんでした。
firemonkeyではデフォルトでDirectXが使用されるといった話も見かけたのですが、
そこからどのように垂直同期を行えばいいのか、という情報を見つけることが出来ませんでした。

Delphiで垂直同期のゲームを作るためにはどのようにすれば良いでしょうか。
ご存知の方がいらっしゃいましたら、よろしくお願いいたします。


take  2013-06-01 01:52:59  No: 44593

数年前に少し組んだ程度なので的確なアドバイスが出来るか
わかりませんが

DirectXを使用して描画する場合
自動的に垂直同期が取られますのでちらつきません

DelphiでDirectXを使う場合
Delphi5の頃はDelphiXというコンポーネントと
書籍をにらめっこしながら作りましたが
最近では「Direct2D 」を使うのが一般的なようです。


べなりあ  2013-06-01 20:46:38  No: 44594

take様、ご返信ありがとうございます。

大変申し訳ございません。
質問の一番重要な部分が抜けておりました。
私がやりたいこととしては、垂直同期信号を読み取って
その際に処理を行う、というものです。
つまり、リフレッシュレートが60Hzであれば処理も60Hz周期で行いたい
というところです…。
時間ではなく、表示フレーム単位でゲーム内時刻を進めたいなと
考えておりまして、このような処理が必要となっております…。

また、「Direct2D」というキーワード、ありがとうございます。
こちらのキーを元に垂直同期信号等が取れないか調べてみます。

後出しになってしまい申し訳ないのですが、垂直同期信号を
ポートから直接読み取ろうと思ったのですが、見つけた資料で
やってみたものの垂直同期信号を表すフラグが常に立ちっぱなしに
なっていて使うことが出来ませんでした…。
方法は0x03DAポートの3bit目を見るというものですが、
もしかしたらそもそも実装にミスがあったのかもしれません。
DirectX側ではなく、こちらの方法で実現出来るということであれば
よろしくお願いいたします。

お手数おかけいたしますが、引き続きよろしくお願いいたします。


take  2013-06-03 17:52:26  No: 44595

べなりあ様へ
やりたいことの内容を理解しました。

60Hzを約0.016秒として、その間隔で発生する
割り込みタイマーがないかということですね。

DirectXを使用する場合には
これまでのタイマーとは別の高精度タイマーが
DirectXライブラリにあったかと思います。

DirectXライブラリ以外では「マルティメディアタイマー」を
使います。

ユニットMMsystemのTMMTimerクラスがそれです

まずは検索してみて使い方がわからないようであれば
再度質問してください。


べなりあ  2013-06-04 07:15:17  No: 44596

take様、ご回答ありがとうございます。

DirectXの高精度タイマーですが、残念ながら見つけることが出来ませんでした。
ですが、GetRasterStatusを用いることで画面更新タイミングまで待機させることが出来、
TimeSetEventと組み合わせて無事画面更新タイミングに合わせて処理を行うことが
出来るようになりました!

様々なキーワードを教えて頂き、ありがとうございました。
これで解決とさせていただきます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加