FPSについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たこやき

FPSについて

#1

投稿記事 by たこやき » 15年前

このシューティングゲームのFPSのソースなのですが、これを実行して移動させとたまに
一瞬止まってそしてすぐに移動するような現象がおきてしまいます。 
FPSの様子も56から46まで落ちる現象(処理落ち?)が起きます。
どの辺を直せばよいのでしょうか?
static DWORD before_time,befoer,Count0t;
DWORD now_time,t;
static int count=0;
long long IdleTime =0;
TCHAR buff[100];
DWORD cnt;
static long long surplus_Time=0;
now_time=timeGetTime();
if(!befoer_time)
befoer_time=timeGetTime();
if(!befoer)
befoer=timeGetTime();
surplus_Time+=1000/FPS-(long long)(now_time-befoer_time);
if(surplus_Time<=0){
IdleTime =0;
}
else
{
if(IdleTime!=surplus_Time)
IdleTime=surplus_Time;
surplus_Time=0;
++count;
}
if(IdleTime>0)
Sleep(IdleTime);
wsprintf(buff,_T("%u\n"),(now_time-before_time)+IdleTime);
OutputDebugString(buff);
before_time=timeGetTime();
cnt=timeGetTime();
t=cnt-before;
if(t>=1000)
{
cnt=t;
FpsDraw=count*1000/t;
count=0;
before=timeGetTime();
}
足りないところがあれば
補足します。よろしくおねがいします。

fatens

Re:FPSについて

#2

投稿記事 by fatens » 15年前

とりあえずFPSを一定にする処理だけにしてみましょう。
そのために必要なのは、
現在の時間:now_time
1秒前の時間:before_time
それらの差を保持する変数:surplus_time
現在のフレーム:frame
理想時間:ideal_time
です。

理想時間 = (DWORD)(frame * 1000.0(ミリ秒) / 60(FPS))
これで何フレーム目に何ミリ秒経過していれば良いのか分かります。

理想時間に達していなかった場合はその分を待機させます。
Sleep(ideal_time - surplus_time)

1秒経過したら、1秒前の時間を現在の時間にして、現在のフレームを0にします。

一度この条件でコードを書いてみてもらえますか?

softya

Re:FPSについて

#3

投稿記事 by softya » 15年前

FPSですが、画面のリフレッシュレートを中途半端に下回っているとティアリングが確実に発生します。
液晶モニタだったら60とかでしょうから、FPSは60、30、20から選ばないといけません。
まず、モニタのリフレッシュレートを確認して下さい。

たこやき

Re:FPSについて

#4

投稿記事 by たこやき » 15年前

fatensさん
返信ありがとうございます。
参考にしてやってみましたが。
static DWORD before_time,before,Count0t;
DWORD now_time,t;
static int frame=0;
DWORD ideal_time=0;
TCHAR buff[100];
DWORD cnt;
static long surplus_time=0;
now_time=timeGetTime();
if(!before_time)
before_time=timeGetTime();
if(!before)
before=timeGetTime();
surplus_time=(frame*1000)/60-(1000/FPS)-((long)now_time-before);
[pre]                ideal_time=(DWORD)(frame*1000)/60;
if(ideal_time-surplus_time<0)
{
surplus_time+=(frame*1000)/60;
}
if((long)ideal_time-surplus_time>0)
Sleep((long)ideal_time-surplus_time);
before=timeGetTime();
frame++;
if(ideal_time>=1000)
{
wsprintf(buff,_T("%d\n"),frame);
OutputDebugString(buff);
before_time=timeGetTime();
frame=0;
}
自分のが正しくプログラミングされてないと思いますが。
どの辺りを直せばよいのでしょうか?
>softyaさん
返信ありがとうございます。
プログラムでカウントしましたが、一秒で60回で毎回16msです。

fatens

Re:FPSについて

#5

投稿記事 by fatens » 15年前

FPSの制御だけなら前に書いた5つの変数で十分なんですけどね。
1秒前の時間を取得
現在のフレームを初期化

//メッセージループ
while (TRUE) {
    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
        if (msg.message == WM_QUIT) break;

        DispatchMessage(&msg);
    }
    else {
        現在の時間を取得
        時間の差を求める
        理想時間の計算

        //ゲームループ

        理想時間 > 時間の差 なら 待機する

        裏画面を表画面に転送

        1秒たったら、1秒前の時間を現在の時間にする・フレームを初期化する

    フレームをインクリメント
    }
}
まあ本来なら専用のスレッドですべきなんでしょうが……

たこやき

Re:FPSについて

#6

投稿記事 by たこやき » 15年前

返信ありがとうございます。
ご指摘のとおりプログラミングしてみたら、処理することが出来ました。
ただ、FPSが61fpsに固定されてしまっていて60に固定が出来ません。
これは仕方のないことなのでしょうか?

たこやき

Re:FPSについて

#7

投稿記事 by たこやき » 15年前

