在 GLUT 中切换显示回调
Switching Display Callback in GLUT
对于最终项目,我和我的朋友们正在制作一个游戏。我们正在使用GLUT(我知道,不是最好的选择)。我们要做的是针对游戏的不同模式(例如初始屏幕、菜单屏幕、游戏屏幕等)具有多个显示回调函数,因此当游戏模式发生变化时,我们会更改回调。所以实际上,这有点像能够在 GLUT 运行时调用glutDisplayFunc
。这可能吗?我们不愿意在整个显示函数中使用巨大的 if/switch 语句,因为我们认为这可能会妨碍性能。如果这种担心是没有根据的,请说出来!
glutDisplayFunc 将指向显示场景的指针作为参数。使用多个显示函数的最简单方法是使用要切换到的显示场景函数指针调用 glutDisplayFunc。
即
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.htmlglutDisplayFunc 更改当前窗口的显示函数,而不是执行像 glutTimerFunc 这样调度要运行的内容的操作。
这个问题有点老了,但我在寻找完全相同问题的解决方案时偶然发现了这个答案。
我认为,更优雅的方法是使用函数指针。首先,创建一个函数指针(可能是全局的):
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 一次。你只有一个额外的函数调用,考虑到用于绘制每一帧内容的函数调用的数量,这应该可以忽略不计......
我们不愿意在整个显示函数中使用巨大的 if/switch 语句,因为我们认为这可能会妨碍性能。
它当然不是最好的编码风格,但性能不是争论。
您可以创建自己的模拟glutDisplayFunc
的系统,例如更改指向所传递函数的函数指针的epicGameDisplayFunc
。
这段代码对我来说工作正常。首先在int main()中,您必须首先调用显示,然后添加glutTimerFenc,您可以在一定时间后调用另一个显示器。
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);
}
}
- 架构决策:返回std::future还是提供回调
- 正在为Xtensa simcall函数编写回调函数
- 如何在C++中使用非静态成员函数作为回调函数
- FLTK:按下哪个按钮 - 将数字传递给按钮的回调 (lambda)
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 用于在回调中调用解析器的设计模式
- 如何使用C++对象的成员函数作为 C 样式回调?
- Java从C++回调到C++回调
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 从不同的 cpp 调用回调函数会导致bad_function_call
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 不带轮询的 SDL2 事件回调
- C++存储带有可变参数的回调
- 回调方法显示错误,类型为"void(*)"的值不能用于初始化类型的实体
- SDL视频显示窗口:如何连接窗口关闭事件回调
- 在状态栏上显示来自不同线程中回调的消息
- GLUT只运行一次显示回调,不输出到终端
- Windows:当我从本机代码回调到托管代码时,将显示“仅消息”窗口
- 在 GLUT 中切换显示回调
- Opengl函数,显示在一个键回调函数