How to update glut window continuously?

╄→尐↘猪︶ㄣ 提交于 2019-11-27 23:58:17

问题


I have a real robot that is ordering my virtual robot in open gl. I want show every movement of my master robot(real robot) in slave (virtual one in open gl) online, so i need to update my glut window continuously, actually as long as real robot moves my virtual one moves too, and all these movement should be online.

I get data from master always with get data function, but I dont know how I should update the window.

Here is my code:

********************************************/

  void OnIdle(void){  
    initSocket();

  printf("\n  Defining Step Time Parameters and Initial Conditions for solving Dynamic equations\n");

  xi=0;
  xf=0.1;
  printf("\n    end value x         : %f ",xf); 
  i=0;  yi[i]=0; 
  i++;yi[i]=-1.570796;
  i++;yi[i]=-1.570796;
  i++;yi[i]=0;
  i++;yi[i]=0;
  i++;yi[i]=0;
  ndata=2; fi=1;

  double counter=0.1;

  Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);


  for(int i=0;i<50;i++)
    //while(1)
  {

      getData();

      printf("\n");
      for(int i=0;i<6; i++)
      {

          printf("%d = %.3f\n", i,drecvbuf[i]);
      }
      printf("\n");

   yi[0]=v1[ndata];
   yi[1]=v2[ndata];
   yi[2]=v3[ndata];
   yi[3]=v4[ndata];
   yi[4]=v5[ndata];
   yi[5]=v6[ndata];
    printf("my nadata %f\n",v1[ndata]);
    counter=counter+0.1;

    Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
    glutPostRedisplay();
 }
  }
/////////////////////////////////////////////////////
  int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowSize(900,500);
    int u=glutCreateWindow("3DOF robot");
    myinit();
    createMenu();
    glutIdleFunc (OnIdle);
    glutDisplayFunc(Display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(KeyDown);

    glutMainLoop(); 

    System::Timers::Timer^ aTimer = gcnew System::Timers::Timer( 100 );

      // Hook up the Elapsed event for the timer.
    aTimer->Elapsed += gcnew System::Timers::ElapsedEventHandler( OnTimedEvent );

      // Set the Interval to 2 seconds (2000 milliseconds).
    aTimer->Enabled = true;
    return 0;

  }

回答1:


You can call glutPostRedisplay after the update, which schedules the window to be redrawn (using GLUT's display func, of course) as soon as it returns to the message queue, I think.

But this won't work if you are continously polling the robot data in an infinite loop as this continously blocks the program. What you should do is use a timer to schedule the robot update in short intervals, so that between these updates the program can return to the main event loop and redraw the window. Or you can call some function, which tells the framework to visit the event loop. Your code sample doesn't really explain how you do it at the moment (or I'm just not familiar with the functions you call).




回答2:


GLUT offers you a idle callback (void (*)(void) signature), set through glutIdleFunc. Retrieve the robot input data in the idle handler. Or use a separate thread polling the data, filling data structures; use a semaphore to unlock idle after new data arrived, use a locking with timeout so that your program remains interactive. Pseudocode:

Semaphore robot_data_semaphore;

void wait_for_data(void)
{
    SemaphoreLockStatus lock_status = 
        semaphore_raise_timeout(robot_data_semaphore, RobotDataTimeout);
    if( lock_status == SEMAPHORE_RAISED ) {
        update_scene_with_robot_data();
        semaphore_lower(robot_data_semaphore);
        glutPostRedisplay();
    }
}

void main(int argc, char *argv[])
{
/* ... */
    semaphore_init(robot_data_semaphore);
    Thread thread_robot_data_poller = thread_create(robot_data_poller);
    glutIdleFunc(wait_for_data);

/* ... */
    thread_start(thread_robot_data_poller);
    glutMainLoop();
}



回答3:


I would do the following. Treat glutMainLoop() as your loop and every time you process one getData() you draw it, it will be faster than you think.

What needs to happen for you to get a 'continuous' update is to:

  1. Process data (getData() then your calculations)
  2. Redraw (Display() glut calls this every time it loops)
  3. Other functions defined using glut_____Func()
  4. Back to 1

Glut keeps going until the program is exited.

//called every time glutMainLoop
//do data processing
void OnIdle(void)
{  
    getData();

    printf("\n");
    for(int i=0;i<6; i++)
    {
        printf("%d = %.3f\n", i,drecvbuf[i]);
    }
    printf("\n");

    yi[0]=v1[ndata];
    yi[1]=v2[ndata];
    yi[2]=v3[ndata];
    yi[3]=v4[ndata];
    yi[4]=v5[ndata];
    yi[5]=v6[ndata];
    printf("my nadata %f\n",v1[ndata]);

    Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
}
//also called every loop of glutMainLoop
void Display()
{
    ...
    //Your previous Display() function just add this:
    glutPostRedisplay(); //everytime you are done 
                        // drawing you put it on the screen
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowSize(900,500);
    int u=glutCreateWindow("3DOF robot");
    myinit();
    createMenu();
    glutIdleFunc (OnIdle);
    glutDisplayFunc(Display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(KeyDown);

    ///////////////
    // SETUP YOUR INITIAL DATA
    System::Timers::Timer^ aTimer = gcnew System::Timers::Timer( 100 );

    // Hook up the Elapsed event for the timer.
    aTimer->Elapsed += gcnew System::Timers::ElapsedEventHandler( OnTimedEvent );

    // Set the Interval to 2 seconds (2000 milliseconds).
    aTimer->Enabled = true;

    initSocket();

    printf("\n  Defining Step Time Parameters and Initial Conditions for solving Dynamic equations\n");

    xi=0;
    xf=0.1;
    printf("\n    end value x         : %f ",xf); 
    i=0;  yi[i]=0; 
    i++;yi[i]=-1.570796;
    i++;yi[i]=-1.570796;
    i++;yi[i]=0;
    i++;yi[i]=0;
    i++;yi[i]=0;
    ndata=2; fi=1;

    Eqdifp(v1,v2,v3,v4,v5,v6,xi,xf,yi,ndata,p,fi);
    //////////////

    //Start the Main Loop
    glutMainLoop(); //This statement blocks, meaning that until you exit the 
                    // glut main loop no statments past this point will be executed.


    return 0;
}


来源:https://stackoverflow.com/questions/6800512/how-to-update-glut-window-continuously

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!