更新窗口显示 OpenGL/GLUT C++

Posted

技术标签:

【中文标题】更新窗口显示 OpenGL/GLUT C++【英文标题】:Update window display OpenGL/GLUT C++ 【发布时间】:2015-05-24 00:34:22 【问题描述】:

我有一个方法,我需要这个方法来显示病毒在使用 GLUT 的网络中的行为(这是我第一次使用图形库)。

我展示了许多连接它们的点和线。该程序运行良好,它完美地显示了网络的初始状态,但是在调用方法模拟后我无法找到更新显示的方法。

这些点会根据计算机的状态改变颜色,所以我需要一种方法来每 3 秒或类似的更新一次显示(网络图)。有任何想法吗?

我已经阅读了有关使用glutPostRedisplay() 或以某种方式使用glutIdleFunc() 的信息,但我不明白如何实现它。感谢您的帮助。

这是我的代码:(但这仅显示初始状态)

void Visualizador::visualizar(int cItr, int ios, double vsc, int vcf, double rc, double grc) 

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1280,720);
glutCreateWindow("Network initial state");
glutDisplayFunc(display); //display creates a number of points (computers) and lines (connections)
glutIdleFunc(display);
glutMainLoop();

for (int i = 0; i < cItr; i++)  //cItr: Number of times the state of the network will be updated
    ostringstream oss;
    oss << "State #" << i+1 << " of the network";
    string windowName = oss.str();
    const char* cstr = windowName.c_str();
    simulator.simulate(1, vsc, vcf, rc, grc); //this method can change which point is infected
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutSetWindowTitle(cstr);
    glutMainLoop();
    

【问题讨论】:

【参考方案1】:

经过大量阅读后,我发现完成我想要做的事情的唯一方法是擦除代码并将我的模拟方法放在显示函数中。以下是代码最终的工作方式:

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1280,720);
glutCreateWindow("Network initial state");
glutDisplayFunc(display);
glutIdleFunc(display);
glutMainLoop();

如您所见,我只留下了代码的顶部。我这样做的原因是因为 glutIdleFunc(display) 将被连续调用,所以如果我在每次 glutIdleFunc() 调用 display 时更改显示函数内部的网络状态(调用模拟),网络就会改变。我还必须将 glutPostRedisplay() 放在 glutIdleFunc() 的底部。调用 glutPostRedisplay() 会导致程序引发一个标志,指示需要重新绘制窗口,或者换句话说,需要更新显示。

尽管存在未知变量,但我还是包含了显示代码,因为它可能对某人有所帮助:

void Visualizador::display() 

if(v->displayCount <= Visualizador::cantIterac) 

    int contVertices = 0;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    for (int i = 0; i < Visualizador::v->grafo.cntVrt*2; i += 2) 
        if (Visualizador::v->grafo.obtEst(contVertices) == Grafo::S) 
            glColor3f(0.0, 1.0, 0.0);
        
        else 
            if (Visualizador::v->grafo.obtEst(contVertices) == Grafo::R) 
                glColor3f(0.5, 0.5, 0.5);
            
            else 
                glColor3f(1.0, 0.0, 0.0); //red
            
        
        glPointSize(5.8);
        glBegin(GL_POINTS);
        glVertex2f(arrPos[i], arrPos[i + 1]);
        contVertices++;
    
    glEnd();

    contVertices = 0;
    glLineWidth(1.6); //Ajusta el ancho de las lineas
    glColor3f(0.2, 1.0, 1.0); //Color blanco
    glBegin(GL_LINES); //empieza a dibujar lineas, cada dos llamadas a la funcion glVertex dibuja una sola linea
    for (int i = 0; i < Visualizador::v->grafo.cntVrt*2; i += 2) 
        int* adyVrt = Visualizador::v->grafo.obtAdy(contVertices);
        for (int j = 0; j < Visualizador::v->grafo.arrVrt[contVertices].lstAdy->obtCntAdy(); j++) 
            glVertex2f(arrPos[i], arrPos[i + 1]);
            glVertex2f(arrPos[adyVrt[j]*2], arrPos[(adyVrt[j]*2) + 1]);
        
        contVertices++;
    
    glEnd();
    glutSwapBuffers();

    if (v->displayCount < Visualizador::cantIterac)
    
        Sleep(500);

        v->simulador.simular(1,Visualizador::virusSpreadC, Visualizador::virusCheckFrec, Visualizador::recoveryC, Visualizador::gainResistance);

        ostringstream oss;
        oss << "State #" << v->displayCount+1 << " of the network";
        string windowName = oss.str();
        const char* cstr = windowName.c_str();
        glutSetWindowTitle(cstr);
        glutPostRedisplay();
    
    v->displayCount++;

else

   glutIdleFunc(NULL);


【讨论】:

以上是关于更新窗口显示 OpenGL/GLUT C++的主要内容,如果未能解决你的问题,请参考以下文章

Mac 上的 OpenGL/GLUT 应用程序无法获得焦点 [关闭]

OpenGL/Glut 无法在其上绘制 [

OpenGL帧率:与窗口大小的关系

OpenGL/Glut glutSolidCube()

C++中的扫描线填充OpenGL/GLUT算法

当作为子进程运行时,OpenGL 窗口不会在 xcode (7.2) 中打开