Rendering loop

Most graphics programs don't just render a single frame and then quit, as ours does right now. To change this, we need to create a rendering loop. These can get rather complex, thus, I will merely show you how to create a simple loop. There are plenty of other resources that show how to do this properly.

We begin with this while loop after our matrix initialisation from last chapter:

// glfwWindowShouldClose is true when the close button has been clicked.
while (!glfwWindowShouldClose(window)) {

}

If you run this code, you'll probably get a window with undefined content that you can't close. Let's address these issues.

  • Undefined window contents: The front buffer is undefined (white surface, trippy effects, depends on system). When we do rendering with OpenGL, the resulting graphics are stored in the back buffer. By calling glfwSwapBuffers, we copy the back buffer to the front buffer (what we see on the window). This is done to prevent flickering caused by the rendering process being visible. Since we never call glfwSwapBuffers, the front buffer's contents are unknown.
  • Window can't be closed: Windows operate using events. Our program isn't processing any events, thus, it cannot get the signal that the window should be closed. Because of this, glfwWindowShouldClose never changes its value.
  • Moving objects will be duplicate: While we can't see this yet, this is an issue that will arise once we do rendering. Essentially, just because we call glfwSwapBuffers, that does not mean that the back buffer will be emptied. We must call glClear to achieve this.

First, we need to deal with the back buffer. As we discussed, let's add a call to glClear:

// GL_COLOR_BUFFER_BIT will clear the colour.
// There are other types of buffers that we'll deal with eventually.
glClear(GL_COLOR_BUFFER_BIT);

Here's where we put our rendering code. For organisational purposes, let's make a render function and call it here.

After we're done with rendering, we swap our buffers so that our drawing is now visible on the window:

// This will also wait for vsync if activated. (See below)
glfwSwapBuffers(window);

Now we ask GLFW to get the latest window events and process them.

glfwPollEvents();

After all that, your program should look something like this:

void render(void) {
    // Render our frame here...
}

int main(int argc, char *argv[]) {
    // ... GLFW stuff
    // ... Transformation matrix init

    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT);

        render();

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}

Enabling VSync

Enabling VSync will ensure that your program renders as fast as the monitor can handle. This is a good way to prevent screen tearing.

Enabling it is easy to do, add this after your call to glfwMakeContextCurrent:

glfwSwapInterval(1);

You can disable VSync at any time the program is running by passing 0 to glfwSwapInterval.

results matching ""

    No results matching ""