Merge pull request #38629 from Technohacker/windows-dwm-ppt-3.2
Use DwmEnableBlurBehindWindow for Windows Per Pixel Transparency
This commit is contained in:
commit
5d26836c78
|
@ -247,10 +247,6 @@ public:
|
||||||
virtual bool get_window_per_pixel_transparency_enabled() const { return false; }
|
virtual bool get_window_per_pixel_transparency_enabled() const { return false; }
|
||||||
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled) {}
|
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled) {}
|
||||||
|
|
||||||
virtual uint8_t *get_layered_buffer_data() { return NULL; }
|
|
||||||
virtual Size2 get_layered_buffer_size() { return Size2(0, 0); }
|
|
||||||
virtual void swap_layered_buffer() {}
|
|
||||||
|
|
||||||
virtual void set_ime_active(const bool p_active) {}
|
virtual void set_ime_active(const bool p_active) {}
|
||||||
virtual void set_ime_position(const Point2 &p_pos) {}
|
virtual void set_ime_position(const Point2 &p_pos) {}
|
||||||
virtual Point2 get_ime_selection() const { return Point2(); }
|
virtual Point2 get_ime_selection() const { return Point2(); }
|
||||||
|
|
|
@ -448,18 +448,7 @@ void RasterizerGLES2::output_lens_distorted_to_screen(RID p_render_target, const
|
||||||
void RasterizerGLES2::end_frame(bool p_swap_buffers) {
|
void RasterizerGLES2::end_frame(bool p_swap_buffers) {
|
||||||
|
|
||||||
if (OS::get_singleton()->is_layered_allowed()) {
|
if (OS::get_singleton()->is_layered_allowed()) {
|
||||||
if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
|
if (!OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
|
||||||
#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED)
|
|
||||||
Size2 wndsize = OS::get_singleton()->get_layered_buffer_size();
|
|
||||||
uint8_t *data = OS::get_singleton()->get_layered_buffer_data();
|
|
||||||
if (data) {
|
|
||||||
glReadPixels(0, 0, wndsize.x, wndsize.y, GL_BGRA, GL_UNSIGNED_BYTE, data);
|
|
||||||
OS::get_singleton()->swap_layered_buffer();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
//clear alpha
|
//clear alpha
|
||||||
glColorMask(false, false, false, true);
|
glColorMask(false, false, false, true);
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
|
|
|
@ -372,18 +372,7 @@ void RasterizerGLES3::output_lens_distorted_to_screen(RID p_render_target, const
|
||||||
void RasterizerGLES3::end_frame(bool p_swap_buffers) {
|
void RasterizerGLES3::end_frame(bool p_swap_buffers) {
|
||||||
|
|
||||||
if (OS::get_singleton()->is_layered_allowed()) {
|
if (OS::get_singleton()->is_layered_allowed()) {
|
||||||
if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
|
if (!OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
|
||||||
#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED)
|
|
||||||
Size2 wndsize = OS::get_singleton()->get_layered_buffer_size();
|
|
||||||
uint8_t *data = OS::get_singleton()->get_layered_buffer_data();
|
|
||||||
if (data) {
|
|
||||||
glReadPixels(0, 0, wndsize.x, wndsize.y, GL_BGRA, GL_UNSIGNED_BYTE, data);
|
|
||||||
OS::get_singleton()->swap_layered_buffer();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
//clear alpha
|
//clear alpha
|
||||||
glColorMask(false, false, false, true);
|
glColorMask(false, false, false, true);
|
||||||
glClearColor(0, 0, 0, 1);
|
glClearColor(0, 0, 0, 1);
|
||||||
|
|
|
@ -2661,7 +2661,6 @@ void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) {
|
||||||
if (!is_layered_allowed()) return;
|
if (!is_layered_allowed()) return;
|
||||||
if (layered_window != p_enabled) {
|
if (layered_window != p_enabled) {
|
||||||
if (p_enabled) {
|
if (p_enabled) {
|
||||||
set_borderless_window(true);
|
|
||||||
GLint opacity = 0;
|
GLint opacity = 0;
|
||||||
[window_object setBackgroundColor:[NSColor clearColor]];
|
[window_object setBackgroundColor:[NSColor clearColor]];
|
||||||
[window_object setOpaque:NO];
|
[window_object setOpaque:NO];
|
||||||
|
@ -2691,9 +2690,6 @@ void OS_OSX::set_borderless_window(bool p_borderless) {
|
||||||
if (p_borderless) {
|
if (p_borderless) {
|
||||||
[window_object setStyleMask:NSWindowStyleMaskBorderless];
|
[window_object setStyleMask:NSWindowStyleMaskBorderless];
|
||||||
} else {
|
} else {
|
||||||
if (layered_window)
|
|
||||||
set_window_per_pixel_transparency_enabled(false);
|
|
||||||
|
|
||||||
[window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (resizable ? NSWindowStyleMaskResizable : 0)];
|
[window_object setStyleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | (resizable ? NSWindowStyleMaskResizable : 0)];
|
||||||
|
|
||||||
// Force update of the window styles
|
// Force update of the window styles
|
||||||
|
|
|
@ -974,27 +974,6 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
maximized = false;
|
maximized = false;
|
||||||
minimized = false;
|
minimized = false;
|
||||||
}
|
}
|
||||||
if (is_layered_allowed() && layered_window) {
|
|
||||||
DeleteObject(hBitmap);
|
|
||||||
|
|
||||||
RECT r;
|
|
||||||
GetWindowRect(hWnd, &r);
|
|
||||||
dib_size = Size2i(r.right - r.left, r.bottom - r.top);
|
|
||||||
|
|
||||||
BITMAPINFO bmi;
|
|
||||||
ZeroMemory(&bmi, sizeof(BITMAPINFO));
|
|
||||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
||||||
bmi.bmiHeader.biWidth = dib_size.x;
|
|
||||||
bmi.bmiHeader.biHeight = dib_size.y;
|
|
||||||
bmi.bmiHeader.biPlanes = 1;
|
|
||||||
bmi.bmiHeader.biBitCount = 32;
|
|
||||||
bmi.bmiHeader.biCompression = BI_RGB;
|
|
||||||
bmi.bmiHeader.biSizeImage = dib_size.x * dib_size.y * 4;
|
|
||||||
hBitmap = CreateDIBSection(hDC_dib, &bmi, DIB_RGB_COLORS, (void **)&dib_data, NULL, 0x0);
|
|
||||||
SelectObject(hDC_dib, hBitmap);
|
|
||||||
|
|
||||||
ZeroMemory(dib_data, dib_size.x * dib_size.y * 4);
|
|
||||||
}
|
|
||||||
//return 0; // Jump Back
|
//return 0; // Jump Back
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -2231,86 +2210,34 @@ void OS_Windows::set_window_per_pixel_transparency_enabled(bool p_enabled) {
|
||||||
if (!is_layered_allowed()) return;
|
if (!is_layered_allowed()) return;
|
||||||
if (layered_window != p_enabled) {
|
if (layered_window != p_enabled) {
|
||||||
if (p_enabled) {
|
if (p_enabled) {
|
||||||
set_borderless_window(true);
|
|
||||||
//enable per-pixel alpha
|
//enable per-pixel alpha
|
||||||
hDC_dib = CreateCompatibleDC(GetDC(hWnd));
|
|
||||||
|
|
||||||
SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
|
DWM_BLURBEHIND bb = { 0 };
|
||||||
|
HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
|
||||||
RECT r;
|
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
|
||||||
GetWindowRect(hWnd, &r);
|
bb.hRgnBlur = hRgn;
|
||||||
dib_size = Size2(r.right - r.left, r.bottom - r.top);
|
bb.fEnable = TRUE;
|
||||||
|
DwmEnableBlurBehindWindow(hWnd, &bb);
|
||||||
BITMAPINFO bmi;
|
|
||||||
ZeroMemory(&bmi, sizeof(BITMAPINFO));
|
|
||||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
||||||
bmi.bmiHeader.biWidth = dib_size.x;
|
|
||||||
bmi.bmiHeader.biHeight = dib_size.y;
|
|
||||||
bmi.bmiHeader.biPlanes = 1;
|
|
||||||
bmi.bmiHeader.biBitCount = 32;
|
|
||||||
bmi.bmiHeader.biCompression = BI_RGB;
|
|
||||||
bmi.bmiHeader.biSizeImage = dib_size.x * dib_size.y * 4;
|
|
||||||
hBitmap = CreateDIBSection(hDC_dib, &bmi, DIB_RGB_COLORS, (void **)&dib_data, NULL, 0x0);
|
|
||||||
SelectObject(hDC_dib, hBitmap);
|
|
||||||
|
|
||||||
ZeroMemory(dib_data, dib_size.x * dib_size.y * 4);
|
|
||||||
|
|
||||||
layered_window = true;
|
layered_window = true;
|
||||||
} else {
|
} else {
|
||||||
//disable per-pixel alpha
|
//disable per-pixel alpha
|
||||||
layered_window = false;
|
layered_window = false;
|
||||||
|
|
||||||
SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
|
DWM_BLURBEHIND bb = { 0 };
|
||||||
|
HRGN hRgn = CreateRectRgn(0, 0, -1, -1);
|
||||||
//cleanup
|
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
|
||||||
DeleteObject(hBitmap);
|
bb.hRgnBlur = hRgn;
|
||||||
DeleteDC(hDC_dib);
|
bb.fEnable = FALSE;
|
||||||
|
DwmEnableBlurBehindWindow(hWnd, &bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *OS_Windows::get_layered_buffer_data() {
|
|
||||||
|
|
||||||
return (is_layered_allowed() && layered_window) ? dib_data : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
Size2 OS_Windows::get_layered_buffer_size() {
|
|
||||||
|
|
||||||
return (is_layered_allowed() && layered_window) ? dib_size : Size2();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_Windows::swap_layered_buffer() {
|
|
||||||
|
|
||||||
if (is_layered_allowed() && layered_window) {
|
|
||||||
|
|
||||||
//premultiply alpha
|
|
||||||
for (int y = 0; y < dib_size.y; y++) {
|
|
||||||
for (int x = 0; x < dib_size.x; x++) {
|
|
||||||
float alpha = (float)dib_data[y * (int)dib_size.x * 4 + x * 4 + 3] / (float)0xFF;
|
|
||||||
dib_data[y * (int)dib_size.x * 4 + x * 4 + 0] *= alpha;
|
|
||||||
dib_data[y * (int)dib_size.x * 4 + x * 4 + 1] *= alpha;
|
|
||||||
dib_data[y * (int)dib_size.x * 4 + x * 4 + 2] *= alpha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//swap layered window buffer
|
|
||||||
POINT ptSrc = { 0, 0 };
|
|
||||||
SIZE sizeWnd = { (long)dib_size.x, (long)dib_size.y };
|
|
||||||
BLENDFUNCTION bf;
|
|
||||||
bf.BlendOp = AC_SRC_OVER;
|
|
||||||
bf.BlendFlags = 0;
|
|
||||||
bf.AlphaFormat = AC_SRC_ALPHA;
|
|
||||||
bf.SourceConstantAlpha = 0xFF;
|
|
||||||
UpdateLayeredWindow(hWnd, NULL, NULL, &sizeWnd, hDC_dib, &ptSrc, 0, &bf, ULW_ALPHA);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OS_Windows::set_borderless_window(bool p_borderless) {
|
void OS_Windows::set_borderless_window(bool p_borderless) {
|
||||||
if (video_mode.borderless_window == p_borderless)
|
if (video_mode.borderless_window == p_borderless)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!p_borderless && layered_window)
|
|
||||||
set_window_per_pixel_transparency_enabled(false);
|
|
||||||
|
|
||||||
video_mode.borderless_window = p_borderless;
|
video_mode.borderless_window = p_borderless;
|
||||||
|
|
||||||
preserve_window_size = true;
|
preserve_window_size = true;
|
||||||
|
@ -3477,7 +3404,6 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
|
||||||
drop_events = false;
|
drop_events = false;
|
||||||
key_event_pos = 0;
|
key_event_pos = 0;
|
||||||
layered_window = false;
|
layered_window = false;
|
||||||
hBitmap = NULL;
|
|
||||||
force_quit = false;
|
force_quit = false;
|
||||||
alt_mem = false;
|
alt_mem = false;
|
||||||
gr_mem = false;
|
gr_mem = false;
|
||||||
|
@ -3534,11 +3460,6 @@ OS_Windows::~OS_Windows() {
|
||||||
wintab_WTClose(wtctx);
|
wintab_WTClose(wtctx);
|
||||||
wtctx = 0;
|
wtctx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_layered_allowed() && layered_window) {
|
|
||||||
DeleteObject(hBitmap);
|
|
||||||
DeleteDC(hDC_dib);
|
|
||||||
}
|
|
||||||
#ifdef STDOUT_FILE
|
#ifdef STDOUT_FILE
|
||||||
fclose(stdo);
|
fclose(stdo);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "drivers/xaudio2/audio_driver_xaudio2.h"
|
#include "drivers/xaudio2/audio_driver_xaudio2.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <dwmapi.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -297,10 +298,6 @@ class OS_Windows : public OS {
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
Point2 last_pos;
|
Point2 last_pos;
|
||||||
|
|
||||||
HBITMAP hBitmap; //DIB section for layered window
|
|
||||||
uint8_t *dib_data;
|
|
||||||
Size2 dib_size;
|
|
||||||
HDC hDC_dib;
|
|
||||||
bool layered_window;
|
bool layered_window;
|
||||||
|
|
||||||
uint32_t move_timer_id;
|
uint32_t move_timer_id;
|
||||||
|
@ -452,10 +449,6 @@ public:
|
||||||
virtual bool get_window_per_pixel_transparency_enabled() const;
|
virtual bool get_window_per_pixel_transparency_enabled() const;
|
||||||
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
|
virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
|
||||||
|
|
||||||
virtual uint8_t *get_layered_buffer_data();
|
|
||||||
virtual Size2 get_layered_buffer_size();
|
|
||||||
virtual void swap_layered_buffer();
|
|
||||||
|
|
||||||
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
|
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
|
||||||
virtual Error close_dynamic_library(void *p_library_handle);
|
virtual Error close_dynamic_library(void *p_library_handle);
|
||||||
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
|
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
|
||||||
|
|
|
@ -964,7 +964,6 @@ void OS_X11::set_window_per_pixel_transparency_enabled(bool p_enabled) {
|
||||||
if (!is_layered_allowed()) return;
|
if (!is_layered_allowed()) return;
|
||||||
if (layered_window != p_enabled) {
|
if (layered_window != p_enabled) {
|
||||||
if (p_enabled) {
|
if (p_enabled) {
|
||||||
set_borderless_window(true);
|
|
||||||
layered_window = true;
|
layered_window = true;
|
||||||
} else {
|
} else {
|
||||||
layered_window = false;
|
layered_window = false;
|
||||||
|
@ -1683,9 +1682,6 @@ void OS_X11::set_borderless_window(bool p_borderless) {
|
||||||
if (get_borderless_window() == p_borderless)
|
if (get_borderless_window() == p_borderless)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!p_borderless && layered_window)
|
|
||||||
set_window_per_pixel_transparency_enabled(false);
|
|
||||||
|
|
||||||
current_videomode.borderless_window = p_borderless;
|
current_videomode.borderless_window = p_borderless;
|
||||||
|
|
||||||
Hints hints;
|
Hints hints;
|
||||||
|
|
Loading…
Reference in New Issue