Search code examples
c++openglglut

Render a frame on demand


I'm currently creating a NTSC signal decoder/simulator, and basically, I'd like to be able to prepare a frame before rendering it, such as, read an array, process data, draw some pixels accordingly, and then render the frame. I've tried getting rid of the glutMainLoop(); thing, and just using a handmade loop:

for(;;) { 
    glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    // Whatever I might have to do goes somewhere in here
    glFlush(); 
}

This, however, doesn't work, glClearColor and glClear, probably also glFlush get executed, but just one time, after that, the program just hangs, what can I do to avoid this?


Solution

  • I've tried getting rid of the glutMainLoop(); thing, and just using a handmade loop
    ... after that, the program just hangs ...

    This is a bad idea, because in general the only way to get a event handling when using GLUT is glutMainLoop().

    See glutMainLoop:

    glutMainLoop enters the GLUT event processing loop. This routine should be called at most once in a GLUT program. Once called, this routine will never return. It will call as necessary any callbacks that have been registered.

    Note, glutMainLoop() doesn't only call the call back function which you have set by glutDisplayFunc, it also receives and processes the IO events like mouse and keyboard events. If you don't use the glutMainLoop(), then you have no event handling and of course no IO event handling. This causes that the program seems to hang and doesn't react on any input.
    Either you have to use glutMainLoop() or you have to switch a other window API like GLFW, where you can explicitly activate the event processing by glfwPollEvents()

    Newer implementations of GLUT, like freeglut provide some additional functionality. glutMainLoopEvent() does the same as glutMainLoop(), but it does it only once. It does a single iteration of the event loop and gives control back immediately. So you can implement your own loop handles your application.

    e.g.

    void display( void )
    {
        glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        // Whatever I might have to do goes somewhere in here
        glFlush();
    }
    
    int main()
    {
        .....
    
        glutDisplayFunc(display);  
    
        .....
    
        for(;;)
        {
            glutMainLoopEvent(); // handle the main loop once
            glutPostRedisplay(); // cause `display` to be called in `glutMainLoopEvent`
        }
    
        .....
    }
    

    It is even possible to set a dummy display function, which does nothing, and do the drawing in the loop:

    e.g.

    void dummyDisplay( void )
    {
        // does nothing
    }
    
    int main()
    {
        .....
    
        glutDisplayFunc(dummyDisplay);  
    
        .....
    
        for(;;)
        {
            glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
            // Whatever I might have to do goes somewhere in here
            glFlush();
    
            glutMainLoopEvent(); // does the event handling once
        }
    
        .....
    }