StarlingGraphics / Starling-Extension-Graphics

flash.display.Graphics style extension for the Starling Flash GPU rendering framework
https://github.com/StarlingGraphics/Starling-Extension-Graphics/wiki
MIT License
282 stars 89 forks source link

Stage resize - null material #136

Closed nukadelic closed 8 years ago

nukadelic commented 9 years ago

This error happened when i resize the stage window on desktop ( starling based app )

Debugger

TypeError: Error #1009: Cannot access a property or method of a null object reference. . . . at starling.display.graphics::Graphic/onContextCreated() . . . [E:\Dev\Utils\starling\display\graphics\Graphic.as:100] . . . at starling.events::EventDispatcher/invokeEvent() . . . [/Users/redge/Dropbox/Development/starling/starling/src/starling/events/EventDispatcher.as:146] . . . at starling.events::EventDispatcher/dispatchEvent() . . . [/Users/redge/Dropbox/Development/starling/starling/src/starling/events/EventDispatcher.as:117] . . . at starling.events::EventDispatcher/dispatchEventWith() . . . [/Users/redge/Dropbox/Development/starling/starling/src/starling/events/EventDispatcher.as:195] . . . at starling.core::Starling/initializeGraphicsAPI() . . . [/Users/redge/Dropbox/Development/starling/starling/src/starling/core/Starling.as:451] . . . at starling.core::Starling/initialize() . . . [/Users/redge/Dropbox/Development/starling/starling/src/starling/core/Starling.as:434] . . . at starling.core::Starling/onContextCreated() . . . [/Users/redge/Dropbox/Development/starling/starling/src/starling/core/Starling.as:691]

Graphic.as private function onContextCreated( event:Event ):void { . . . hasValidatedGeometry = false; . . . isInvalid = true; . . . uvsInvalid = true; . . . _material.restoreOnLostContext();

. . . onGraphicLostContext(); } ---------

At that moment _material is equal to null

My Classes

StageControl.as var stageW:int; var stageH:int; App.input.onResize.add( function( x:int, y:int ):void { . . . stageW = x; . . . stageH = y; . . . App.input.onContext3DCreated.addOnce( function():void { . . . . . . App.display.stage.render( stageW, stageH ); . . . }); }); ---------

AppStage.as private function addChildren():void { . . . backgroundData = new BitmapData( 32, 32, false, 0xFF000000 ); . . . backgroundData.fillRect( new Rectangle( 0, 0, 16, 16 ), 0xFF3E3E3E ); . . . backgroundData.fillRect( new Rectangle( 16, 16, 16, 16 ), 0xFF3E3E3E ); . . . backgroundTexture = Texture.fromBitmapData( backgroundData, false, true, 1, 'bgra', true ); . . . background = new Shape(); . . . Starling.current.stage.addChildAt( background, 0 ); }

public function render( newWidth:int, newHeight:int ):void { . . . background.graphics.clear(); . . . background.graphics.beginTextureFill( backgroundTexture, . . . new Matrix( scale, 0, 0, scale,container.x, container.y ) ); . . . background.graphics.drawRect( 0, 0, width, height); . . . background.graphics.endFill(); ); ---------

Info

nukadelic commented 9 years ago

OK so i had a look into the source code and found a temporary solution specific for my project. The error was happening because my Input class adds a context3DCreate event to the current starling instance, but since the starling.display.graphics.Graphic object does it too, it get's executed after the input's event listener does. Then i have decided to manually add a new static variable onGraphicLostContextComplete( DisplayObject ) type of Signal which will be dispatched in the onGraphicLostContext() method inside the starling.display.graphics.Graphic class. After that i have used this signal to listen to the background (Shape) context 3D creation event listener inside my stage renderer.

EDIT

Above method will force you to count the amount of Graphic objects with no event dispatch and check if the current is the last one :\

Instead adding delayed timer after the context 3D is lost seems to work better for me :P

EDIT

SOLUTION

To listen when every single graphic instance will be recovered after lost context 3D, simply reinstall the event listener at your target object to be pushed into the end of the event queue =)

Example:

App > Input.as public function pushContext3DEventToBottom():void { . . . // Reinstall context 3D event listener . . . Starling.current.removeEventListener( 'context3DCreate', eContext3DCreate ); . . . Starling.current.addEventListener( 'context3DCreate', eContext3DCreate ); }

StageControl.as App.input.onResize.add( function( x:int, y:int ):void { . . . App.input.pushContext3DEventToBottom(); . . . App.input.onContext3DCreated.addOnce( function():void { . . . . . . App.display.stage.render( App.sw, App.sh ); . . . }); }

IonSwitz commented 8 years ago

I have submitted a fix for Lost Context. It seems to work better now, but I have only a limited set of test cases.