ソースです。
static DWORD before_time;
DWORD now_time,t;
DWORD ideal_time=0;
static int frame=0;
TCHAR buff[100];
DWORD cnt;
static long surplus_time=0;
now_time=timeGetTime();
if(!before_time)
before_time=timeGetTime();
surplus_time=(long)(now_time-before_time);
ideal_time=(DWORD)(frame*1000)/60
if((long)ideal_time-surplus_time>0)
Sleep((long)ideal_time-surplus_time);
if(surplus_time>=1000)
{
FpsDraw=frame;
before_time=timeGetTime();
frame=0;
}
frame++;

たこやき

Re:FPSについて

#8

投稿記事 by たこやき » 15年前

度々すみません。あとカクカクが取れません。

fatens

Re:FPSについて

#9

投稿記事 by fatens » 15年前

surplus_timeはDWORDで良いですしstaticである必要もありません。
またソースの投稿は始めと終わりをpreで一度だけ囲んでください。
不要なスペースも消して。

FPSが61になってしまうのは工夫すれば何とかなるのかもしれません。

ところで、ソースでは計算や描画にかかる時間を無視してフレームを制御しているように見えますが……

たこやき

Re:FPSについて

#10

投稿記事 by たこやき » 15年前

返信ありがとうございます。
計算の処理や描画の処理はその後に処理してます。もしかしてなにか勘違いか
間違っていますでしょうか?
ご指摘よろしくお願いします。

softya

Re:FPSについて

#11

投稿記事 by softya » 15年前

fatensさんがNo:47217で言うとおりにしてもらえますか。
FPS制御だけのメインを含んだプログラムを書いてみて下さい。他の制御は絵を一枚出すだけぐらいで。
それで、全部のコードを添付する形でお願いします。
ちゃんと、タブでインデントを整理して下さいね。

ここもチェックです。
http://dixq.net/g/51.html

たこやき

Re:FPSについて

#12

投稿記事 by たこやき » 15年前

返信ありがとうございます。
これです。

たこやき

Re:FPSについて

#13

投稿記事 by たこやき » 15年前

一からやるのは面倒くさかったのでゲームごと送ります。キー入力は出来ないですけど・・・

softya

Re:FPSについて

#14

投稿記事 by softya » 15年前

試しに、今のをFPS処理をコメントアウトして、代わりの下記サイトのFPS関数を組み込んでみて下さい。
http://dixq.net/g/51.html
それとDraw();の後のSleep(1);は次のようにすれば不要だと思います。
今の状態: Fps();→Draw();→Sleep(1);
新しい状態:Draw();→wait_fanc();
case WM_PAINT:のインデントも間違っているので直して下さいね。

たこやき

Re:FPSについて

#15

投稿記事 by たこやき » 15年前

返信ありがとうございます。
ここのサイトのFPSの制御は最終手段として使いたいので、
他に方法はないのでしょうか?

たこやき

Re:FPSについて

#16

投稿記事 by たこやき » 15年前

最終手段しか方法はないのでしょうか?

たこやき

Re:FPSについて

#17

投稿記事 by たこやき » 15年前

あとここのFPS制御を使ってもカクカクが起きてしまいます。

fatens

Re:FPSについて

#18

投稿記事 by fatens » 15年前

いろいろ漁ってたら昔のソースが出てきたので、少し修正して添付しました。
コメントは大して付けてませんが似たような感じですし、
それほど難しい処理はしていませんので読み解いてください。

FPSの制御部分はあれだけ書いた割に適当なコードですが、
私の方では問題なく(カクカクになったりせず)動いているので良しとしましょう。
(FPSの表示はしていないので実際どうなのかは知りませんが)

FPSを一定に保つことももちろん重要なことですが、
いくら60FPSがキープできたとしても内容が良くなければゲームとしては成り立たないので、
とりあえずこのソースで動くのであれば、これを元にして内容を作り込んでいくことをお薦めします。

たこやき

Re:FPSについて

#19

投稿記事 by たこやき » 15年前

最後の質問にします。
そのソースでやってみましたが、今度はティアリングが発生します。
計ったらFPSも62fpsか61fpsとなってしまします。
これらは無視しても大丈夫なのでしょうか?

fatens

Re:FPSについて

#20

投稿記事 by fatens » 15年前

>そのソースでやってみましたが、今度はティアリングが発生します。

Win32 APIだけではティアリングを防ぐことはできません。
どうしても防ぎたいならDirectXなどを使うしかないと思います。


>計ったらFPSも62fpsか 61fpsとなってしまします。

1フレーム16ミリ秒になっているので約62.5fpsになるでしょうね。
先にも書きましたが、少しぐらいの誤差なら無視して進めた方が良いと思います。
別に後で直すこともできますから。

たこやき

Re:FPSについて

#21

投稿記事 by たこやき » 15年前

そうですか。。。

>先にも書きましたが、少しぐらいの誤差なら無視して進めた方が良いと思います。
>別に後で直すこともできますから。
わかりました。
回答ありがとうございました!

たこやき

Re:FPSについて

#22

投稿記事 by たこやき » 15年前

解決しました。

閉鎖

“C言語何でも質問掲示板” へ戻る