1

对于最终项目,我和我的朋友正在制作一个游戏。我们正在使用 GLUT(我知道,这不是最佳选择)。我们想做的是针对游戏的不同模式(例如启动画面、菜单画面、游戏画面等)有多个显示回调函数,所以当游戏模式改变时,我们改变回调。glutDisplayFunc所以实际上,它有点像在 GLUT 运行时能够调用。这可能吗?我们不愿意在整体显示函数中使用巨大的 if/switch 语句,因为我们认为它可能会影响性能。如果这种担心是没有根据的,请说出来!

4

4 回答 4

2

glutDisplayFunc 将指向显示场景的指针作为参数。使用多个显示函数最简单的方法是简单地调用 glutDisplayFunc 与您要切换到的显示场景函数指针。

IE

void render1() {
    //.. display something
}

void render2() {
    //.. display something else
}

//...
void someEvent() {
    if(iWantToRender1) {
        glutDisplayFunc(render1);
        glutIdleFunc(render1);
    } else {
        glutDisplayFunc(render2);
        glutIdleFunc(render2);
    }
}

这与在 render1/render2 中使用 if/else 不同,因为它会更改要调用的函数。如果您查看 GLUT 的文档,http: //www.opengl.org/resources/libraries/glut/spec3/node46.html glutDisplayFunc 会更改当前窗口的显示功能,而不是执行类似 glutTimerFunc 之类的操作,后者会安排要运行的内容。

于 2011-05-08T02:42:03.893 回答
1

这个问题有点老了,但我偶然发现了这个答案,同时为完全相同的问题寻找解决方案。

我认为,更优雅的方法是使用函数指针。首先,您创建一个函数指针(可能是全局的):

void (*foo)(void);

之后,您可以创建不同的绘图功能,例如:

void draw_1()    
{    
  /* Draw fancy stuff */
}

void draw_2()
{
  /* Draw other fancy stuff */
}

现在你需要一个“mainloop-mainloop”函数,它由 glutMainLoop 调用,它引用你的指针:

void mainloop_mainloop()
{    
  (*foo)();
}

正如我所说,这个函数必须是你的 glutMainLoop,所以你设置它:

glutDisplayFunc(mainloop_mainloop);

glutIdleFunc(mainloop_mainloop);

当然,您必须在某处设置函数指针:

foo = &draw_1;

如果您现在希望切换到另一个绘图上下文,您只需更改指针。例如,您可以在菜单中实现此功能:

if (menuentry==1) foo = &draw_1;

if (menuentry==2) foo = &draw_2;

等等……

这使您能够留在 glut 主循环内而不会弄乱显示功能,并且性能也不会受到损害,因为您只设置了一次 if/switch。您只有一个额外的函数调用,考虑到用于在每一帧中绘制您的东西的函数调用的数量,这应该可以忽略不计......

于 2012-04-03T14:26:17.867 回答
0

我们不愿意在整体显示函数中使用巨大的 if/switch 语句,因为我们认为它可能会影响性能。

它当然不是最好的编码风格,但性能不是一个论据。

您可以制作自己的模拟系统glutDisplayFunc,例如epicGameDisplayFunc将函数指针更改为传递的函数。

于 2011-05-08T02:23:09.540 回答
0

这段代码对我来说很好用。首先在 int main() 中,您必须调用第一个显示,然后添加 glutTimerFunc,您可以在一定时间后调用另一个显示。

void MyTimerFunc(int value);

int main(int argc, char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
    glutInitWindowSize(700,500);
    glutInitWindowPosition(0,0);
    glutCreateWindow("Animated Road Crossing Alert System");
    initOpenGl();
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutTimerFunc(20000, MyTimerFunc, 0);
    glutMainLoop();
    return 0;
}

void MyTimerFunc(int value)
{
   if (value == 0) // passed in in main
   {
      glutDisplayFunc(display1);
      glutIdleFunc(display1);

      // Change to a new display function in 2 seconds
      glutTimerFunc(40000, MyTimerFunc, 1);
   }
   else if(value==1)
   {
     glutDisplayFunc(display2);
     glutIdleFunc(display2);
   }

}
于 2018-07-04T16:48:00.837 回答