如何连续更新过剩窗口?

时间:2011-07-23 12:57:53

标签: opengl loops c++-cli glut

我有一个真正的机器人正在开放我的虚拟机器人。我希望在线显示我的主机器人(真正的机器人)在奴隶(虚拟的一个在开放的gl)中的每一个动作,所以我需要连续更新我的过剩窗口,实际上只要真正的机器人移动我的虚拟移动也是如此,所有这些运动应该在线。

我总是使用get data函数从master获取数据,但我不知道应该如何更新窗口。

这是我的代码:

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

  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;

  }

3 个答案:

答案 0 :(得分:8)

你可以在更新后调用glutPostRedisplay,我认为,一旦它返回到消息队列,就会调度窗口重绘(当然是使用GLUT的显示功能)。

但是,如果您在无限循环中不断轮询机器人数据,这将不起作用,因为这会不断阻止程序。您应该做的是使用计时器以短时间间隔安排机器人更新,以便在这些更新之间程序可以返回主事件循环并重绘窗口。或者你可以调用一些函数,它告诉框架访问事件循环。你的代码示例并没有真正解释你现在是怎么做的(或者我只是不熟悉你调用的函数)。

答案 1 :(得分:2)

GLUT为您提供空闲回调(void (*)(void)签名),通过glutIdleFunc设置。在空闲处理程序中检索机器人输入数据。或者使用单独的线程轮询数据,填充数据结构;在新数据到达后使用信号量解锁空闲,使用超时锁定,以便您的程序保持交互。伪代码:

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();
}

答案 2 :(得分:0)

我会做以下事情。将glutMainLoop()视为您的循环,每次处理一个getData()时,它都会比您想象的更快。

要获得“持续”更新,您需要做的是:

  1. 处理数据(getData()然后计算)
  2. 重绘(每次循环时Display()过剩调用此内容)
  3. 使用glut_____Func()
  4. 定义的其他功能
  5. 返回1
  6. Glut一直持续到程序退出。

    //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;
    }