最終的なプロジェクトとして、友達と私はゲームを作っています。私たちはGLUTを使用しています(私は知っていますが、最良の選択ではありません). やりたいことは、ゲームのさまざまなモード (スプラッシュ画面、メニュー画面、ゲームプレイ画面など) に対して複数のディスプレイ コールバック関数を用意することです。そのため、ゲーム モードが変更されると、コールバックを変更します。glutDisplayFunc
事実上、 GLUT の実行中に呼び出すことができるようなものです。これは可能ですか?パフォーマンスを妨げる可能性があるため、表示関数全体に巨大な if/switch ステートメントを含めることには消極的です。この懸念が根拠のないものである場合は、そう言ってください。
4 に答える
glutDisplayFunc は、表示シーンへのポインタを引数として取ります。複数の表示関数を使用する最も簡単な方法は、切り替え先の表示シーン関数ポインターを指定して glutDisplayFunc を呼び出すだけです。
すなわち
void render1() {
//.. display something
}
void render2() {
//.. display something else
}
//...
void someEvent() {
if(iWantToRender1) {
glutDisplayFunc(render1);
glutIdleFunc(render1);
} else {
glutDisplayFunc(render2);
glutIdleFunc(render2);
}
}
これは、呼び出す関数が変わるため、render1/render2 で if/else を使用する場合とは異なります。GLUT のドキュメントを見ると、http: //www.opengl.org/resources/libraries/glut/spec3/node46.html glutDisplayFunc は現在のウィンドウの表示機能を変更します。何かを実行するようにスケジュールする glutTimerFunc のようなことをするのではありません。
この質問はちょっと古いですが、まったく同じ問題の解決策を探しているときに、この答えに出くわしました。
より洗練されたアプローチは、関数ポインターの使用だと思います。まず、関数ポインタを作成します (グローバルの場合があります)。
void (*foo)(void);
その後、さまざまな描画関数を作成します。たとえば、次のようになります。
void draw_1()
{
/* Draw fancy stuff */
}
void draw_2()
{
/* Draw other fancy stuff */
}
次に、ポインタを参照する glutMainLoop によって呼び出される「mainloop-mainloop」関数が必要です。
void mainloop_mainloop()
{
(*foo)();
}
先ほど言ったように、この関数は glutMainLoop でなければならないので、次のように設定します。
glutDisplayFunc(mainloop_mainloop);
glutIdleFunc(mainloop_mainloop);
もちろん、関数ポインターをどこかに設定する必要があります。
foo = &draw_1;
別の描画コンテキストに切り替えたい場合は、ポインターを変更するだけです。たとえば、メニューでこれを実装できます。
if (menuentry==1) foo = &draw_1;
if (menuentry==2) foo = &draw_2;
など...
これにより、表示機能を台無しにすることなく大量のメインループ内にとどまることができ、if/switch を 1 回だけ設定するため、パフォーマンスも損なわれません。追加の関数呼び出しが 1 つだけありますが、これは、フレームごとに描画するために使用される関数呼び出しの量を考慮すると無視できるはずです...
パフォーマンスを妨げる可能性があるため、表示関数全体に巨大な if/switch ステートメントを含めることには消極的です。
これは確かに最適なコーディング スタイルではありませんが、パフォーマンスは議論の余地がありません。
渡された関数への関数ポインタを変更するglutDisplayFunc
など、をシミュレートする独自のシステムを作成できます。epicGameDisplayFunc