質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
GLFW

GLFWは、OpenGLを使用してアプリ開発を行うためのフレームワークです。Macにも対応しているマルチプラットフォームであることが特徴。ウィンドウ管理、解像度切り替え、入力管理などの機能を持ちます。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1059閲覧

ミリ秒を使ってフレームレートを制御したい。

退会済みユーザー

退会済みユーザー

総合スコア0

GLFW

GLFWは、OpenGLを使用してアプリ開発を行うためのフレームワークです。Macにも対応しているマルチプラットフォームであることが特徴。ウィンドウ管理、解像度切り替え、入力管理などの機能を持ちます。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/06/22 08:53

編集2021/06/25 05:06

提示コードのvoid Wait();関数の内部のstd::cout<<関数部の出力が提示画像です。質問ですが参考サイトと同じようにミリ秒を使ってフレームレートを60に固定させたいのですがなぜwaitTime変数の値がマイナスなのでしょうか?提示コードではglfwGetTime();関数は秒数をdouble型で返すのでそれに1000掛けてミリ秒を取得しています。色々表示させてみて値を確認した結果参考サイトは間違えているということはわかったのですがではどうやってフレームレートを60で制御するのでしょうか?

知りたいこと 
マイナスの値が返ってくるがこれは正しいのでしょうか?普通15,14といった値が返ってくることを想定しているのですが

確認したこと
変数はすべてコンストラクタ部で0で初期化
参考サイトの移し間違えを確認

参考サイト: https://dixq.net/g/03_14.html
イメージ説明

cpp

1 2// ##################################### ミリ秒を取得 ##################################### 3int FrameWork::Window::getNowTime() 4{ 5 return (int)(glfwGetTime() * 1000.0f); 6} 7 8// ##################################### 待機フレームを計算 ##################################### 9void FrameWork::Window::FrameUpdate(glm::vec4 color) 10{ 11 float c = 1.0f / 255.0f; 12 glClearColor(color.x * c, color.y * c, color.z * c, color.w * c); //カラーバッファのクリア色 13 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); //フレームバッファを初期化 14 15 glEnable(GL_BLEND); //アルファブレンド有効 16 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //ブレンドタイプ 17 18 19 //フレームレートを制御する 20 if (count == 0) 21 { 22 startCount = getNowTime(); 23 } 24 25 if (count == FRAME_RATE) 26 { 27 startCount = getNowTime(); 28 count = 0; 29 } 30 31 //count++; 32 count += 1; 33} 34 35// ##################################### フレームを取得 ##################################### 36int FrameWork::Window::getFrame()const 37{ 38 return count; 39} 40 41// ##################################### フレームレート 待機 ##################################### 42void FrameWork::Window::Wait() 43{ 44 int tookTime = getNowTime() - startCount; 45 int waitTime = count * 1000 / FRAME_RATE - tookTime; 46 47 //std::cout << "waitTime: " << waitTime << std::endl; 48 49 50 std::cout << "tookTime: " << tookTime << std::endl; 51 std::cout << "waitTime: " << waitTime << std::endl; 52 std::cout << "count: " << count << std::endl; 53 std::cout << "getNowTime(): " << getNowTime() << std::endl; 54 std::cout << "((int)(count * 1000) / FRAME_RATE): " << ((int)(count * 1000) / FRAME_RATE) << std::endl; 55 std::cout << std::endl; 56 57 58 59 if (waitTime > 0) 60 { 61 std::this_thread::sleep_for(std::chrono::milliseconds(waitTime)); 62 63 } 64} 65

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

itagagaki

2021/06/22 09:05

countはFrameUpdateが呼ばれるたびにインクリメントされるカウンターのようなので、単位がわかりませんね。FrameUpdateがどういう頻度で呼ばれるかに依存しますよね。
fana

2021/06/22 09:20

まぁ,おそらく FrameUpdate() と wait() が交互に呼ばれる形なんでしょうけど,そういうことは明示しないと意味不明ですね.
fana

2021/06/22 09:25

> なぜwaitTime変数の値がマイナスなのでしょうか? (「参考サイト」のURLの先は私の環境ではとある理由で見れないのですが)質問に提示されたコードの雰囲気からやっていることを推測すると, waitTimeの値が負になることは普通にあり得ることだと思いますが,何が問題点なのでしょうか?
guest

