开发者

Switching Display Callback in GLUT

开发者 https://www.devze.com 2023-03-04 06:03 出处:网络
For a final project, my friends and I are making a game. We\'re using GLUT (I know, not the best choice). What we would l开发者_开发百科ike to do is to have multiple display callback functions for dif

For a final project, my friends and I are making a game. We're using GLUT (I know, not the best choice). What we would l开发者_开发百科ike to do is to have multiple display callback functions for different modes of the game (eg. splash screen, menu screen, gameplay screen, etc.), so when the game mode changes, we change the callback. So in effect, it's sort of like being able to call glutDisplayFunc while GLUT is running. Is this possible? We're reluctant to have a giant if/switch statement in an overall display function because we think it may hinder performance. If this concern is unfounded, please say so!


glutDisplayFunc takes a pointer to a display scene as an argument. The easiest way to use multiple display functions is to simply call glutDisplayFunc with the display scene function pointer you want to switch to.

i.e.

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

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

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

This is different than using an if/else in render1/render2 because it changes which function to call. If you look at GLUT's documentation, http://www.opengl.org/resources/libraries/glut/spec3/node46.html glutDisplayFunc changes the current window's display function, rather than doing something like glutTimerFunc, which schedules something to be run.


This question is kind of old, but I stumbled upon this answer, while looking for a solution for exactly the same problem.

I think, a more elegant approach would be the use of function pointers. First, you create a function pointer (might be global):

void (*foo)(void);

after that, you create your different drawing functions, e.g.:

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

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

Now you need a "mainloop-mainloop"-function, which is called by glutMainLoop an which refers to your pointer:

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

As I said, this function has to be your glutMainLoop, so you set it:

glutDisplayFunc(mainloop_mainloop);

glutIdleFunc(mainloop_mainloop);

Of course, you'll have to set your function pointer somewhere:

foo = &draw_1;

If you now wish to switch to another drawing context, you'll just have to change the pointer. You might implement this for instance in a menu:

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

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

an so on ...

This enables you, to remain inside the glut mainloop without messing up the display functions and performance won't be hurt either, as you set your if/switch only once. You just have one additional function call, which should neglectible considering the amount of function calls used to draw your stuff each single frame ...


We're reluctant to have a giant if/switch statement in an overall display function because we think it may hinder performance.

It certainly isn't the best coding style, but performance isn't an argument.

You can make your own system that simulates glutDisplayFunc, like epicGameDisplayFunc that changes a function pointer to the passed function.


This code is working fine for me. At first in int main() you have to call first display and then adding glutTimerFunc you can call another display after certain time.

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

}
0

精彩评论

暂无评论...
验证码 换一张
取 消