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 吗?或 glutTimerFunc 指向 IterateLoop 将循环分成小循环?(在那种情况下,它应该如何从类内部将一个 void 指针传递给一个类成员?:S)

笔记; 我可以重写代码,所以我接受每一个建议,但我认为将我所有的流体动力学操作都放在一个类中很重要。

4

3 回答 3

1

从概念上讲,渲染和求解是两件不同的事情,您不应该直接在求解器中进行渲染。可以这样想:你的求解器可以在没有任何 GUI 的情况下完成它的工作,所以 GUI 只是位于它之上的东西。所以把它放在不同的班级。

有两种基本方法:线程和非线程。您的求解器包含当前时间的当前状态,并且应该能够将其状态推进到下一个时间范围。因此,您可以在 a 中进行求解(一次迭代)glutIdleFunc,这有点难看:

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

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

或者在单独的线程中进行求解,存储状态,并让 OpenGL 线程获取它进行渲染。

一方面是您不一定知道计算下一个状态所需的时间是否与从一帧到下一帧的时间有关,但您的问题并没有说明这是否是一个问题。

于 2013-05-25T12:07:49.223 回答
0

我在这里留下了一个适合我的棘手解决方案,因为我不建议采用这种方法;可能您将不得不解决与“非静态成员函数...”错误相关的许多问题。

有两个类,流体动力学和可视化。

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 Loop。
  3. 您应该在 main() 之外静态初始化一些类参数,减少对您的控制。
于 2013-05-26T00:36:30.430 回答
-1

说真的,我不会使用 GLUT,而是使用 Qt,它提供了出色的跨平台 GL 包装。

您可以只使用 QGLWidget 并将您的 GL 代码嵌入到绘制小部件中。网上有很多例子。然后你也可以使用Qt的事件系统和QTimers等来触发场景的更新和重绘。

或者您可以使用 QGraphicsView 渲染到 QGLWidget。然后再次在渲染 QGraphicsScene 时,您可以嵌入 GL 代码。这允许更多的自由,您可以免费获得很多东西,例如更好的鼠标输入处理或视图顶部的小部件。

可能性是无穷无尽的,你不会用 GLUT 编写更多的代码。作为 QGraphicsView 的一个不错的相对较小的示例,请参见:http: //qt.gitorious.org/qt-labs/modelviewer

这是一个非常强大的概念(只是使用 QGLWidget 更容易)。

于 2013-05-24T19:46:20.437 回答