diff options
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/CMakeLists.txt | 4 | ||||
-rw-r--r-- | intern/ghost/GHOST_ISystem.h | 2 | ||||
-rw-r--r-- | intern/ghost/GHOST_Types.h | 3 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextGLX.cpp | 33 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextGLX.h | 3 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextWGL.cpp | 69 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ContextWGL.h | 4 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_System.cpp | 8 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_System.h | 6 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemWin32.cpp | 7 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 1 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWin32.cpp | 51 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowWin32.h | 3 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.cpp | 150 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.h | 3 |
15 files changed, 259 insertions, 88 deletions
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index d31e9472168..e549a48d4b9 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -223,6 +223,10 @@ elseif(WITH_X11) ) endif() + if(WITH_X11_ALPHA) + add_definitions(-DWITH_X11_ALPHA) + endif() + if(WITH_INPUT_NDOF) list(APPEND SRC intern/GHOST_NDOFManagerUnix.cpp diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index 4c48473c7b8..08045b93db9 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -277,7 +277,7 @@ public: */ virtual GHOST_TSuccess beginFullScreen( const GHOST_DisplaySetting& setting, GHOST_IWindow **window, - const bool stereoVisual, const GHOST_TUns16 numOfAASamples = 0) = 0; + const bool stereoVisual, const bool alphaBackground = 0, const GHOST_TUns16 numOfAASamples = 0) = 0; /** * Updates the resolution while in fullscreen mode. diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index b3e560ab4b4..7e77ba3a41f 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -57,7 +57,8 @@ typedef struct { typedef enum { GHOST_glStereoVisual = (1 << 0), - GHOST_glDebugContext = (1 << 1) + GHOST_glDebugContext = (1 << 1), + GHOST_glAlphaBackground = (1 << 2), } GHOST_GLFlags; diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp index 90d810b7986..4b735bbd07c 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.cpp +++ b/intern/ghost/intern/GHOST_ContextGLX.cpp @@ -62,6 +62,7 @@ GHOST_ContextGLX::GHOST_ContextGLX( Window window, Display *display, XVisualInfo *visualInfo, + GLXFBConfig fbconfig, int contextProfileMask, int contextMajorVersion, int contextMinorVersion, @@ -70,6 +71,7 @@ GHOST_ContextGLX::GHOST_ContextGLX( : GHOST_Context(stereoVisual, numOfAASamples), m_display(display), m_visualInfo(visualInfo), + m_fbconfig(fbconfig), m_window(window), m_contextProfileMask(contextProfileMask), m_contextMajorVersion(contextMajorVersion), @@ -285,19 +287,25 @@ const bool GLXEW_ARB_create_context_robustness = attribs[i++] = 0; /* Create a GL 3.x context */ - GLXFBConfig *framebuffer_config = NULL; + if (m_fbconfig) { - int glx_attribs[64]; - int fbcount = 0; + m_context = glXCreateContextAttribsARB(m_display, m_fbconfig, s_sharedContext, true, attribs); + } + else { + GLXFBConfig *framebuffer_config = NULL; + { + int glx_attribs[64]; + int fbcount = 0; - GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_numOfAASamples, m_stereoVisual, true); + GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_numOfAASamples, m_stereoVisual, false, true); - framebuffer_config = glXChooseFBConfig(m_display, DefaultScreen(m_display), glx_attribs, &fbcount); - } + framebuffer_config = glXChooseFBConfig(m_display, DefaultScreen(m_display), glx_attribs, &fbcount); + } - if (framebuffer_config) { - m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs); - XFree(framebuffer_config); + if (framebuffer_config) { + m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs); + XFree(framebuffer_config); + } } } else { @@ -401,16 +409,11 @@ GHOST_TSuccess GHOST_ContextGLX::getSwapInterval(int &intervalOut) int GHOST_X11_GL_GetAttributes( int *attribs, int attribs_max, int samples, bool is_stereo_visual, + bool need_alpha, bool for_fb_config) { int i = 0; -#ifdef GHOST_OPENGL_ALPHA - const bool need_alpha = true; -#else - const bool need_alpha = false; -#endif - #ifdef GHOST_OPENGL_STENCIL const bool need_stencil = true; #else diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h index 8c2231a0b01..f0f010d1942 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.h +++ b/intern/ghost/intern/GHOST_ContextGLX.h @@ -66,6 +66,7 @@ public: Window window, Display *display, XVisualInfo *visualInfo, + GLXFBConfig fbconfig, int contextProfileMask, int contextMajorVersion, int contextMinorVersion, @@ -128,6 +129,7 @@ private: Display *m_display; XVisualInfo *m_visualInfo; + GLXFBConfig m_fbconfig; Window m_window; const int m_contextProfileMask; @@ -151,6 +153,7 @@ private: int GHOST_X11_GL_GetAttributes( int *attribs, int attribs_max, int samples, bool is_stereo_visual, + bool need_alpha, bool for_fb_config); #endif // __GHOST_CONTEXTGLX_H__ diff --git a/intern/ghost/intern/GHOST_ContextWGL.cpp b/intern/ghost/intern/GHOST_ContextWGL.cpp index cb580f60bd7..75e2f94c3a3 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.cpp +++ b/intern/ghost/intern/GHOST_ContextWGL.cpp @@ -63,6 +63,7 @@ static bool is_crappy_intel_card() GHOST_ContextWGL::GHOST_ContextWGL( bool stereoVisual, + bool alphaBackground, GHOST_TUns16 numOfAASamples, HWND hWnd, HDC hDC, @@ -78,6 +79,7 @@ GHOST_ContextWGL::GHOST_ContextWGL( m_contextMajorVersion(contextMajorVersion), m_contextMinorVersion(contextMinorVersion), m_contextFlags(contextFlags), + m_alphaBackground(alphaBackground), m_contextResetNotificationStrategy(contextResetNotificationStrategy), m_hGLRC(NULL) #ifdef WITH_GLEW_MX @@ -168,7 +170,7 @@ GHOST_TSuccess GHOST_ContextWGL::activateDrawingContext() /* Ron Fosner's code for weighting pixel formats and forcing software. * See http://www.opengl.org/resources/faq/technical/weight.cpp */ -static int weight_pixel_format(PIXELFORMATDESCRIPTOR &pfd) +static int weight_pixel_format(PIXELFORMATDESCRIPTOR &pfd, PIXELFORMATDESCRIPTOR &preferredPFD) { int weight = 0; @@ -194,11 +196,12 @@ static int weight_pixel_format(PIXELFORMATDESCRIPTOR &pfd) weight += pfd.cColorBits - 8; -#ifdef GHOST_OPENGL_ALPHA - if (pfd.cAlphaBits > 0) + if (preferredPFD.cAlphaBits > 0 && pfd.cAlphaBits > 0) + weight++; +#ifdef WIN32_COMPOSITING + if ((preferredPFD.dwFlags & PFD_SUPPORT_COMPOSITION) && (pfd.dwFlags & PFD_SUPPORT_COMPOSITION)) weight++; #endif - #ifdef GHOST_OPENGL_STENCIL if (pfd.cStencilBits >= 8) weight++; @@ -239,7 +242,7 @@ static int choose_pixel_format_legacy(HDC hDC, PIXELFORMATDESCRIPTOR &preferredP WIN32_CHK(check == lastPFD); - int w = weight_pixel_format(pfd); + int w = weight_pixel_format(pfd, preferredPFD); if (w > weight) { weight = w; @@ -496,7 +499,10 @@ int GHOST_ContextWGL::_choose_pixel_format_arb_2( { std::vector<int> iAttributes; +#define _MAX_PIXEL_FORMATS 32 + int iPixelFormat = 0; + int iPixelFormats[_MAX_PIXEL_FORMATS]; int samples; @@ -521,8 +527,31 @@ int GHOST_ContextWGL::_choose_pixel_format_arb_2( sRGB); UINT nNumFormats; - WIN32_CHK(wglChoosePixelFormatARB(m_hDC, &(iAttributes[0]), NULL, 1, &iPixelFormat, &nNumFormats)); - + WIN32_CHK(wglChoosePixelFormatARB(m_hDC, &(iAttributes[0]), NULL, _MAX_PIXEL_FORMATS, iPixelFormats, &nNumFormats)); + +#ifdef WIN32_COMPOSITING + if (needAlpha && nNumFormats) { + // scan through all pixel format to make sure one supports compositing + PIXELFORMATDESCRIPTOR pfd; + int i; + + for (i = 0; i < nNumFormats; i++) { + if (DescribePixelFormat(m_hDC, iPixelFormats[i], sizeof(PIXELFORMATDESCRIPTOR), &pfd)) { + if (pfd.dwFlags & PFD_SUPPORT_COMPOSITION) { + iPixelFormat = iPixelFormats[i]; + break; + } + } + } + if (i == nNumFormats) { + fprintf(stderr, + "Warning! Unable to find a pixel format with compositing capability.\n"); + iPixelFormat = iPixelFormats[0]; + } + } + else +#endif + iPixelFormat = iPixelFormats[0]; /* total number of formats that match (regardless of size of iPixelFormat array) * see: WGL_ARB_pixel_format extension spec */ if (nNumFormats > 0) @@ -538,7 +567,7 @@ int GHOST_ContextWGL::_choose_pixel_format_arb_2( // check how many samples were actually gotten if (iPixelFormat != 0) { int iQuery[] = { WGL_SAMPLES_ARB }; - int actualSamples; + int actualSamples, alphaBits; wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &actualSamples); if (actualSamples != *numOfAASamples) { @@ -549,6 +578,14 @@ int GHOST_ContextWGL::_choose_pixel_format_arb_2( *numOfAASamples = actualSamples; // set context property to actual value } + if (needAlpha) { + iQuery[0] = WGL_ALPHA_BITS_ARB; + wglGetPixelFormatAttribivARB(m_hDC, iPixelFormat, 0, 1, iQuery, &alphaBits); + if (alphaBits == 0) { + fprintf(stderr, + "Warning! Unable to find a frame buffer with alpha channel.\n"); + } + } } else { *numOfAASamples = 0; @@ -674,9 +711,15 @@ int GHOST_ContextWGL::choose_pixel_format( PFD_DRAW_TO_WINDOW | PFD_SWAP_COPY | /* support swap copy */ PFD_DOUBLEBUFFER | /* support double-buffering */ - (stereoVisual ? PFD_STEREO : 0), /* support stereo */ + (stereoVisual ? PFD_STEREO : 0) |/* support stereo */ + ( +#ifdef WIN32_COMPOSITING + needAlpha ? PFD_SUPPORT_COMPOSITION : /* support composition for transparent background */ +#endif + 0 + ), PFD_TYPE_RGBA, /* color type */ - 24, /* preferred color depth */ + (needAlpha ? 32 : 24), /* preferred color depth */ 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ needAlpha ? 8 : 0, /* alpha buffer */ 0, /* alpha shift (ignored) */ @@ -727,11 +770,7 @@ static void reportContextString(const char *name, const char *dummy, const char GHOST_TSuccess GHOST_ContextWGL::initializeDrawingContext() { -#ifdef GHOST_OPENGL_ALPHA - const bool needAlpha = true; -#else - const bool needAlpha = false; -#endif + const bool needAlpha = m_alphaBackground; #ifdef GHOST_OPENGL_STENCIL const bool needStencil = true; diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h index 3b04a33b662..580b4dcb82f 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.h +++ b/intern/ghost/intern/GHOST_ContextWGL.h @@ -32,6 +32,8 @@ #ifndef __GHOST_CONTEXTWGL_H__ #define __GHOST_CONTEXTWGL_H__ +//#define WIN32_COMPOSITING + #include "GHOST_Context.h" #ifdef WITH_GLEW_MX @@ -65,6 +67,7 @@ public: */ GHOST_ContextWGL( bool stereoVisual, + bool alphaBackground, GHOST_TUns16 numOfAASamples, HWND hWnd, HDC hDC, @@ -164,6 +167,7 @@ private: const int m_contextMajorVersion; const int m_contextMinorVersion; const int m_contextFlags; + const bool m_alphaBackground; const int m_contextResetNotificationStrategy; HGLRC m_hGLRC; diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp index 639ce451d23..c53580818e6 100644 --- a/intern/ghost/intern/GHOST_System.cpp +++ b/intern/ghost/intern/GHOST_System.cpp @@ -140,7 +140,7 @@ bool GHOST_System::validWindow(GHOST_IWindow *window) GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window, - const bool stereoVisual, const GHOST_TUns16 numOfAASamples) + const bool stereoVisual, const bool alphaBackground, const GHOST_TUns16 numOfAASamples) { GHOST_TSuccess success = GHOST_kFailure; GHOST_ASSERT(m_windowManager, "GHOST_System::beginFullScreen(): invalid window manager"); @@ -152,7 +152,7 @@ GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting); if (success == GHOST_kSuccess) { //GHOST_PRINT("GHOST_System::beginFullScreen(): creating full-screen window\n"); - success = createFullScreenWindow((GHOST_Window **)window, setting, stereoVisual, numOfAASamples); + success = createFullScreenWindow((GHOST_Window **)window, setting, stereoVisual, alphaBackground, numOfAASamples); if (success == GHOST_kSuccess) { m_windowManager->beginFullScreen(*window, stereoVisual); } @@ -349,12 +349,14 @@ GHOST_TSuccess GHOST_System::exit() } GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings, - const bool stereoVisual, const GHOST_TUns16 numOfAASamples) + const bool stereoVisual, const bool alphaBackground, const GHOST_TUns16 numOfAASamples) { GHOST_GLSettings glSettings = {0}; if (stereoVisual) glSettings.flags |= GHOST_glStereoVisual; + if (alphaBackground) + glSettings.flags |= GHOST_glAlphaBackground; glSettings.numOfAASamples = numOfAASamples; /* note: don't use getCurrentDisplaySetting() because on X11 we may diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h index c4951adb4fd..a10259bc9e9 100644 --- a/intern/ghost/intern/GHOST_System.h +++ b/intern/ghost/intern/GHOST_System.h @@ -144,8 +144,8 @@ public: * \return Indication of success. */ GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window, - const bool stereoVisual, const GHOST_TUns16 numOfAASamples = 0); - + const bool stereoVisual, const bool alphaBackground, const GHOST_TUns16 numOfAASamples = 0); + /** * Updates the resolution while in fullscreen mode. * \param setting The new setting of the display. @@ -336,7 +336,7 @@ protected: * \return Indication of success. */ GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings, - const bool stereoVisual, const GHOST_TUns16 numOfAASamples = 0); + const bool stereoVisual, const bool alphaBackground = 0, const GHOST_TUns16 numOfAASamples = 0); /** The display manager (platform dependent). */ GHOST_DisplayManager *m_displayManager; diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 43fb5dc4205..ed08ce02f47 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -241,6 +241,7 @@ GHOST_IWindow *GHOST_SystemWin32::createWindow( state, type, ((glSettings.flags & GHOST_glStereoVisual) != 0), + ((glSettings.flags & GHOST_glAlphaBackground) != 0), glSettings.numOfAASamples, parentWindow, ((glSettings.flags & GHOST_glDebugContext) != 0)); @@ -408,7 +409,11 @@ GHOST_TSuccess GHOST_SystemWin32::init() ::LoadIcon(NULL, IDI_APPLICATION); } wc.hCursor = ::LoadCursor(0, IDC_ARROW); - wc.hbrBackground = 0; + wc.hbrBackground = +#ifdef INW32_COMPISITING + (HBRUSH)CreateSolidBrush +#endif + (0x00000000); wc.lpszMenuName = 0; wc.lpszClassName = L"GHOST_WindowClass"; diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index c9946c13122..25daa8ce2a7 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -310,6 +310,7 @@ createWindow(const STR_String& title, left, top, width, height, state, parentWindow, type, ((glSettings.flags & GHOST_glStereoVisual) != 0), exclusive, + ((glSettings.flags & GHOST_glAlphaBackground) != 0), glSettings.numOfAASamples, (glSettings.flags & GHOST_glDebugContext) != 0); if (window) { diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 81c08f4fc06..c9bcb38ab68 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -43,7 +43,9 @@ #else # include "GHOST_ContextWGL.h" #endif - +#ifdef WIN32_COMPOSITING +#include <Dwmapi.h> +#endif #include <math.h> #include <string.h> @@ -70,7 +72,8 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, GHOST_TUns32 height, GHOST_TWindowState state, GHOST_TDrawingContextType type, - bool wantStereoVisual, + bool wantStereoVisual, + bool alphaBackground, GHOST_TUns16 wantNumOfAASamples, GHOST_TEmbedderWindowID parentwindowhwnd, bool is_debug) @@ -83,6 +86,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, m_hasGrabMouse(false), m_nPressedButtons(0), m_customCursor(0), + m_wantAlphaBackground(alphaBackground), m_wintab(NULL), m_tabletData(NULL), m_tablet(0), @@ -181,17 +185,17 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, wchar_t *title_16 = alloc_utf16_from_8((char *)(const char *)title, 0); m_hWnd = ::CreateWindowW( - s_windowClassName, // pointer to registered class name - title_16, // pointer to window name - wintype, // window style - left, // horizontal position of window - top, // vertical position of window - width, // window width - height, // window height - (HWND) m_parentWindowHwnd, // handle to parent or owner window - 0, // handle to menu or child-window identifier - ::GetModuleHandle(0), // handle to application instance - 0); // pointer to window-creation data + s_windowClassName, // pointer to registered class name + title_16, // pointer to window name + wintype, // window style + left, // horizontal position of window + top, // vertical position of window + width, // window width + height, // window height + (HWND)m_parentWindowHwnd, // handle to parent or owner window + 0, // handle to menu or child-window identifier + ::GetModuleHandle(0), // handle to application instance + 0); // pointer to window-creation data free(title_16); } else { @@ -243,6 +247,24 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, } ::ShowWindow(m_hWnd, nCmdShow); +#ifdef WIN32_COMPOSITING + if (alphaBackground && parentwindowhwnd == 0) { + + HRESULT hr = S_OK; + + // Create and populate the Blur Behind structure + DWM_BLURBEHIND bb = { 0 }; + + // Enable Blur Behind and apply to the entire client area + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.fEnable = true; + bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1); + + // Apply Blur Behind + hr = DwmEnableBlurBehindWindow(m_hWnd, &bb); + DeleteObject(bb.hRgnBlur); + } +#endif // Force an initial paint of the window ::UpdateWindow(m_hWnd); } @@ -622,6 +644,7 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty #if defined(WITH_GL_PROFILE_CORE) GHOST_Context *context = new GHOST_ContextWGL( m_wantStereoVisual, + m_wantAlphaBackground, m_wantNumOfAASamples, m_hWnd, m_hDC, @@ -632,6 +655,7 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty #elif defined(WITH_GL_PROFILE_ES20) GHOST_Context *context = new GHOST_ContextWGL( m_wantStereoVisual, + m_wantAlphaBackground, m_wantNumOfAASamples, m_hWnd, m_hDC, @@ -642,6 +666,7 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty #elif defined(WITH_GL_PROFILE_COMPAT) GHOST_Context *context = new GHOST_ContextWGL( m_wantStereoVisual, + m_wantAlphaBackground, m_wantNumOfAASamples, m_hWnd, m_hDC, diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index b508c2f37df..a1cf58c9ceb 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -89,6 +89,7 @@ public: GHOST_TWindowState state, GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, bool wantStereoVisual = false, + bool alphaBackground = false, GHOST_TUns16 wantNumOfAASamples = 0, GHOST_TEmbedderWindowID parentWindowHwnd = 0, bool is_debug = false); @@ -328,6 +329,8 @@ private: int m_nPressedButtons; /** HCURSOR structure of the custom cursor */ HCURSOR m_customCursor; + /** request GL context aith alpha channel */ + bool m_wantAlphaBackground; /** ITaskbarList3 structure for progress bar*/ ITaskbarList3 *m_Bar; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index e68e0901dab..a12ecec6371 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -33,7 +33,9 @@ #include <X11/cursorfont.h> #include <X11/Xatom.h> #include <X11/Xutil.h> - +#ifdef WITH_X11_ALPHA +#include <X11/extensions/Xrender.h> +#endif #include "GHOST_WindowX11.h" #include "GHOST_SystemX11.h" #include "STR_String.h" @@ -164,15 +166,21 @@ static const unsigned long BLENDER_ICON_48x48x32[] = { static XVisualInfo *x11_visualinfo_from_glx( Display *display, - bool stereoVisual, GHOST_TUns16 *r_numOfAASamples) + bool stereoVisual, + GHOST_TUns16 *r_numOfAASamples, + bool needAlpha, + GLXFBConfig *fbconfig) { - XVisualInfo *visualInfo = NULL; + XVisualInfo *visual = NULL; GHOST_TUns16 numOfAASamples = *r_numOfAASamples; + int glx_major, glx_minor, glx_version; /* GLX version: major.minor */ GHOST_TUns16 actualSamples; + int glx_attribs[64]; + + *fbconfig = NULL; /* Set up the minimum attributes that we require and see if * X can find us a visual matching those requirements. */ - int glx_major, glx_minor; /* GLX version: major.minor */ if (!glXQueryVersion(display, &glx_major, &glx_minor)) { fprintf(stderr, @@ -182,53 +190,118 @@ static XVisualInfo *x11_visualinfo_from_glx( return NULL; } + glx_version = glx_major*100 + glx_minor; - /* GLX >= 1.4 required for multi-sample */ - if ((glx_major > 1) || (glx_major == 1 && glx_minor >= 4)) { + if (glx_version >= 104) { actualSamples = numOfAASamples; } else { numOfAASamples = 0; actualSamples = 0; } + +#ifdef WITH_X11_ALPHA + if ( needAlpha + && glx_version >= 103 + && (glXChooseFBConfig || + (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB((const GLubyte *)"glXChooseFBConfig")) != NULL) + && (glXGetVisualFromFBConfig || + (glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)glXGetProcAddressARB((const GLubyte *)"glXGetVisualFromFBConfig")) != NULL) + ) { + GLXFBConfig *fbconfigs; + int nbfbconfig; + int i; + + for (;;) { + + GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, true); + + fbconfigs = glXChooseFBConfig(display, DefaultScreen(display), glx_attribs, &nbfbconfig); + + /* Any sample level or even zero, which means oversampling disabled, is good + * but we need a valid visual to continue */ + if (nbfbconfig > 0) { + /* take a frame buffer config that has alpha cap */ + for (i=0 ;i<nbfbconfig; i++) { + visual = (XVisualInfo*)glXGetVisualFromFBConfig(display, fbconfigs[i]); + if (!visual) + continue; + /* if we don't need a alpha background, the first config will do, otherwise + * test the alphaMask as it won't necessarily be present */ + if (needAlpha) { + XRenderPictFormat *pict_format = XRenderFindVisualFormat(display, visual->visual); + if (!pict_format) + continue; + if (pict_format->direct.alphaMask <= 0) + continue; + } + *fbconfig = fbconfigs[i]; + break; + } + XFree(fbconfigs); + if (i<nbfbconfig) { + if (actualSamples < numOfAASamples) { + fprintf(stderr, + "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " + "Substituting one that uses %d samples.\n", + numOfAASamples, actualSamples); + } + break; + } + visual = NULL; + } - /* Find the display with highest samples, starting at level requested */ - for (;;) { - int glx_attribs[64]; - - GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, false); - - visualInfo = glXChooseVisual(display, DefaultScreen(display), glx_attribs); - - /* Any sample level or even zero, which means oversampling disabled, is good - * but we need a valid visual to continue */ - if (visualInfo != NULL) { - if (actualSamples < numOfAASamples) { + if (actualSamples == 0) { + /* All options exhausted, cannot continue */ fprintf(stderr, - "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " - "Substituting one that uses %d samples.\n", - numOfAASamples, actualSamples); + "%s:%d: X11 glXChooseVisual() failed, " + "verify working openGL system!\n", + __FILE__, __LINE__); + + return NULL; + } + else { + --actualSamples; } - break; } + } + else +#endif + { + /* legacy, don't use extension */ + for (;;) { + GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, false); + + visual = glXChooseVisual(display, DefaultScreen(display), glx_attribs); + + /* Any sample level or even zero, which means oversampling disabled, is good + * but we need a valid visual to continue */ + if (visual != NULL) { + if (actualSamples < numOfAASamples) { + fprintf(stderr, + "Warning! Unable to find a multisample pixel format that supports exactly %d samples. " + "Substituting one that uses %d samples.\n", + numOfAASamples, actualSamples); + } + break; + } - if (actualSamples == 0) { - /* All options exhausted, cannot continue */ - fprintf(stderr, - "%s:%d: X11 glXChooseVisual() failed, " - "verify working openGL system!\n", - __FILE__, __LINE__); + if (actualSamples == 0) { + /* All options exhausted, cannot continue */ + fprintf(stderr, + "%s:%d: X11 glXChooseVisual() failed, " + "verify working openGL system!\n", + __FILE__, __LINE__); - return NULL; - } - else { - --actualSamples; + return NULL; + } + else { + --actualSamples; + } } } - *r_numOfAASamples = actualSamples; - - return visualInfo; + return visual; } GHOST_WindowX11:: @@ -244,10 +317,12 @@ GHOST_WindowX11(GHOST_SystemX11 *system, GHOST_TDrawingContextType type, const bool stereoVisual, const bool exclusive, + const bool alphaBackground, const GHOST_TUns16 numOfAASamples, const bool is_debug) : GHOST_Window(width, height, state, stereoVisual, exclusive, numOfAASamples), m_display(display), m_visualInfo(NULL), + m_fbconfig(NULL), m_normal_state(GHOST_kWindowStateNormal), m_system(system), m_invalid_window(false), @@ -264,7 +339,7 @@ GHOST_WindowX11(GHOST_SystemX11 *system, m_is_debug_context(is_debug) { if (type == GHOST_kDrawingContextTypeOpenGL) { - m_visualInfo = x11_visualinfo_from_glx(m_display, stereoVisual, &m_wantNumOfAASamples); + m_visualInfo = x11_visualinfo_from_glx(m_display, stereoVisual, &m_wantNumOfAASamples, alphaBackground, (GLXFBConfig*)&m_fbconfig); } else { XVisualInfo tmp = {0}; @@ -1240,6 +1315,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type m_window, m_display, m_visualInfo, + (GLXFBConfig)m_fbconfig, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, 3, 2, GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), @@ -1251,6 +1327,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type m_window, m_display, m_visualInfo, + (GLXFBConfig)m_fbconfig, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 2, 0, GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), @@ -1262,6 +1339,7 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type m_window, m_display, m_visualInfo, + (GLXFBConfig)m_fbconfig, 0, // profile bit 0, 0, GHOST_OPENGL_GLX_CONTEXT_FLAGS | (m_is_debug_context ? GLX_CONTEXT_DEBUG_BIT_ARB : 0), diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index 5beb7b43032..0738e3d47b8 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -73,6 +73,7 @@ public: * \param parentWindow Parent (embedder) window * \param type The type of drawing context installed in this window. * \param stereoVisual Stereo visual for quad buffered stereo. + * \param alphaBackground Enable alpha blending of window with display background * \param numOfAASamples Number of samples used for AA (zero if no AA) */ GHOST_WindowX11( @@ -88,6 +89,7 @@ public: GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone, const bool stereoVisual = false, const bool exclusive = false, + const bool alphaBackground = false, const GHOST_TUns16 numOfAASamples = 0, const bool is_debug = false ); @@ -321,6 +323,7 @@ private: Window m_window; Display *m_display; XVisualInfo *m_visualInfo; + void *m_fbconfig; GHOST_TWindowState m_normal_state; |