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

时间:2015-05-24 00:34:22

标签: c++ events opengl graphics glut

我有一个方法,我需要这个方法来显示使用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 个答案:

答案 0 :(得分:0)

经过大量阅读后,我发现完成我尝试做的唯一方法是擦除代码并将我的模拟方法放在显示功能中。以下是代码最终的工作原理:

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

正如您所看到的,我只留下代码的顶部。我这样做的原因是因为glutIdleFunc(显示)将被连续调用,所以如果我每次在显示函数内调用网络状态(调用模拟),每次glutIdleFunc()调用显示网络都会改变。此外,我不得不将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);
}
}