Как постоянно обновлять окно перенасыщения?

У меня есть настоящий робот, который заказывает моего виртуального робота в open gl. Я хочу показать каждое движение моего главного робота (настоящего робота) в ведомом (виртуальном в открытом gl) онлайн, поэтому мне нужно постоянно обновлять окно перенасыщения, на самом деле, пока реальный робот перемещает мой виртуальный тоже, и все эти движение должно быть онлайн.

Я всегда получаю данные от мастера с помощью функции получения данных, но я не знаю, как мне обновить окно.

Вот мой код:

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

  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;

  }

person Likak    schedule 23.07.2011    source источник
comment
Не хочу помечать это как таковое, так как я не знаком, но System::Timers::Timer^ aTimer = gcnew System::Timers::Timer( 100 ); мне кажется C++/CLI?   -  person Bart    schedule 23.07.2011
comment
@Bart Как только вы видите ^, это определенно C++/CLI.   -  person Christian Rau    schedule 23.07.2011
comment
на самом деле, gcnew — гораздо более сильный индикатор C++/CLI. ^ является допустимым оператором в стандартном C++.   -  person Ben Voigt    schedule 23.07.2011
comment
@ Бен Да, ты прав, не думал о xor.   -  person Christian Rau    schedule 23.07.2011


Ответы (3)


Вы можете вызвать glutPostRedisplay после обновления, которое запланирует перерисовку окна (конечно, используя функцию отображения GLUT), как только оно вернется в очередь сообщений, я думаю.

Но это не сработает, если вы постоянно опрашиваете данные робота в бесконечном цикле, так как это постоянно блокирует программу. Что вам нужно сделать, так это использовать таймер, чтобы запланировать обновление робота через короткие промежутки времени, чтобы между этими обновлениями программа могла вернуться к основному циклу событий и перерисовать окно. Или вы можете вызвать некоторую функцию, которая сообщает фреймворку посетить цикл событий. Ваш пример кода на самом деле не объясняет, как вы это делаете в данный момент (или я просто не знаком с функциями, которые вы вызываете).

person Christian Rau    schedule 23.07.2011
comment
дорогая Кристин, спасибо за ответ - person Likak; 24.07.2011
comment
на самом деле я новичок в open gl и даже в c++, не такой профессиональный. - person Likak; 24.07.2011
comment
поэтому я бы предпочел использовать функцию opengl, что-то вроде той, что вы сказали (glutPostRedisplay), но я не знаю, как это сделать. мне нужно что-то не такое сложное! - person Likak; 24.07.2011
comment
я редактировал коды вверх, и это предложенный способ, который я пробовал, но он не работал, я запутался :(( - person Likak; 24.07.2011
comment
@bahare Кстати, glutPostRedisplay принадлежит НЕ OpenGL, а GLUT. OpenGL — это интерфейс для программирования графического оборудования (отображения вещей), тогда как GLUT — это библиотека абстракций графического интерфейса пользователя, упрощающая создание простых программ OpenGL. Но OpenGL не имеет ничего общего с такими задачами, как графический интерфейс или обработка событий. - person Christian Rau; 28.07.2011

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();
}
person datenwolf    schedule 23.07.2011
comment
я попробовал то, что вы сказали, но это не сработало, я изменил коды повышения и использовал ваш способ, не могли бы вы взглянуть и сказать, что с этим? tnx много :) - person Likak; 24.07.2011
comment
@bahare: обработчик простоя должен вернуться в течение примерно 50 мс, чтобы программа оставалась отзывчивой. Также обновление дисплея не произойдет, пока обработчик ожидания не вернется. glutPostRedisplay просто устанавливает какой-то флаг. В обработчике простоя вы должны сделать то, что вы бы поместили в ветку цикла обработки событий по умолчанию — без цикла. - person datenwolf; 24.07.2011
comment
не могли бы вы исправить коды вверх так, как вы говорите! Я пробовал много способов, но это не работает. - person Likak; 24.07.2011
comment
@bahare: Для этого мне потребуется полный исходный код, поскольку опубликованная вами часть не содержит достаточной информации. - person datenwolf; 25.07.2011

Я бы сделал следующее. Относитесь к glutMainLoop() как к своему циклу, и каждый раз, когда вы обрабатываете один getData(), вы рисуете его, это будет быстрее, чем вы думаете.

Что должно произойти, чтобы вы получали «непрерывное» обновление:

  1. Обработать данные (getData() затем ваши расчеты)
  2. Перерисовка (Display() перенасыщение вызывает это каждый раз, когда зацикливается)
  3. Другие функции, определенные с помощью glut_____Func()
  4. Назад к 1

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;
}
person Gideon W    schedule 25.07.2011