ppy / osu-framework

A game framework written with osu! in mind.
MIT License
1.66k stars 417 forks source link

Allow custom clear color for the window background #6205

Open Erinaaaaaaa opened 7 months ago

Erinaaaaaaa commented 7 months ago

A feature like this would allow making transparent applications for OBS.

In this specific scenario, a transparent clear color would likely allow for better management of transparency than chroma keying for example.

I tried an implementation a few days ago with just being able to change the clear color to transparent, but then I ran into issues with alpha blending (see the dark blobs below around the green and red lights) - let me know if you'd like me to upload a branch with my changes. image

bdach commented 7 months ago

Use a Box that fills all available space for chroma-keying? Or if you really don't want to, write a custom DrawNode for the root-level container that calls Renderer.Clear?

I don't see any reason to make any changes to framework to support this.

I'm not even sure how "clearing with transparent colour" works or does anything useful at all. It's not like the WM will know that the game has cleared its surface to transparent?

Erinaaaaaaa commented 7 months ago

A transparent clear color allows using the "Allow Transparency" option in OBS' Game Capture to capture a transparent image directly for compositing a stream. An example of an app that already does this is Vtuber avatar tool VSeeFace.

In this case, I'm making a telemetry HUD overlay for F1 games (hence the screenshot above) as playing them in VR removes any and all HUD - in fact, the screenshot comes from OBS: image

The main reason why I'm looking specifically for a transparent clear is to make sure I'm not limited in the colors I can use - the wheel lights (the row of 15 rectangles) has all three primary colors (green, red, and blue in that order), and I'm not entirely sure a chroma key would work all that well, though I haven't tried either.

That being said, I didn't consider the option of a custom DrawNode, so technically I suppose it's already possible to clear to a custom color? I'd generally like an easier way to change just the color, but a framework change might indeed not be needed for that. I'll need to play around with this, but then alpha blending might remain an issue, which would probably need a separate issue/discussion.

peppy commented 7 months ago

We won't have any official use for this, so I'd recommend implementing yourself. If it's simple enough, we can consider merging the feature.

Keep in mind that implementing will have serious cross-platform concerns (ie. it likely won't be usable on mobile) and that may increase implementation complexity.

smoogipoo commented 7 months ago

The first thing I'd check is to see if this works in theory by changing this line: https://github.com/ppy/osu-framework/blob/613cfdc0244c04409151dd0f81a790d00f4af711/osu.Framework/Graphics/Rendering/Renderer.cs#L268

Then, I think the best way is for a custom DrawNode as previously proposed:

protected override DrawNode CreateDrawNode() => new GameDrawNode(this);

private class GameDrawNode : CompositeDrawableDrawNode
{
    public GameDrawNode(CompositeDrawable source)
        : base(source)
    {
    }

    protected override void Draw(IRenderer renderer)
    {
        renderer.Clear(new ClearInfo(Color4.Pink));
        base.Draw(renderer);
    }
}
EVAST9919 commented 6 months ago

but then I ran into issues with alpha blending (see the dark blobs below around the green and red lights)

Simplest solution for this would be using additive blending for glow. If you are using EdgeEffect - there's an EffectBlending parameter. (Though I'm not sure how it will react to transparent background and your particular use case, so testing from your end is required)