BGE: alpha on frame buffer and precedence of MSAA over swap.
A new option '-a' can be passed to the blenderplayer. It forces the framebuffer to have an alpha channel. This can be used in VideoTexture to return a image with alpha channel with ImageViewport (provided alpha is set to True on the ImageViewport object and that the background color alpha channel is 0, which is the default). Without the -a option, the frame buffer has no alpha channel and ImageViewport always returns an opaque image, no matter what. In Linux, the player window will be rendered transparently over the desktop. In Windows, the player window is still rendered opaque because transparency of the window is only possible using the 'compositing' functions of Windows. The code is there but not enabled (look for WIN32_COMPOSITING) because 1) it doesn't work so well 2) it requires a DLL that is only available on Vista and up. give precedence to AA over Swap copy: Certain GPU (intel) will not allow MSAA together with swap copy. Previously, swap copy had priority over MSAA: fewer AA samples would be chosen if it was the condition to get swap copy. This patch reverse the logic: swap copy will be abandonned if another swap method (undefined or exchange) will provide the number of AA samples requested. If no AA samples is requested, swap copy still has the priority of course.
This commit is contained in:
parent
5da02ab9e2
commit
8529b2f925
|
@ -273,6 +273,7 @@ endif()
|
|||
if(WITH_X11)
|
||||
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
|
||||
option(WITH_X11_XF86VMODE "Enable X11 video mode switching" ON)
|
||||
option(WITH_X11_ALPHA "Enable X11 transparent background" ON)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
|
@ -723,6 +724,7 @@ if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
|||
set(WITH_X11 OFF)
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
set(WITH_X11_XF86VMODE OFF)
|
||||
set(WITH_X11_ALPHA OFF)
|
||||
set(WITH_GHOST_XDND OFF)
|
||||
set(WITH_INPUT_IME OFF)
|
||||
endif()
|
||||
|
@ -862,6 +864,16 @@ if(WITH_X11)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_X11_ALPHA)
|
||||
find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH})
|
||||
mark_as_advanced(X11_Xrender_LIB)
|
||||
if (X11_Xrender_LIB)
|
||||
list(APPEND PLATFORM_LINKLIBS ${X11_Xrender_LIB})
|
||||
else()
|
||||
set(WITH_X11_ALPHA OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
|
@ -3199,6 +3211,7 @@ if(FIRST_RUN)
|
|||
|
||||
info_cfg_text("System Options:")
|
||||
info_cfg_option(WITH_INSTALL_PORTABLE)
|
||||
info_cfg_option(WITH_X11_ALPHA)
|
||||
info_cfg_option(WITH_X11_XF86VMODE)
|
||||
info_cfg_option(WITH_X11_XINPUT)
|
||||
info_cfg_option(WITH_MEM_JEMALLOC)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_numOfAASamples, m_stereoVisual, true);
|
||||
|
||||
framebuffer_config = glXChooseFBConfig(m_display, DefaultScreen(m_display), glx_attribs, &fbcount);
|
||||
m_context = glXCreateContextAttribsARB(m_display, m_fbconfig, s_sharedContext, true, attribs);
|
||||
}
|
||||
else {
|
||||
GLXFBConfig *framebuffer_config = NULL;
|
||||
{
|
||||
int glx_attribs[64];
|
||||
int fbcount = 0;
|
||||
|
||||
if (framebuffer_config) {
|
||||
m_context = glXCreateContextAttribsARB(m_display, framebuffer_config[0], s_sharedContext, True, attribs);
|
||||
XFree(framebuffer_config);
|
||||
GHOST_X11_GL_GetAttributes(glx_attribs, 64, m_numOfAASamples, m_stereoVisual, false, true);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
/* Find the display with highest samples, starting at level requested */
|
||||
for (;;) {
|
||||
int glx_attribs[64];
|
||||
for (;;) {
|
||||
|
||||
GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, false);
|
||||
GHOST_X11_GL_GetAttributes(glx_attribs, 64, actualSamples, stereoVisual, needAlpha, true);
|
||||
|
||||
visualInfo = glXChooseVisual(display, DefaultScreen(display), glx_attribs);
|
||||
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 (visualInfo != 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);
|
||||
/* 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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__);
|
||||
|
||||
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),
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -301,7 +301,7 @@ bool GPG_Application::startScreenSaverFullScreen(
|
|||
const int stereoMode,
|
||||
const GHOST_TUns16 samples)
|
||||
{
|
||||
bool ret = startFullScreen(width, height, bpp, frequency, stereoVisual, stereoMode, samples);
|
||||
bool ret = startFullScreen(width, height, bpp, frequency, stereoVisual, stereoMode, 0, samples);
|
||||
if (ret)
|
||||
{
|
||||
HWND ghost_hwnd = findGhostWindowHWND(m_mainWindow);
|
||||
|
@ -325,6 +325,7 @@ bool GPG_Application::startWindow(
|
|||
int windowHeight,
|
||||
const bool stereoVisual,
|
||||
const int stereoMode,
|
||||
const int alphaBackground,
|
||||
const GHOST_TUns16 samples)
|
||||
{
|
||||
GHOST_GLSettings glSettings = {0};
|
||||
|
@ -333,6 +334,8 @@ bool GPG_Application::startWindow(
|
|||
//STR_String title ("Blender Player - GHOST");
|
||||
if (stereoVisual)
|
||||
glSettings.flags |= GHOST_glStereoVisual;
|
||||
if (alphaBackground)
|
||||
glSettings.flags |= GHOST_glAlphaBackground;
|
||||
glSettings.numOfAASamples = samples;
|
||||
|
||||
m_mainWindow = fSystem->createWindow(title, windowLeft, windowTop, windowWidth, windowHeight, GHOST_kWindowStateNormal,
|
||||
|
@ -360,6 +363,7 @@ bool GPG_Application::startEmbeddedWindow(
|
|||
const GHOST_TEmbedderWindowID parentWindow,
|
||||
const bool stereoVisual,
|
||||
const int stereoMode,
|
||||
const int alphaBackground,
|
||||
const GHOST_TUns16 samples)
|
||||
{
|
||||
GHOST_TWindowState state = GHOST_kWindowStateNormal;
|
||||
|
@ -367,6 +371,8 @@ bool GPG_Application::startEmbeddedWindow(
|
|||
|
||||
if (stereoVisual)
|
||||
glSettings.flags |= GHOST_glStereoVisual;
|
||||
if (alphaBackground)
|
||||
glSettings.flags |= GHOST_glAlphaBackground;
|
||||
glSettings.numOfAASamples = samples;
|
||||
|
||||
if (parentWindow != 0)
|
||||
|
@ -394,6 +400,7 @@ bool GPG_Application::startFullScreen(
|
|||
int bpp,int frequency,
|
||||
const bool stereoVisual,
|
||||
const int stereoMode,
|
||||
const int alphaBackground,
|
||||
const GHOST_TUns16 samples,
|
||||
bool useDesktop)
|
||||
{
|
||||
|
@ -407,7 +414,7 @@ bool GPG_Application::startFullScreen(
|
|||
setting.bpp = bpp;
|
||||
setting.frequency = frequency;
|
||||
|
||||
fSystem->beginFullScreen(setting, &m_mainWindow, stereoVisual, samples);
|
||||
fSystem->beginFullScreen(setting, &m_mainWindow, stereoVisual, alphaBackground, samples);
|
||||
m_mainWindow->setCursorVisibility(false);
|
||||
/* note that X11 ignores this (it uses a window internally for fullscreen) */
|
||||
m_mainWindow->setState(GHOST_kWindowStateFullScreen);
|
||||
|
|
|
@ -65,13 +65,13 @@ public:
|
|||
bool startWindow(STR_String& title,
|
||||
int windowLeft, int windowTop,
|
||||
int windowWidth, int windowHeight,
|
||||
const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0);
|
||||
const bool stereoVisual, const int stereoMode, const int alphaBackground=0, const GHOST_TUns16 samples=0);
|
||||
bool startFullScreen(int width, int height,
|
||||
int bpp, int frequency,
|
||||
const bool stereoVisual, const int stereoMode,
|
||||
const bool stereoVisual, const int stereoMode, const int alphaBackground = 0,
|
||||
const GHOST_TUns16 samples=0, bool useDesktop=false);
|
||||
bool startEmbeddedWindow(STR_String& title, const GHOST_TEmbedderWindowID parent_window,
|
||||
const bool stereoVisual, const int stereoMode, const GHOST_TUns16 samples=0);
|
||||
const bool stereoVisual, const int stereoMode, const int alphaBackground=0, const GHOST_TUns16 samples=0);
|
||||
#ifdef WIN32
|
||||
bool startScreenSaverFullScreen(int width, int height,
|
||||
int bpp, int frequency,
|
||||
|
|
|
@ -444,6 +444,7 @@ int main(
|
|||
int validArguments=0;
|
||||
bool samplesParFound = false;
|
||||
GHOST_TUns16 aasamples = 0;
|
||||
int alphaBackground = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
char **argv;
|
||||
|
@ -838,6 +839,12 @@ int main(
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 'a': // allow window to blend with display background
|
||||
{
|
||||
i++;
|
||||
alphaBackground = 1;
|
||||
break;
|
||||
}
|
||||
default: //not recognized
|
||||
{
|
||||
printf("Unknown argument: %s\n", argv[i++]);
|
||||
|
@ -1041,7 +1048,7 @@ int main(
|
|||
#endif
|
||||
{
|
||||
app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
|
||||
stereoWindow, stereomode, aasamples, (scene->gm.playerflag & GAME_PLAYER_DESKTOP_RESOLUTION));
|
||||
stereoWindow, stereomode, alphaBackground, aasamples, (scene->gm.playerflag & GAME_PLAYER_DESKTOP_RESOLUTION));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1088,7 +1095,7 @@ int main(
|
|||
app.startEmbeddedWindow(title, parentWindow, stereoWindow, stereomode, aasamples);
|
||||
else
|
||||
app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
|
||||
stereoWindow, stereomode, aasamples);
|
||||
stereoWindow, stereomode, alphaBackground, aasamples);
|
||||
|
||||
if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0)) {
|
||||
GPU_set_mipmap(0);
|
||||
|
|
Loading…
Reference in New Issue