From a8ea120caeade1b12db4452844a3ac203611eb50 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 15 Jan 2013 20:00:27 +0100 Subject: [PATCH] Removed internal fbconfig enum and selection. --- src/context.c | 163 ----------- src/egl_context.c | 251 ++++------------- src/glx_context.c | 654 ++++++++++++++++++--------------------------- src/internal.h | 20 +- src/wgl_context.c | 368 +++++++++---------------- src/wgl_platform.h | 2 +- 6 files changed, 448 insertions(+), 1010 deletions(-) diff --git a/src/context.c b/src/context.c index d8f1a46f..438d8201 100644 --- a/src/context.c +++ b/src/context.c @@ -92,169 +92,6 @@ static GLboolean parseGLVersion(int* api, int* major, int* minor, int* rev) ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// -//======================================================================== -// Return the available framebuffer config closest to the desired values -// This is based on the manual GLX Visual selection from 2.6 -//======================================================================== - -const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, - const _GLFWfbconfig* alternatives, - unsigned int count) -{ - unsigned int i; - unsigned int missing, leastMissing = UINT_MAX; - unsigned int colorDiff, leastColorDiff = UINT_MAX; - unsigned int extraDiff, leastExtraDiff = UINT_MAX; - const _GLFWfbconfig* current; - const _GLFWfbconfig* closest = NULL; - - for (i = 0; i < count; i++) - { - current = alternatives + i; - - if (desired->stereo > 0 && current->stereo == 0) - { - // Stereo is a hard constraint - continue; - } - - // Count number of missing buffers - { - missing = 0; - - if (desired->alphaBits > 0 && current->alphaBits == 0) - missing++; - - if (desired->depthBits > 0 && current->depthBits == 0) - missing++; - - if (desired->stencilBits > 0 && current->stencilBits == 0) - missing++; - - if (desired->auxBuffers > 0 && current->auxBuffers < desired->auxBuffers) - missing += desired->auxBuffers - current->auxBuffers; - - if (desired->samples > 0 && current->samples == 0) - { - // Technically, several multisampling buffers could be - // involved, but that's a lower level implementation detail and - // not important to us here, so we count them as one - missing++; - } - } - - // These polynomials make many small channel size differences matter - // less than one large channel size difference - - // Calculate color channel size difference value - { - colorDiff = 0; - - if (desired->redBits > 0) - { - colorDiff += (desired->redBits - current->redBits) * - (desired->redBits - current->redBits); - } - - if (desired->greenBits > 0) - { - colorDiff += (desired->greenBits - current->greenBits) * - (desired->greenBits - current->greenBits); - } - - if (desired->blueBits > 0) - { - colorDiff += (desired->blueBits - current->blueBits) * - (desired->blueBits - current->blueBits); - } - } - - // Calculate non-color channel size difference value - { - extraDiff = 0; - - if (desired->alphaBits > 0) - { - extraDiff += (desired->alphaBits - current->alphaBits) * - (desired->alphaBits - current->alphaBits); - } - - if (desired->depthBits > 0) - { - extraDiff += (desired->depthBits - current->depthBits) * - (desired->depthBits - current->depthBits); - } - - if (desired->stencilBits > 0) - { - extraDiff += (desired->stencilBits - current->stencilBits) * - (desired->stencilBits - current->stencilBits); - } - - if (desired->accumRedBits > 0) - { - extraDiff += (desired->accumRedBits - current->accumRedBits) * - (desired->accumRedBits - current->accumRedBits); - } - - if (desired->accumGreenBits > 0) - { - extraDiff += (desired->accumGreenBits - current->accumGreenBits) * - (desired->accumGreenBits - current->accumGreenBits); - } - - if (desired->accumBlueBits > 0) - { - extraDiff += (desired->accumBlueBits - current->accumBlueBits) * - (desired->accumBlueBits - current->accumBlueBits); - } - - if (desired->accumAlphaBits > 0) - { - extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) * - (desired->accumAlphaBits - current->accumAlphaBits); - } - - if (desired->samples > 0) - { - extraDiff += (desired->samples - current->samples) * - (desired->samples - current->samples); - } - - if (desired->sRGB) - { - if (!current->sRGB) - extraDiff++; - } - } - - // Figure out if the current one is better than the best one found so far - // Least number of missing buffers is the most important heuristic, - // then color buffer size match and lastly size match for other buffers - - if (missing < leastMissing) - closest = current; - else if (missing == leastMissing) - { - if ((colorDiff < leastColorDiff) || - (colorDiff == leastColorDiff && extraDiff < leastExtraDiff)) - { - closest = current; - } - } - - if (current == closest) - { - leastMissing = missing; - leastColorDiff = colorDiff; - leastExtraDiff = extraDiff; - } - } - - return closest; -} - - //======================================================================== // Checks whether the client API part of the window config is sane //======================================================================== diff --git a/src/egl_context.c b/src/egl_context.c index eb2815f1..34c1f2f8 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -32,6 +32,7 @@ #include #include +#include //======================================================================== @@ -52,139 +53,62 @@ static _GLFW_TLS _GLFWwindow* _glfwCurrentWindow = NULL; +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + //======================================================================== -// Returns the specified attribute of the specified EGLConfig +// Initialize EGL //======================================================================== -static int getConfigAttrib(EGLConfig config, int attrib) +int _glfwInitOpenGL(void) { - int value; - eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value); - return value; + _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY); + if (_glfw.egl.display == EGL_NO_DISPLAY) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Failed to get EGL display"); + return GL_FALSE; + } + + if (!eglInitialize(_glfw.egl.display, + &_glfw.egl.versionMajor, + &_glfw.egl.versionMinor)) + { + _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Failed to initialize EGL"); + return GL_FALSE; + } + + if (_glfwPlatformExtensionSupported("EGL_KHR_create_context")) + _glfw.egl.KHR_create_context = GL_TRUE; + + return GL_TRUE; } //======================================================================== -// Return a list of available and usable framebuffer configs +// Terminate EGL //======================================================================== -static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - unsigned int* found) +void _glfwTerminateOpenGL(void) { - EGLConfig* configs; - _GLFWfbconfig* result; - int i, count = 0; - - *found = 0; - - eglGetConfigs(_glfw.egl.display, NULL, 0, &count); - - configs = (EGLConfig*) malloc(sizeof(EGLConfig) * count); - if (!configs) - { - _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); - return NULL; - } - - eglGetConfigs(_glfw.egl.display, configs, count, &count); - if (!count) - { - free(configs); - - _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned"); - return NULL; - } - - result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count); - if (!result) - { - free(configs); - - _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); - return NULL; - } - - for (i = 0; i < count; i++) - { - _GLFWfbconfig* f = result + *found; - -#if defined(_GLFW_X11) - if (!getConfigAttrib(configs[i], EGL_NATIVE_VISUAL_ID)) - { - // Only consider EGLConfigs with associated visuals - continue; - } -#endif // _GLFW_X11 - - if (!(getConfigAttrib(configs[i], EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER)) - { - // Only consider RGB(A) EGLConfigs - continue; - } - - if (!(getConfigAttrib(configs[i], EGL_SURFACE_TYPE) & EGL_WINDOW_BIT)) - { - // Only consider window EGLConfigs - continue; - } - - if (wndconfig->clientAPI == GLFW_OPENGL_ES_API) - { - if (wndconfig->glMajor == 1) - { - if (!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT)) - continue; - } - else - { - if (!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) - continue; - } - } - else if (wndconfig->clientAPI == GLFW_OPENGL_API) - { - if (!(getConfigAttrib(configs[i], EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT)) - continue; - } - - f->redBits = getConfigAttrib(configs[i], EGL_RED_SIZE); - f->greenBits = getConfigAttrib(configs[i], EGL_GREEN_SIZE); - f->blueBits = getConfigAttrib(configs[i], EGL_BLUE_SIZE); - - f->alphaBits = getConfigAttrib(configs[i], EGL_ALPHA_SIZE); - f->depthBits = getConfigAttrib(configs[i], EGL_DEPTH_SIZE); - f->stencilBits = getConfigAttrib(configs[i], EGL_STENCIL_SIZE); - - f->samples = getConfigAttrib(configs[i], EGL_SAMPLES); - - // NOTE: There does not appear to be any way to request sRGB - // framebuffers for OpenGL or GLES contexts; only for OpenVG ones - f->sRGB = GL_FALSE; - - f->platformID = (GLFWintptr) getConfigAttrib(configs[i], EGL_CONFIG_ID); - - (*found)++; - } - - free(configs); - return result; + eglTerminate(_glfw.egl.display); } //======================================================================== -// Create the actual OpenGL(|ES) context +// Prepare for creation of the OpenGL context //======================================================================== #define setEGLattrib(attribName, attribValue) \ { \ attribs[index++] = attribName; \ attribs[index++] = attribValue; \ + assert(index < sizeof(attribs) / sizeof(attribs[0])); \ } -static int createContext(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - EGLint fbconfigID) +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig) { int attribs[40]; EGLint count; @@ -198,7 +122,28 @@ static int createContext(_GLFWwindow* window, { int index = 0; - setEGLattrib(EGL_CONFIG_ID, fbconfigID); + setEGLattrib(EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER); + + if (fbconfig->redBits) + setEGLattrib(EGL_RED_SIZE, fbconfig->redBits); + if (fbconfig->greenBits) + setEGLattrib(EGL_GREEN_SIZE, fbconfig->greenBits); + if (fbconfig->blueBits) + setEGLattrib(EGL_BLUE_SIZE, fbconfig->blueBits); + if (fbconfig->alphaBits) + setEGLattrib(EGL_BLUE_SIZE, fbconfig->alphaBits); + + if (fbconfig->depthBits) + setEGLattrib(EGL_DEPTH_SIZE, fbconfig->depthBits); + if (fbconfig->stencilBits) + setEGLattrib(EGL_STENCIL_SIZE, fbconfig->stencilBits); + + if (fbconfig->samples) + { + setEGLattrib(EGL_SAMPLE_BUFFERS, 1); + setEGLattrib(EGL_SAMPLES, fbconfig->samples); + } + setEGLattrib(EGL_NONE, EGL_NONE); eglChooseConfig(_glfw.egl.display, attribs, &config, 1, &count); @@ -351,90 +296,6 @@ static int createContext(_GLFWwindow* window, #undef setEGLattrib -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -//======================================================================== -// Initialize EGL -//======================================================================== - -int _glfwInitOpenGL(void) -{ - _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY); - if (_glfw.egl.display == EGL_NO_DISPLAY) - { - _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Failed to get EGL display"); - return GL_FALSE; - } - - if (!eglInitialize(_glfw.egl.display, - &_glfw.egl.versionMajor, - &_glfw.egl.versionMinor)) - { - _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Failed to initialize EGL"); - return GL_FALSE; - } - - if (_glfwPlatformExtensionSupported("EGL_KHR_create_context")) - _glfw.egl.KHR_create_context = GL_TRUE; - - return GL_TRUE; -} - - -//======================================================================== -// Terminate EGL -//======================================================================== - -void _glfwTerminateOpenGL(void) -{ - eglTerminate(_glfw.egl.display); -} - - -//======================================================================== -// Prepare for creation of the OpenGL context -//======================================================================== - -int _glfwCreateContext(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWfbconfig* fbconfig) -{ - _GLFWfbconfig closest; - - // Choose the best available fbconfig - { - unsigned int fbcount; - _GLFWfbconfig* fbconfigs; - const _GLFWfbconfig* result; - - fbconfigs = getFBConfigs(window, wndconfig, &fbcount); - if (!fbconfigs) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "EGL: No usable EGLFBConfigs found"); - return GL_FALSE; - } - - result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); - if (!result) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "EGL: No EGLFBConfig matched the criteria"); - - free(fbconfigs); - return GL_FALSE; - } - - closest = *result; - free(fbconfigs); - } - - return createContext(window, wndconfig, closest.platformID); -} - - //======================================================================== // Destroy the OpenGL context //======================================================================== diff --git a/src/glx_context.c b/src/glx_context.c index 8021e050..7b57f632 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -32,6 +32,7 @@ #include #include +#include // This is the only glXGetProcAddress variant not declared by glxext.h @@ -65,156 +66,6 @@ static unsigned long _glfwErrorCode = Success; static _GLFW_TLS _GLFWwindow* _glfwCurrentWindow = NULL; -//======================================================================== -// Returns the specified attribute of the specified GLXFBConfig -// NOTE: Do not call this unless we have found GLX 1.3+ or GLX_SGIX_fbconfig -//======================================================================== - -static int getFBConfigAttrib(_GLFWwindow* window, GLXFBConfig fbconfig, int attrib) -{ - int value; - - if (_glfw.glx.SGIX_fbconfig) - { - _glfw.glx.GetFBConfigAttribSGIX(_glfw.x11.display, - fbconfig, attrib, &value); - } - else - glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value); - - return value; -} - - -//======================================================================== -// Return a list of available and usable framebuffer configs -//======================================================================== - -static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) -{ - GLXFBConfig* fbconfigs; - _GLFWfbconfig* result; - int i, count = 0; - const char* vendor; - GLboolean trustWindowBit = GL_TRUE; - - *found = 0; - - if (_glfw.glx.versionMajor == 1 && _glfw.glx.versionMinor < 3) - { - if (!_glfw.glx.SGIX_fbconfig) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "GLX: GLXFBConfig support not found"); - return NULL; - } - } - - vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR); - - if (strcmp(vendor, "Chromium") == 0) - { - // HACK: This is a (hopefully temporary) workaround for Chromium - // (VirtualBox GL) not setting the window bit on any GLXFBConfigs - trustWindowBit = GL_FALSE; - } - - if (_glfw.glx.SGIX_fbconfig) - { - fbconfigs = _glfw.glx.ChooseFBConfigSGIX(_glfw.x11.display, - _glfw.x11.screen, - NULL, - &count); - if (!count) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "GLX: No GLXFBConfigs returned"); - return NULL; - } - } - else - { - fbconfigs = glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &count); - if (!count) - { - _glfwInputError(GLFW_API_UNAVAILABLE, - "GLX: No GLXFBConfigs returned"); - return NULL; - } - } - - result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count); - if (!result) - { - _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); - return NULL; - } - - for (i = 0; i < count; i++) - { - _GLFWfbconfig* f = result + *found; - - if (!getFBConfigAttrib(window, fbconfigs[i], GLX_DOUBLEBUFFER) || - !getFBConfigAttrib(window, fbconfigs[i], GLX_VISUAL_ID)) - { - // Only consider double-buffered GLXFBConfigs with associated visuals - continue; - } - - if (!(getFBConfigAttrib(window, - fbconfigs[i], - GLX_RENDER_TYPE) & GLX_RGBA_BIT)) - { - // Only consider RGBA GLXFBConfigs - continue; - } - - if (!(getFBConfigAttrib(window, fbconfigs[i], GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT)) - { - if (trustWindowBit) - { - // Only consider window GLXFBConfigs - continue; - } - } - - f->redBits = getFBConfigAttrib(window, fbconfigs[i], GLX_RED_SIZE); - f->greenBits = getFBConfigAttrib(window, fbconfigs[i], GLX_GREEN_SIZE); - f->blueBits = getFBConfigAttrib(window, fbconfigs[i], GLX_BLUE_SIZE); - - f->alphaBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ALPHA_SIZE); - f->depthBits = getFBConfigAttrib(window, fbconfigs[i], GLX_DEPTH_SIZE); - f->stencilBits = getFBConfigAttrib(window, fbconfigs[i], GLX_STENCIL_SIZE); - - f->accumRedBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_RED_SIZE); - f->accumGreenBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_GREEN_SIZE); - f->accumBlueBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_BLUE_SIZE); - f->accumAlphaBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_ALPHA_SIZE); - - f->auxBuffers = getFBConfigAttrib(window, fbconfigs[i], GLX_AUX_BUFFERS); - f->stereo = getFBConfigAttrib(window, fbconfigs[i], GLX_STEREO); - - if (_glfw.glx.ARB_multisample) - f->samples = getFBConfigAttrib(window, fbconfigs[i], GLX_SAMPLES); - else - f->samples = 0; - - if (_glfw.glx.ARB_framebuffer_sRGB) - f->sRGB = getFBConfigAttrib(window, fbconfigs[i], GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); - else - f->sRGB = GL_FALSE; - - f->platformID = (GLFWintptr) getFBConfigAttrib(window, fbconfigs[i], GLX_FBCONFIG_ID); - - (*found)++; - } - - XFree(fbconfigs); - - return result; -} - - //======================================================================== // Error handler used when creating a context with the GLX_ARB_create_context // extension set @@ -231,242 +82,29 @@ static int errorHandler(Display *display, XErrorEvent* event) // Create the OpenGL context using legacy API //======================================================================== -static void createLegacyContext(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - GLXFBConfig fbconfig, - GLXContext share) +static GLXContext createLegacyContext(_GLFWwindow* window, + GLXFBConfig fbconfig, + GLXContext share) { if (_glfw.glx.SGIX_fbconfig) { - window->glx.context = - _glfw.glx.CreateContextWithConfigSGIX(_glfw.x11.display, - fbconfig, - GLX_RGBA_TYPE, - share, - True); + return _glfw.glx.CreateContextWithConfigSGIX(_glfw.x11.display, + fbconfig, + GLX_RGBA_TYPE, + share, + True); } else { - window->glx.context = glXCreateNewContext(_glfw.x11.display, - fbconfig, - GLX_RGBA_TYPE, - share, - True); + return glXCreateNewContext(_glfw.x11.display, + fbconfig, + GLX_RGBA_TYPE, + share, + True); } } -//======================================================================== -// Create the OpenGL context -//======================================================================== - -#define setGLXattrib(attribName, attribValue) \ - attribs[index++] = attribName; \ - attribs[index++] = attribValue; - -static int createContext(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - GLXFBConfigID fbconfigID) -{ - int attribs[40]; - GLXFBConfig* fbconfig; - GLXContext share = NULL; - - if (wndconfig->share) - share = wndconfig->share->glx.context; - - // Retrieve the previously selected GLXFBConfig - { - int dummy, index = 0; - - setGLXattrib(GLX_FBCONFIG_ID, (int) fbconfigID); - setGLXattrib(None, None); - - if (_glfw.glx.SGIX_fbconfig) - { - fbconfig = _glfw.glx.ChooseFBConfigSGIX(_glfw.x11.display, - _glfw.x11.screen, - attribs, - &dummy); - } - else - { - fbconfig = glXChooseFBConfig(_glfw.x11.display, - _glfw.x11.screen, - attribs, - &dummy); - } - - if (fbconfig == NULL) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "GLX: Failed to retrieve the selected GLXFBConfig"); - return GL_FALSE; - } - } - - // Retrieve the corresponding visual - if (_glfw.glx.SGIX_fbconfig) - { - window->glx.visual = - _glfw.glx.GetVisualFromFBConfigSGIX(_glfw.x11.display, *fbconfig); - } - else - { - window->glx.visual = glXGetVisualFromFBConfig(_glfw.x11.display, - *fbconfig); - } - - if (window->glx.visual == NULL) - { - XFree(fbconfig); - - _glfwInputError(GLFW_PLATFORM_ERROR, - "GLX: Failed to retrieve visual for GLXFBConfig"); - return GL_FALSE; - } - - if (wndconfig->clientAPI == GLFW_OPENGL_ES_API) - { - if (!_glfw.glx.ARB_create_context || - !_glfw.glx.ARB_create_context_profile || - !_glfw.glx.EXT_create_context_es2_profile) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "GLX: OpenGL ES requested but " - "GLX_EXT_create_context_es2_profile is unavailable"); - return GL_FALSE; - } - } - - if (wndconfig->glForward) - { - if (!_glfw.glx.ARB_create_context) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "GLX: Forward compatibility requested but " - "GLX_ARB_create_context_profile is unavailable"); - return GL_FALSE; - } - } - - if (wndconfig->glProfile) - { - if (!_glfw.glx.ARB_create_context || - !_glfw.glx.ARB_create_context_profile) - { - _glfwInputError(GLFW_VERSION_UNAVAILABLE, - "GLX: An OpenGL profile requested but " - "GLX_ARB_create_context_profile is unavailable"); - return GL_FALSE; - } - } - - if (_glfw.glx.ARB_create_context) - { - int index = 0, mask = 0, flags = 0, strategy = 0; - - if (wndconfig->clientAPI == GLFW_OPENGL_API) - { - if (wndconfig->glForward) - flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; - - if (wndconfig->glDebug) - flags |= GLX_CONTEXT_DEBUG_BIT_ARB; - - if (wndconfig->glProfile) - { - if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE) - mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE) - mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - } - } - else - mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; - - if (wndconfig->glRobustness != GLFW_NO_ROBUSTNESS) - { - if (_glfw.glx.ARB_create_context_robustness) - { - if (wndconfig->glRobustness == GLFW_NO_RESET_NOTIFICATION) - strategy = GLX_NO_RESET_NOTIFICATION_ARB; - else if (wndconfig->glRobustness == GLFW_LOSE_CONTEXT_ON_RESET) - strategy = GLX_LOSE_CONTEXT_ON_RESET_ARB; - - flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; - } - } - - if (wndconfig->glMajor != 1 || wndconfig->glMinor != 0) - { - // NOTE: Only request an explicitly versioned context when - // necessary, as explicitly requesting version 1.0 does not always - // return the highest available version - - setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, wndconfig->glMajor); - setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor); - } - - if (mask) - setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); - - if (flags) - setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags); - - if (strategy) - setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, strategy); - - setGLXattrib(None, None); - - // This is the only place we set an Xlib error handler, and we only do - // it because glXCreateContextAttribsARB generates a BadMatch error if - // the requested OpenGL version is unavailable (instead of a civilized - // response like returning NULL) - _glfwErrorCode = Success; - XSetErrorHandler(errorHandler); - - window->glx.context = - _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, - *fbconfig, - share, - True, - attribs); - - // We are done, so unset the error handler again (see above) - XSetErrorHandler(NULL); - - if (window->glx.context == NULL) - { - // HACK: This is a fallback for the broken Mesa implementation of - // GLX_ARB_create_context_profile, which fails default 1.0 context - // creation with a GLXBadProfileARB error in violation of the spec - if (_glfwErrorCode == _glfw.glx.errorBase + GLXBadProfileARB && - wndconfig->clientAPI == GLFW_OPENGL_API && - wndconfig->glProfile == GLFW_OPENGL_NO_PROFILE && - wndconfig->glForward == GL_FALSE) - { - createLegacyContext(window, wndconfig, *fbconfig, share); - } - } - } - else - createLegacyContext(window, wndconfig, *fbconfig, share); - - XFree(fbconfig); - - if (window->glx.context == NULL) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create context"); - return GL_FALSE; - } - - return GL_TRUE; -} - -#undef setGLXattrib - - ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// @@ -616,39 +254,267 @@ void _glfwTerminateOpenGL(void) // Prepare for creation of the OpenGL context //======================================================================== +#define setGLXattrib(attribName, attribValue) \ +{ \ + attribs[index++] = attribName; \ + attribs[index++] = attribValue; \ + assert(index < sizeof(attribs) / sizeof(attribs[0])); \ +} + int _glfwCreateContext(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig) { - _GLFWfbconfig closest; + int attribs[40]; + GLXFBConfig* native; + GLXContext share = NULL; - // Choose the best available fbconfig + if (wndconfig->share) + share = wndconfig->share->glx.context; + + // Find a suitable GLXFBConfig { - unsigned int fbcount; - _GLFWfbconfig* fbconfigs; - const _GLFWfbconfig* result; + int count, index = 0; - fbconfigs = getFBConfigs(window, &fbcount); - if (!fbconfigs) - return GL_FALSE; + setGLXattrib(GLX_DOUBLEBUFFER, True); + setGLXattrib(GLX_X_RENDERABLE, True); - result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); - if (!result) + if (fbconfig->redBits) + setGLXattrib(GLX_RED_SIZE, fbconfig->redBits); + if (fbconfig->greenBits) + setGLXattrib(GLX_GREEN_SIZE, fbconfig->greenBits); + if (fbconfig->blueBits) + setGLXattrib(GLX_BLUE_SIZE, fbconfig->blueBits); + if (fbconfig->alphaBits) + setGLXattrib(GLX_BLUE_SIZE, fbconfig->alphaBits); + + if (fbconfig->depthBits) + setGLXattrib(GLX_DEPTH_SIZE, fbconfig->depthBits); + if (fbconfig->stencilBits) + setGLXattrib(GLX_STENCIL_SIZE, fbconfig->stencilBits); + + if (fbconfig->auxBuffers) + setGLXattrib(GLX_AUX_BUFFERS, fbconfig->auxBuffers); + + if (fbconfig->accumRedBits) + setGLXattrib(GLX_ACCUM_RED_SIZE, fbconfig->accumRedBits); + if (fbconfig->accumGreenBits) + setGLXattrib(GLX_ACCUM_GREEN_SIZE, fbconfig->accumGreenBits); + if (fbconfig->accumBlueBits) + setGLXattrib(GLX_ACCUM_BLUE_SIZE, fbconfig->accumBlueBits); + if (fbconfig->accumAlphaBits) + setGLXattrib(GLX_ACCUM_BLUE_SIZE, fbconfig->accumAlphaBits); + + if (fbconfig->stereo) + setGLXattrib(GLX_STEREO, True); + + if (_glfw.glx.ARB_multisample) { - _glfwInputError(GLFW_PLATFORM_ERROR, - "GLX: No GLXFBConfig matched the criteria"); - - free(fbconfigs); - return GL_FALSE; + if (fbconfig->samples) + { + setGLXattrib(GLX_SAMPLE_BUFFERS_ARB, 1); + setGLXattrib(GLX_SAMPLES_ARB, fbconfig->samples); + } } - closest = *result; - free(fbconfigs); + if (_glfw.glx.ARB_framebuffer_sRGB) + { + if (fbconfig->sRGB) + setGLXattrib(GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, True); + } + + setGLXattrib(None, None); + + if (_glfw.glx.SGIX_fbconfig) + { + native = _glfw.glx.ChooseFBConfigSGIX(_glfw.x11.display, + _glfw.x11.screen, + attribs, + &count); + } + else + { + native = glXChooseFBConfig(_glfw.x11.display, + _glfw.x11.screen, + attribs, + &count); + } + + if (native == NULL) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "GLX: Failed to find a suitable GLXFBConfig"); + return GL_FALSE; + } } - return createContext(window, wndconfig, closest.platformID); + // Retrieve the corresponding visual + if (_glfw.glx.SGIX_fbconfig) + { + window->glx.visual = + _glfw.glx.GetVisualFromFBConfigSGIX(_glfw.x11.display, *native); + } + else + { + window->glx.visual = glXGetVisualFromFBConfig(_glfw.x11.display, + *native); + } + + if (window->glx.visual == NULL) + { + XFree(native); + + _glfwInputError(GLFW_PLATFORM_ERROR, + "GLX: Failed to retrieve visual for GLXFBConfig"); + return GL_FALSE; + } + + if (wndconfig->clientAPI == GLFW_OPENGL_ES_API) + { + if (!_glfw.glx.ARB_create_context || + !_glfw.glx.ARB_create_context_profile || + !_glfw.glx.EXT_create_context_es2_profile) + { + XFree(native); + + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "GLX: OpenGL ES requested but " + "GLX_EXT_create_context_es2_profile is unavailable"); + return GL_FALSE; + } + } + + if (wndconfig->glForward) + { + if (!_glfw.glx.ARB_create_context) + { + XFree(native); + + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "GLX: Forward compatibility requested but " + "GLX_ARB_create_context_profile is unavailable"); + return GL_FALSE; + } + } + + if (wndconfig->glProfile) + { + if (!_glfw.glx.ARB_create_context || + !_glfw.glx.ARB_create_context_profile) + { + XFree(native); + + _glfwInputError(GLFW_VERSION_UNAVAILABLE, + "GLX: An OpenGL profile requested but " + "GLX_ARB_create_context_profile is unavailable"); + return GL_FALSE; + } + } + + if (_glfw.glx.ARB_create_context) + { + int index = 0, mask = 0, flags = 0, strategy = 0; + + if (wndconfig->clientAPI == GLFW_OPENGL_API) + { + if (wndconfig->glForward) + flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + + if (wndconfig->glDebug) + flags |= GLX_CONTEXT_DEBUG_BIT_ARB; + + if (wndconfig->glProfile) + { + if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE) + mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE) + mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + } + } + else + mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; + + if (wndconfig->glRobustness != GLFW_NO_ROBUSTNESS) + { + if (_glfw.glx.ARB_create_context_robustness) + { + if (wndconfig->glRobustness == GLFW_NO_RESET_NOTIFICATION) + strategy = GLX_NO_RESET_NOTIFICATION_ARB; + else if (wndconfig->glRobustness == GLFW_LOSE_CONTEXT_ON_RESET) + strategy = GLX_LOSE_CONTEXT_ON_RESET_ARB; + + flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; + } + } + + if (wndconfig->glMajor != 1 || wndconfig->glMinor != 0) + { + // NOTE: Only request an explicitly versioned context when + // necessary, as explicitly requesting version 1.0 does not always + // return the highest available version + + setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, wndconfig->glMajor); + setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor); + } + + if (mask) + setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); + + if (flags) + setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags); + + if (strategy) + setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, strategy); + + setGLXattrib(None, None); + + // This is the only place we set an Xlib error handler, and we only do + // it because glXCreateContextAttribsARB generates a BadMatch error if + // the requested OpenGL version is unavailable (instead of a civilized + // response like returning NULL) + _glfwErrorCode = Success; + XSetErrorHandler(errorHandler); + + window->glx.context = + _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, + *native, + share, + True, + attribs); + + // We are done, so unset the error handler again (see above) + XSetErrorHandler(NULL); + + if (window->glx.context == NULL) + { + // HACK: This is a fallback for the broken Mesa implementation of + // GLX_ARB_create_context_profile, which fails default 1.0 context + // creation with a GLXBadProfileARB error in violation of the spec + if (_glfwErrorCode == _glfw.glx.errorBase + GLXBadProfileARB && + wndconfig->clientAPI == GLFW_OPENGL_API && + wndconfig->glProfile == GLFW_OPENGL_NO_PROFILE && + wndconfig->glForward == GL_FALSE) + { + window->glx.context = createLegacyContext(window, *native, share); + } + } + } + else + window->glx.context = createLegacyContext(window, *native, share); + + XFree(native); + + if (window->glx.context == NULL) + { + _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create context"); + return GL_FALSE; + } + + return GL_TRUE; } +#undef setGLXattrib + //======================================================================== // Destroy the OpenGL context diff --git a/src/internal.h b/src/internal.h index a69b1ee0..269ff0c6 100644 --- a/src/internal.h +++ b/src/internal.h @@ -177,11 +177,8 @@ struct _GLFWwndconfig /*! @brief Framebuffer configuration. * - * This describes buffers and their sizes. It also contains - * a platform-specific ID used to map back to the backend API's object. - * - * It is used to pass framebuffer parameters from shared code to the - * platform API and also to enumerate and select available framebuffer configs. + * This describes buffers and their sizes. It is used to pass framebuffer + * parameters from shared code to the platform API. */ struct _GLFWfbconfig { @@ -199,7 +196,6 @@ struct _GLFWfbconfig GLboolean stereo; int samples; GLboolean sRGB; - GLFWintptr platformID; }; @@ -671,18 +667,6 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); */ int _glfwStringInExtensionString(const char* string, const GLubyte* extensions); -/*! @brief Chooses the framebuffer config that best matches the desired one. - * @param[in] desired The desired framebuffer config. - * @param[in] alternatives The framebuffer configs supported by the system. - * @param[in] count The number of entries in the alternatives array. - * @return The framebuffer config most closely matching the desired one, or @c - * NULL if none fulfilled the hard constraints of the desired values. - * @ingroup utility - */ -const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, - const _GLFWfbconfig* alternatives, - unsigned int count); - /*! @brief Checks and reads back properties from the current context. * @return @c GL_TRUE if successful, or @c GL_FALSE if the context is unusable. * @ingroup utility diff --git a/src/wgl_context.c b/src/wgl_context.c index 3fa0776f..8ec09049 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -32,6 +32,7 @@ #include #include +#include //======================================================================== @@ -64,7 +65,7 @@ static void initWGLExtensions(_GLFWwindow* window) { // This needs to include every function pointer loaded below window->wgl.SwapIntervalEXT = NULL; - window->wgl.GetPixelFormatAttribivARB = NULL; + window->wgl.ChoosePixelFormatARB = NULL; window->wgl.GetExtensionsStringARB = NULL; window->wgl.GetExtensionsStringEXT = NULL; window->wgl.CreateContextAttribsARB = NULL; @@ -135,215 +136,146 @@ static void initWGLExtensions(_GLFWwindow* window) if (_glfwPlatformExtensionSupported("WGL_ARB_pixel_format")) { - window->wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) - wglGetProcAddress("wglGetPixelFormatAttribivARB"); + window->wgl.ChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) + wglGetProcAddress("wglChoosePixelFormatARB"); - if (window->wgl.GetPixelFormatAttribivARB) + if (window->wgl.ChoosePixelFormatARB) window->wgl.ARB_pixel_format = GL_TRUE; } } -//======================================================================== -// Returns the specified attribute of the specified pixel format -// NOTE: Do not call this unless we have found WGL_ARB_pixel_format -//======================================================================== - -static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib) -{ - int value = 0; - - if (!window->wgl.GetPixelFormatAttribivARB(window->wgl.dc, - pixelFormat, - 0, 1, &attrib, &value)) - { - // NOTE: We should probably handle this error somehow - return 0; - } - - return value; -} - +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// //======================================================================== -// Return a list of available and usable framebuffer configs -//======================================================================== - -static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) -{ - _GLFWfbconfig* fbconfigs; - PIXELFORMATDESCRIPTOR pfd; - int i, available; - - *found = 0; - - if (window->wgl.ARB_pixel_format) - { - available = getPixelFormatAttrib(window, - 1, - WGL_NUMBER_PIXEL_FORMATS_ARB); - } - else - { - available = DescribePixelFormat(window->wgl.dc, - 1, - sizeof(PIXELFORMATDESCRIPTOR), - NULL); - } - - if (!available) - { - _glfwInputError(GLFW_API_UNAVAILABLE, "WGL: No pixel formats found"); - return NULL; - } - - fbconfigs = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * available); - if (!fbconfigs) - { - _glfwInputError(GLFW_OUT_OF_MEMORY, NULL); - return NULL; - } - - for (i = 1; i <= available; i++) - { - _GLFWfbconfig* f = fbconfigs + *found; - - if (window->wgl.ARB_pixel_format) - { - // Get pixel format attributes through WGL_ARB_pixel_format - if (!getPixelFormatAttrib(window, i, WGL_SUPPORT_OPENGL_ARB) || - !getPixelFormatAttrib(window, i, WGL_DRAW_TO_WINDOW_ARB) || - !getPixelFormatAttrib(window, i, WGL_DOUBLE_BUFFER_ARB)) - { - continue; - } - - if (getPixelFormatAttrib(window, i, WGL_PIXEL_TYPE_ARB) != - WGL_TYPE_RGBA_ARB) - { - continue; - } - - if (getPixelFormatAttrib(window, i, WGL_ACCELERATION_ARB) == - WGL_NO_ACCELERATION_ARB) - { - continue; - } - - f->redBits = getPixelFormatAttrib(window, i, WGL_RED_BITS_ARB); - f->greenBits = getPixelFormatAttrib(window, i, WGL_GREEN_BITS_ARB); - f->blueBits = getPixelFormatAttrib(window, i, WGL_BLUE_BITS_ARB); - f->alphaBits = getPixelFormatAttrib(window, i, WGL_ALPHA_BITS_ARB); - - f->depthBits = getPixelFormatAttrib(window, i, WGL_DEPTH_BITS_ARB); - f->stencilBits = getPixelFormatAttrib(window, i, WGL_STENCIL_BITS_ARB); - - f->accumRedBits = getPixelFormatAttrib(window, i, WGL_ACCUM_RED_BITS_ARB); - f->accumGreenBits = getPixelFormatAttrib(window, i, WGL_ACCUM_GREEN_BITS_ARB); - f->accumBlueBits = getPixelFormatAttrib(window, i, WGL_ACCUM_BLUE_BITS_ARB); - f->accumAlphaBits = getPixelFormatAttrib(window, i, WGL_ACCUM_ALPHA_BITS_ARB); - - f->auxBuffers = getPixelFormatAttrib(window, i, WGL_AUX_BUFFERS_ARB); - f->stereo = getPixelFormatAttrib(window, i, WGL_STEREO_ARB); - - if (window->wgl.ARB_multisample) - f->samples = getPixelFormatAttrib(window, i, WGL_SAMPLES_ARB); - else - f->samples = 0; - - if (window->wgl.ARB_framebuffer_sRGB) - f->sRGB = getPixelFormatAttrib(window, i, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB); - else - f->sRGB = GL_FALSE; - } - else - { - // Get pixel format attributes through old-fashioned PFDs - - if (!DescribePixelFormat(window->wgl.dc, - i, - sizeof(PIXELFORMATDESCRIPTOR), - &pfd)) - { - continue; - } - - if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) || - !(pfd.dwFlags & PFD_SUPPORT_OPENGL) || - !(pfd.dwFlags & PFD_DOUBLEBUFFER)) - { - continue; - } - - if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && - (pfd.dwFlags & PFD_GENERIC_FORMAT)) - { - continue; - } - - if (pfd.iPixelType != PFD_TYPE_RGBA) - continue; - - f->redBits = pfd.cRedBits; - f->greenBits = pfd.cGreenBits; - f->blueBits = pfd.cBlueBits; - f->alphaBits = pfd.cAlphaBits; - - f->depthBits = pfd.cDepthBits; - f->stencilBits = pfd.cStencilBits; - - f->accumRedBits = pfd.cAccumRedBits; - f->accumGreenBits = pfd.cAccumGreenBits; - f->accumBlueBits = pfd.cAccumBlueBits; - f->accumAlphaBits = pfd.cAccumAlphaBits; - - f->auxBuffers = pfd.cAuxBuffers; - f->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; - - // PFD pixel formats do not support FSAA - f->samples = 0; - - // PFD pixel formats do not support sRGB - f->sRGB = GL_FALSE; - } - - f->platformID = i; - - (*found)++; - } - - if (*found == 0) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32/WGL: No usable pixel formats found"); - - free(fbconfigs); - return NULL; - } - - return fbconfigs; -} - - -//======================================================================== -// Creates an OpenGL context on the specified device context +// Prepare for creation of the OpenGL context //======================================================================== #define setWGLattrib(attribName, attribValue) \ +{ \ attribs[index++] = attribName; \ - attribs[index++] = attribValue; + attribs[index++] = attribValue; \ + assert(index < sizeof(attribs) / sizeof(attribs[0])); \ +} -static GLboolean createContext(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - int pixelFormat) +int _glfwCreateContext(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig) { int attribs[40]; + int pixelFormat; PIXELFORMATDESCRIPTOR pfd; HGLRC share = NULL; if (wndconfig->share) share = wndconfig->share->wgl.context; + window->wgl.dc = GetDC(window->win32.handle); + if (!window->wgl.dc) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to retrieve DC for window"); + return GL_FALSE; + } + + if (window->wgl.ARB_pixel_format) + { + int index = 0; + UINT count; + + setWGLattrib(WGL_SUPPORT_OPENGL_ARB, TRUE); + setWGLattrib(WGL_DRAW_TO_WINDOW_ARB, TRUE); + setWGLattrib(WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB); + setWGLattrib(WGL_DOUBLE_BUFFER_ARB, TRUE); + + if (fbconfig->redBits) + setWGLattrib(WGL_RED_BITS_ARB, fbconfig->redBits); + if (fbconfig->greenBits) + setWGLattrib(WGL_GREEN_BITS_ARB, fbconfig->greenBits); + if (fbconfig->blueBits) + setWGLattrib(WGL_BLUE_BITS_ARB, fbconfig->blueBits); + if (fbconfig->alphaBits) + setWGLattrib(WGL_BLUE_BITS_ARB, fbconfig->alphaBits); + + if (fbconfig->depthBits) + setWGLattrib(WGL_DEPTH_BITS_ARB, fbconfig->depthBits); + if (fbconfig->stencilBits) + setWGLattrib(WGL_STENCIL_BITS_ARB, fbconfig->stencilBits); + + if (fbconfig->auxBuffers) + setWGLattrib(WGL_AUX_BUFFERS_ARB, fbconfig->auxBuffers); + + if (fbconfig->accumRedBits) + setWGLattrib(WGL_ACCUM_RED_BITS_ARB, fbconfig->accumRedBits); + if (fbconfig->accumGreenBits) + setWGLattrib(WGL_ACCUM_GREEN_BITS_ARB, fbconfig->accumGreenBits); + if (fbconfig->accumBlueBits) + setWGLattrib(WGL_ACCUM_BLUE_BITS_ARB, fbconfig->accumBlueBits); + if (fbconfig->accumAlphaBits) + setWGLattrib(WGL_ACCUM_BLUE_BITS_ARB, fbconfig->accumAlphaBits); + + if (fbconfig->stereo) + setWGLattrib(WGL_STEREO_ARB, TRUE); + + if (window->wgl.ARB_multisample) + { + if (fbconfig->samples) + { + setWGLattrib(WGL_SAMPLE_BUFFERS_ARB, 1); + setWGLattrib(WGL_SAMPLES_ARB, fbconfig->samples); + } + } + + if (window->wgl.ARB_framebuffer_sRGB) + { + if (fbconfig->sRGB) + setWGLattrib(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, TRUE); + } + + setWGLattrib(0, 0); + + if (!window->wgl.ChoosePixelFormatARB(window->wgl.dc, + attribs, + NULL, + 1, + &pixelFormat, + &count)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to find a suitable pixel format"); + return GL_FALSE; + } + } + else + { + ZeroMemory(&pfd, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + + pfd.dwFlags |= PFD_DRAW_TO_WINDOW | + PFD_SUPPORT_OPENGL | + PFD_DOUBLEBUFFER; + + if (fbconfig->stereo) + pfd.dwFlags |= PFD_STEREO; + + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = fbconfig->redBits + + fbconfig->greenBits + + fbconfig->blueBits; + pfd.cAlphaBits = fbconfig->alphaBits; + pfd.cAccumBits = fbconfig->accumRedBits + + fbconfig->accumGreenBits + + fbconfig->accumBlueBits; + pfd.cDepthBits = fbconfig->depthBits; + pfd.cStencilBits = fbconfig->stencilBits; + pfd.cAuxBuffers = fbconfig->auxBuffers; + + pixelFormat = ChoosePixelFormat(window->wgl.dc, &pfd); + } + if (!DescribePixelFormat(window->wgl.dc, pixelFormat, sizeof(pfd), &pfd)) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -352,6 +284,14 @@ static GLboolean createContext(_GLFWwindow* window, return GL_FALSE; } + if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) && + (pfd.dwFlags & PFD_GENERIC_FORMAT)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Win32: Failed to find an accelerated pixel format"); + return GL_FALSE; + } + if (!SetPixelFormat(window->wgl.dc, pixelFormat, &pfd)) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -453,56 +393,6 @@ static GLboolean createContext(_GLFWwindow* window, #undef setWGLattrib -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -//======================================================================== -// Prepare for creation of the OpenGL context -//======================================================================== - -int _glfwCreateContext(_GLFWwindow* window, - const _GLFWwndconfig* wndconfig, - const _GLFWfbconfig* fbconfig) -{ - _GLFWfbconfig closest; - - window->wgl.dc = GetDC(window->win32.handle); - if (!window->wgl.dc) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to retrieve DC for window"); - return GL_FALSE; - } - - // Choose the best available fbconfig - { - unsigned int fbcount; - _GLFWfbconfig* fbconfigs; - const _GLFWfbconfig* result; - - fbconfigs = getFBConfigs(window, &fbcount); - if (!fbconfigs) - return GL_FALSE; - - result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); - if (!result) - { - _glfwInputError(GLFW_FORMAT_UNAVAILABLE, - "Win32/WGL: No pixel format matched the criteria"); - - free(fbconfigs); - return GL_FALSE; - } - - closest = *result; - free(fbconfigs); - } - - return createContext(window, wndconfig, (int) closest.platformID); -} - - //======================================================================== // Destroy the OpenGL context //======================================================================== diff --git a/src/wgl_platform.h b/src/wgl_platform.h index 90428510..5983aef5 100644 --- a/src/wgl_platform.h +++ b/src/wgl_platform.h @@ -56,7 +56,7 @@ typedef struct _GLFWcontextWGL // Platform specific extensions (context specific) PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT; - PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB; + PFNWGLCHOOSEPIXELFORMATARBPROC ChoosePixelFormatARB; PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT; PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB; PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;