プロが教える店舗&オフィスのセキュリティ対策術

今DirectDrawを使ったプログラムを組んでいて、そのプロジェクト内でFPSの制御関数(図1)を作りました。その関数は引数を1つ持っていて、その引数に渡した値がそのままフレームレートになるはずなのですが、実際は引数に指定した値よりもフレームレートが落ちています。
  図1
FpsControl(60);

          1/60フレームレート
FPS制御をしていない時にFPSを計ったときには500~600fps
は出ていましたので処理自体が遅いわけではないと思います。
FPS制御関数はメッセージループ部分(図2)で使っています。
  図2
while(TRUE){
//メッセージがある場合
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
if(msg.message == WM_QUIT)break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}else{//メッセージが無い場合

if(FpsControl(60))Game_Main();//プログラ ムのメイン部分 ↑
   ↑
}        ↑
                  ↑
               **ここで使ってます**

関数の内部処理は何度も確認したので間違ってないと思います。
ずっとこのバグについて考えいろいろ試しましたが、
結局原因はわからずここに助けを求めに来ました。
お願いします。

A 回答 (2件)

開発環境や実際のFpsControl関数が何をやってるかわかりませんが、


とりあえず下記のようにやればできると思います。

// メッセージループ
while(TRUE){
if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ){
// 通常のWindowメッセージの処理


}
else{
// FPS制御
static INT now_time = 0, old_time = 0;

timeBeginPeriod(1);
now_time = timeGetTime();
timeEndPeriod(1);
if( (now_time-old_time) >= (1000/60) ){
old_time = now_time;

// メイン処理
Game_Main();
}
}
}
    • good
    • 0

こんにちは、honiyonです。



 精密にフレームレートを計算するには、様々な処理にかかる時間を考慮しないとダメだと思います。

FpsControl(60) とすると、60fpsだから、0.1msec待機する、という処理になっていませんか?
 例えば表示処理に0.05msecかかっていたとすれば、1フレームにつき0.05msecの誤差が出ます。これを考慮しないといけません。

 これの解決の一例ですが、

 1.処理の開始にFpsControl_Startを呼び出す。(ここで時間計測開始)
 2.表示処理を行う
 3.FpsControl_Wait(60)を呼び出す。
   ここで60fps計算で、0.1msecまたならければならない。しかし1~3までくるのに0.05mesecかかった。
   0.1msec - 0.05msec = 0.05msecの停止とする。ただし、計算結果がマイナス(処理速度がたりない)場合は停止せずにreturnする。

 なんて形にすれば良いと思います。
 
 ちょっと分かりづらい説明かも知れませんが伝わりましたでしょうか(^^;
 参考になれば幸いです(..

#的外してたらスイマセン...
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!