axmolengine / axmol

Axmol Engine – A Multi-platform Engine for Desktop, XBOX (UWP) and Mobile games. (A fork of Cocos2d-x-4.0)
https://axmol.dev
MIT License
868 stars 195 forks source link

Clipping issue with different child stencils #1956

Closed rh101 closed 3 months ago

rh101 commented 3 months ago

If different stencils are added as children of a parent stencil, then the last child stencil added is applied to all other stencil positions.

For example, in the cpp-tests void HoleDemo::pokeHoleAtPoint(Vec2 point), change this line:

auto holeStencil = Sprite::create("Images/hole_stencil.png");

to this: auto holeStencil = RandomHelper::random_int(0, 1) == 0 ? Sprite::create("Images/hole_stencil.png") : Sprite::create("Images/hole_stencil2.png");

Add this hole_stencil2.png image to the to the axmol\tests\cpp-tests\Content\Images folder: hole_stencil2

Run cpp-tests, then click on "29:Node: Clipping" test. Then navigate to "2:Hole Demo". Click on the spinning square image, and you will see the following: image image

MP4 video of issue: https://github.com/axmolengine/axmol/assets/8603230/5c82dd9a-be6d-4246-8193-9b0217f3329e

The problem is that the last image used as a stencil is applied to all other existing stencils.

The expected output is that each new stencil would not affect the previous stencils applied, so there should be a mix of round and square holes in that image.

Is this a limitation of the ClippingNode, or is this a bug?

rh101 commented 3 months ago

I think this has something to do with the ProgramState being set on all child stencil nodes. They are all being set to the same ProgramState instance, but if this is changed to be a unique instance per child, then the problem is fixed, but memory usage goes up because of some other issue that I'm trying to track down.

rh101 commented 3 months ago

Issue should now be fixed in PR #1957

The resulting output is now this: image

To reproduce this output, then in addition to the cpp-tests changes mentioned in the initial post above, also change this line: holesClipper->setStencil(_holesStencil);

to this: holesClipper->setStencil(_holesStencil, true);