Issue #54 open

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

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 (4)

  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. Log in to comment