Как постоянно обновлять окно glut?
У меня есть настоящий робот, который заказывает мой виртуальный робот в open gl. Я хочу показать каждое движение моего главного робота (реального робота) в slave (virtual one in open gl) онлайн, поэтому мне нужно постоянно обновлять окно перенасыщения, на самом деле, пока реальный робот движется, мой виртуальный тоже движется, и все эти движения должны быть онлайн.
Я получаю данные от мастера всегда с функцией get data, но я не знаю, как я должен обновить окно.
вот мой код:
********************************************/
void OnIdle(void){
initSocket();
printf("n Defining Step Time Parameters and Initial Conditions for solving Dynamic equationsn");
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 = %.3fn", 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 %fn",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 ответов
вы можете вызвать glutPostRedisplay после обновления, которое планирует перерисовывать окно (используя функцию отображения GLUT, конечно), как только оно вернется в очередь сообщений, я думаю.
но это не будет работать, если вы постоянно опрашиваете данные робота в бесконечном цикле, поскольку это постоянно блокирует программу. Что вам нужно сделать, так это использовать таймер для планирования обновления робота в короткие промежутки времени, чтобы между этими обновлениями программа могла вернуться к основному циклу событий и перерисуйте окно. Или вы можете вызвать некоторую функцию, которая сообщает фреймворку посетить цикл событий. Ваш пример кода на самом деле не объясняет, как вы это делаете в данный момент (или я просто не знаком с функциями, которые вы вызываете).
GLUT предлагает вам простой обратный вызов (void (*)(void)
подпись), установлен через glutIdleFunc
. Получить входные данные робота в обработчике idle. Или используйте отдельный поток опроса данных, заполняя структуры данных; используйте семафор для разблокировки простоя после поступления новых данных, используйте блокировку с таймаутом, чтобы ваша программа оставалась интерактивной. Псевдокод:
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();
}
Я бы сделал следующее. Лечить glutMainLoop()
как ваш цикл и каждый раз, когда вы обрабатываете один getData()
вы его нарисуете, это будет быстрее, чем вы думаете.
что должно произойти, для вас, чтобы получить 'непрерывные обновления:
- обработка данных (
getData()
значит, твои расчеты) - Redraw (
Display()
glut называет это каждый раз, когда он петляет) - другие функции, определенные с помощью
glut_____Func()
- назад к 1
перенасыщение продолжает работать, пока программа не выйдет.
//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;
}