2

流体力学コードの結果を視覚化するためのいくつかの OpenGL/Glut 関数を作成しています (すべて C++ で)。私のデータは、グローバルとして宣言されたマトリックスに格納されています。

疑似コードは次のとおりです。

class fluid_dynamics{
    //...
    void set_conditions();    // Here is my opengl init function
    void solve();             // This is an iterative loop with stop criteria
    void IterateLoop();
}

solve() 関数にはループがあります。

void fluid_dynamics::solve(){
    glutDisplayFunc(DisplayMatrix);

    IterateLoop(  // here I update my data each n-steps
                  // and I want to update my "scene" every time I do that.
               );
    glutMainLoop();          

私は OpenGL にはまったく慣れていませんが、IterateLoop() 関数内で glutPostRedisplay() を使用すると、ループが終了するまで新しいイメージが実行されないことを理解している限り (glutPostRedisplay() はフラグを設定してアイドル状態になるまで待機するため)、だから...何かアイデアはありますか?(1)

glutIdleFunc を使用することは可能ですか? または、ループを小さなものに分割する IterateLoop を指す glutTimerFunc ですか? (その場合、クラス内からクラスメンバーに void ポインターを渡す方法は?:S)

ノート; コードを書き直すこともできるので、すべての提案を受け入れますが、すべての流体力学操作をクラス内に置くことが重要だと思います。

4

3 に答える 3

1

概念的には、レンダリングと解決は 2 つの異なるものであり、ソルバーで直接レンダリングを行うべきではありません。このように考えてみてください: ソルバーは GUI がなくても機能するので、GUI はその上にあるものにすぎません。だから、別のクラスに入れてください。

スレッド化と非スレッド化の 2 つの基本的なアプローチがあります。ソルバーは現時点での現在の状態で構成されており、その状態を次の時間枠に進めることができるはずです。したがって、 a で解決 (1 回の反復) を行うことができますがglutIdleFunc、これは少し醜いです:

solver* g_solver;
void step()
{
  g_solver->step();
}

int main()
{
  ...
  g_solver = &solver;
  glutIdleFunc(&step);
}

または、別のスレッドで解決を行い、状態を保存し、レンダリングのために OpenGL スレッドに取得させます。

その1つの側面は、次の状態を計算するのにかかる時間が、あるフレームから次のフレームまでの時間と関係があるかどうかを必ずしも知らないということですが、あなたの質問はそれが問題であるかどうかを述べていません.

于 2013-05-25T12:07:49.223 に答える
0

私はこのアプローチを取ることをお勧めしないので、私にとってはうまくいくトリッキーな解決策をここに残しました。おそらく、「非静的メンバー関数...」エラーに関連する多くの問題を解決する必要があります。

fluid_dynamics と Visualize の 2 つのクラスがあります。

class fluid_dynamics{
    //...
    void set_conditions();    // Here is my opengl init function
    void IterateStep();
}

すべての IterateStep は、グローバル配列を新しい結果で更新します。

class visualize{
    visualize()              // main constructor, set the opengl environment; buffer mode, 
                             // window size, etc, and call glutDisplayFunc() and glutMainLoop()
    static void display();   
    static fluid_dynamics *copy; //statically initialized copy of a fluid_dynamics obj.

ここに表示メンバー:

visualize::display(){
    ... //draw scene
    if-condition{            //control iteration < max. iterations condition
    fluid_dynamics::IterateStep(*copy)
    }
    glutPostRedisplay();
}

短所;

  1. glutDisplayFunct は静的関数を必要とするため、ほとんどすべての関数 (またはクラス メンバー) は静的である必要があります。
  2. glutMainLoop ループに依存しているため、ソルバーの制御がいくらか失われます。
  3. main() の外でいくつかのクラス パラメータを静的に初期化する必要があります。
于 2013-05-26T00:36:30.430 に答える
-1

真剣に私は GLUT を使用せず、代わりに優れたクロスプラットフォーム GL ラッピングを提供する Qt を使用します。

QGLWidget を使用して、GL コードをウィジェットの描画に埋め込むことができます。ウェブ上にはたくさんの例があります。その後、Qt のイベント システムや QTimers などを使用して、シーンの更新と再描画をトリガーすることもできます。

または、QGraphicsView レンダリングを QGLWidget に使用することもできます。次に、QGraphicsScene のレンダリング中に GL コードを埋め込むことができます。これにより、さらに自由度が増し、無料で多くのものを手に入れることができます。たとえば、マウス入力処理の改善や、ビューの上にあるウィジェットなどです。

可能性は無限であり、GLUT を使用する場合よりも多くのコードを記述する必要はありません。QGraphicsView を使用した比較的小さな例として、http://qt.gitorious.org/qt-labs/modelviewer を参照してください

これは非常に強力な概念です (ただし、QGLWidget を使用する方が簡単です)。

于 2013-05-24T19:46:20.437 に答える