回答2

0

ベストアンサー

なぜwaitTime変数の値がマイナスなのでしょうか?

そりゃあ,

int waitTime = count * 1000 / FRAME_RATE - tookTime;

として,waitTimeの値は引き算で計算されていますから
- の左側の値よりも右側の値が大きい場合には負の値になるわけで.


要は,「ある処理を時刻tのタイミングで実施したい」として,それが実際に可能かどうかは動作状況次第だということ.
その処理を実施することが可能となったときには,既に「時刻t」とは遥か過去になっているかもしれない.

60fps であれば,「1フレーム」の処理が 1/60[s] 以内に終われない場合には,スケジュールは押してしまうわけで.



マイナスの値が返ってくるがこれは正しいのでしょうか?普通15,14といった値が返ってくることを想定しているのですが

int tookTime = getNowTime() - startCount; int waitTime = count * 1000 / FRAME_RATE - tookTime;
  • tookTime とは,ある時刻 startCount からの経過時間.

(言い換えれば,startCount を基準時刻(0)とした時刻)

  • count * 1000 / FRAME_RATE とは,count番目のフレームの処理を実施したい時刻.

(この時刻も startCount を基準時刻(0)としたもの)

waitTime とは,この2つの引き算なのだから,

「今の時刻は tookTime なんだけど,処理を実施したい時刻になるまでにはどれだけ時間がありますかね」 

という値だ.

どれだけ時間があるだろうか? なんてのは,現在の時刻 tookTime 次第である.
(なのに,それが「15とか14たるべき」という話は一体どこからやってくるのか?)

残りは 15[ms] あるかもしれないし,1[ms] しかないかもしれない.

時刻 tookTime は「処理を実施したい時刻よりも後の時刻」かもしれない.
その場合,当然ながら,waitTimeは負の値になる.

投稿2021/06/23 04:53

編集2021/06/25 05:32
fana

総合スコア11658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/06/25 03:23

この処理は正しいのでしょうか?
fana

2021/06/25 04:01

「何が正しいのか?」は,あなた次第なのだと,何度言えばよいのか. 所望の動作をしているのならば "正しい" のだろうし,違うのならば "正しくない",ということになるんじゃないの? 処理の正当性について(?)何か不明点があるならば,元ネタが書いてたところに対して問うべきでは. (まぁ問う手段があるのかも知らんけども)
fana

2021/06/25 05:36

「60FPSにしたい」←これはただの願望. 実際の処理が1フレームあたり 0.5秒 かかってしまうとしたら, なにをどうやっても 60FPS なんて達成できない. そのような場合,waitTime は負の値となるであろう. わかりやすく言えばそういうこと.
guest

0

画面への標準出力は意外と遅いのでやめた方がいいです

特にご提示のプログラムの場合endlを乱用しています。
この場合、endlごとにフラッシュ(書き込み動作)するためより遅くなる事が懸念されます。

今回の場合、改行のためだけならば"\n"を書き込むべきかと思います。


というわけで、解決策としては

  1. endlの代わりに"\n"を使う。
  2. std::coutをやめる
  3. 標準出力をやめる(OutputDebugStringあたりが代替候補)

の順に試していくことになるかと思います。

投稿2021/06/22 10:28

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/06/22 10:43 編集

> 解決策としては… とのことですが,そもそも何が解決すべき課題なのか?が不明瞭であるように思います. 確かに「何で私のプログラムの各フレームの処理速度が遅いのか? 改善するには?」という話であるようにも読める気はしますが, 「各フレームの処理速度が遅いと → waitTimeが負の値になり得る」というところがまず理解されているのかどうか疑問です.
asm

2021/06/22 15:52

> fanaさん なるほど。確かにその問題もありましたね。
fana

2021/06/23 01:02

今現在だけ必要なデバッグ用の出力(ずっと残すコードじゃない)であって, 別にリアルタイムに表示される必要もなさそうなので, 毎フレーム出力するんじゃなくて,各時点での値を適当に配列か何かに貯め込んでおいて 後からそれを出力すればいいんじゃないかな.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問