vipnj / away3d

Automatically exported from code.google.com/p/away3d
0 stars 0 forks source link

Setting MovieMaterial.lockH / lockW after render() causes failure to render bitmap #92

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create a scene with an object with a MovieMaterial
2. Call .render() in ENTER_FRAME
3. Set lockW or lockH on the MovieMaterial after the call to .render() but
before the flash player has a chance to actually render on screen

What is the expected output? What do you see instead?
Expected: The view3D.render() output is shown on screen without the lockW
applied
Actual:   The view3D.render() output shows no texture where the material's
lockW has been changed

What version of the product are you using? On what operating system?
Same as in issue 91

Please provide any additional information below.

This is really strange. I'd expect that .render() "puts down" what will
appear on the stage, but it seems that one can "post factum" modify the
visual result by changing lockW/lockH after the .render() call. I guess
this has something to do with calls to bitmap.dispose() in the lockW/lockH
setters, which probably "pulls the rug out" under the bitmap texture before
the flash player actually has a chance to "commit to screen" whatever
happens in ENTER_FRAME. 

I noticed this because I tried to apply a TweenLite tween to a
movieMaterial's lockH property; apparently TweenLite runs an ENTER_FRAME
handler after my own render() but before the flash player gets to render on
the screen.

Here's a reproducible test case. Hit a key to toggle between setting lockH
before and after render(). With DOES_IT_WORK set to false, the
moviematerial faces are invisible.

package {
    import away3d.cameras.HoverCamera3D;
    import away3d.containers.View3D;
    import away3d.materials.MovieMaterial;
    import away3d.primitives.Cube;
    import away3d.primitives.data.CubeMaterialsData;

    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;
    import flash.text.TextFormat;
    import flash.utils.getTimer;

    public class test_lockhtween extends Sprite
    {
        protected var _view3D:View3D;
        protected var _cam:HoverCamera3D;
        protected var _material:MovieMaterial;
        protected var DOES_IT_WORK:Boolean = false;

        public function test_lockhtween()
        {
            stage.scaleMode = StageScaleMode.NO_SCALE; stage.align =
StageAlign.TOP_LEFT; stage.frameRate = 30;
            _cam = new HoverCamera3D();
            _view3D = new View3D({camera:_cam});
            addChild(_view3D);
            var texture:Sprite = new Sprite(); var tf:TextField = new
TextField(); tf.defaultTextFormat = new TextFormat(null, 128, 0xFF0000);
tf.autoSize = TextFieldAutoSize.LEFT; tf.text = 'Hello world';
texture.addChild(tf);
            _material = new MovieMaterial(texture, {autoUpdate: true,
transparent:false, lockH: 256, lockW: 256});
            var cube:Cube = new Cube({cubeMaterials:new
CubeMaterialsData({top:_material,left:_material,front:_material})});
            _view3D.scene.addChild(cube);
            stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
            stage.addEventListener(KeyboardEvent.KEY_DOWN,
function(e:Event):void{ DOES_IT_WORK = !DOES_IT_WORK; });
        }

        protected function onEnterFrame(e:Event):void
        {
            if (DOES_IT_WORK) _material.lockH = 256 +
Math.sin(getTimer()*0.003)*256; 
            _view3D.x = stage.stageWidth/2; _view3D.y = stage.stageHeight/2;
            _cam.targetpanangle = mouseX/stage.stageWidth * 180 - 90;
            _cam.targettiltangle = mouseY/stage.stageHeight * 180 - 90;
            _cam.hover();
            _view3D.render();
            // Setting lockH after render() but before ENTER_FRAME is done
causes transparent bitmap to be rendered :(
            if (!DOES_IT_WORK) _material.lockH = 256 +
Math.sin(getTimer()*0.003)*256;
        }
    }
}

Original issue reported on code.google.com by postmes...@gmail.com on 3 Feb 2010 at 12:04

GoogleCodeExporter commented 9 years ago
For what it's worth, I worked around this issue in TweenLite, by attaching my
view3d.render() ENTER_FRAME handler to TweenLite.timingSprite with a low 
priority,
instead of hooking onto stage or "this". This ensures .render() is the last 
thing
called of all the ENTER_FRAMEs.

Original comment by postmes...@gmail.com on 3 Feb 2010 at 12:43