skaslev / gl3w

Simple OpenGL core profile loading
http://github.com/skaslev/gl3w
The Unlicense
705 stars 157 forks source link

What if the function is neither in opengl32.dll nor from wglGetProcAddress? #57

Closed ghost closed 6 years ago

ghost commented 6 years ago

Take Windows as an example. The function pointers are retrieved in get_proc(). It first tries to retrieve a function pointer from wglGetProcAddress, assuming it is an extension. If not, it then find it in opengl32.dll using GetProcAddress. However, the return value of GetProcAddress is not checked, which seems to be assuming that the function must be in opengl32.dll. But on what is this assumption based? What if an OpenGL function is neither in opengl32.dll nor from wglGetProcAddress?

PS: the current code of get_proc():

static GL3WglProc get_proc(const char *proc)
{
    GL3WglProc res;

    res = (GL3WglProc)wgl_get_proc_address(proc);
    if (!res)
        res = (GL3WglProc)GetProcAddress(libgl, proc);
    return res;
}
ikskuh commented 6 years ago

This is reasonable behaviour for machines that don't support all the functions from glcorearb.h. Imagine compiling your application with all functions from OpenGL 4.6, but targeting OpenGL 3.3.

When starting the application on a system that does not support newer functions than those of OpenGL 3.3, the application should still run and not emit any errors or warnings regarding missing functions.

ghost commented 6 years ago

I'm afraid you misunderstand my question. I'm not asking what you are trying to answer.

ikskuh commented 6 years ago

Well, the function will return NULL if that was the initial question

ghost commented 6 years ago

@MasterQ32: Thank you for your willingness to answer. I think a more relevant answer can be tendered from some others.

tombsar commented 6 years ago

If an OpenGL function is not found in either of those locations, then it is not present on the local machine. Returning NULL in these situations seems correct to me; it will raise a segfault only if you try to use this function, and otherwise continue normally.

ghost commented 6 years ago

So the functions listed in union GL3WProcs or <GL/glcorearb.h> are just all OpenGL functions in the standard, not the actual available (in opengl32.dll or from wglGetProcAddress as extensions) OpenGL functions provided by the platform on which I ran the python script to generate the gl3w.c. Right? So all gl3w does is to mark a function item -- if it is available in the platform on which the application is running, the item is the function pointer, otherwise the item is NULL. So a serious application using gl3w should check whether the OpenGL function to be used is NULL or not before calling it, just as parse_version of gl3w.c checks glGetIntegerv:

static int parse_version(void)
{
    if (!glGetIntegerv)
        return GL3W_ERROR_INIT;

    glGetIntegerv(GL_MAJOR_VERSION, &version.major);
    glGetIntegerv(GL_MINOR_VERSION, &version.minor);
        ......
}

Am I right?

tombsar commented 6 years ago

Yes, that all sounds right to me. On Windows you can only find out what functionality is actually available at runtime, so not everything in the OpenGL headers will work. There is definitely an argument to be made that gl3w should check for failures, at least for core functionality, but I presume the author decided the extra safety wasn't worth the overhead or code complexity. If you want your code to be completely safe, you should check every OpenGL function pointer before use.

In practice, however, you should be safe using any core OpenGL functionality for a given OpenGL version after checking gl3wIsSupported. If a graphics driver claims it supports a given OpenGL version, but then does not give you the function pointers, that would be a serious bug in the driver. If you want to use anything defined as an OpenGL extension, or that comes from a spec version newer than what you requested, then you should definitely check for NULL before using it.

ghost commented 6 years ago

@tombsar: Thank you very much for the clear remarks.

tombsar commented 6 years ago

Closing this. Please reopen if you have further questions.