OpenGLの使い方について疑問があったので質問しました.
OpenGLを用いて3Dのゲームを作っています.しかし,
どうも処理が遅くカクカクした動きになってしまいます.
描画の量が多くなるにつれて遅くなっているので,原因は
描画の時に原因があるようです.ダブルバッファリング
を用いて描画しているのですが,描画のときは…
1「描画関数の実行」(glVertex3f()などの実行)
2「裏に描画」(見えていないバッファに描画)
3「裏表入れ替え」(2つのバッファを交換)
0「一定時間待機して自分自身を呼び出す」
(60FPSなら1/60秒程度)
を繰り返すものと考えています.
「1230」と繰り返せば通常通り動くのですが,
「1」に計算がかかりすぎると,「2」と「3」が遅れてしまい,
カクカクしてしまうのだろうと考えました.
(↑これがそもそも間違っていたらすいません><)
そこで,対策を2つ考えたのですが,これでいいでしょうか?
それとも,もっと良い方法はないでしょうか?(「1」を
速くするしか方法はないでしょうか?)
【1】一定時間待機する秒数を可変的にする
現在のところ,「0」では,1/60秒待機させています.
しかし,1に1/30秒かかったとすると,「1230」を
1回繰り返すのに,3/60秒かかってしまうことになり,
結局FPSは20止まりです.
そこで,「123」でかかった時間を記録し,その秒数
を1/60から引いた分だけ「0」で待機すれば,1/60秒になる
だろう,という方法です.
【2】描画のタイミングを変える
現在のところ,「1230」の順番で繰り返しています.
しかし,これでは描画の関数を呼び出した時,「1」に
1/30秒かかったとすると,実際に表示できるのは1/30秒後
ということになります.よって,プログラムの始めに
「1232」を実行しておき,描画の関数の中身は
「3120」とする,という方法です.
(そもそも,「2」と「3」のタイミングを
離せるのかどうかもよくわかりません><)
もちろん【1】と【2】の方法は併用もできると思っています.
「2」はOpenGLに入っているglFlush()
「3」はOpenGLに入っているglutSwapBuffers()
「0」はOpenGLに入っているglutTimerFunc()
を用いています.
質問が長くなってしまいましたが,よろしくお願いします.
参考までに…
【OS】Mac OS10.7(Lion)
【開発環境】Xcode3
【言語】c++
【プログラミング歴】6年(c++2年,OpenGL1年)
【CPU】2.66 GHz Intel Core 2 Duo
【メモリ】4 GB 1067 MHz DDR3
No.1ベストアンサー
- 回答日時:
OpenGLではglVertex等を呼び出すとその都度描画を実行するのではなく、複数の処理をまとめて実行するようになっています。
glFlushは、それが呼び出された時点で未消化の命令がある場合それを全部実行する、という処理なので1と2はセットと考えたほうが良いです。
したがって、処理の手順の分類としては
1「描画関数の実行」(glVertex3f()などの実行 == 見えていないバッファに描画)
2「裏表入れ替え」(2つのバッファを交換)
0「一定時間待機して自分自身を呼び出す」
が正しいです。
【1】について
予想されている仮定で正しいと思います。
待機時間を一定にした場合、
FPS = 1秒 / ( 毎フレームで必要な処理時間 + 待機時間 )
となってしまい、狙ったFPSにはなりません。
ちなみに、動画を再生するような場合、
現フレームまでに経過しているはずの時間 = FPS * 処理したフレーム数
次の待機時間 = 現フレームまでに経過しているはずの時間 - 実際に経過した時間
という感じで処理しなければずれが発生します。
【2】について
これはおそらく意味は無いと思います。
1を開始点としてみると
修正前:
描画関数の実行 → 裏表入れ替え → 一定時間待機 → 描画関数の実行 → ...
修正後:
描画関数の実行 → 一定時間待機 → 裏表入れ替え → 描画関数の実行 → ...
となるだけで結果にはほとんど違いは無いと思います。
「裏表入れ替え」を行うと、もっと最後に処理したOpenGLの命令によって作られたレンダリング結果が画面に反映されることになるので、
修正前:直前に処理した描画内容が画面に表示された状態で待機
修正後:2回前に処理した描画内容が画面に表示された状態で待機
となり、おそらくこれはやらないほうが良いと思います。
基本的には、処理落ちしている場合、
> 「1」を速くするしか方法はない
ということになります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) エクセルマクロでアニメを作る方法を教えてください。 1 2023/02/07 14:27
- Firefox(ファイヤーフォックス) Firefox bookmarkの検索BOXでのインクリメンタルサーチを止めたい 5 2022/06/29 12:15
- オンラインゲーム PC版フォートナイトの人の多い場面でカクつきます 2 2022/06/02 23:33
- Windows 10 Win10の起動が遅い(OSは最新)ハードを交換しても解決しない 5 2023/03/25 01:04
- CAD・DTP 「機能ブロック図」の描画用フリーソフトを教えてください 1 2022/09/23 16:12
- Excel(エクセル) エクセルVBA マクロ処理中のポップアップメッセージについて 1 2023/08/04 21:34
- その他(ネットショッピング・通販・ECサイト) 初期不良の対応について 5 2023/07/21 19:46
- モニター・ディスプレイ 長文です。デスクトップPCのHDMI入力機能について 4 2022/09/20 17:58
- 美術・アート トレパク疑惑をかけられにくくするには ここ最近いわゆるトレパク警察のいいがかりがが厳しくなったようで 1 2023/08/21 09:59
- その他(プログラミング・Web制作) Pythonによる物理の斜方投射の位置座標表示について 2 2023/06/05 12:46
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
PCで「使用可能な場合はグラフ...
-
TextBoxに文字を書いても表示さ...
-
NVIDIAのシェーダーキャッシュ
-
[VB.net] DataGridViewの列ヘッ...
-
ブレゼンハムのアルゴリズムに...
-
vc++のpictureboxにopenGLの画...
-
画像の印刷について
-
MFC ビットマップ描画で残像が残る
-
VB6のform Load
-
VB6,リストボックスの特定行の...
-
UpdateData( FALSE); による文...
-
ワード2019 描画ツールの書式が...
-
C++にて、塗りつぶされた円を描...
-
ダイアログベースの再描画について
-
WM_PAINTとWM_MOVEで同じ事をし...
-
Windowのちらつき防止
-
FlexGridの一部のみ表示を更新...
-
InvalidateRectの使い方について
-
C言語(dxlib)のDrawboxについ...
-
LineToやMoveToにて描画した線...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB6,リストボックスの特定行の...
-
[VB.net] DataGridViewの列ヘッ...
-
NVIDIAのシェーダーキャッシュ
-
MFCでOnPaintのタイミング
-
TextBoxに文字を書いても表示さ...
-
word
-
UpdateData( FALSE); による文...
-
VC++プログラムをつかったBMP画...
-
InvalidateRectの使い方について
-
OneNote 2010 文字と描画がずれる
-
StretchBlt関数について
-
C# ラバーバンドの描画を快適に...
-
エクセルでガンチャートを作成...
-
C++にて、塗りつぶされた円を描...
-
VBAにGDI+を参照させる方法
-
GDI+で高速な描画
-
MFC DrawText 背景色とフォント
-
FlexGridの一部のみ表示を更新...
-
MFCのタイマーのつかい方を教え...
-
Labelの文字をスクロールする際...
おすすめ情報