Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental support for windows with per-pixel transparency. #14622

Merged
merged 1 commit into from
May 8, 2018

Conversation

bruvzg
Copy link
Member

@bruvzg bruvzg commented Dec 13, 2017

Supports:

  • macOS support (Using NSOpenGLCPSurfaceOpacity)
  • Windows support (Using UpdateLayeredWindow)
  • X11 support (Selecting XVisualInfo with alpha)

New APIs:

  • Project setting display/window/allow_per_pixel_transparency (default value: false) - enables per-pixel transparency support (this should be enabled in project settings and can't be changed at runtime)

  • Project setting display/window/per_pixel_transparency (default value: false) - sets initial window transparency state

  • Project setting display/window/per_pixel_transparency_splash (default value: false) - sets splash screen transparency state (set boot splash to custom .png with alpha channel)

  • bool OS::window_per_pixel_transparency_enabled property
    Enables/Disables per pixel transparency, when transparency is enabled window mode is switched to borderless.

Usage:

  • Set window/allow_per_pixel_transparency = true in project settings.
  • Set OS.window_per_pixel_transparency_enabled = true or display/window/per_pixel_transparency project setting to enable transparency.
  • In most cases you want to disable main viewport background rendering by calling get_tree().get_root().set_transparent_background(true), or change Environment->Default Clear Color alpha value.

Video:

https://streamable.com/ukpxq

Screenshots:

macOS

mac1
mac2

Windows 10

windows1
windows2

Linux/X11

linux1
linux2

Demo:

physics_platformer_transp.zip (Updated)

Note:

I have removed get_absolute_mouse_position API from this PR since it was buggy on some Linux distros and there's more advanced and convenient PR for window movement/resizing: #16512

Here's its code if someone needs it
Point2 OS_OSX::get_absolute_mouse_position() const {

	const NSPoint mouse_pos = [NSEvent mouseLocation];

	for (NSScreen *screen in [NSScreen screens]) {
		NSRect frame = [screen frame];
		if (NSMouseInRect(mouse_pos, frame, NO)) {
			return Vector2((int)mouse_pos.x, (int)-mouse_pos.y);
		}
	}

	WARN_PRINTS(TTR("No mouse found."));
	return Vector2();
}

Point2 OS_Windows::get_absolute_mouse_position() const {

	POINT pos = { 0, 0 };
	GetCursorPos(&pos);

	return Vector2((int)pos.x, (int)pos.y);
}

Point2 OS_X11::get_absolute_mouse_position() const {

	int number_of_screens = XScreenCount(x11_display);
	for (int i = 0; i < number_of_screens; i++) {
		Window root, child;
		int root_x, root_y, win_x, win_y;
		unsigned int mask;
		if (XQueryPointer(x11_display, XRootWindow(x11_display, i), &root, &child, &root_x, &root_y, &win_x, &win_y, &mask)) {
			XWindowAttributes root_attrs;
			XGetWindowAttributes(x11_display, root, &root_attrs);

			return Vector2(root_attrs.x + root_x, root_attrs.y + root_y);
		}
	}

	WARN_PRINTS(TTR("No mouse found."));
	return Vector2();
}

Fixes #18009, and partially #6511

@MarianoGnu
Copy link
Contributor

Point2 Input::get_absolute_mouse_position()
I'm curious about how this works with several monitors, is there a way to get the current monitor wich mouse is in and therefore it's resolution? Not thinking in any special usecase

@bruvzg
Copy link
Member Author

bruvzg commented Dec 13, 2017

@MarianoGnu Works with multiple monitors (Tested with two monitors on macOS and Windows).

I don't know any way to get monitor where mouse is in directly and get resolution, but it is possible to get current monitor using OS::get_screen_position(int p_screen) and OS::get_screen_size(int p_screen).

@MarianoGnu
Copy link
Contributor

so Input::get_absolute_mouse_position() will return the position of the current monitor or the position relative to the main monitor? (if you have secondary monitor on the right and mouse is there position.x would be monitor1.width+monitor2.current_x)

@bruvzg
Copy link
Member Author

bruvzg commented Dec 13, 2017

so Input::get_absolute_mouse_position() will return the position of the current monitor or the position relative to the main monitor?

Relative to main monitor.

if you have secondary monitor on the right and mouse is there position.x would be monitor1.width+monitor2.current_x

Yes.

@blurymind
Copy link

NICE!! :D

@bruvzg bruvzg force-pushed the non-rectangular-windows branch from 25111f2 to c1baef7 Compare December 13, 2017 17:57
@bruvzg
Copy link
Member Author

bruvzg commented Dec 13, 2017

Update: added X11 support.

@bruvzg bruvzg force-pushed the non-rectangular-windows branch 2 times, most recently from 3392c81 to a849859 Compare December 15, 2017 10:38
@akien-mga
Copy link
Member

Thanks a lot for your contribution!
We are now entering a strict release freeze for Godot 3.0 and will only consider major bug fixes. We won't merge new features and enhancements anymore until 3.0 is released.

Moving this PR to the 3.1 milestone, to be reviewed once the release freeze is lifted. It could eventually be cherry-picked for a future 3.0.1 maintenance release if it doesn't change the user-facing APIs and doesn't compromise the engine's stability.

@akien-mga akien-mga added this to the 3.1 milestone Jan 4, 2018
@bruvzg bruvzg force-pushed the non-rectangular-windows branch from a849859 to d9a6c46 Compare January 4, 2018 15:02
@bruvzg bruvzg force-pushed the non-rectangular-windows branch from d9a6c46 to f142704 Compare January 16, 2018 10:14
@MarianoGnu MarianoGnu mentioned this pull request Feb 7, 2018
4 tasks
@silverkorn
Copy link

For UWP, I guess you already checked that:
https://docs.microsoft.com/en-us/windows/uwp/design/style/acrylic#custom-acrylic-brush ?

@bruvzg bruvzg force-pushed the non-rectangular-windows branch 3 times, most recently from cb47012 to c5f8cdb Compare March 1, 2018 16:34
@vnen vnen mentioned this pull request Apr 5, 2018
@bruvzg bruvzg force-pushed the non-rectangular-windows branch from c5f8cdb to 397ad84 Compare April 6, 2018 13:32
@bruvzg bruvzg force-pushed the non-rectangular-windows branch from 397ad84 to ddae098 Compare April 7, 2018 14:12
@bruvzg bruvzg changed the title [WIP] Experimental support for windows with per-pixel transparency. Experimental support for windows with per-pixel transparency. Apr 7, 2018
@Timofffee
Copy link
Contributor

Bump

@hpvb
Copy link
Member

hpvb commented May 8, 2018

X11 code looks good.

@hpvb hpvb merged commit e668757 into godotengine:master May 8, 2018
@bruvzg bruvzg deleted the non-rectangular-windows branch May 8, 2018 17:19
bruvzg added a commit to bruvzg/godot that referenced this pull request May 18, 2018
akien-mga added a commit that referenced this pull request May 18, 2018
malcolmhoward pushed a commit to malcolmhoward/godot that referenced this pull request Jul 31, 2018
malcolmhoward pushed a commit to malcolmhoward/godot that referenced this pull request Jul 31, 2018
@FransGerards
Copy link

Hi there, I tried this script but the background doesn't get transparent. Is there something I need to change in this script?

godot transparency

@akien-mga
Copy link
Member

You have to set OS.window_allow_per_pixel_transparency_enabled to true too.

@bruvzg
Copy link
Member Author

bruvzg commented Feb 28, 2019

I need to change in this script?

Names of the settings were changed in #26087.

Open Project Setting and make sure that “display > window > per pixel transparency > allowed” and “display > window > per pixel transparency > splash” are selected.

@FransGerards
Copy link

I checked the project settings. Both the options are selected.
and I changed the name settings. Still this doesn't work.

godot transparency 2

@bruvzg
Copy link
Member Author

bruvzg commented Feb 28, 2019

There's no OS.window_allow_per_pixel_transparency_enabled, allow should be checked in setting and can't be changed at runtime (it's controlling gl context creation).

If it is project created before #26087, make sure it's one under per pixel transparency subsection not the one on the top of the list.

screenshot 2019-02-28 at 13 22 50

Then you can use OS.window_per_pixel_transparency_enabled = true/false to control window transparency and get_tree().get_root().set_transparent_background(true/false) to enable/disable viewport background (in most cases you want both).

@bruvzg
Copy link
Member Author

bruvzg commented Feb 28, 2019

Here's minimal test project with up to date settings - tranp.zip

@FransGerards
Copy link

I tried to open the test project but it won't open.

I have now checked the boxes.

godot transparency 3

@bruvzg
Copy link
Member Author

bruvzg commented Feb 28, 2019

I tried to open the test project but it won't open.

Which Godot version are you using?

@FransGerards
Copy link

Im using Godot_v3.0.6-stable_win64

@bruvzg
Copy link
Member Author

bruvzg commented Feb 28, 2019

Im using Godot_v3.0.6

Per-pixel transparency is 3.1 feature, it's not available in 3.0.

@FransGerards
Copy link

Im using Godot_v3.0.6

Per-pixel transparency is 3.1 feature, it's not available in 3.0.

Where can i find the 3.1 version?

@bruvzg
Copy link
Member Author

bruvzg commented Feb 28, 2019

Where can i find the 3.1 version?

It's not released, latest beta is available at https://godotengine.org/article/dev-snapshot-godot-3-1-beta-8

@FransGerards
Copy link

FransGerards commented Feb 28, 2019

Thanks, I downloaded the beta. Now I can open you test project.

This is the result I get when opening
godot transparency 4

When I put it on its a black background

I opent the gamefile again and this one is transparent.

I'm know figuring out why. Thanks for the help!

@ducklin5
Copy link
Contributor

So it not possible to have transparency and the OS borders? I've tried this:

func _ready():
	OS.window_per_pixel_transparency_enabled = true
	get_tree().get_root().set_transparent_background(true)
	OS.window_borderless = false # Black instead of transparent

@Ashesh3
Copy link
Contributor

Ashesh3 commented May 10, 2020

So it not possible to have transparency and the OS borders? I've tried this:

func _ready():
	OS.window_per_pixel_transparency_enabled = true
	get_tree().get_root().set_transparent_background(true)
	OS.window_borderless = false # Black instead of transparent

+1 having the same issue @bruvzg , any updates on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Window Transparency
10 participants