Fixed SDL_GL_GetAttribute queries for framebuffer component sizes in Core Profile OpenGL contexts.
authorAlex Szpakowski <slime73@gmail.com>
Wed, 06 May 2015 12:54:51 -0300
changeset 9589a583c42c51d7
parent 9588 2c2b2c13450b
child 9590 597d75e56b12
Fixed SDL_GL_GetAttribute queries for framebuffer component sizes in Core Profile OpenGL contexts.

Fixes bugzilla #2060.
src/video/SDL_video.c
     1.1 --- a/src/video/SDL_video.c	Wed May 06 12:42:14 2015 -0300
     1.2 +++ b/src/video/SDL_video.c	Wed May 06 12:54:51 2015 -0300
     1.3 @@ -2793,19 +2793,37 @@
     1.4  SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
     1.5  {
     1.6  #if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     1.7 -    void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
     1.8 -    GLenum(APIENTRY * glGetErrorFunc) (void);
     1.9 +    void (APIENTRY *glGetIntegervFunc) (GLenum pname, GLint * params);
    1.10 +    GLenum (APIENTRY *glGetErrorFunc) (void);
    1.11      GLenum attrib = 0;
    1.12      GLenum error = 0;
    1.13  
    1.14 +    /*
    1.15 +     * Some queries in Core Profile desktop OpenGL 3+ contexts require
    1.16 +     * glGetFramebufferAttachmentParameteriv instead of glGetIntegerv. Note that
    1.17 +     * the enums we use for the former function don't exist in OpenGL ES 2, and
    1.18 +     * the function itself doesn't exist prior to OpenGL 3 and OpenGL ES 2.
    1.19 +     */
    1.20 +#if SDL_VIDEO_OPENGL
    1.21 +    const GLubyte *(APIENTRY *glGetStringFunc) (GLenum name);
    1.22 +    void (APIENTRY *glGetFramebufferAttachmentParameterivFunc) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
    1.23 +    GLenum attachment = GL_BACK_LEFT;
    1.24 +    GLenum attachmentattrib = 0;
    1.25 +
    1.26 +    glGetStringFunc = SDL_GL_GetProcAddress("glGetString");
    1.27 +    if (!glGetStringFunc) {
    1.28 +        return SDL_SetError("Failed getting OpenGL glGetString entry point");
    1.29 +    }
    1.30 +#endif
    1.31 +
    1.32      glGetIntegervFunc = SDL_GL_GetProcAddress("glGetIntegerv");
    1.33      if (!glGetIntegervFunc) {
    1.34 -        return -1;
    1.35 +        return SDL_SetError("Failed getting OpenGL glGetIntegerv entry point");
    1.36      }
    1.37  
    1.38      glGetErrorFunc = SDL_GL_GetProcAddress("glGetError");
    1.39      if (!glGetErrorFunc) {
    1.40 -        return -1;
    1.41 +        return SDL_SetError("Failed getting OpenGL glGetError entry point");
    1.42      }
    1.43  
    1.44      /* Clear value in any case */
    1.45 @@ -2813,15 +2831,27 @@
    1.46  
    1.47      switch (attr) {
    1.48      case SDL_GL_RED_SIZE:
    1.49 +#if SDL_VIDEO_OPENGL
    1.50 +        attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE;
    1.51 +#endif
    1.52          attrib = GL_RED_BITS;
    1.53          break;
    1.54      case SDL_GL_BLUE_SIZE:
    1.55 +#if SDL_VIDEO_OPENGL
    1.56 +        attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE;
    1.57 +#endif
    1.58          attrib = GL_BLUE_BITS;
    1.59          break;
    1.60      case SDL_GL_GREEN_SIZE:
    1.61 +#if SDL_VIDEO_OPENGL
    1.62 +        attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE;
    1.63 +#endif
    1.64          attrib = GL_GREEN_BITS;
    1.65          break;
    1.66      case SDL_GL_ALPHA_SIZE:
    1.67 +#if SDL_VIDEO_OPENGL
    1.68 +        attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE;
    1.69 +#endif
    1.70          attrib = GL_ALPHA_BITS;
    1.71          break;
    1.72      case SDL_GL_DOUBLEBUFFER:
    1.73 @@ -2836,9 +2866,17 @@
    1.74          return 0;
    1.75  #endif
    1.76      case SDL_GL_DEPTH_SIZE:
    1.77 +#if SDL_VIDEO_OPENGL
    1.78 +        attachment = GL_DEPTH;
    1.79 +        attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE;
    1.80 +#endif
    1.81          attrib = GL_DEPTH_BITS;
    1.82          break;
    1.83      case SDL_GL_STENCIL_SIZE:
    1.84 +#if SDL_VIDEO_OPENGL
    1.85 +        attachment = GL_STENCIL;
    1.86 +        attachmentattrib = GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE;
    1.87 +#endif
    1.88          attrib = GL_STENCIL_BITS;
    1.89          break;
    1.90  #if SDL_VIDEO_OPENGL
    1.91 @@ -2868,18 +2906,10 @@
    1.92          return 0;
    1.93  #endif
    1.94      case SDL_GL_MULTISAMPLEBUFFERS:
    1.95 -#if SDL_VIDEO_OPENGL
    1.96 -        attrib = GL_SAMPLE_BUFFERS_ARB;
    1.97 -#else
    1.98          attrib = GL_SAMPLE_BUFFERS;
    1.99 -#endif
   1.100          break;
   1.101      case SDL_GL_MULTISAMPLESAMPLES:
   1.102 -#if SDL_VIDEO_OPENGL
   1.103 -        attrib = GL_SAMPLES_ARB;
   1.104 -#else
   1.105          attrib = GL_SAMPLES;
   1.106 -#endif
   1.107          break;
   1.108      case SDL_GL_CONTEXT_RELEASE_BEHAVIOR:
   1.109  #if SDL_VIDEO_OPENGL
   1.110 @@ -2890,23 +2920,23 @@
   1.111          break;
   1.112      case SDL_GL_BUFFER_SIZE:
   1.113          {
   1.114 -            GLint bits = 0;
   1.115 -            GLint component;
   1.116 -
   1.117 -            /*
   1.118 -             * there doesn't seem to be a single flag in OpenGL
   1.119 -             * for this!
   1.120 -             */
   1.121 -            glGetIntegervFunc(GL_RED_BITS, &component);
   1.122 -            bits += component;
   1.123 -            glGetIntegervFunc(GL_GREEN_BITS, &component);
   1.124 -            bits += component;
   1.125 -            glGetIntegervFunc(GL_BLUE_BITS, &component);
   1.126 -            bits += component;
   1.127 -            glGetIntegervFunc(GL_ALPHA_BITS, &component);
   1.128 -            bits += component;
   1.129 -
   1.130 -            *value = bits;
   1.131 +            int rsize = 0, gsize = 0, bsize = 0, asize = 0;
   1.132 +
   1.133 +            /* There doesn't seem to be a single flag in OpenGL for this! */
   1.134 +            if (SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &rsize) < 0) {
   1.135 +                return -1;
   1.136 +            }
   1.137 +            if (SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &gsize) < 0) {
   1.138 +                return -1;
   1.139 +            }
   1.140 +            if (SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &bsize) < 0) {
   1.141 +                return -1;
   1.142 +            }
   1.143 +            if (SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &asize) < 0) {
   1.144 +                return -1;
   1.145 +            }
   1.146 +
   1.147 +            *value = rsize + gsize + bsize + asize;
   1.148              return 0;
   1.149          }
   1.150      case SDL_GL_ACCELERATED_VISUAL:
   1.151 @@ -2965,7 +2995,21 @@
   1.152          return SDL_SetError("Unknown OpenGL attribute");
   1.153      }
   1.154  
   1.155 -    glGetIntegervFunc(attrib, (GLint *) value);
   1.156 +#if SDL_VIDEO_OPENGL
   1.157 +    if (attachmentattrib && isAtLeastGL3((const char *) glGetStringFunc(GL_VERSION))) {
   1.158 +        glGetFramebufferAttachmentParameterivFunc = SDL_GL_GetProcAddress("glGetFramebufferAttachmentParameteriv");
   1.159 +
   1.160 +        if (glGetFramebufferAttachmentParameterivFunc) {
   1.161 +            glGetFramebufferAttachmentParameterivFunc(GL_FRAMEBUFFER, attachment, attachmentattrib, (GLint *) value);
   1.162 +        } else {
   1.163 +            return SDL_SetError("Failed getting OpenGL glGetFramebufferAttachmentParameteriv entry point");
   1.164 +        }
   1.165 +    } else
   1.166 +#endif
   1.167 +    {
   1.168 +        glGetIntegervFunc(attrib, (GLint *) value);
   1.169 +    }
   1.170 +
   1.171      error = glGetErrorFunc();
   1.172      if (error != GL_NO_ERROR) {
   1.173          if (error == GL_INVALID_ENUM) {