Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#120 Calling glGetString(GL_EXTENSION) even in Core/FC context

open
nobody
API (59)
3
2012-09-15
2010-01-07
No

GLEW is calling glGetString(GL_EXTENSIONS) always for extensions even if the current context is a forward-compatible or core context. This is invalid behavior since glGetString(GL_EXTENSIONS) was deprecated in 3.0 for the Forward-Compatible context.

The best thing to do would be to instead:
1) Determine if glGetStringi is available. If so, always use glGetIntegerv(GL_NUM_EXTENSIONS, xxx) and glGetStringi(GL_EXTENSION, ) to determine if any extension exists.
2) Use glGetString if glGetStringi is not available (this should only be possible in an OpenGL implementation not supporting 3.0+).

I've seen this in 3 files : glew_init_gl.c, visualinfo.c, and mipmap.c.

I tried to make the changes myself, but the Visual Studio projects can't find many of the files after I synced.

Discussion

1 2 > >> (Page 1 of 2)
  • I've made a code snippet below for glew_init_gl.c. The main concern I have is how do I make sure glGetStringi is setup or, if not, set it up properly before the call?

    GLboolean glewGetExtension (const char name)
    {

    const GLubyte
    s;
    GLuint dot, n;
    GLint major, minor, num, iter;
    GLubyte p;
    GLubyte
    end;
    GLuint len = _glewStrLen((const GLubyte*)name);

    / query opengl version /
    s = glGetString(GL_VERSION);
    dot = _glewStrCLen(s, '.');
    if (dot == 0)
    return GLEW_ERROR_NO_GL_VERSION;

    major = s[dot-1]-'0';
    minor = s[dot+1]-'0';

    / If we're 3.0 or greater use glGetStringi instead.
    * since this works with both Core, Compatible, and
    * Forward-Compatible contexts
    /
    if (major > 3 && major < 9)
    {
    glGetIntegerv(GL_NUM_EXTENSIONS, &num);
    if (glGetError() == GL_NO_ERROR && num > 0)
    {
    for (iter = 0; iter < num; iter++)
    {
    p = (GLubyte)glGetStringi(GL_EXTENSION, iter);
    n = _glewStrLen(p);
    if (len == n && _glewStrSame((const GLubyte
    )name, p, n)) return GL_TRUE;
    }
    }
    }

    p = (GLubyte)glGetString(GL_EXTENSIONS);
    if (0 == p) return GL_FALSE;
    end = p + _glewStrLen(p);
    while (p < end)
    {
    n = _glewStrCLen(p, ' ');
    if (len == n && _glewStrSame((const GLubyte
    )name, p, n)) return GL_TRUE;
    p += n+1;
    }
    return GL_FALSE;
    }

     
  • Funto
    Funto
    2010-01-16

    I experienced the same problem.

    glprogrammer >> in your code snippet, I think you should not return "GLEW_ERROR_NO_GL_VERSION", as the function returns a GLboolean, and I think this is a mistake :

    / If we're 3.0 or greater use glGetStringi instead.
    since this works with both Core, Compatible, and
    Forward-Compatible contexts /
    if (major > 3 && major < 9)

    => shouldn't it be just "if(major >= 3)" ?

    I hope this will be fixed soon in GLEW...

     
  • Funto
    Funto
    2010-01-16

    Here is my modified version for glewGetExtension(), which seems to work (glprogrammer >> yours does not even compile, so I think you did not test it...) :

    static GLboolean _glewGetExtensionPriorGL3 (const char name)
    {
    GLubyte
    p;
    GLubyte end;
    GLuint len = _glewStrLen((const GLubyte
    )name);
    p = (GLubyte)glGetString(GL_EXTENSIONS);
    if (0 == p) return GL_FALSE;
    end = p + _glewStrLen(p);
    while (p < end)
    {
    GLuint n = _glewStrCLen(p, ' ');
    if (len == n && _glewStrSame((const GLubyte
    )name, p, n)) return GL_TRUE;
    p += n+1;
    }
    return GL_FALSE;
    }

    static GLboolean _glewGetExtensionGL3 (const char name)
    {
    GLubyte
    s;
    GLint num, iter;
    GLuint len = _glewStrLen((const GLubyte*)name);
    GLuint n;
    glGetIntegerv(GL_NUM_EXTENSIONS, &num);

    for(iter = 0 ; iter < num ; iter++)
    {
    s = (GLubyte)glGetStringi(GL_EXTENSIONS, iter);
    n = _glewStrLen(s);
    if(n == len && _glewStrSame((const GLubyte
    )name, s, len))
    return GL_TRUE;
    }
    return GL_FALSE;
    }

    GLboolean glewGetExtension (const char name)
    {
    const GLubyte
    s;
    GLuint dot;
    GLint major;

    / query opengl version /
    s = glGetString(GL_VERSION);
    dot = _glewStrCLen(s, '.');
    if (dot == 0)
    return GL_FALSE;

    major = s[dot-1]-'0';

    / If we're 3.0 or greater use glGetStringi instead.
    * since this works with both Core, Compatible, and
    * Forward-Compatible contexts
    /
    if (major >= 3)
    return _glewGetExtensionGL3(name);
    else
    return _glewGetExtensionPriorGL3(name);
    }

    Feel free to do what you want with this snippet.

     
  • That seems reasonable.

    Thanks.

    On a side note, I was never able to get the dev studio projects working. It always complained about missing source. Is there a forum on building I can follow?

    Thanks again

     
  • Is this going to be fixed soon? I was kind of hoping to see it in 1.5.3.

    It's a pretty big issue since some vendors throw errors when you use removed functionality in a core context.

     
  • That'd be fine if I wanted to use a different tool, but I've already started using GLEW.

    Is this something you're not planning on supporting properly in GLEW? I see the Core context as a very important feature in the future of OpenGL.

     
  • Nigel Stewart
    Nigel Stewart
    2010-05-03

    I think GLEW can and should support Core context, but I am not in a position currently to spend time implementing that. I'd be happy to help with reviewing patches, etc. The most obvious limitation of gl3w is the lack of extension support.

     
  • dzyashu
    dzyashu
    2010-10-03

    We can just test glGetStringi - it is assigned if we use OGL >= 3.x, so glewGetExtension(...) can be implemented this way:

    GLboolean glewGetExtension (const char name)
    {

    GLubyte
    p;
    GLubyte end;
    GLuint len = _glewStrLen((const GLubyte
    )name);
    GLint i;
    if (glGetStringi)
    {
    GLint num_extensions;
    glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
    for (i = 0; i < num_extensions; ++ i)
    {
    if (_glewStrSame((const GLubyte)name, glGetStringi(GL_EXTENSIONS, i), len)) return GL_TRUE;
    }
    }
    else
    {
    p = (GLubyte
    )glGetString(GL_EXTENSIONS);
    if (0 == p) return GL_FALSE;
    end = p + _glewStrLen(p);
    while (p < end)
    {
    GLuint n = _glewStrCLen(p, ' ');
    if (len == n && _glewStrSame((const GLubyte*)name, p, n)) return GL_TRUE;
    p += n+1;
    }
    }
    return GL_FALSE;
    }

    Certainly, list of extensions should be cached...

     
  • MG_code
    MG_code
    2010-10-05

    Here's my personal fix to the problem: http://pastebin.com/rAMvHEQ2

    It only uses glGetStringi() when glGetString() fails, and is otherwise identical to the original function.

    Aside from being as unobtrusive a change as possible, this method also means we don't query OpenGL version to find out which functions are available. It just goes for whatever works first.

    I find this to be the more parsimonious way of doing things, as it cuts out any complications arising from context and profile modes (foward-compat, core, backward compat...) now and in the foreseeable future.

     
1 2 > >> (Page 1 of 2)


Anonymous


Cancel   Add attachments