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

DisplacementMapFilter Issue #882

Closed
Vabavia opened this issue Jul 10, 2016 · 6 comments
Closed

DisplacementMapFilter Issue #882

Vabavia opened this issue Jul 10, 2016 · 6 comments
Labels

Comments

@Vabavia
Copy link

Vabavia commented Jul 10, 2016

Hi once again, as promised, I wrote small standalone example that reproduces my problem:
When masked field moved DisplacementMapFilter acts unexpected. It moves when hold enabled (but must stay in position), and stays at top left corner when field cropped and field must be cropped to.

package {

    import flash.display.BitmapData;
    import flash.display.BitmapDataChannel;
    import flash.display.BlendMode;
    import flash.display.GradientType;
    import flash.display.Shape;
    import flash.display.SpreadMethod;
    import flash.display.Sprite;
    import flash.geom.Matrix;
    import flash.geom.Rectangle;
    import flash.system.Capabilities;

    import starling.core.Starling;
    import starling.display.Image;
    import starling.display.Quad;
    import starling.display.Sprite;
    import starling.events.Event;
    import starling.events.KeyboardEvent;
    import starling.filters.DisplacementMapFilter;
    import starling.text.TextField;
    import starling.textures.Texture;

    [SWF(width="640", height="360", frameRate="30", backgroundColor="#000000")]
    public class TestDisplacementMap extends flash.display.Sprite {
        private var board:Image;
        private var position:TextField;
        private var holdPosition:Boolean;

        public function TestDisplacementMap() {
            var starling:Starling = new Starling(starling.display.Sprite, stage, new Rectangle(0, 0, 640, 360));
            starling.stage.stageWidth = 640;
            starling.stage.stageHeight = 360;
            starling.enableErrorChecking = Capabilities.isDebugger;
            starling.skipUnchangedFrames = true;
            starling.addEventListener(Event.ROOT_CREATED, onRootCreated);
            starling.start();
        }

        private function update():void {
            position.text = 'x=' + board.x + ', y=' + board.y + '\nHold: ' + holdPosition;
            if (holdPosition) {
                DisplacementMapFilter(board.filter).mapX = -board.x;
                DisplacementMapFilter(board.filter).mapY = -board.y;
            }
        }

        private static function createWarpTexture(w:Number, h:Number, size:Number):Texture {
            var warpBD:BitmapData = new BitmapData(w, h, false, 0x7f7f7f);
            var warpShape:Shape = new Shape();
            var matrix:Matrix = new Matrix();
            matrix.createGradientBox(size, size, 0, 0, 0);
            warpShape.graphics.beginGradientFill(
                GradientType.RADIAL,
                [0x000000, 0x7F7F7F, 0x000000],
                [1, 1, 1],
                [0x00, 0x7F, 0xFF],
                matrix,
                SpreadMethod.PAD
            );
            warpShape.graphics.drawRect(0, 0, size, size);
            warpBD.draw(warpShape, null, null, BlendMode.ADD);
            var warpTexture:Texture = Texture.fromBitmapData(warpBD);
            return warpTexture;
        }

        private static function createBoardTexture(w:int, h:int, cellSize:int):Texture {
            var boardBD:BitmapData = new BitmapData(w, h, false, 0xf0f0f0);
            var rect:Rectangle = new Rectangle();
            for (var i:int = 0; i < w / cellSize; i++) {
                for (var j:int = 0; j < h / cellSize; j++) {
                    if ((i + j) % 2) {
                        rect.setTo(i * cellSize, j * cellSize, cellSize, cellSize);
                        boardBD.fillRect(rect, 0x0f0f0f);
                    }
                }
            }
            var boardTexture:Texture = Texture.fromBitmapData(boardBD);
            return boardTexture;
        }

        private function onRootCreated(event:Event):void {
            var root:starling.display.Sprite = event.data as starling.display.Sprite;
            var boardTexture:Texture = createBoardTexture(800, 600, 10);
            board = new Image(boardTexture);

            var mask:Quad = new Quad(320, 320);
            board.mask = mask;
            root.addChild(mask);

            root.addChild(board);

            var warpTexture:Texture = createWarpTexture(320, 320, 60);
            var warp:Image = new Image(warpTexture);
            warp.x = 320;
            root.addChild(warp);

            var filter:DisplacementMapFilter = new DisplacementMapFilter(
                warpTexture,
                BitmapDataChannel.RED,
                BitmapDataChannel.GREEN,
                40,
                40
            );
            board.filter = filter;

            position = new TextField(320, 40);
            position.format.color = 0x00ff00;
            position.y = 320;
            root.addChild(position);

            var help:TextField = new TextField(
                320, 40,
                'Use Arrows To Move Board,\nPress "H" For Filter Hold Position'
            );
            help.format.color = 0x00ff00;
            help.x = 320;
            help.y = 320;
            root.addChild(help);


            Starling.current.stage.addEventListener(KeyboardEvent.KEY_DOWN, onDebugKeyInput);
            update();
        }

        private function onDebugKeyInput(event:KeyboardEvent):void {
            switch (event.keyCode) {
                case 37:
                    board.x -= 15;
                    break;
                case 38:
                    board.y -= 15;
                    break;
                case 39:
                    board.x += 15;
                    break;
                case 40:
                    board.y += 15;
                    break;
                case 72:
                    holdPosition = !holdPosition;
                    break;
            }
            update();
        }
    }
}
@PrimaryFeather
Copy link
Contributor

Thanks a lot for creating the sample! I'll look into it as soon as time permits.

@PrimaryFeather
Copy link
Contributor

I just had a look at it, and can reproduce it. Thanks again for taking the time to create the sample!

Just one question: even without a mask, the filter acts wrongly, right? When moved out of the screen, the map texture should first be cropped and then move out, too. That't the main issue here — right?

@PrimaryFeather
Copy link
Contributor

Oh, and one more thing: a quick fix is to call "filter.cache()". Then it will act as expected (until the filtered object changes, then you have to make that call again.

(Still, I'd like this to work consistently even without that workaround.)

@PrimaryFeather
Copy link
Contributor

I think that should do it! Please try it out and let me know if that works for you.
In any case, thanks a lot for pointing me at this problem!

@Vabavia
Copy link
Author

Vabavia commented Jul 20, 2016

Thank you! Fix work perfect, problem solved!

@PrimaryFeather
Copy link
Contributor

I'm glad to hear that! 😄
All the best for the rest of your project!

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

No branches or pull requests

2 participants