From 1a33796098696c40c3a490ad0cee97fc07f8cf77 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Mon, 22 Feb 2016 18:08:15 +0100 Subject: [PATCH 01/34] Add support for transparent X11/GLX window --- examples/gears.c | 3 ++ include/GLFW/glfw3.h | 1 + src/glx_context.c | 98 ++++++++++++++++++++++++++++++++++++++++---- src/glx_context.h | 35 ++++++++++++++-- src/internal.h | 2 + src/window.c | 7 ++++ src/x11_window.c | 2 +- 7 files changed, 135 insertions(+), 13 deletions(-) diff --git a/examples/gears.c b/examples/gears.c index 29e63f58b..c5897dcca 100644 --- a/examples/gears.c +++ b/examples/gears.c @@ -172,6 +172,7 @@ static GLfloat angle = 0.f; /* OpenGL draw function & timing */ static void draw(void) { + glClearColor(0., 0., 0., 0.); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); @@ -311,6 +312,8 @@ int main(int argc, char *argv[]) } glfwWindowHint(GLFW_DEPTH_BITS, 16); + glfwWindowHint(GLFW_ALPHA_BITS, 8); + glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE); window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL ); if (!window) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 41e5f7d8c..2e6ed0c14 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -627,6 +627,7 @@ extern "C" { #define GLFW_AUTO_ICONIFY 0x00020006 #define GLFW_FLOATING 0x00020007 #define GLFW_MAXIMIZED 0x00020008 +#define GLFW_TRANSPARENT 0x00020009 #define GLFW_RED_BITS 0x00021001 #define GLFW_GREEN_BITS 0x00021002 diff --git a/src/glx_context.c b/src/glx_context.c index 22ec7e10a..b4b8b589f 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -47,7 +47,10 @@ static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib) // Return a list of available and usable framebuffer configs // -static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result) +static GLFWbool chooseFBConfig( + const _GLFWfbconfig* desired, + GLXFBConfig* result, + GLFWbool findTransparent) { GLXFBConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; @@ -56,6 +59,10 @@ static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result const char* vendor; GLFWbool trustWindowBit = GLFW_TRUE; + if (findTransparent && !(_glfw.xrender.major || _glfw.xrender.minor)) { + findTransparent = GLFW_FALSE; + } + // HACK: This is a (hopefully temporary) workaround for Chromium // (VirtualBox GL) not setting the window bit on any GLXFBConfigs vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR); @@ -73,6 +80,7 @@ static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; +selectionloop: for (i = 0; i < nativeCount; i++) { const GLXFBConfig n = nativeConfigs[i]; @@ -89,6 +97,22 @@ static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result continue; } + if( findTransparent ) { + XVisualInfo *visualinfo; + XRenderPictFormat *pictFormat; + + visualinfo = glXGetVisualFromFBConfig(_glfw.x11.display, n); + if (!visualinfo) + continue; + + pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual); + if( !pictFormat ) + continue; + + if( !pictFormat->direct.alphaMask ) + continue; + } + u->redBits = getFBConfigAttrib(n, GLX_RED_SIZE); u->greenBits = getFBConfigAttrib(n, GLX_GREEN_SIZE); u->blueBits = getFBConfigAttrib(n, GLX_BLUE_SIZE); @@ -118,6 +142,12 @@ static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result u->glx = n; usableCount++; } + // reiterate the selection loop without looking for transparency supporting + // formats if no matchig FB configs for a transparent window were found. + if( findTransparent && !usableCount ) { + findTransparent = GLFW_FALSE; + goto selectionloop; + } closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); if (closest) @@ -152,7 +182,7 @@ static GLXContext createLegacyContext(_GLFWwindow* window, GLFWbool _glfwInitGLX(void) { int i; - const char* sonames[] = + const char* sonames_glx[] = { #if defined(__CYGWIN__) "libGL-1.so", @@ -163,14 +193,32 @@ GLFWbool _glfwInitGLX(void) NULL }; - - for (i = 0; sonames[i]; i++) + const char* sonames_xrender[] = { - _glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL); +#if defined(__CYGWIN__) + "libXrender-1.so", +#else + "libXrender.so.1", + "libXrender.so", +#endif + NULL + }; + + + for (i = 0; sonames_glx[i]; i++) + { + _glfw.glx.handle = dlopen(sonames_glx[i], RTLD_LAZY | RTLD_GLOBAL); if (_glfw.glx.handle) break; } + for (i = 0; sonames_xrender[i]; i++) + { + _glfw.xrender.handle = dlopen(sonames_xrender[i], RTLD_LAZY | RTLD_GLOBAL); + if (_glfw.xrender.handle) + break; + } + if (!_glfw.glx.handle) { _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX"); @@ -230,6 +278,37 @@ GLFWbool _glfwInitGLX(void) return GLFW_FALSE; } + // Xrender support is optional and not a requirement for GLX + // to work. Xrender is required for selecting a FB config that + // supports a picture format with an alpha mask, which in turn + // is required for transparent windows. I Xrender is not supported + // the GLFW_TRANSPARENT window hint is ignored. + _glfw.xrender.errorBase = 0; + _glfw.xrender.eventBase = 0; + _glfw.xrender.major = 0; + _glfw.xrender.minor = 0; + if (_glfw.xrender.handle) do { + int errorBase, eventBase, major, minor; + _glfw.xrender.QueryExtension = + dlsym(_glfw.xrender.handle, "XRenderQueryExtension"); + _glfw.xrender.QueryVersion = + dlsym(_glfw.xrender.handle, "XRenderQueryVersion"); + _glfw.xrender.FindVisualFormat = + dlsym(_glfw.xrender.handle, "XRenderFindVisualFormat"); + + if ( !XRenderQueryExtension(_glfw.x11.display, &errorBase, &eventBase)) { + break; + } + if ( !XRenderQueryVersion(_glfw.x11.display, &major, &minor)) { + break; + } + + _glfw.xrender.errorBase = errorBase; + _glfw.xrender.eventBase = eventBase; + _glfw.xrender.major = major; + _glfw.xrender.minor = minor; + } while(0); + if (_glfwPlatformExtensionSupported("GLX_EXT_swap_control")) { _glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) @@ -324,7 +403,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, if (ctxconfig->share) share = ctxconfig->share->context.glx.handle; - if (!chooseFBConfig(fbconfig, &native)) + if (!chooseFBConfig(fbconfig, &native, window->transparent)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "GLX: Failed to find a suitable GLXFBConfig"); @@ -507,14 +586,15 @@ void _glfwDestroyContextGLX(_GLFWwindow* window) // Returns the Visual and depth of the chosen GLXFBConfig // -GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig, +GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth) { GLXFBConfig native; XVisualInfo* result; - if (!chooseFBConfig(fbconfig, &native)) + if (!chooseFBConfig(fbconfig, &native, wndconfig->transparent)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "GLX: Failed to find a suitable GLXFBConfig"); @@ -530,7 +610,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig, } *visual = result->visual; - *depth = result->depth; + *depth = result->depth; XFree(result); return GLFW_TRUE; diff --git a/src/glx_context.h b/src/glx_context.h index dc54c7973..81b7d1e6b 100644 --- a/src/glx_context.h +++ b/src/glx_context.h @@ -74,6 +74,7 @@ typedef struct __GLXFBConfig* GLXFBConfig; typedef struct __GLXcontext* GLXContext; typedef void (*__GLXextproc)(void); +// libGL.so function pointer typedefs typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*); typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int); typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*); @@ -93,7 +94,7 @@ typedef XVisualInfo* (*PFNGLXGETVISUALFROMFBCONFIGPROC)(Display*,GLXFBConfig); typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const int*); typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow); -// libGL.so function pointer typedefs +// libGL.so function identifier overlays #define glXGetFBConfigs _glfw.glx.GetFBConfigs #define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib #define glXGetClientString _glfw.glx.GetClientString @@ -108,9 +109,19 @@ typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow); #define glXCreateWindow _glfw.glx.CreateWindow #define glXDestroyWindow _glfw.glx.DestroyWindow +// libXrender.so function pointer typedefs +typedef Bool (*PFNXRENDERQUERYEXTENSIONPROC)(Display*,int*,int*); +typedef Status (*PFNXRENDERQUERYVERSIONPROC)(Display*dpy,int*,int*); +typedef XRenderPictFormat* (*PFNXRENDERFINDVISUALFORMATPROC)(Display*,Visual const *); + +// libXrender.so function identifier overlays +#define XRenderQueryExtension _glfw.xrender.QueryExtension +#define XRenderQueryVersion _glfw.xrender.QueryVersion +#define XRenderFindVisualFormat _glfw.xrender.FindVisualFormat + #define _GLFW_PLATFORM_FBCONFIG GLXFBConfig glx #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx -#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx +#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx ; _GLFWlibraryXrender xrender // GLX-specific per-context data @@ -170,6 +181,23 @@ typedef struct _GLFWlibraryGLX } _GLFWlibraryGLX; +// Xrender-specific global data +// +typedef struct _GLFWlibraryXrender +{ + int major, minor; + int eventBase; + int errorBase; + + // dlopen handle for libGL.so.1 + void* handle; + + // Xrender functions (subset required for transparent window) + PFNXRENDERQUERYEXTENSIONPROC QueryExtension; + PFNXRENDERQUERYVERSIONPROC QueryVersion; + PFNXRENDERFINDVISUALFORMATPROC FindVisualFormat; +} _GLFWlibraryXrender; + GLFWbool _glfwInitGLX(void); void _glfwTerminateGLX(void); @@ -177,7 +205,8 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); void _glfwDestroyContextGLX(_GLFWwindow* window); -GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig, +GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth); diff --git a/src/internal.h b/src/internal.h index 358da2562..a11890366 100644 --- a/src/internal.h +++ b/src/internal.h @@ -252,6 +252,7 @@ struct _GLFWwndconfig GLFWbool resizable; GLFWbool visible; GLFWbool decorated; + GLFWbool transparent; GLFWbool focused; GLFWbool autoIconify; GLFWbool floating; @@ -341,6 +342,7 @@ struct _GLFWwindow // Window settings and state GLFWbool resizable; GLFWbool decorated; + GLFWbool transparent; GLFWbool autoIconify; GLFWbool floating; GLFWbool closed; diff --git a/src/window.c b/src/window.c index f051370e1..11b9b0add 100644 --- a/src/window.c +++ b/src/window.c @@ -178,6 +178,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->monitor = wndconfig.monitor; window->resizable = wndconfig.resizable; window->decorated = wndconfig.decorated; + window->transparent = wndconfig.transparent; window->autoIconify = wndconfig.autoIconify; window->floating = wndconfig.floating; window->cursorMode = GLFW_CURSOR_NORMAL; @@ -256,6 +257,7 @@ void glfwDefaultWindowHints(void) _glfw.hints.window.resizable = GLFW_TRUE; _glfw.hints.window.visible = GLFW_TRUE; _glfw.hints.window.decorated = GLFW_TRUE; + _glfw.hints.window.transparent = GLFW_FALSE; _glfw.hints.window.focused = GLFW_TRUE; _glfw.hints.window.autoIconify = GLFW_TRUE; @@ -330,6 +332,9 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_DECORATED: _glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE; break; + case GLFW_TRANSPARENT: + _glfw.hints.window.transparent = value ? GLFW_TRUE : GLFW_FALSE; + break; case GLFW_FOCUSED: _glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE; break; @@ -650,6 +655,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) return window->resizable; case GLFW_DECORATED: return window->decorated; + case GLFW_TRANSPARENT: + return window->transparent; case GLFW_FLOATING: return window->floating; case GLFW_CLIENT_API: diff --git a/src/x11_window.c b/src/x11_window.c index 2f9130a74..a2b96a997 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1431,7 +1431,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, else { #if defined(_GLFW_GLX) - if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth)) + if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth)) return GLFW_FALSE; #elif defined(_GLFW_EGL) if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth)) From e9693a13fece33cb2042151e501cee83f29bdc00 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Mon, 22 Feb 2016 18:55:30 +0100 Subject: [PATCH 02/34] Always reset transparency flag --- src/glx_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/glx_context.c b/src/glx_context.c index b4b8b589f..7d9cc0e1a 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -59,7 +59,7 @@ static GLFWbool chooseFBConfig( const char* vendor; GLFWbool trustWindowBit = GLFW_TRUE; - if (findTransparent && !(_glfw.xrender.major || _glfw.xrender.minor)) { + if ( !(_glfw.xrender.major || _glfw.xrender.minor) ) { findTransparent = GLFW_FALSE; } From 19c2a53dc0d42fdbeac74ef2d848e32f238c2634 Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Mon, 22 Feb 2016 19:42:21 +0100 Subject: [PATCH 03/34] Free visualinfo and picture format info structures Fixes a memory leak. --- src/glx_context.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/glx_context.c b/src/glx_context.c index 7d9cc0e1a..fedfc50d4 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -79,7 +79,9 @@ static GLFWbool chooseFBConfig( usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; - + + XVisualInfo *visualinfo = NULL; + XRenderPictFormat *pictFormat = NULL; selectionloop: for (i = 0; i < nativeCount; i++) { @@ -98,13 +100,21 @@ selectionloop: } if( findTransparent ) { - XVisualInfo *visualinfo; - XRenderPictFormat *pictFormat; + if( visualinfo ) { + XFree( visualinfo ); + visualinfo = NULL; + } + visualinfo = glXGetVisualFromFBConfig(_glfw.x11.display, n); if (!visualinfo) continue; + if( pictFormat ) { + XFree( pictFormat ); + pictFormat = NULL; + } + pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual); if( !pictFormat ) continue; @@ -141,6 +151,15 @@ selectionloop: u->glx = n; usableCount++; + + if( visualinfo ) { + XFree( visualinfo ); + visualinfo = NULL; + } + if( pictFormat ) { + XFree( pictFormat ); + pictFormat = NULL; + } } // reiterate the selection loop without looking for transparency supporting // formats if no matchig FB configs for a transparent window were found. From 9825849a09da830437bea787a5d2bd29089cbecd Mon Sep 17 00:00:00 2001 From: Wolfgang Draxinger Date: Mon, 22 Feb 2016 21:03:18 +0100 Subject: [PATCH 04/34] Add X11/EGL transparent window support Seems like Mesa EGL fbconfigs don't match with transparent picture formats. --- src/egl_context.c | 49 ++++++++++++++++++++++++--- src/egl_context.h | 3 +- src/glx_context.c | 83 ++++++---------------------------------------- src/glx_context.h | 30 +---------------- src/x11_init.c | 49 +++++++++++++++++++++++++++ src/x11_platform.h | 27 ++++++++++++++- src/x11_window.c | 2 +- 7 files changed, 133 insertions(+), 110 deletions(-) diff --git a/src/egl_context.c b/src/egl_context.c index 827ccbfd3..d3c35ef79 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -86,13 +86,21 @@ static int getConfigAttrib(EGLConfig config, int attrib) // static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* desired, - EGLConfig* result) + EGLConfig* result, + GLFWbool findTransparent) { EGLConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; int i, nativeCount, usableCount; +#if defined(_GLFW_X11) + XVisualInfo visualTemplate = {0}; + if ( !(_glfw.xrender.major || _glfw.xrender.minor) ) { + findTransparent = GLFW_FALSE; + } +#endif // _GLFW_X11 + eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); if (!nativeCount) { @@ -106,6 +114,7 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig, usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; +selectionloop: for (i = 0; i < nativeCount; i++) { const EGLConfig n = nativeConfigs[i]; @@ -121,8 +130,31 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig, #if defined(_GLFW_X11) // Only consider EGLConfigs with associated Visuals - if (!getConfigAttrib(n, EGL_NATIVE_VISUAL_ID)) + visualTemplate.visualid = getConfigAttrib(n, EGL_NATIVE_VISUAL_ID); + if (!visualTemplate.visualid) continue; + + if( findTransparent ) { + int n_vi; + XVisualInfo *visualinfo; + XRenderPictFormat *pictFormat; + + visualinfo = XGetVisualInfo(_glfw.x11.display, VisualIDMask, &visualTemplate, &n_vi); + if (!visualinfo) + continue; + + pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual); + if( !pictFormat ) { + XFree( visualinfo ); + continue; + } + + if( !pictFormat->direct.alphaMask ) { + XFree( visualinfo ); + continue; + } + XFree( visualinfo ); + } #endif // _GLFW_X11 if (ctxconfig->api == GLFW_OPENGL_ES_API) @@ -158,6 +190,12 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig, u->egl = n; usableCount++; } + // reiterate the selection loop without looking for transparency supporting + // formats if no matchig FB configs for a transparent window were found. + if( findTransparent && !usableCount ) { + findTransparent = GLFW_FALSE; + goto selectionloop; + } closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); if (closest) @@ -297,7 +335,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, if (ctxconfig->share) share = ctxconfig->share->context.egl.handle; - if (!chooseFBConfigs(ctxconfig, fbconfig, &config)) + if (!chooseFBConfigs(ctxconfig, fbconfig, &config, window->transparent)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Failed to find a suitable EGLConfig"); @@ -535,7 +573,8 @@ void _glfwDestroyContextEGL(_GLFWwindow* window) // Returns the Visual and depth of the chosen EGLConfig // #if defined(_GLFW_X11) -GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig, +GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth) { @@ -545,7 +584,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig, EGLint visualID = 0, count = 0; const long vimask = VisualScreenMask | VisualIDMask; - if (!chooseFBConfigs(ctxconfig, fbconfig, &native)) + if (!chooseFBConfigs(ctxconfig, fbconfig, &native, wndconfig->transparent)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Failed to find a suitable EGLConfig"); diff --git a/src/egl_context.h b/src/egl_context.h index 15d5a1258..b37263311 100644 --- a/src/egl_context.h +++ b/src/egl_context.h @@ -207,7 +207,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, const _GLFWfbconfig* fbconfig); void _glfwDestroyContextEGL(_GLFWwindow* window); #if defined(_GLFW_X11) -GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig, +GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth); #endif /*_GLFW_X11*/ diff --git a/src/glx_context.c b/src/glx_context.c index fedfc50d4..ca225e244 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -80,8 +80,6 @@ static GLFWbool chooseFBConfig( usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; - XVisualInfo *visualinfo = NULL; - XRenderPictFormat *pictFormat = NULL; selectionloop: for (i = 0; i < nativeCount; i++) { @@ -100,27 +98,24 @@ selectionloop: } if( findTransparent ) { - - if( visualinfo ) { - XFree( visualinfo ); - visualinfo = NULL; - } + XVisualInfo *visualinfo; + XRenderPictFormat *pictFormat; visualinfo = glXGetVisualFromFBConfig(_glfw.x11.display, n); if (!visualinfo) continue; - if( pictFormat ) { - XFree( pictFormat ); - pictFormat = NULL; + pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual); + if( !pictFormat ) { + XFree( visualinfo ); + continue; } - pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual); - if( !pictFormat ) - continue; - - if( !pictFormat->direct.alphaMask ) + if( !pictFormat->direct.alphaMask ) { + XFree( visualinfo ); continue; + } + XFree( visualinfo ); } u->redBits = getFBConfigAttrib(n, GLX_RED_SIZE); @@ -151,15 +146,6 @@ selectionloop: u->glx = n; usableCount++; - - if( visualinfo ) { - XFree( visualinfo ); - visualinfo = NULL; - } - if( pictFormat ) { - XFree( pictFormat ); - pictFormat = NULL; - } } // reiterate the selection loop without looking for transparency supporting // formats if no matchig FB configs for a transparent window were found. @@ -212,17 +198,6 @@ GLFWbool _glfwInitGLX(void) NULL }; - const char* sonames_xrender[] = - { -#if defined(__CYGWIN__) - "libXrender-1.so", -#else - "libXrender.so.1", - "libXrender.so", -#endif - NULL - }; - for (i = 0; sonames_glx[i]; i++) { @@ -231,13 +206,6 @@ GLFWbool _glfwInitGLX(void) break; } - for (i = 0; sonames_xrender[i]; i++) - { - _glfw.xrender.handle = dlopen(sonames_xrender[i], RTLD_LAZY | RTLD_GLOBAL); - if (_glfw.xrender.handle) - break; - } - if (!_glfw.glx.handle) { _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX"); @@ -297,37 +265,6 @@ GLFWbool _glfwInitGLX(void) return GLFW_FALSE; } - // Xrender support is optional and not a requirement for GLX - // to work. Xrender is required for selecting a FB config that - // supports a picture format with an alpha mask, which in turn - // is required for transparent windows. I Xrender is not supported - // the GLFW_TRANSPARENT window hint is ignored. - _glfw.xrender.errorBase = 0; - _glfw.xrender.eventBase = 0; - _glfw.xrender.major = 0; - _glfw.xrender.minor = 0; - if (_glfw.xrender.handle) do { - int errorBase, eventBase, major, minor; - _glfw.xrender.QueryExtension = - dlsym(_glfw.xrender.handle, "XRenderQueryExtension"); - _glfw.xrender.QueryVersion = - dlsym(_glfw.xrender.handle, "XRenderQueryVersion"); - _glfw.xrender.FindVisualFormat = - dlsym(_glfw.xrender.handle, "XRenderFindVisualFormat"); - - if ( !XRenderQueryExtension(_glfw.x11.display, &errorBase, &eventBase)) { - break; - } - if ( !XRenderQueryVersion(_glfw.x11.display, &major, &minor)) { - break; - } - - _glfw.xrender.errorBase = errorBase; - _glfw.xrender.eventBase = eventBase; - _glfw.xrender.major = major; - _glfw.xrender.minor = minor; - } while(0); - if (_glfwPlatformExtensionSupported("GLX_EXT_swap_control")) { _glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) diff --git a/src/glx_context.h b/src/glx_context.h index 81b7d1e6b..cc3f22983 100644 --- a/src/glx_context.h +++ b/src/glx_context.h @@ -109,19 +109,9 @@ typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow); #define glXCreateWindow _glfw.glx.CreateWindow #define glXDestroyWindow _glfw.glx.DestroyWindow -// libXrender.so function pointer typedefs -typedef Bool (*PFNXRENDERQUERYEXTENSIONPROC)(Display*,int*,int*); -typedef Status (*PFNXRENDERQUERYVERSIONPROC)(Display*dpy,int*,int*); -typedef XRenderPictFormat* (*PFNXRENDERFINDVISUALFORMATPROC)(Display*,Visual const *); - -// libXrender.so function identifier overlays -#define XRenderQueryExtension _glfw.xrender.QueryExtension -#define XRenderQueryVersion _glfw.xrender.QueryVersion -#define XRenderFindVisualFormat _glfw.xrender.FindVisualFormat - #define _GLFW_PLATFORM_FBCONFIG GLXFBConfig glx #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx -#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx ; _GLFWlibraryXrender xrender +#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx // GLX-specific per-context data @@ -181,24 +171,6 @@ typedef struct _GLFWlibraryGLX } _GLFWlibraryGLX; -// Xrender-specific global data -// -typedef struct _GLFWlibraryXrender -{ - int major, minor; - int eventBase; - int errorBase; - - // dlopen handle for libGL.so.1 - void* handle; - - // Xrender functions (subset required for transparent window) - PFNXRENDERQUERYEXTENSIONPROC QueryExtension; - PFNXRENDERQUERYVERSIONPROC QueryVersion; - PFNXRENDERFINDVISUALFORMATPROC FindVisualFormat; -} _GLFWlibraryXrender; - - GLFWbool _glfwInitGLX(void); void _glfwTerminateGLX(void); GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, diff --git a/src/x11_init.c b/src/x11_init.c index e73bb1314..e04d98b1c 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -474,6 +474,18 @@ static void detectEWMH(void) // static GLFWbool initExtensions(void) { + int i; + const char* sonames_xrender[] = + { +#if defined(__CYGWIN__) + "libXrender-1.so", +#else + "libXrender.so.1", + "libXrender.so", +#endif + NULL + }; + // Find or create window manager atoms _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", @@ -615,6 +627,43 @@ static GLFWbool initExtensions(void) _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True); + // Xrender support is optional and not a requirement for GLX/EGL + // to work. Xrender is required for selecting a FB config that + // supports a picture format with an alpha mask, which in turn + // is required for transparent windows. I Xrender is not supported + // the GLFW_TRANSPARENT window hint is ignored. + for (i = 0; sonames_xrender[i]; i++) + { + _glfw.xrender.handle = dlopen(sonames_xrender[i], RTLD_LAZY | RTLD_GLOBAL); + if (_glfw.xrender.handle) + break; + } + _glfw.xrender.errorBase = 0; + _glfw.xrender.eventBase = 0; + _glfw.xrender.major = 0; + _glfw.xrender.minor = 0; + if (_glfw.xrender.handle) do { + int errorBase, eventBase, major, minor; + _glfw.xrender.QueryExtension = + dlsym(_glfw.xrender.handle, "XRenderQueryExtension"); + _glfw.xrender.QueryVersion = + dlsym(_glfw.xrender.handle, "XRenderQueryVersion"); + _glfw.xrender.FindVisualFormat = + dlsym(_glfw.xrender.handle, "XRenderFindVisualFormat"); + + if ( !XRenderQueryExtension(_glfw.x11.display, &errorBase, &eventBase)) { + break; + } + if ( !XRenderQueryVersion(_glfw.x11.display, &major, &minor)) { + break; + } + + _glfw.xrender.errorBase = errorBase; + _glfw.xrender.eventBase = eventBase; + _glfw.xrender.major = major; + _glfw.xrender.minor = minor; + } while(0); + return GLFW_TRUE; } diff --git a/src/x11_platform.h b/src/x11_platform.h index 8d791f074..6a95ea263 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -103,10 +103,20 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk #define _glfw_dlsym(handle, name) dlsym(handle, name) #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11 -#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 +#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11 ; _GLFWlibraryXrender xrender #define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11 #define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorX11 x11 +// libXrender.so function pointer typedefs +typedef Bool (*PFNXRENDERQUERYEXTENSIONPROC)(Display*,int*,int*); +typedef Status (*PFNXRENDERQUERYVERSIONPROC)(Display*dpy,int*,int*); +typedef XRenderPictFormat* (*PFNXRENDERFINDVISUALFORMATPROC)(Display*,Visual const *); + +// libXrender.so function identifier overlays +#define XRenderQueryExtension _glfw.xrender.QueryExtension +#define XRenderQueryVersion _glfw.xrender.QueryVersion +#define XRenderFindVisualFormat _glfw.xrender.FindVisualFormat + // X11-specific per-window data // @@ -255,6 +265,21 @@ typedef struct _GLFWlibraryX11 } _GLFWlibraryX11; +// Xrender-specific global data +typedef struct _GLFWlibraryXrender +{ + int major, minor; + int eventBase; + int errorBase; + + // dlopen handle for libGL.so.1 + void* handle; + + // Xrender functions (subset required for transparent window) + PFNXRENDERQUERYEXTENSIONPROC QueryExtension; + PFNXRENDERQUERYVERSIONPROC QueryVersion; + PFNXRENDERFINDVISUALFORMATPROC FindVisualFormat; +} _GLFWlibraryXrender; // X11-specific per-monitor data // diff --git a/src/x11_window.c b/src/x11_window.c index a2b96a997..d85229328 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1434,7 +1434,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth)) return GLFW_FALSE; #elif defined(_GLFW_EGL) - if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth)) + if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth)) return GLFW_FALSE; #endif } From 95b4c2c17f121181731587392b9d93a151b2dfe1 Mon Sep 17 00:00:00 2001 From: Christopher Pelloux Date: Tue, 23 Feb 2016 21:53:55 -0500 Subject: [PATCH 05/34] add to .gitignore a VS2015 file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c2450f75c..4d59cce85 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ Debug Release MinSizeRel RelWithDebInfo +*.VC.opendb # CMake files Makefile From 5796b966bf76716137c74a1eb07c75d7b3a9e9ed Mon Sep 17 00:00:00 2001 From: Christopher Pelloux Date: Tue, 23 Feb 2016 23:40:22 -0500 Subject: [PATCH 06/34] add transparent window support for Windows Vista and up --- examples/gears.c | 1 + src/win32_init.c | 2 ++ src/win32_platform.h | 12 ++++++++++++ src/win32_window.c | 13 +++++++++++++ 4 files changed, 28 insertions(+) diff --git a/examples/gears.c b/examples/gears.c index c5897dcca..7e3ca4391 100644 --- a/examples/gears.c +++ b/examples/gears.c @@ -314,6 +314,7 @@ int main(int argc, char *argv[]) glfwWindowHint(GLFW_DEPTH_BITS, 16); glfwWindowHint(GLFW_ALPHA_BITS, 8); glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE); + glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL ); if (!window) diff --git a/src/win32_init.c b/src/win32_init.c index 57acdb3ae..8029999a1 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -97,6 +97,8 @@ static GLFWbool loadLibraries(void) GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); _glfw.win32.dwmapi.DwmFlush = (DWMFLUSH_T) GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush"); + _glfw.win32.dwmapi.DwmEnableBlurBehindWindow = (DWMENABLEBLURBEHINDWINDOW_T) + GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow"); } _glfw.win32.shcore.instance = LoadLibraryA("shcore.dll"); diff --git a/src/win32_platform.h b/src/win32_platform.h index 47b4999a6..eabf40376 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -120,21 +120,32 @@ typedef enum PROCESS_DPI_AWARENESS } PROCESS_DPI_AWARENESS; #endif /*DPI_ENUMS_DECLARED*/ +typedef struct _DWM_BLURBEHIND +{ + DWORD dwFlags; + BOOL fEnable; + HRGN hRgnBlur; + BOOL fTransitionOnMaximized; +} DWM_BLURBEHIND, *PDWM_BLURBEHIND; + // winmm.dll function pointer typedefs typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T)(UINT,LPJOYCAPS,UINT); typedef MMRESULT (WINAPI * JOYGETPOS_T)(UINT,LPJOYINFO); typedef MMRESULT (WINAPI * JOYGETPOSEX_T)(UINT,LPJOYINFOEX); typedef DWORD (WINAPI * TIMEGETTIME_T)(void); +typedef HRESULT(WINAPI * DWMENABLEBLURBEHINDWINDOW_T)(HWND, const DWM_BLURBEHIND*); #define _glfw_joyGetDevCaps _glfw.win32.winmm.joyGetDevCaps #define _glfw_joyGetPos _glfw.win32.winmm.joyGetPos #define _glfw_joyGetPosEx _glfw.win32.winmm.joyGetPosEx #define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime +#define _glfw_DwmEnableBlurBehindWindow _glfw.win32.dwmapi.DwmEnableBlurBehindWindow // user32.dll function pointer typedefs typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void); typedef BOOL (WINAPI * CHANGEWINDOWMESSAGEFILTEREX_T)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT); #define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware #define _glfw_ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx +#define _glfw_DwmEnableBlurBehindWindow _glfw.win32.dwmapi.DwmEnableBlurBehindWindow // dwmapi.dll function pointer typedefs typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*); @@ -237,6 +248,7 @@ typedef struct _GLFWlibraryWin32 HINSTANCE instance; DWMISCOMPOSITIONENABLED_T DwmIsCompositionEnabled; DWMFLUSH_T DwmFlush; + DWMENABLEBLURBEHINDWINDOW_T DwmEnableBlurBehindWindow; } dwmapi; // shcore.dll diff --git a/src/win32_window.c b/src/win32_window.c index 5bbd04096..13375bdf3 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -732,6 +732,19 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) window->win32.numer = GLFW_DONT_CARE; window->win32.denom = GLFW_DONT_CARE; + // Accelerated transparent windows + // It currently doesn't support decorated windows. + // If decorated is required we just return an opaque window. + // Since DwmEnableBlurBehindWindow is supported since Vista, + // previous versions will simply get an opaque window. + if (!window->decorated && _glfw_DwmEnableBlurBehindWindow && window->transparent) { + DWM_BLURBEHIND bb = { 0 }; + bb.dwFlags = 3; // DWM_BB_ENABLE | DWM_BB_BLURREGION + bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1); // an invalid hRgnBlur makes the the window transparent + bb.fEnable = TRUE; + _glfw_DwmEnableBlurBehindWindow(window->win32.handle, &bb); + } + return GLFW_TRUE; } From 25313317f00578b3b2430a10a4d2cd3aa6b3c681 Mon Sep 17 00:00:00 2001 From: Christopher Pelloux Date: Tue, 1 Mar 2016 15:41:47 -0500 Subject: [PATCH 07/34] add filtering of pixelformat composition for win32 transparent window --- src/wgl_context.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/wgl_context.c b/src/wgl_context.c index afc85bab1..0c3ebfae2 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -133,6 +133,20 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window, { const int n = i + 1; _GLFWfbconfig* u = usableConfigs + usableCount; + PIXELFORMATDESCRIPTOR pfd; + + if (window->transparent) { + if (!DescribePixelFormat(window->context.wgl.dc, + n, + sizeof(PIXELFORMATDESCRIPTOR), + &pfd)) + { + continue; + } + + if (!(pfd.dwFlags & PFD_SUPPORT_COMPOSITION)) + continue; + } if (_glfw.wgl.ARB_pixel_format) { @@ -188,11 +202,9 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window, } else { - PIXELFORMATDESCRIPTOR pfd; - // Get pixel format attributes through legacy PFDs - if (!DescribePixelFormat(window->context.wgl.dc, + if (!window->transparent && !DescribePixelFormat(window->context.wgl.dc, n, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) @@ -239,6 +251,13 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window, u->wgl = n; usableCount++; } + // Reiterate the selection loop without looking for transparency supporting + // formats if no matching pixelformat for a transparent window were found. + if (window->transparent && !usableCount) { + window->transparent = GLFW_FALSE; + free(usableConfigs); + return choosePixelFormat(window, desired, result); + } if (!usableCount) { From fe81dd989902313cc6f38d8088a0b80585f84188 Mon Sep 17 00:00:00 2001 From: Christopher Pelloux Date: Tue, 1 Mar 2016 17:00:55 -0500 Subject: [PATCH 08/34] fix: handle better DwmEnableBlurBehindWindow --- src/wgl_context.c | 22 ++++++++++++++++++++++ src/win32_platform.h | 12 +++++++++--- src/win32_window.c | 13 ------------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/wgl_context.c b/src/wgl_context.c index 0c3ebfae2..9a1fbf423 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -493,6 +493,28 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, } } + if (window->transparent) { + if (!isCompositionEnabled || !_glfw_DwmEnableBlurBehindWindow) { + window->transparent = GLFW_FALSE; + } + else + { + HRESULT hr = S_OK; + + DWM_BLURBEHIND bb = { 0 }; + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1); // makes the window transparent + bb.fEnable = TRUE; + hr = _glfw_DwmEnableBlurBehindWindow(window->win32.handle, &bb); + + if (!SUCCEEDED(hr)) { + window->transparent = GLFW_FALSE; + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to enable blur behind window required for transparency"); + } + } + } + return GLFW_TRUE; } diff --git a/src/win32_platform.h b/src/win32_platform.h index eabf40376..643991a91 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -120,6 +120,12 @@ typedef enum PROCESS_DPI_AWARENESS } PROCESS_DPI_AWARENESS; #endif /*DPI_ENUMS_DECLARED*/ +#if !defined(_DWMAPI_H_) +// Blur behind data structures +#define DWM_BB_ENABLE 0x00000001 // fEnable has been specified +#define DWM_BB_BLURREGION 0x00000002 // hRgnBlur has been specified +#define DWM_BB_TRANSITIONONMAXIMIZED 0x00000004 // fTransitionOnMaximized has been specified + typedef struct _DWM_BLURBEHIND { DWORD dwFlags; @@ -127,31 +133,31 @@ typedef struct _DWM_BLURBEHIND HRGN hRgnBlur; BOOL fTransitionOnMaximized; } DWM_BLURBEHIND, *PDWM_BLURBEHIND; +#endif // winmm.dll function pointer typedefs typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T)(UINT,LPJOYCAPS,UINT); typedef MMRESULT (WINAPI * JOYGETPOS_T)(UINT,LPJOYINFO); typedef MMRESULT (WINAPI * JOYGETPOSEX_T)(UINT,LPJOYINFOEX); typedef DWORD (WINAPI * TIMEGETTIME_T)(void); -typedef HRESULT(WINAPI * DWMENABLEBLURBEHINDWINDOW_T)(HWND, const DWM_BLURBEHIND*); #define _glfw_joyGetDevCaps _glfw.win32.winmm.joyGetDevCaps #define _glfw_joyGetPos _glfw.win32.winmm.joyGetPos #define _glfw_joyGetPosEx _glfw.win32.winmm.joyGetPosEx #define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime -#define _glfw_DwmEnableBlurBehindWindow _glfw.win32.dwmapi.DwmEnableBlurBehindWindow // user32.dll function pointer typedefs typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void); typedef BOOL (WINAPI * CHANGEWINDOWMESSAGEFILTEREX_T)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT); #define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware #define _glfw_ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx -#define _glfw_DwmEnableBlurBehindWindow _glfw.win32.dwmapi.DwmEnableBlurBehindWindow // dwmapi.dll function pointer typedefs typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*); typedef HRESULT (WINAPI * DWMFLUSH_T)(VOID); +typedef HRESULT (WINAPI * DWMENABLEBLURBEHINDWINDOW_T)(HWND, const DWM_BLURBEHIND*); #define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled #define _glfw_DwmFlush _glfw.win32.dwmapi.DwmFlush +#define _glfw_DwmEnableBlurBehindWindow _glfw.win32.dwmapi.DwmEnableBlurBehindWindow // shcore.dll function pointer typedefs typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS); diff --git a/src/win32_window.c b/src/win32_window.c index 13375bdf3..5bbd04096 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -732,19 +732,6 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) window->win32.numer = GLFW_DONT_CARE; window->win32.denom = GLFW_DONT_CARE; - // Accelerated transparent windows - // It currently doesn't support decorated windows. - // If decorated is required we just return an opaque window. - // Since DwmEnableBlurBehindWindow is supported since Vista, - // previous versions will simply get an opaque window. - if (!window->decorated && _glfw_DwmEnableBlurBehindWindow && window->transparent) { - DWM_BLURBEHIND bb = { 0 }; - bb.dwFlags = 3; // DWM_BB_ENABLE | DWM_BB_BLURREGION - bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1); // an invalid hRgnBlur makes the the window transparent - bb.fEnable = TRUE; - _glfw_DwmEnableBlurBehindWindow(window->win32.handle, &bb); - } - return GLFW_TRUE; } From 4ccda807aaeb67f71857e1628132f685e4127c5f Mon Sep 17 00:00:00 2001 From: Christopher Pelloux Date: Thu, 3 Mar 2016 16:33:47 -0500 Subject: [PATCH 09/34] Fix win8+ transparent area not repainting --- examples/gears.c | 9 +++- src/wgl_context.c | 110 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 101 insertions(+), 18 deletions(-) diff --git a/examples/gears.c b/examples/gears.c index 7e3ca4391..1d64e72ca 100644 --- a/examples/gears.c +++ b/examples/gears.c @@ -298,10 +298,17 @@ static void init(void) glEnable(GL_NORMALIZE); } +GLFWerrorfun ErrorFun(int i, const char* str) { + char buf[255]; + sprintf(buf, "%d: %s", i, str); + MessageBoxA(0, buf, "Error", MB_ICONERROR | MB_OK); +} /* program entry */ int main(int argc, char *argv[]) { + glfwSetErrorCallback(ErrorFun); + GLFWwindow* window; int width, height; @@ -314,7 +321,7 @@ int main(int argc, char *argv[]) glfwWindowHint(GLFW_DEPTH_BITS, 16); glfwWindowHint(GLFW_ALPHA_BITS, 8); glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE); - glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); + glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL ); if (!window) diff --git a/src/wgl_context.c b/src/wgl_context.c index 9a1fbf423..ec7d952f5 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -256,6 +256,8 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window, if (window->transparent && !usableCount) { window->transparent = GLFW_FALSE; free(usableConfigs); + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: No pixel format found for transparent window. Ignoring transparency."); return choosePixelFormat(window, desired, result); } @@ -344,6 +346,96 @@ void _glfwTerminateWGL(void) assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \ } +// Reliably check windows version as done in VersionHelpers.h +// needed for transparent window +static inline GLFWbool +isWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 }; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} + +static GLFWbool isWindows8OrGreater() { + GLFWbool isWin8OrGreater = isWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0) ? GLFW_TRUE: GLFW_FALSE; + return isWin8OrGreater; +} + +static GLFWbool setupTransparentWindow(HWND handle, GLFWbool isDecorated) { + if (!isCompositionEnabled) { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Composition needed for transparent window is disabled"); + } + if (!_glfw_DwmEnableBlurBehindWindow) { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Unable to load DwmEnableBlurBehindWindow required for transparent window"); + return GLFW_FALSE; + } + + HRESULT hr = S_OK; + + DWM_BLURBEHIND bb = { 0 }; + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1); // makes the window transparent + bb.fEnable = TRUE; + hr = _glfw_DwmEnableBlurBehindWindow(handle, &bb); + + if (!SUCCEEDED(hr)) { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to enable blur behind window required for transparent window"); + return GLFW_FALSE; + } + + // Decorated windows on Windows 8+ don't repaint the transparent background + // leaving a trail behind animations. + // Hack: making the window layered with a transparency color key seems to fix this. + // Normally, when specifying a transparency color key to be used when composing + // the layered window, all pixels painted by the window in this color will be transparent. + // That doesn't seem to be the case anymore on Windows 8+, at least when used with + // DwmEnableBlurBehindWindow + negative region. + if (isDecorated && isWindows8OrGreater()) { + long style = GetWindowLong(handle, GWL_EXSTYLE); + if (!style) { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to retrieve extended styles. GetLastError: %d", + GetLastError()); + return GLFW_FALSE; + } + style |= WS_EX_LAYERED; + if (!SetWindowLongPtr(handle, GWL_EXSTYLE, style)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to add layered style. GetLastError: %d", + GetLastError()); + return GLFW_FALSE; + } + if (!SetLayeredWindowAttributes(handle, + // Using a color key not equal to black to fix the trailing issue. + // When set to black, something is making the hit test not resize with the + // window frame. + RGB(0, 193, 48), + 255, + LWA_COLORKEY)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "WGL: Failed to set layered window. GetLastError: %d", + GetLastError()); + return GLFW_FALSE; + } + } + return GLFW_TRUE; +} + // Create the OpenGL or OpenGL ES context // GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, @@ -494,25 +586,9 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, } if (window->transparent) { - if (!isCompositionEnabled || !_glfw_DwmEnableBlurBehindWindow) { + if (!setupTransparentWindow(window->win32.handle, window->decorated)) { window->transparent = GLFW_FALSE; } - else - { - HRESULT hr = S_OK; - - DWM_BLURBEHIND bb = { 0 }; - bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; - bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1); // makes the window transparent - bb.fEnable = TRUE; - hr = _glfw_DwmEnableBlurBehindWindow(window->win32.handle, &bb); - - if (!SUCCEEDED(hr)) { - window->transparent = GLFW_FALSE; - _glfwInputError(GLFW_PLATFORM_ERROR, - "WGL: Failed to enable blur behind window required for transparency"); - } - } } return GLFW_TRUE; From a0d82754d58ab1a3060ae325f2fd34bcc397ce64 Mon Sep 17 00:00:00 2001 From: Christopher Pelloux Date: Sat, 5 Mar 2016 10:00:12 -0500 Subject: [PATCH 10/34] cleanup --- examples/gears.c | 8 -------- src/wgl_context.c | 17 +++++++++++------ 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/examples/gears.c b/examples/gears.c index 1d64e72ca..bc667ddea 100644 --- a/examples/gears.c +++ b/examples/gears.c @@ -298,17 +298,9 @@ static void init(void) glEnable(GL_NORMALIZE); } -GLFWerrorfun ErrorFun(int i, const char* str) { - char buf[255]; - sprintf(buf, "%d: %s", i, str); - MessageBoxA(0, buf, "Error", MB_ICONERROR | MB_OK); -} - /* program entry */ int main(int argc, char *argv[]) { - glfwSetErrorCallback(ErrorFun); - GLFWwindow* window; int width, height; diff --git a/src/wgl_context.c b/src/wgl_context.c index ec7d952f5..3a9a42b00 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -366,12 +366,14 @@ isWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServiceP return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; } -static GLFWbool isWindows8OrGreater() { +static GLFWbool isWindows8OrGreater() +{ GLFWbool isWin8OrGreater = isWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0) ? GLFW_TRUE: GLFW_FALSE; return isWin8OrGreater; } -static GLFWbool setupTransparentWindow(HWND handle, GLFWbool isDecorated) { +static GLFWbool setupTransparentWindow(_GLFWwindow* window) +{ if (!isCompositionEnabled) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Composition needed for transparent window is disabled"); @@ -383,6 +385,7 @@ static GLFWbool setupTransparentWindow(HWND handle, GLFWbool isDecorated) { } HRESULT hr = S_OK; + HWND handle = window->win32.handle; DWM_BLURBEHIND bb = { 0 }; bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; @@ -403,7 +406,8 @@ static GLFWbool setupTransparentWindow(HWND handle, GLFWbool isDecorated) { // the layered window, all pixels painted by the window in this color will be transparent. // That doesn't seem to be the case anymore on Windows 8+, at least when used with // DwmEnableBlurBehindWindow + negative region. - if (isDecorated && isWindows8OrGreater()) { + if (window->decorated && isWindows8OrGreater()) + { long style = GetWindowLong(handle, GWL_EXSTYLE); if (!style) { _glfwInputError(GLFW_PLATFORM_ERROR, @@ -433,6 +437,7 @@ static GLFWbool setupTransparentWindow(HWND handle, GLFWbool isDecorated) { return GLFW_FALSE; } } + return GLFW_TRUE; } @@ -585,10 +590,10 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, } } - if (window->transparent) { - if (!setupTransparentWindow(window->win32.handle, window->decorated)) { + if (window->transparent) + { + if (!setupTransparentWindow(window)) window->transparent = GLFW_FALSE; - } } return GLFW_TRUE; From 43f116fa40d5147d66c6392e1eb5690c7497dd93 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 7 Mar 2016 21:17:05 +0100 Subject: [PATCH 11/34] Cleanup --- src/wgl_context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wgl_context.c b/src/wgl_context.c index 3a9a42b00..ccf951d99 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -408,7 +408,7 @@ static GLFWbool setupTransparentWindow(_GLFWwindow* window) // DwmEnableBlurBehindWindow + negative region. if (window->decorated && isWindows8OrGreater()) { - long style = GetWindowLong(handle, GWL_EXSTYLE); + long style = GetWindowLongPtrW(handle, GWL_EXSTYLE); if (!style) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to retrieve extended styles. GetLastError: %d", @@ -416,7 +416,7 @@ static GLFWbool setupTransparentWindow(_GLFWwindow* window) return GLFW_FALSE; } style |= WS_EX_LAYERED; - if (!SetWindowLongPtr(handle, GWL_EXSTYLE, style)) + if (!SetWindowLongPtrW(handle, GWL_EXSTYLE, style)) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to add layered style. GetLastError: %d", From 9ab285f440d0aca1517f077214c0c7bb147259a3 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Fri, 15 Sep 2017 05:29:21 +0700 Subject: [PATCH 12/34] transparent windows for OSX --- examples/CMakeLists.txt | 1 + examples/transparent.c | 170 ++++++++++++++++++++++++++++++++++++++++ include/GLFW/glfw3.h | 6 ++ src/cocoa_window.m | 12 ++- src/context.c | 6 ++ src/internal.h | 3 + src/nsgl_context.m | 6 ++ src/wgl_context.c | 2 + src/window.c | 7 ++ 9 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 examples/transparent.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f7a2ebe43..44ee743c7 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -37,6 +37,7 @@ add_executable(offscreen offscreen.c ${ICON} ${GLAD}) add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD}) add_executable(simple WIN32 MACOSX_BUNDLE simple.c ${ICON} ${GLAD}) add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD}) +add_executable(transparent WIN32 MACOSX_BUNDLE transparent.c ${ICON} ${GLAD}) add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD}) target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}") diff --git a/examples/transparent.c b/examples/transparent.c new file mode 100644 index 000000000..195e95623 --- /dev/null +++ b/examples/transparent.c @@ -0,0 +1,170 @@ +//======================================================================== +// Simple GLFW example +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +//! [code] + +#include +#include + +#include "linmath.h" + +#include +#include + +static const struct +{ + float x, y; + float r, g, b; +} vertices[3] = +{ + { -0.6f, -0.4f, 1.f, 0.f, 0.f }, + { 0.6f, -0.4f, 0.f, 1.f, 0.f }, + { 0.f, 0.6f, 0.f, 0.f, 1.f } +}; + +static const char* vertex_shader_text = +"uniform mat4 MVP;\n" +"attribute vec3 vCol;\n" +"attribute vec2 vPos;\n" +"varying vec3 color;\n" +"void main()\n" +"{\n" +" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n" +" color = vCol;\n" +"}\n"; + +static const char* fragment_shader_text = +"varying vec3 color;\n" +"void main()\n" +"{\n" +" gl_FragColor = vec4(color, 1.0);\n" +"}\n"; + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + glfwSetWindowShouldClose(window, GLFW_TRUE); +} + +int main(void) +{ + GLFWwindow* window; + GLuint vertex_buffer, vertex_shader, fragment_shader, program; + GLint mvp_location, vpos_location, vcol_location; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); + + glfwWindowHint(GLFW_ALPHA_BITS, 8); + glfwWindowHint(GLFW_ALPHA_MASK, GLFW_TRUE); + glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); + + window = glfwCreateWindow(256, 256, "Transparent window example", NULL, NULL); + if (!window) + { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetWindowPos(window, 300, 300); + + glfwSetKeyCallback(window, key_callback); + + glfwMakeContextCurrent(window); + gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); + glfwSwapInterval(1); + + // NOTE: OpenGL error checks have been omitted for brevity + + glGenBuffers(1, &vertex_buffer); + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + vertex_shader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL); + glCompileShader(vertex_shader); + + fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL); + glCompileShader(fragment_shader); + + program = glCreateProgram(); + glAttachShader(program, vertex_shader); + glAttachShader(program, fragment_shader); + glLinkProgram(program); + + mvp_location = glGetUniformLocation(program, "MVP"); + vpos_location = glGetAttribLocation(program, "vPos"); + vcol_location = glGetAttribLocation(program, "vCol"); + + glEnableVertexAttribArray(vpos_location); + glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE, + sizeof(float) * 5, (void*) 0); + glEnableVertexAttribArray(vcol_location); + glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE, + sizeof(float) * 5, (void*) (sizeof(float) * 2)); + + while (!glfwWindowShouldClose(window)) + { + float ratio; + int width, height; + mat4x4 m, p, mvp; + + glfwGetFramebufferSize(window, &width, &height); + ratio = width / (float) height; + + glViewport(0, 0, width, height); + glClearColor(0,0,0,0.5); + glClear(GL_COLOR_BUFFER_BIT); + + mat4x4_identity(m); + mat4x4_rotate_Z(m, m, (float) glfwGetTime()); + mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f); + mat4x4_mul(mvp, p, m); + + glUseProgram(program); + glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glfwDestroyWindow(window); + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + +//! [code] diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 05e76a9ae..1ccee4dfc 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -868,6 +868,12 @@ extern "C" { * Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER). */ #define GLFW_DOUBLEBUFFER 0x00021010 +/*! @brief Context ALPHA Mask hint and attribute. + * + * Context window alpha [hint](@ref GLFW_ALPHA_MASK_hint) and + * [attribute](@ref GLFW_ALPHA_MASK_attrib). + */ +#define GLFW_ALPHA_MASK 0x00021011 /*! @brief Context client API hint and attribute. * * Context client API [hint](@ref GLFW_CLIENT_API_hint) and diff --git a/src/cocoa_window.m b/src/cocoa_window.m index cd4f3f894..3359c31c4 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -413,7 +413,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (BOOL)isOpaque { - return YES; + // Set to NO even if alphaMask is not used; + // The NSView/GLFWContentView does not need to be opaque anyway, + // and to avoid keeping track of alphaMask inside the NSView we + // just return NO here instead. + return NO; } - (BOOL)canBecomeKeyView @@ -1081,6 +1085,12 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, if (wndconfig->ns.retina) [window->ns.view setWantsBestResolutionOpenGLSurface:YES]; + if (wndconfig->alphaMask) + { + [window->ns.object setOpaque:NO]; + [window->ns.object setBackgroundColor:[NSColor clearColor]]; + } + [window->ns.object setContentView:window->ns.view]; [window->ns.object makeFirstResponder:window->ns.view]; [window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]]; diff --git a/src/context.c b/src/context.c index 1a26356e1..4c52d3da1 100644 --- a/src/context.c +++ b/src/context.c @@ -182,6 +182,12 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, continue; } + if (desired->alphaMask > 0 && current->alphaMask == 0) + { + // Alpha mask is a hard constraint + continue; + } + // Count number of missing buffers { missing = 0; diff --git a/src/internal.h b/src/internal.h index a95d1f867..1ee138378 100644 --- a/src/internal.h +++ b/src/internal.h @@ -304,6 +304,7 @@ struct _GLFWwndconfig GLFWbool floating; GLFWbool maximized; GLFWbool centerCursor; + GLFWbool alphaMask; struct { GLFWbool retina; GLFWbool frame; @@ -347,6 +348,7 @@ struct _GLFWfbconfig int redBits; int greenBits; int blueBits; + int alphaMask; int alphaBits; int depthBits; int stencilBits; @@ -405,6 +407,7 @@ struct _GLFWwindow GLFWbool autoIconify; GLFWbool floating; GLFWbool shouldClose; + GLFWbool transparent; void* userPointer; GLFWvidmode videoMode; _GLFWmonitor* monitor; diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 8504f0b97..d75c1f32e 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -296,6 +296,12 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, return GLFW_FALSE; } + if (fbconfig->alphaMask) + { + GLint opaque = 0; + [window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity]; + } + [window->context.nsgl.object setView:window->ns.view]; window->context.makeCurrent = makeContextCurrentNSGL; diff --git a/src/wgl_context.c b/src/wgl_context.c index 1f2b12a50..29f8ba887 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -201,6 +201,8 @@ static int choosePixelFormat(_GLFWwindow* window, } u->handle = n; + // always able to create alpha mask on win + u->alphaMask = desired->alphaMask; usableCount++; } diff --git a/src/window.c b/src/window.c index 5c33217de..34c531033 100644 --- a/src/window.c +++ b/src/window.c @@ -147,11 +147,13 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, fbconfig = _glfw.hints.framebuffer; ctxconfig = _glfw.hints.context; wndconfig = _glfw.hints.window; + fbconfig.alphaMask = _glfw.hints.framebuffer.alphaMask ? GLFW_TRUE : GLFW_FALSE; wndconfig.width = width; wndconfig.height = height; wndconfig.title = title; ctxconfig.share = (_GLFWwindow*) share; + wndconfig.alphaMask = _glfw.hints.framebuffer.alphaMask ? GLFW_TRUE : GLFW_FALSE; if (ctxconfig.share) { @@ -182,6 +184,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->decorated = wndconfig.decorated; window->autoIconify = wndconfig.autoIconify; window->floating = wndconfig.floating; + window->transparent = wndconfig.alphaMask; window->cursorMode = GLFW_CURSOR_NORMAL; window->minwidth = GLFW_DONT_CARE; @@ -262,6 +265,7 @@ void glfwDefaultWindowHints(void) _glfw.hints.framebuffer.depthBits = 24; _glfw.hints.framebuffer.stencilBits = 8; _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE; + _glfw.hints.framebuffer.alphaMask = GLFW_FALSE; // The default is to select the highest available refresh rate _glfw.hints.refreshRate = GLFW_DONT_CARE; @@ -315,6 +319,9 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_DOUBLEBUFFER: _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE; return; + case GLFW_ALPHA_MASK: + _glfw.hints.framebuffer.alphaMask = value; + return; case GLFW_SAMPLES: _glfw.hints.framebuffer.samples = value; return; From a5e83e59fad98c2a7e5244af64e71407c70a69f7 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sat, 16 Sep 2017 15:51:46 +0700 Subject: [PATCH 13/34] Add alphaMask handling to glx_content, allowing X11 to find FBConfigs --- src/glx_context.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/glx_context.c b/src/glx_context.c index e545fa0fe..1a86600f2 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -97,6 +97,8 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE); u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE); + u->alphaMask = getGLXFBConfigAttrib(n, GLX_RGBA); + u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE); u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE); u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE); From 2fbb5268da04f649befbc21b397ac5db3d0e3ab6 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sat, 16 Sep 2017 17:09:09 +0700 Subject: [PATCH 14/34] Transparency on X11 via more precise FBConfig selection --- CMakeLists.txt | 7 ++++++- src/glx_context.c | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 56c1f386d..84d632f28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,7 +241,12 @@ if (_GLFW_X11) # Set up library and include paths list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}") - list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}") + list(APPEND glfw_LIBRARIES "${X11_Xrender_LIB}" "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}") + + # Check for XRender (image composition and pict format querying) + if (NOT X11_Xrender_FOUND) + message(FATAL_ERROR "The XRender headers were not found") + endif() # Check for XRandR (modern resolution switching and gamma control) if (NOT X11_Xrandr_FOUND) diff --git a/src/glx_context.c b/src/glx_context.c index 1a86600f2..169b0f9e9 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -55,6 +55,8 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res int i, nativeCount, usableCount; const char* vendor; GLFWbool trustWindowBit = GLFW_TRUE; + XVisualInfo *visual; + XRenderPictFormat *pict_format; // HACK: This is a (hopefully temporary) workaround for Chromium // (VirtualBox GL) not setting the window bit on any GLXFBConfigs @@ -64,6 +66,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res nativeConfigs = glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount); + if (!nativeConfigs || !nativeCount) { _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned"); @@ -89,6 +92,10 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res continue; } + visual = glXGetVisualFromFBConfig(_glfw.x11.display, n); + pict_format = XRenderFindVisualFormat(_glfw.x11.display, visual->visual); + u->alphaMask = pict_format->direct.alphaMask > 0; + u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE); u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE); u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE); @@ -97,8 +104,6 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE); u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE); - u->alphaMask = getGLXFBConfigAttrib(n, GLX_RGBA); - u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE); u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE); u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE); From 38ad18d145b8f5829a9d9fd0d94161d6315f843e Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sat, 16 Sep 2017 20:40:38 +0700 Subject: [PATCH 15/34] Ignore .vs directory when opening CMake project natively inside VisualStudio --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dd88e65e4..584b7b136 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ Release MinSizeRel RelWithDebInfo *.xcodeproj +.vs # CMake files Makefile From 28dc3b9a4520e97f0bbf64c8964f9c4ba9cd128a Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sat, 16 Sep 2017 20:41:47 +0700 Subject: [PATCH 16/34] Fix windows build: Always assume windows is good at transparent windows --- src/wgl_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wgl_context.c b/src/wgl_context.c index 29f8ba887..b28d7255e 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -202,7 +202,7 @@ static int choosePixelFormat(_GLFWwindow* window, u->handle = n; // always able to create alpha mask on win - u->alphaMask = desired->alphaMask; + u->alphaMask = 1; usableCount++; } From 4881f0b3aec3472014036de4303f8262952892be Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sat, 16 Sep 2017 20:50:16 +0700 Subject: [PATCH 17/34] Transparent demo building on windows --- examples/CMakeLists.txt | 2 +- examples/transparent.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 44ee743c7..8eb32bbcc 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -45,7 +45,7 @@ if (RT_LIBRARY) target_link_libraries(particles "${RT_LIBRARY}") endif() -set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave) +set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave transparent) set(CONSOLE_BINARIES offscreen) set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES diff --git a/examples/transparent.c b/examples/transparent.c index 195e95623..de795c93f 100644 --- a/examples/transparent.c +++ b/examples/transparent.c @@ -72,7 +72,8 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, glfwSetWindowShouldClose(window, GLFW_TRUE); } -int main(void) +/* program entry */ +int main(int argc, char *argv[]) { GLFWwindow* window; GLuint vertex_buffer, vertex_shader, fragment_shader, program; From 7a9e8d5c3b3ffbb7cd0b67bfbd278aeb8294590f Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sat, 16 Sep 2017 22:25:01 +0700 Subject: [PATCH 18/34] Rename hint to GLFW_TRANSPARENT to play better with others --- examples/transparent.c | 2 +- include/GLFW/glfw3.h | 6 +++--- src/window.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/transparent.c b/examples/transparent.c index de795c93f..098e50ad7 100644 --- a/examples/transparent.c +++ b/examples/transparent.c @@ -88,7 +88,7 @@ int main(int argc, char *argv[]) glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_ALPHA_BITS, 8); - glfwWindowHint(GLFW_ALPHA_MASK, GLFW_TRUE); + glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE); glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); window = glfwCreateWindow(256, 256, "Transparent window example", NULL, NULL); diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 1ccee4dfc..131f20795 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -870,10 +870,10 @@ extern "C" { #define GLFW_DOUBLEBUFFER 0x00021010 /*! @brief Context ALPHA Mask hint and attribute. * - * Context window alpha [hint](@ref GLFW_ALPHA_MASK_hint) and - * [attribute](@ref GLFW_ALPHA_MASK_attrib). + * Context window alpha [hint](@ref GLFW_TRANSPARENT_hint) and + * [attribute](@ref GLFW_TRANSPARENT_attrib). */ -#define GLFW_ALPHA_MASK 0x00021011 +#define GLFW_TRANSPARENT 0x00021011 /*! @brief Context client API hint and attribute. * * Context client API [hint](@ref GLFW_CLIENT_API_hint) and diff --git a/src/window.c b/src/window.c index 34c531033..de6fc568e 100644 --- a/src/window.c +++ b/src/window.c @@ -319,7 +319,7 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_DOUBLEBUFFER: _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE; return; - case GLFW_ALPHA_MASK: + case GLFW_TRANSPARENT: _glfw.hints.framebuffer.alphaMask = value; return; case GLFW_SAMPLES: From 40de269e91c7a365ede6bc8ee639d62f727b0058 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 00:03:35 +0700 Subject: [PATCH 19/34] Merge fixes for transparent WGL/DWM from transparent-windows --- src/internal.h | 1 - src/wgl_context.c | 57 ++++++++--------------------------------------- 2 files changed, 9 insertions(+), 49 deletions(-) diff --git a/src/internal.h b/src/internal.h index 35ffc8ece..826296674 100644 --- a/src/internal.h +++ b/src/internal.h @@ -409,7 +409,6 @@ struct _GLFWwindow GLFWbool autoIconify; GLFWbool floating; GLFWbool shouldClose; - GLFWbool transparent; void* userPointer; GLFWvidmode videoMode; _GLFWmonitor* monitor; diff --git a/src/wgl_context.c b/src/wgl_context.c index af7416d01..867ecd60d 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -224,7 +224,7 @@ static int choosePixelFormat(_GLFWwindow* window, free(usableConfigs); _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: No pixel format found for transparent window. Ignoring transparency."); - return choosePixelFormat(window, desired, result); + return choosePixelFormat(window, ctxconfig, fbconfig); } if (!usableCount) @@ -535,7 +535,7 @@ static GLFWbool isWindows8OrGreater() static GLFWbool setupTransparentWindow(_GLFWwindow* window) { - if (!isCompositionEnabled) { + if (!DwmIsCompositionEnabled) { _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Composition needed for transparent window is disabled"); } @@ -783,53 +783,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, ctxconfig->minor); } } - else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB)) { - // TODO: _glfwInputError - } - } - } + else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB)) - if (window->transparent) - { - if (!setupTransparentWindow(window)) - window->transparent = GLFW_FALSE; - } - - return GLFW_TRUE; -} - -#undef setWGLattrib - -// Destroy the OpenGL context -// -void _glfwDestroyContextWGL(_GLFWwindow* window) -{ - if (window->context.wgl.handle) - { - wglDeleteContext(window->context.wgl.handle); - window->context.wgl.handle = NULL; - } -} - -// Analyzes the specified context for possible recreation -// -int _glfwAnalyzeContextWGL(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) -{ - GLFWbool required = GLFW_FALSE; - - if (_glfw.wgl.extensionsLoaded) - return _GLFW_RECREATION_NOT_NEEDED; - - _glfwPlatformMakeContextCurrent(window); - loadExtensions(); - - if (ctxconfig->api == GLFW_OPENGL_API) - { - if (ctxconfig->forward) - { - if (!_glfw.wgl.ARB_create_context) { _glfwInputError(GLFW_VERSION_UNAVAILABLE, "WGL: Driver does not support the requested OpenGL profile"); @@ -877,6 +832,12 @@ int _glfwAnalyzeContextWGL(_GLFWwindow* window, } } + if (window->transparent) + { + if (!setupTransparentWindow(window)) + window->transparent = GLFW_FALSE; + } + window->context.makeCurrent = makeContextCurrentWGL; window->context.swapBuffers = swapBuffersWGL; window->context.swapInterval = swapIntervalWGL; From 98563d8d4bfed9336ab09768d3d83edf04fe1711 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 00:31:41 +0700 Subject: [PATCH 20/34] Merge fixes for X11 --- src/glx_context.c | 6 +-- src/x11_init.c | 128 ++++++++++++++++++++++------------------------ src/x11_window.c | 4 +- 3 files changed, 67 insertions(+), 71 deletions(-) diff --git a/src/glx_context.c b/src/glx_context.c index 96e706d1a..546321826 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -120,9 +120,9 @@ selectionloop: XFree( visualinfo ); } - u->redBits = getFBConfigAttrib(n, GLX_RED_SIZE); - u->greenBits = getFBConfigAttrib(n, GLX_GREEN_SIZE); - u->blueBits = getFBConfigAttrib(n, GLX_BLUE_SIZE); + u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE); + u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE); + u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE); u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE); u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE); diff --git a/src/x11_init.c b/src/x11_init.c index 0597a9162..ee25adc20 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -480,7 +480,8 @@ static GLFWbool initExtensions(void) } _glfw.x11.xi.handle = dlopen("libXi.so.6", RTLD_LAZY | RTLD_GLOBAL); - if (_glfw.x11.xi.handle) + + if (_glfw.x11.xi.handle) { _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion) dlsym(_glfw.x11.xi.handle, "XIQueryVersion"); @@ -505,72 +506,68 @@ static GLFWbool initExtensions(void) } } - // Check for RandR extension - if (XRRQueryExtension(_glfw.x11.display, - &_glfw.x11.randr.eventBase, - &_glfw.x11.randr.errorBase)) { + // Check for RandR extension + _glfw.x11.randr.handle = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_GLOBAL); - _glfw.x11.randr.handle = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_GLOBAL); - - if (_glfw.x11.randr.handle) - { - _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma) - dlsym(_glfw.x11.randr.handle, "XRRAllocGamma"); - _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma) - dlsym(_glfw.x11.randr.handle, "XRRFreeGamma"); - _glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo) - dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo"); - _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma) - dlsym(_glfw.x11.randr.handle, "XRRFreeGamma"); - _glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo) - dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo"); - _glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources) - dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources"); - _glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma) - dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma"); - _glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize) - dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize"); - _glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo) - dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo"); - _glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo) - dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo"); - _glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary) - dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary"); - _glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent) - dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent"); - _glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension) - dlsym(_glfw.x11.randr.handle, "XRRQueryExtension"); - _glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion) - dlsym(_glfw.x11.randr.handle, "XRRQueryVersion"); - _glfw.x11.randr.SelectInput = (PFN_XRRSelectInput) - dlsym(_glfw.x11.randr.handle, "XRRSelectInput"); - _glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig) - dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig"); - _glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma) - dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma"); - _glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration) - dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration"); + if (_glfw.x11.randr.handle) + { + _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma) + dlsym(_glfw.x11.randr.handle, "XRRAllocGamma"); + _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma) + dlsym(_glfw.x11.randr.handle, "XRRFreeGamma"); + _glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo) + dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo"); + _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma) + dlsym(_glfw.x11.randr.handle, "XRRFreeGamma"); + _glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo) + dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo"); + _glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources) + dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources"); + _glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma) + dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma"); + _glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize) + dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize"); + _glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo) + dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo"); + _glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo) + dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo"); + _glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary) + dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary"); + _glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent) + dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent"); + _glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension) + dlsym(_glfw.x11.randr.handle, "XRRQueryExtension"); + _glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion) + dlsym(_glfw.x11.randr.handle, "XRRQueryVersion"); + _glfw.x11.randr.SelectInput = (PFN_XRRSelectInput) + dlsym(_glfw.x11.randr.handle, "XRRSelectInput"); + _glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig) + dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig"); + _glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma) + dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma"); + _glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration) + dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration"); + + if (XRRQueryExtension(_glfw.x11.display, + &_glfw.x11.randr.eventBase, + &_glfw.x11.randr.errorBase)) + { + if (XRRQueryVersion(_glfw.x11.display, + &_glfw.x11.randr.major, + &_glfw.x11.randr.minor)) + { + // The GLFW RandR path requires at least version 1.3 + if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3) + _glfw.x11.randr.available = GLFW_TRUE; + } + else + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "X11: Failed to query RandR version"); + } + } + } - if (XRRQueryExtension(_glfw.x11.display, - &_glfw.x11.randr.eventBase, - &_glfw.x11.randr.errorBase)) - { - if (XRRQueryVersion(_glfw.x11.display, - &_glfw.x11.randr.major, - &_glfw.x11.randr.minor)) - { - // The GLFW RandR path requires at least version 1.3 - if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3) - _glfw.x11.randr.available = GLFW_TRUE; - } - else - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "X11: Failed to query RandR version"); - } - } - } - } if (_glfw.x11.randr.available) { XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, @@ -1056,4 +1053,3 @@ const char* _glfwPlatformGetVersionString(void) #endif ; } - diff --git a/src/x11_window.c b/src/x11_window.c index cdc57e736..759435c34 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1808,14 +1808,14 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, { if (!_glfwInitGLX()) return GLFW_FALSE; - if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth)) + if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth)) return GLFW_FALSE; } else if (ctxconfig->source == GLFW_EGL_CONTEXT_API) { if (!_glfwInitEGL()) return GLFW_FALSE; - if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth)) + if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth)) return GLFW_FALSE; } else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API) From 1d44ad152e8f7efa0b7b8742e227a20b046150f3 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 00:49:42 +0700 Subject: [PATCH 21/34] Renaming alphaMask flag to 'transparent' for consistency --- src/context.c | 6 ------ src/egl_context.c | 4 ++-- src/glx_context.c | 35 +++++++++++++++++++++-------------- src/internal.h | 3 +-- src/wgl_context.c | 6 ++++-- src/window.c | 9 ++++----- 6 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/context.c b/src/context.c index 4c52d3da1..1a26356e1 100644 --- a/src/context.c +++ b/src/context.c @@ -182,12 +182,6 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired, continue; } - if (desired->alphaMask > 0 && current->alphaMask == 0) - { - // Alpha mask is a hard constraint - continue; - } - // Count number of missing buffers { missing = 0; diff --git a/src/egl_context.c b/src/egl_context.c index 820407e97..8c0fae1c4 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -492,7 +492,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, if (ctxconfig->share) share = ctxconfig->share->context.egl.handle; - if (!chooseEGLConfig(ctxconfig, fbconfig, &config, fbconfig->alphaMask)) + if (!chooseEGLConfig(ctxconfig, fbconfig, &config, fbconfig->transparent)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Failed to find a suitable EGLConfig"); @@ -738,7 +738,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, const long vimask = VisualScreenMask | VisualIDMask; - if (!chooseEGLConfig(ctxconfig, fbconfig, &native, wndconfig->alphaMask)) + if (!chooseEGLConfig(ctxconfig, fbconfig, &native, wndconfig->transparent)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Failed to find a suitable EGLConfig"); diff --git a/src/glx_context.c b/src/glx_context.c index 546321826..6a82463f4 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -64,6 +64,8 @@ static GLFWbool chooseGLXFBConfig( findTransparent = GLFW_FALSE; } + findTransparent = GLFW_TRUE; + // HACK: This is a (hopefully temporary) workaround for Chromium // (VirtualBox GL) not setting the window bit on any GLXFBConfigs vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR); @@ -81,7 +83,7 @@ static GLFWbool chooseGLXFBConfig( usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableCount = 0; - + selectionloop: for (i = 0; i < nativeCount; i++) { @@ -99,25 +101,31 @@ selectionloop: continue; } - if( findTransparent ) { + if( findTransparent ) { XVisualInfo *visualinfo; XRenderPictFormat *pictFormat; - visualinfo = glXGetVisualFromFBConfig(_glfw.x11.display, n); - if (!visualinfo) - continue; + visualinfo = glXGetVisualFromFBConfig(_glfw.x11.display, n); + if (!visualinfo) { + printf("!visualinfo: bail\n"); + continue; + } pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual); if( !pictFormat ) { - XFree( visualinfo ); - continue; - } + printf("!pictFormat: bail\n"); + XFree( visualinfo ); + continue; + } if( !pictFormat->direct.alphaMask ) { - XFree( visualinfo ); - continue; - } - XFree( visualinfo ); + printf("!pictFormat->direct alphaMask: bail\n"); + XFree( visualinfo ); + continue; + } + + printf("looking for transparent visual: didn't find\n"); + XFree( visualinfo ); } u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE); @@ -150,7 +158,7 @@ selectionloop: usableCount++; } // reiterate the selection loop without looking for transparency supporting - // formats if no matchig FB configs for a transparent window were found. + // formats if no matchig FB configs for a transparent window were found. if( findTransparent && !usableCount ) { findTransparent = GLFW_FALSE; goto selectionloop; @@ -722,4 +730,3 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle) return window->context.glx.window; } - diff --git a/src/internal.h b/src/internal.h index 826296674..54f8fa355 100644 --- a/src/internal.h +++ b/src/internal.h @@ -305,7 +305,6 @@ struct _GLFWwndconfig GLFWbool floating; GLFWbool maximized; GLFWbool centerCursor; - GLFWbool alphaMask; struct { GLFWbool retina; GLFWbool frame; @@ -349,7 +348,7 @@ struct _GLFWfbconfig int redBits; int greenBits; int blueBits; - int alphaMask; + int transparent; int alphaBits; int depthBits; int stencilBits; diff --git a/src/wgl_context.c b/src/wgl_context.c index 867ecd60d..1be457209 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -213,8 +213,10 @@ static int choosePixelFormat(_GLFWwindow* window, } u->handle = n; - // always able to create alpha mask on win - u->alphaMask = 1; + + // always able to go transparent on win dwmapi + u->transparent = 1; + usableCount++; } // Reiterate the selection loop without looking for transparency supporting diff --git a/src/window.c b/src/window.c index 625e2523b..7ee2b8c97 100644 --- a/src/window.c +++ b/src/window.c @@ -147,13 +147,13 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, fbconfig = _glfw.hints.framebuffer; ctxconfig = _glfw.hints.context; wndconfig = _glfw.hints.window; - fbconfig.alphaMask = _glfw.hints.framebuffer.alphaMask ? GLFW_TRUE : GLFW_FALSE; + fbconfig.transparent = _glfw.hints.framebuffer.transparent ? GLFW_TRUE : GLFW_FALSE; wndconfig.width = width; wndconfig.height = height; wndconfig.title = title; ctxconfig.share = (_GLFWwindow*) share; - wndconfig.alphaMask = _glfw.hints.framebuffer.alphaMask ? GLFW_TRUE : GLFW_FALSE; + wndconfig.transparent = _glfw.hints.framebuffer.transparent ? GLFW_TRUE : GLFW_FALSE; if (ctxconfig.share) { @@ -185,7 +185,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->transparent = wndconfig.transparent; window->autoIconify = wndconfig.autoIconify; window->floating = wndconfig.floating; - window->transparent = wndconfig.alphaMask; window->cursorMode = GLFW_CURSOR_NORMAL; window->minwidth = GLFW_DONT_CARE; @@ -267,7 +266,7 @@ void glfwDefaultWindowHints(void) _glfw.hints.framebuffer.depthBits = 24; _glfw.hints.framebuffer.stencilBits = 8; _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE; - _glfw.hints.framebuffer.alphaMask = GLFW_FALSE; + _glfw.hints.framebuffer.transparent = GLFW_FALSE; // The default is to select the highest available refresh rate _glfw.hints.refreshRate = GLFW_DONT_CARE; @@ -322,7 +321,7 @@ GLFWAPI void glfwWindowHint(int hint, int value) _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE; return; case GLFW_TRANSPARENT: - _glfw.hints.framebuffer.alphaMask = value; + _glfw.hints.framebuffer.transparent = value; return; case GLFW_SAMPLES: _glfw.hints.framebuffer.samples = value; From 817b697b7ca82270a90e378ae55cda618046c4f6 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 01:08:07 +0700 Subject: [PATCH 22/34] Fix cocoa window usage to new transparent flag --- src/cocoa_window.m | 4 ++-- src/nsgl_context.m | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 3359c31c4..9c48ee361 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -413,7 +413,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; - (BOOL)isOpaque { - // Set to NO even if alphaMask is not used; + // Set to NO even if transparent is not used; // The NSView/GLFWContentView does not need to be opaque anyway, // and to avoid keeping track of alphaMask inside the NSView we // just return NO here instead. @@ -1085,7 +1085,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, if (wndconfig->ns.retina) [window->ns.view setWantsBestResolutionOpenGLSurface:YES]; - if (wndconfig->alphaMask) + if (wndconfig->transparent) { [window->ns.object setOpaque:NO]; [window->ns.object setBackgroundColor:[NSColor clearColor]]; diff --git a/src/nsgl_context.m b/src/nsgl_context.m index d75c1f32e..a7cbf00f3 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -296,7 +296,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, return GLFW_FALSE; } - if (fbconfig->alphaMask) + if (fbconfig->transparent) { GLint opaque = 0; [window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity]; From 88b4ada658ff312864ede6746b30e87b9317347f Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 02:23:27 +0700 Subject: [PATCH 23/34] Update visual/depth initialization to that of master instead of transparent-windows branch --- src/x11_window.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index 759435c34..a7b672624 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1828,14 +1828,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, if (ctxconfig->client == GLFW_NO_API || ctxconfig->source == GLFW_OSMESA_CONTEXT_API) { - -#if defined(_GLFW_GLX) - if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth)) - return GLFW_FALSE; -#elif defined(_GLFW_EGL) - if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth)) - return GLFW_FALSE; -#endif + visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen); + depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen); } if (!createNativeWindow(window, wndconfig, visual, depth)) From 4c4174b7330060ff408448aace59d596c3443b9a Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 02:26:46 +0700 Subject: [PATCH 24/34] Cleanup: comments and CmakeLists.txt --- CMakeLists.txt | 7 +------ include/GLFW/glfw3.h | 4 ++-- src/glx_context.c | 4 ---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84d632f28..56c1f386d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -241,12 +241,7 @@ if (_GLFW_X11) # Set up library and include paths list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}") - list(APPEND glfw_LIBRARIES "${X11_Xrender_LIB}" "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}") - - # Check for XRender (image composition and pict format querying) - if (NOT X11_Xrender_FOUND) - message(FATAL_ERROR "The XRender headers were not found") - endif() + list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}") # Check for XRandR (modern resolution switching and gamma control) if (NOT X11_Xrandr_FOUND) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index b236d7d8f..a82da57e9 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -869,9 +869,9 @@ extern "C" { * Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER). */ #define GLFW_DOUBLEBUFFER 0x00021010 -/*! @brief Context ALPHA Mask hint and attribute. +/*! @brief Window transparency hint and attribute. * - * Context window alpha [hint](@ref GLFW_TRANSPARENT_hint) and + * Context window transparency [hint](@ref GLFW_TRANSPARENT_hint) and * [attribute](@ref GLFW_TRANSPARENT_attrib). */ #define GLFW_TRANSPARENT 0x00021011 diff --git a/src/glx_context.c b/src/glx_context.c index 6a82463f4..b2ca4ac01 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -107,24 +107,20 @@ selectionloop: visualinfo = glXGetVisualFromFBConfig(_glfw.x11.display, n); if (!visualinfo) { - printf("!visualinfo: bail\n"); continue; } pictFormat = XRenderFindVisualFormat(_glfw.x11.display, visualinfo->visual); if( !pictFormat ) { - printf("!pictFormat: bail\n"); XFree( visualinfo ); continue; } if( !pictFormat->direct.alphaMask ) { - printf("!pictFormat->direct alphaMask: bail\n"); XFree( visualinfo ); continue; } - printf("looking for transparent visual: didn't find\n"); XFree( visualinfo ); } From 2422d25f9e794ffb4a539bdbaca6bc39377bb7a5 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 14:10:51 +0700 Subject: [PATCH 25/34] Remove c++ style inline keyword for support on older MSVC compilers --- src/wgl_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wgl_context.c b/src/wgl_context.c index 1be457209..5c5d90bd7 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -511,7 +511,7 @@ void _glfwTerminateWGL(void) // Reliably check windows version as done in VersionHelpers.h // needed for transparent window -static inline GLFWbool +static GLFWbool isWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) { OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0,{ 0 }, 0, 0 }; From 838630cecdf8f81682d6fe1b18de17f790c46c7a Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 14:13:20 +0700 Subject: [PATCH 26/34] After merging #723, transparent demo is redundant as gears demo does the same thing --- examples/CMakeLists.txt | 3 +- examples/transparent.c | 171 ---------------------------------------- 2 files changed, 1 insertion(+), 173 deletions(-) delete mode 100644 examples/transparent.c diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 8eb32bbcc..f7a2ebe43 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -37,7 +37,6 @@ add_executable(offscreen offscreen.c ${ICON} ${GLAD}) add_executable(particles WIN32 MACOSX_BUNDLE particles.c ${ICON} ${TINYCTHREAD} ${GETOPT} ${GLAD}) add_executable(simple WIN32 MACOSX_BUNDLE simple.c ${ICON} ${GLAD}) add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD}) -add_executable(transparent WIN32 MACOSX_BUNDLE transparent.c ${ICON} ${GLAD}) add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD}) target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}") @@ -45,7 +44,7 @@ if (RT_LIBRARY) target_link_libraries(particles "${RT_LIBRARY}") endif() -set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave transparent) +set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave) set(CONSOLE_BINARIES offscreen) set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES diff --git a/examples/transparent.c b/examples/transparent.c deleted file mode 100644 index 098e50ad7..000000000 --- a/examples/transparent.c +++ /dev/null @@ -1,171 +0,0 @@ -//======================================================================== -// Simple GLFW example -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -//! [code] - -#include -#include - -#include "linmath.h" - -#include -#include - -static const struct -{ - float x, y; - float r, g, b; -} vertices[3] = -{ - { -0.6f, -0.4f, 1.f, 0.f, 0.f }, - { 0.6f, -0.4f, 0.f, 1.f, 0.f }, - { 0.f, 0.6f, 0.f, 0.f, 1.f } -}; - -static const char* vertex_shader_text = -"uniform mat4 MVP;\n" -"attribute vec3 vCol;\n" -"attribute vec2 vPos;\n" -"varying vec3 color;\n" -"void main()\n" -"{\n" -" gl_Position = MVP * vec4(vPos, 0.0, 1.0);\n" -" color = vCol;\n" -"}\n"; - -static const char* fragment_shader_text = -"varying vec3 color;\n" -"void main()\n" -"{\n" -" gl_FragColor = vec4(color, 1.0);\n" -"}\n"; - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error: %s\n", description); -} - -static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) -{ - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) - glfwSetWindowShouldClose(window, GLFW_TRUE); -} - -/* program entry */ -int main(int argc, char *argv[]) -{ - GLFWwindow* window; - GLuint vertex_buffer, vertex_shader, fragment_shader, program; - GLint mvp_location, vpos_location, vcol_location; - - glfwSetErrorCallback(error_callback); - - if (!glfwInit()) - exit(EXIT_FAILURE); - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); - - glfwWindowHint(GLFW_ALPHA_BITS, 8); - glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE); - glfwWindowHint(GLFW_DECORATED, GLFW_TRUE); - - window = glfwCreateWindow(256, 256, "Transparent window example", NULL, NULL); - if (!window) - { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwSetWindowPos(window, 300, 300); - - glfwSetKeyCallback(window, key_callback); - - glfwMakeContextCurrent(window); - gladLoadGLLoader((GLADloadproc) glfwGetProcAddress); - glfwSwapInterval(1); - - // NOTE: OpenGL error checks have been omitted for brevity - - glGenBuffers(1, &vertex_buffer); - glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - vertex_shader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertex_shader, 1, &vertex_shader_text, NULL); - glCompileShader(vertex_shader); - - fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment_shader, 1, &fragment_shader_text, NULL); - glCompileShader(fragment_shader); - - program = glCreateProgram(); - glAttachShader(program, vertex_shader); - glAttachShader(program, fragment_shader); - glLinkProgram(program); - - mvp_location = glGetUniformLocation(program, "MVP"); - vpos_location = glGetAttribLocation(program, "vPos"); - vcol_location = glGetAttribLocation(program, "vCol"); - - glEnableVertexAttribArray(vpos_location); - glVertexAttribPointer(vpos_location, 2, GL_FLOAT, GL_FALSE, - sizeof(float) * 5, (void*) 0); - glEnableVertexAttribArray(vcol_location); - glVertexAttribPointer(vcol_location, 3, GL_FLOAT, GL_FALSE, - sizeof(float) * 5, (void*) (sizeof(float) * 2)); - - while (!glfwWindowShouldClose(window)) - { - float ratio; - int width, height; - mat4x4 m, p, mvp; - - glfwGetFramebufferSize(window, &width, &height); - ratio = width / (float) height; - - glViewport(0, 0, width, height); - glClearColor(0,0,0,0.5); - glClear(GL_COLOR_BUFFER_BIT); - - mat4x4_identity(m); - mat4x4_rotate_Z(m, m, (float) glfwGetTime()); - mat4x4_ortho(p, -ratio, ratio, -1.f, 1.f, 1.f, -1.f); - mat4x4_mul(mvp, p, m); - - glUseProgram(program); - glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat*) mvp); - glDrawArrays(GL_TRIANGLES, 0, 3); - - glfwSwapBuffers(window); - glfwPollEvents(); - } - - glfwDestroyWindow(window); - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - -//! [code] From 0f98e188d23e9f32237a9b09778942cfeb74b208 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 15:06:01 +0700 Subject: [PATCH 27/34] Update documentation for framebuffer hint: GLFW_TRANSPARENT --- docs/window.dox | 4 ++++ include/GLFW/glfw3.h | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/window.dox b/docs/window.dox index d9a837f63..30b426206 100644 --- a/docs/window.dox +++ b/docs/window.dox @@ -228,6 +228,10 @@ newly created full screen windows. Possible values are `GLFW_TRUE` and @subsubsection window_hints_fb Framebuffer related hints +@anchor GLFW_TRANSPARENT_hint +__GLFW_TRANSPARENT__ specifies whether the framebuffer will support transparency +in the background. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. + @anchor GLFW_RED_BITS @anchor GLFW_GREEN_BITS @anchor GLFW_BLUE_BITS diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index a82da57e9..e1f1e8a43 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -869,10 +869,9 @@ extern "C" { * Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER). */ #define GLFW_DOUBLEBUFFER 0x00021010 -/*! @brief Window transparency hint and attribute. +/*! @brief Framebuffer transparency hint. * - * Context window transparency [hint](@ref GLFW_TRANSPARENT_hint) and - * [attribute](@ref GLFW_TRANSPARENT_attrib). + * Framebuffer transparency [hint](@ref GLFW_TRANSPARENT_hint). */ #define GLFW_TRANSPARENT 0x00021011 /*! @brief Context client API hint and attribute. From b8157fea5d097c329b8c80a083bb836c85430391 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 21:39:11 +0700 Subject: [PATCH 28/34] Cleanup wndconfig usage. After merging with glfw:transparent, it seems transparent flags are passed around on both fbconfig and wndconfig. This has caused the need to change method signature of a few internal apis. This commit safely removes that redundancy. --- src/cocoa_window.m | 2 +- src/egl_context.c | 5 ++--- src/egl_context.h | 3 +-- src/glx_context.c | 13 ++++++------- src/glx_context.h | 3 +-- src/internal.h | 1 - src/wgl_context.c | 12 ++++++------ src/window.c | 3 --- src/x11_window.c | 4 ++-- 9 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 9c48ee361..b51e36d80 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1085,7 +1085,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, if (wndconfig->ns.retina) [window->ns.view setWantsBestResolutionOpenGLSurface:YES]; - if (wndconfig->transparent) + if (_glfw.hints.framebuffer->transparent) { [window->ns.object setOpaque:NO]; [window->ns.object setBackgroundColor:[NSColor clearColor]]; diff --git a/src/egl_context.c b/src/egl_context.c index 8c0fae1c4..70ec35c38 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -726,8 +726,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, // Returns the Visual and depth of the chosen EGLConfig // #if defined(_GLFW_X11) -GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, +GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth) { @@ -738,7 +737,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, const long vimask = VisualScreenMask | VisualIDMask; - if (!chooseEGLConfig(ctxconfig, fbconfig, &native, wndconfig->transparent)) + if (!chooseEGLConfig(ctxconfig, fbconfig, &native, fbconfig->transparent)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Failed to find a suitable EGLConfig"); diff --git a/src/egl_context.h b/src/egl_context.h index aa339baac..bfab5111f 100644 --- a/src/egl_context.h +++ b/src/egl_context.h @@ -211,8 +211,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); #if defined(_GLFW_X11) -GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, +GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth); #endif /*_GLFW_X11*/ diff --git a/src/glx_context.c b/src/glx_context.c index b2ca4ac01..fdc97bb8e 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -283,7 +283,7 @@ static void destroyContextGLX(_GLFWwindow* window) GLFWbool _glfwInitGLX(void) { int i; - const char* sonames_glx[] = + const char* sonames[] = { #if defined(_GLFW_GLX_LIBRARY) _GLFW_GLX_LIBRARY, @@ -299,9 +299,9 @@ GLFWbool _glfwInitGLX(void) if (_glfw.glx.handle) return GLFW_TRUE; - for (i = 0; sonames_glx[i]; i++) + for (i = 0; sonames[i]; i++) { - _glfw.glx.handle = dlopen(sonames_glx[i], RTLD_LAZY | RTLD_GLOBAL); + _glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL); if (_glfw.glx.handle) break; } @@ -664,15 +664,14 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, // Returns the Visual and depth of the chosen GLXFBConfig // -GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, +GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth) { GLXFBConfig native; XVisualInfo* result; - if (!chooseGLXFBConfig(fbconfig, &native, wndconfig->transparent)) + if (!chooseGLXFBConfig(fbconfig, &native, fbconfig->transparent)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "GLX: Failed to find a suitable GLXFBConfig"); @@ -688,7 +687,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, } *visual = result->visual; - *depth = result->depth; + *depth = result->depth; XFree(result); return GLFW_TRUE; diff --git a/src/glx_context.h b/src/glx_context.h index 27635d42d..a8cdf7398 100644 --- a/src/glx_context.h +++ b/src/glx_context.h @@ -174,8 +174,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); void _glfwDestroyContextGLX(_GLFWwindow* window); -GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, - const _GLFWctxconfig* ctxconfig, +GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth); diff --git a/src/internal.h b/src/internal.h index 54f8fa355..fab544df8 100644 --- a/src/internal.h +++ b/src/internal.h @@ -299,7 +299,6 @@ struct _GLFWwndconfig GLFWbool resizable; GLFWbool visible; GLFWbool decorated; - GLFWbool transparent; GLFWbool focused; GLFWbool autoIconify; GLFWbool floating; diff --git a/src/wgl_context.c b/src/wgl_context.c index 5c5d90bd7..278a38008 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -85,7 +85,7 @@ static int choosePixelFormat(_GLFWwindow* window, _GLFWfbconfig* u = usableConfigs + usableCount; PIXELFORMATDESCRIPTOR pfd; - if (window->transparent) { + if (fbconfig->transparent) { if (!DescribePixelFormat(window->context.wgl.dc, n, sizeof(PIXELFORMATDESCRIPTOR), @@ -168,7 +168,7 @@ static int choosePixelFormat(_GLFWwindow* window, { // Get pixel format attributes through legacy PFDs - if (!window->transparent && !DescribePixelFormat(window->context.wgl.dc, + if (!fbconfig->transparent && !DescribePixelFormat(window->context.wgl.dc, n, sizeof(PIXELFORMATDESCRIPTOR), &pfd)) @@ -221,8 +221,8 @@ static int choosePixelFormat(_GLFWwindow* window, } // Reiterate the selection loop without looking for transparency supporting // formats if no matching pixelformat for a transparent window were found. - if (window->transparent && !usableCount) { - window->transparent = GLFW_FALSE; + if (fbconfig->transparent && !usableCount) { + fbconfig->transparent = GLFW_FALSE; free(usableConfigs); _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: No pixel format found for transparent window. Ignoring transparency."); @@ -834,10 +834,10 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, } } - if (window->transparent) + if (fbconfig->transparent) { if (!setupTransparentWindow(window)) - window->transparent = GLFW_FALSE; + fbconfig->transparent = GLFW_FALSE; } window->context.makeCurrent = makeContextCurrentWGL; diff --git a/src/window.c b/src/window.c index 7ee2b8c97..5af847d1c 100644 --- a/src/window.c +++ b/src/window.c @@ -153,7 +153,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, wndconfig.height = height; wndconfig.title = title; ctxconfig.share = (_GLFWwindow*) share; - wndconfig.transparent = _glfw.hints.framebuffer.transparent ? GLFW_TRUE : GLFW_FALSE; if (ctxconfig.share) { @@ -182,7 +181,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, window->monitor = (_GLFWmonitor*) monitor; window->resizable = wndconfig.resizable; window->decorated = wndconfig.decorated; - window->transparent = wndconfig.transparent; window->autoIconify = wndconfig.autoIconify; window->floating = wndconfig.floating; window->cursorMode = GLFW_CURSOR_NORMAL; @@ -252,7 +250,6 @@ void glfwDefaultWindowHints(void) _glfw.hints.window.resizable = GLFW_TRUE; _glfw.hints.window.visible = GLFW_TRUE; _glfw.hints.window.decorated = GLFW_TRUE; - _glfw.hints.window.transparent = GLFW_FALSE; _glfw.hints.window.focused = GLFW_TRUE; _glfw.hints.window.autoIconify = GLFW_TRUE; diff --git a/src/x11_window.c b/src/x11_window.c index a7b672624..aee89d402 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -1808,14 +1808,14 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, { if (!_glfwInitGLX()) return GLFW_FALSE; - if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth)) + if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth)) return GLFW_FALSE; } else if (ctxconfig->source == GLFW_EGL_CONTEXT_API) { if (!_glfwInitEGL()) return GLFW_FALSE; - if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth)) + if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth)) return GLFW_FALSE; } else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API) From 96d49ba28d33ac0071ebb8400e0fbadf42680731 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 21:56:39 +0700 Subject: [PATCH 29/34] Add transparent flag piping to choosePixelFormat() due to fbconfig being const. In the event transparency cannot be achieved, choosePixelFormat() recurses itself with this flag set to GLFW_FALSE. --- src/wgl_context.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/wgl_context.c b/src/wgl_context.c index 278a38008..5064583d2 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -56,7 +56,8 @@ static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib // static int choosePixelFormat(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) + const _GLFWfbconfig* fbconfig, + const int transparent) { _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; @@ -215,18 +216,17 @@ static int choosePixelFormat(_GLFWwindow* window, u->handle = n; // always able to go transparent on win dwmapi - u->transparent = 1; + u->transparent = GLFW_TRUE; usableCount++; } // Reiterate the selection loop without looking for transparency supporting // formats if no matching pixelformat for a transparent window were found. if (fbconfig->transparent && !usableCount) { - fbconfig->transparent = GLFW_FALSE; free(usableConfigs); _glfwInputError(GLFW_PLATFORM_ERROR, "WGL: No pixel format found for transparent window. Ignoring transparency."); - return choosePixelFormat(window, ctxconfig, fbconfig); + return choosePixelFormat(window, ctxconfig, fbconfig, GLFW_FALSE); } if (!usableCount) @@ -629,7 +629,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, return GLFW_FALSE; } - pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig); + pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig, fbconfig->transparent); if (!pixelFormat) return GLFW_FALSE; @@ -837,7 +837,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, if (fbconfig->transparent) { if (!setupTransparentWindow(window)) - fbconfig->transparent = GLFW_FALSE; + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "WGL: Failed to setup window as transparent as requested"); } window->context.makeCurrent = makeContextCurrentWGL; From 680d10bbb55742a582fef08f6b6fed7ad52ffcaa Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 22:04:56 +0700 Subject: [PATCH 30/34] Fix struct pointer typo for OSX --- src/cocoa_window.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index b51e36d80..e4af6d9fc 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -1085,7 +1085,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window, if (wndconfig->ns.retina) [window->ns.view setWantsBestResolutionOpenGLSurface:YES]; - if (_glfw.hints.framebuffer->transparent) + if (_glfw.hints.framebuffer.transparent) { [window->ns.object setOpaque:NO]; [window->ns.object setBackgroundColor:[NSColor clearColor]]; From 0e9ade81a3d46257de44deb0ba9ccbf1b1e1087f Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 22:20:45 +0700 Subject: [PATCH 31/34] Cleanup: Use GLFWbool instead of int --- src/internal.h | 5 ++--- src/wgl_context.c | 2 +- src/window.c | 2 -- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/internal.h b/src/internal.h index fab544df8..eb80e24ff 100644 --- a/src/internal.h +++ b/src/internal.h @@ -347,7 +347,6 @@ struct _GLFWfbconfig int redBits; int greenBits; int blueBits; - int transparent; int alphaBits; int depthBits; int stencilBits; @@ -358,7 +357,8 @@ struct _GLFWfbconfig int auxBuffers; GLFWbool stereo; int samples; - GLFWbool sRGB; + GLFWbool sRGB; + GLFWbool transparent; GLFWbool doublebuffer; uintptr_t handle; }; @@ -403,7 +403,6 @@ struct _GLFWwindow // Window settings and state GLFWbool resizable; GLFWbool decorated; - GLFWbool transparent; GLFWbool autoIconify; GLFWbool floating; GLFWbool shouldClose; diff --git a/src/wgl_context.c b/src/wgl_context.c index 5064583d2..e1f817008 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -57,7 +57,7 @@ static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib static int choosePixelFormat(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, - const int transparent) + const GLFWbool transparent) { _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; diff --git a/src/window.c b/src/window.c index 5af847d1c..3590ce830 100644 --- a/src/window.c +++ b/src/window.c @@ -733,8 +733,6 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) return window->resizable; case GLFW_DECORATED: return window->decorated; - case GLFW_TRANSPARENT: - return window->transparent; case GLFW_FLOATING: return window->floating; case GLFW_AUTO_ICONIFY: From ffca92195428885b72220620fc6467ac3402c524 Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Sun, 17 Sep 2017 22:24:38 +0700 Subject: [PATCH 32/34] Use flag from fbconfig instead of window (now removed) --- src/glx_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/glx_context.c b/src/glx_context.c index fdc97bb8e..aaa2c8bd0 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -483,7 +483,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, if (ctxconfig->share) share = ctxconfig->share->context.glx.handle; - if (!chooseGLXFBConfig(fbconfig, &native, window->transparent)) + if (!chooseGLXFBConfig(fbconfig, &native, fbconfig->transparent)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, From aa7853376492a0159bbee88c1ea33f5f52108bba Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Mon, 18 Sep 2017 00:36:31 +0700 Subject: [PATCH 33/34] Cleanup: remove rogue debug statement --- src/glx_context.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/glx_context.c b/src/glx_context.c index aaa2c8bd0..e48ef70fd 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -64,8 +64,6 @@ static GLFWbool chooseGLXFBConfig( findTransparent = GLFW_FALSE; } - findTransparent = GLFW_TRUE; - // HACK: This is a (hopefully temporary) workaround for Chromium // (VirtualBox GL) not setting the window bit on any GLXFBConfigs vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR); From 9a2890d611e367565c9f2955fbbe0f201f025d7d Mon Sep 17 00:00:00 2001 From: Bailey Cosier Date: Mon, 18 Sep 2017 00:59:12 +0700 Subject: [PATCH 34/34] Both `chooseEGLConfig()` and `chooseGLXConfig()` can also be reverted. Since the findTransparent (GLFWbool) is sourced from the already provided `fbconfig` anyways. --- src/egl_context.c | 15 +++++++-------- src/glx_context.c | 14 +++++--------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/egl_context.c b/src/egl_context.c index 70ec35c38..ff8b8aedc 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -87,13 +87,13 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib) // static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* desired, - EGLConfig* result, - GLFWbool findTransparent) + EGLConfig* result) { EGLConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; const _GLFWfbconfig* closest; int i, nativeCount, usableCount; + GLFWbool findTransparent = desired->transparent; #if defined(_GLFW_X11) XVisualInfo visualTemplate = {0}; @@ -138,7 +138,7 @@ selectionloop: int n_vi; XVisualInfo *visualinfo; XRenderPictFormat *pictFormat; - + visualinfo = XGetVisualInfo(_glfw.x11.display, VisualIDMask, &visualTemplate, &n_vi); if (!visualinfo) continue; @@ -191,10 +191,10 @@ selectionloop: usableCount++; } // reiterate the selection loop without looking for transparency supporting - // formats if no matchig FB configs for a transparent window were found. + // formats if no matchig FB configs for a transparent window were found. if( findTransparent && !usableCount ) { findTransparent = GLFW_FALSE; - goto selectionloop; + goto selectionloop; } closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); @@ -492,7 +492,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, if (ctxconfig->share) share = ctxconfig->share->context.egl.handle; - if (!chooseEGLConfig(ctxconfig, fbconfig, &config, fbconfig->transparent)) + if (!chooseEGLConfig(ctxconfig, fbconfig, &config)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Failed to find a suitable EGLConfig"); @@ -737,7 +737,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig, const long vimask = VisualScreenMask | VisualIDMask; - if (!chooseEGLConfig(ctxconfig, fbconfig, &native, fbconfig->transparent)) + if (!chooseEGLConfig(ctxconfig, fbconfig, &native)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Failed to find a suitable EGLConfig"); @@ -804,4 +804,3 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle) return window->context.egl.surface; } - diff --git a/src/glx_context.c b/src/glx_context.c index e48ef70fd..a6ce6e672 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -47,11 +47,7 @@ static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib) // Return the GLXFBConfig most closely matching the specified hints // -static GLFWbool chooseGLXFBConfig( - const _GLFWfbconfig* desired, - GLXFBConfig* result, - GLFWbool findTransparent) - +static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result) { GLXFBConfig* nativeConfigs; _GLFWfbconfig* usableConfigs; @@ -59,6 +55,7 @@ static GLFWbool chooseGLXFBConfig( int i, nativeCount, usableCount; const char* vendor; GLFWbool trustWindowBit = GLFW_TRUE; + GLFWbool findTransparent = desired->transparent; if ( !(_glfw.xrender.major || _glfw.xrender.minor) ) { findTransparent = GLFW_FALSE; @@ -155,7 +152,7 @@ selectionloop: // formats if no matchig FB configs for a transparent window were found. if( findTransparent && !usableCount ) { findTransparent = GLFW_FALSE; - goto selectionloop; + goto selectionloop; } closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); @@ -481,8 +478,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, if (ctxconfig->share) share = ctxconfig->share->context.glx.handle; - if (!chooseGLXFBConfig(fbconfig, &native, fbconfig->transparent)) - + if (!chooseGLXFBConfig(fbconfig, &native)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "GLX: Failed to find a suitable GLXFBConfig"); @@ -669,7 +665,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig, GLXFBConfig native; XVisualInfo* result; - if (!chooseGLXFBConfig(fbconfig, &native, fbconfig->transparent)) + if (!chooseGLXFBConfig(fbconfig, &native)) { _glfwInputError(GLFW_FORMAT_UNAVAILABLE, "GLX: Failed to find a suitable GLXFBConfig");