Support for OpenGL 3.x, specifically obsolete glGetString(GL_EXTENSIONS)

Issue #54 resolved
Randall O'Reilly
created an issue

glGetString(GL_EXTENSIONS) is obsolete as of OpenGL 3.0. most drivers seem to be tolerant of its continued use, but at least some cases on Linux are NOT, and this call returns NULL, thus causing an actual crash in the code.

The following patch fixes both the crash and provides a work-around using the new glGetStringi function. We have committed this on our svn repository of the code, which we are using until we figure out bitbucket and it seems to be up and running smoothly: https://grey.colorado.edu/svn/coin3d/coin/trunk

However, there are apparently a few other incompatibilities in the new drivers beyond this one, which we are still working on. We'll update this ticket with that info..

=================================================================== --- gl.cpp (revision 2) +++ gl.cpp (revision 17) @@ -758,7 +758,7 @@ start = extensions; extlen = strlen(ext);

  • while (1) {
  • while (start) { const char * where = strstr(start, ext); if (!where) goto done;

@@ -2411,7 +2411,56 @@

 gi->rendererstr = (const char *)glGetString(GL_RENDERER);
 gi->extensionsstr = (const char *)glGetString(GL_EXTENSIONS);
  • // gi->extensionsstr = NULL; / for testing /

  • /* the above is deprecated and may return NULL, in which case we need to do it

  • the new way, producing same results as the old way.. */
  • +#ifndef GL_NUM_EXTENSIONS +# define GL_NUM_EXTENSIONS 0x821D +#endif
  • if(gi->extensionsstr == NULL) {
  • typedef GLubyte* (APIENTRY * COIN_PFNGLGETSTRINGIPROC)(GLenum enm, GLuint idx);
  • COIN_PFNGLGETSTRINGIPROC glGetStringi = 0;
  • glGetStringi = (COIN_PFNGLGETSTRINGIPROC)cc_glglue_getprocaddress(gi,
  • "glGetStringi");
  • if(glGetStringi != NULL) {
  • GLint n = 0;
  • glGetIntegerv(GL_NUM_EXTENSIONS, &n);
  • if(n > 0) {
  • int exlen = 1024;
  • char exs = (char)malloc(exlen * sizeof(char));
  • int cpos = 0;
  • for (int i = 0; i < n; i++) {
  • const char exc = (char)glGetStringi(GL_EXTENSIONS, i);
  • int excl = strlen(exc);
  • if(cpos + excl + 1 > exlen) {
  • exlen += 1024;
  • exs = (char*)realloc(exs, exlen * sizeof(char));
  • }
  • strcpy(exs + cpos, exc);
  • cpos += excl;
  • exs[cpos++] = ' '; // space separated -- overwrites null..
  • }
  • exs[++cpos] = '\0'; // null terminate
  • // printf("exts: %s\n", exs); // comment out after debugging!!
  • gi->extensionsstr = exs; // note: exs is never freed!!
  • }
  • else {
  • cc_debugerror_postwarning("cc_glglue_instance",
  • "glGetIntegerv(GL_NUM_EXTENSIONS) did not return a value, so unable to get extensions for this gl driver, version: ",
  • gi->versionstr /* , " vendor: ",
  • gi->vendorstr */ );
  • }
  • }
  • else {
  • cc_debugerror_postwarning("cc_glglue_instance",
  • "glGetString(GL_EXTENSIONS) returned null, but glGetStringi is NULL, so unable to get extensions for this gl driver, version:",
  • gi->versionstr /* , " vendor: ",
  • gi->vendorstr */ );
  • }
  • } +

Comments (11)

  1. Roy Walmsley

    Randall,

    I have modified the code based on your input above. I have committed this (having tested on Windows) to the source. Note that I have updated three files. Please will you check my update and verify that your problem is resolved. Then I will close this issue.

    Roy

  2. Bastiaan Veelo

    I am comparing https://grey.colorado.edu/svn/coin3d/coin/trunk/ with the official Hg repository from where you forked it off in order to merge your fixes back upstream. Hopefully you will be able to use the official sources in the future.

    I am disregarding changes to the build system, as the intention is that CMake will obsolete all that.

    1. r16 and r17 are incorporated through commit ac03012d7c1a and pull request #82.
    2. r47 is covered by pull request #8.

    The only remaining change is in r15 with the following diff to src/glue/gl.cpp:

    Index: gl.cpp
    ===================================================================
    --- gl.cpp  (revision 14)
    +++ gl.cpp  (revision 15)
    @@ -758,7 +758,7 @@
       start = extensions;
       extlen = strlen(ext);
    
    -  while (1) {
    +  while (start) {
         const char * where = strstr(start, ext);
         if (!where) goto done;
    

    Whether r15 improves things or not is a bit vague, looking at your commit messsage. Is this something we should have up-stream?

    Thanks, Bastiaan.

  3. Vitaliy

    Randall O'Reilly wrote.

    glGetString(GL_EXTENSIONS) is obsolete as of OpenGL 3.0. most drivers seem to be tolerant of its continued use, but at least some cases on Linux are NOT, and this call returns NULL, thus causing an actual crash in the code.<

    Can you give my more info about this, please? It happened with my on Linux Mint. Sorry for my English.

  4. Log in to comment