Search code examples
cperformanceopenglglfwglew

Why is initializing gl3w so much faster than initializing GLEW?


I'm using GLFW to set the OpenGL context and then test the speed of each library by initializing it multiple times, with all optimization flags on.

On my machine, gl3w can be initialized 100 times in about 0.5 seconds:

#include "gl3w.h"
#include <GLFW/glfw3.h>

int main(void)
{
    if (!glfwInit()) return 1;
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    GLFWwindow *win = glfwCreateWindow(960, 540, "Title", NULL, NULL);
    if (!win) return 2;
    glfwMakeContextCurrent(win);

    for (int i = 0; i < 100; ++i) if (gl3wInit()) return 3;
    if (!gl3wIsSupported(3, 3)) return 4;

    glfwDestroyWindow(win);
    glfwTerminate();

    return 0;
}

While initializing GLEW 100 times takes about 2.5 seconds, making it about 5 times slower!

#include <GL/glew.h>
#include <GLFW/glfw3.h>

int main(void)
{
    if (!glfwInit()) return 1;
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    GLFWwindow *win = glfwCreateWindow(960, 540, "Title", NULL, NULL);
    if (!win) return 2;
    glfwMakeContextCurrent(win);

    glewExperimental = GL_TRUE;
    for (int i = 0; i < 100; ++i) if (glewInit()) return 3;

    glfwDestroyWindow(win);
    glfwTerminate();

    return 0;
}

I am very surprised about this since both of these libraries are designed to fit the same purpose. Could someone explain what the difference is all about?

By the way, omitting the glewExperimental = GL_TRUE; cuts time to 0.3 seconds, but then GLEW isn't initializing correctly because glBindVertexArray(0); just afterwards throws a segmentation fault while it shouldn't.


Solution

  • Because GLEW is doing more work than GL3W.

    GL3W consists of only the functions from the OpenGL header glcorearb.h. This contains the functions in OpenGL 4.5, as well as many ARB extensions. This means it does not include other extension functions or non-core profile stuff.

    GLEW gives you every function in the OpenGL registry. Also, there's this:

    glewExperimental = GL_TRUE;
    

    Normally, GLEW will check to see if a particular extension is supported before trying to load its functions. By using that, you're telling GLEW not to do that check. Instead, it will try to load every function regardless of whether the extension is specified or not.

    You may have been told that you have to use this switch. That's not true anymore.

    See, OpenGL 3.0 changed how you test extensions in OpenGL. And thus, the old method was deprecated, and thus removed in 3.1 and core profile 3.2+.

    However, GLEW kept using the old extension testing functionality. As such, you had to use that switch if you wanted to use GLEW with a core profile.

    GLEW 2.0, eight years later, finally fixed this... long after about a half dozen much better OpenGL loading libraries solved the problem many times over. But in any case, the point is that you shouldn't use this switch with GLEW 2.0.