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

Fix: Track blendMode changes at the Context3D level instead of OpenGLRenderer level. #2635

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

andresa88
Copy link
Contributor

Fixes behavior when a blendMode is assigned to a child at the top of the layer stack in a container and the container's cacheAsBitmap is set to true. The child OpenGLRenderer will change the Context3D blend settings and so the parent renderer needs to be able to update the blend settings if the supplied blendMode differs from the one last used in the child renderer.

… OpenGLRenderer level.

Fixes behavior when a blendMode is assigned to a child in a container with cacheAsBitmap = true.
@joshtynjala
Copy link
Member

Can you write some simple code that demonstrates how to reproduce the issue? Thanks!

@andresa88
Copy link
Contributor Author

Sure here you go! The green square should be opaque, but is instead blended with BlendMode.ADD and so it appears transparent. But once the scene is re-rendered, the green squared is blended correctly.

OTOH if you set container.cacheAsBitmap to false, the green square is opaque from the start as expected.

package;

import haxe.Timer;
import openfl.display.Sprite;
import openfl.display.BlendMode;

class Main extends Sprite
{
	public function new ()
	{
		super ();

		stage.color = 0;

		var container = new Sprite();
		var red = createSquare(0xFFFF0000);
		var green = createSquare(0xFF00FF00);
		var blue = createSquare(0xFF0000FF);

		stage.addChild(container);
		container.addChild(red);
		container.addChild(blue);
		stage.addChild(green);

		blue.x = 100;
		blue.y = 100;
		green.x = 200;
		green.y = 200;

		// green should be opaque from the start
		container.cacheAsBitmap = true;
		blue.blendMode = BlendMode.ADD;

		var tick = new Timer(1000);
		tick.run = function()
		{
			// Re-render. This fixes the issue... at least until the next time 
			// the cached bitmap needs to be re-rendered
			green.x += 50;
			tick.stop();
		}
	}

	function createSquare(color: Int)
	{
		var square = new Sprite();
		square.graphics.beginFill(color);
		square.graphics.drawRect(0, 0, 400, 400);
		square.graphics.endFill();
		return square;
	}
}

@joshtynjala
Copy link
Member

joshtynjala commented May 5, 2023

I can reproduce the issue using the supplied code. I checked in Flash too, and I confirm that green should be opaque from the start.

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

Successfully merging this pull request may close these issues.

None yet

2 participants