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
285 stars 88 forks source link

AIR - Native Window #64

Closed spacelab-sp closed 10 years ago

spacelab-sp commented 11 years ago

I have two instances of Starling, one in the main stage, and a second on the native window.

When I use the graphics in the Native Window (the 2nd), the graphics do not appear, is something I'm doing wrong, or the Graphics API support only one instance of Starling?

IonSwitz commented 11 years ago

This is a bit tricker to reproduce than the other issue you reported. Here, I don't have a way to reproduce the issue in an easy way, but from reading the code, I would think that it ought to be possible to use more than one instance of Starling.

However, there are a few locations where the 2nd Starling instance has to be made "Current" before doing anything.

So, for example, when a Graphic class on the 2nd Starling instance is created, or the Shape class that holds it, the 2nd Starling instance has to be "Current", as Starling.current is used in the constructor.

The same goes for the Graphic "render" method, although that is perhaps more intuitive.

So, basically, the answer to your question is: I don't know if there is a limitation of using only one Starling instance, but if there is, I can't really see why by reading the code. The Starling.current instance is being used in all places that seem appropriate, as far as I can see.

Are you using the SWC or the source tree to build the application? If you are using the SWC, would it be possible for you to try with the source tree? The two are, at the moment, not fully synched. The code tree unfortunately contains some fixes that are not replicated in the SWC.

spacelab-sp commented 10 years ago

If I understand right, when I create a second instance of Starling, I define starling.makeCurrent ();?

Do not know if I did something wrong, but don't worked.

In the files below, I create two windows, and two instances of Starling, the two windows have two squares each, one created with Graphics and another with the Quad class. In the second window, the object created with Graphics does not appear, created with the Quad, appears.

Flash Builder Project: https://www.dropbox.com/s/6eqz7gjeoo0vx9h/NativeWindowTest.rar

IonSwitz commented 10 years ago

Ok, I have found the problem here.

The mistake lies in Graphic.as

The class is using two static shaders, one vertex shader and one fragment shader, initialized in the Graphic constructor.

In the scenario with one Starling instance, this works fine, but when we have multiple Starling instances, these only get created once instead of once for each Starling instance.

I have a fix for this, basically caching the vertex shaders depending on what Starling instance is current, so the shaders are cached once per Starling instance, and I will check that in soonish, when I feel confident about the solution.

So, yes, there will be proper support for multiple Starling windows, but at the moment the fix isn't committed.

Thank you for reporting this issue! :)

IonSwitz commented 10 years ago

If you want to play around with it yourself, you can solve it locally by doing this:

in Graphic.as:

comment out the default shaders and replace them with two dictionaries:

//  protected static var defaultVertexShader    :StandardVertexShader;
//  protected static var defaultFragmentShader  :VertexColorFragmentShader;

    protected static var defaultVertexShaderDictionary:Dictionary = new Dictionary(true);
    protected static var defaultFragmentShaderDictionary:Dictionary = new Dictionary(true);

and, then in the constructor, add this:

         var currentStarling:Starling = Starling.current;

        var vertexShader:StandardVertexShader = defaultVertexShaderDictionary[currentStarling];
        if ( vertexShader == null )
        {
            vertexShader = new StandardVertexShader();
            defaultVertexShaderDictionary[currentStarling] = vertexShader;
        }

        var fragmentShader:VertexColorFragmentShader = defaultFragmentShaderDictionary[currentStarling];
        if ( fragmentShader == null )
        {
            fragmentShader = new VertexColorFragmentShader();
            defaultFragmentShaderDictionary[currentStarling] = fragmentShader;
        }

        _material = new StandardMaterial( vertexShader, fragmentShader );

instead of the code that uses the defaultVertexShader and defaultFragmentShader variables.

spacelab-sp commented 10 years ago

Nice! Good to know that we have a fix!

I tried what you said, and checked to see if I did everything correctly, and doesn't worked But not bother, I can wait for the fix.

IonSwitz commented 10 years ago

I am sorry, I forgot this part: In your SecondWindow class, you need to make the Starling instance of that window current before creating the Shape in timerCompleteHandler. Like this:

    private var myStarling:Starling;

    public function SecondWindow()
    {
        super();

        myStarling = Starling.current;

        var timer:Timer = new Timer(1000, 1);

        timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerCompleteHandler);

        timer.start();
    }

    private function timerCompleteHandler(e:TimerEvent):void
    {
        myStarling.makeCurrent() ;

        shape = new Shape;
        quad = new Quad(50, 50, 0);

        shape.graphics.beginFill(0xFFFFFF);
        shape.graphics.lineStyle(1, 0xCCCCCC);
        shape.graphics.drawRect(0, 0, 200, 200);
        shape.graphics.endFill();
        shape.x = shape.y = 100;
        quad.x = quad.y = 310;

        addChild(quad);
        addChild(shape);

        addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }
IonSwitz commented 10 years ago

The fix has now been added to the master. The SWC has still not been updated

IonSwitz commented 10 years ago

Closing this Issue