将C++ OpenGL 项目与另一个C++项目集成

Integrating C++ OpenGL project with another C++ project

本文关键字:C++ 项目 集成 另一个 OpenGL      更新时间:2023-10-16

我正在使用一个读取数据文件、执行一些计算并在标准输出上显示结果的项目。后来我想为结果提供 3D 图形视图,所以我创建了一个新的 OpenGL 项目,将数据显示为 3D 对象。

现在的问题是,我无法找到集成这两个独立项目的方法,因为我的 OpenGL 项目中的main()进入了一个非终止glutMainLoop()循环,我无法弄清楚在我的第一个项目main()将循环放在哪里!

/**** Proj1 ****/
int main()
{  
    while(ESC key not pressed)
    {
        // read data file
        // do some processing
        // show results on standard output
    }
} 
/**** Proj2 ****/
int main()
{
    glutInit(&argc, argv);
    Init();
    glutDisplayFunc(Display);
    glutKeyboardFunc(Keyboard);
    glutMouseFunc(Mouse);
    glutIdleFunc(Idle);
    glutMainLoop();
}

要求在 Proj1 和 Proj2 之间混合最少的代码。是否可以执行以下操作:

/**** Proj1 ****/
#include <filesFromProj2>
int main()
{
    while(ESC key not pressed)
    {
          // read data file
          // do some processing
          proj2.showResult(result)   // how to do this ?
    }
}

最简单的解决方案是放弃 GLUT 并使用 OpenGL 窗口框架来实现事件循环。GLFW将是直接的选择。然后,与其使用永远不会返回的不透明glutMainLoop,不如在你旁边调用glfwPollEvents是你的 stdio 处理。

GLUT 将事件处理代码与显示代码分离。如果你习惯了完全控制循环的范式,感觉很奇怪,但这并不难处理。基本上,你需要保持一个你的glutDisplayFunc会做出反应的状态,并在glutKeyboardFunc中更新该状态。所以在伪代码中(似乎你已经C++了):

displayFunc:
  if state.showProj1
    proj1.showResult
  else if state.showProj2
    proj2.showResult
keyboardFunc
  if keyPressed(esc)
    state.showProj1 = false
    state.showProj2 = true
    glutPostRedisplay()

好的,所以这是一些非常幼稚的代码,但它应该知道如何更改您的状态以响应用户输入,这反过来又会影响您正在渲染的内容。

如前面的回答所述,如果您希望显式控制程序循环(而不是基于事件的范例),您可以在 GLFW 和 SDL 中有一些不错的选择,但当然会有一些提升,因为 GLUT 以完全不同的方式做事。

找到了一个解决方案,所以自己回答供大家参考:

我迫切需要一种解决方法,而不必将我现有的过剩基本代码更改为 GLFWSDF 等。

在互联网上挖掘更多内容,我发现freeglut支持一个函数glutMainLoopEvent(),该函数"导致freeglut在其事件循环中处理一次迭代的事件。这允许应用程序控制自己的事件循环,并且仍然使用freeglut窗口系统。

此外,freeglut 支持glut 的所有函数(或者至少支持我的程序中使用的所有 glut 函数)。所以,我不必更改我的过剩基本代码。

解决方法的伪代码如下所示。我欢迎你的评论。

#include <gl/freeglut.h>
#include <filesFromProj2>
int main()
{
    glutInit(&argc, argv);
    Init();
    glutDisplayFunc(Display);
    glutKeyboardFunc(Keyboard);
    glutMouseFunc(Mouse);
    glutIdleFunc(Idle);
    // glutMainLoop();       // Do not use this
    while(ESC key not pressed)
    {
        // read data file
        // do some processing
        proj2.showresults(results)
        glutMainLoopEvent();    // One iteration only
        Display();              // Call the func used with glutDisplayFunc()
    }
    glutLeaveMainLoop();
}

我也认为多线程,也可以解决这个问题。一个线程用于 glutMainLoop(),另一个用于数据处理!