Gamua / Starling-Framework

The Cross Platform Game Engine
http://www.starling-framework.org
Other
2.84k stars 819 forks source link

Shared instance of DistanceFieldStyle causes an error #909

Closed jarkkosyrjala closed 7 years ago

jarkkosyrjala commented 7 years ago

Using an instance of DistanceFieldStyle in more than one TextField causes an exception:

exception, information=TypeError: Error #2007: Parameter indexBuffer must be non-null.

Here's a small Class to reproduce the error:

package {

import starling.display.Sprite;
import starling.styles.DistanceFieldStyle;
import starling.text.BitmapFont;
import starling.text.TextField;
import starling.text.TextFormat;
import starling.textures.Texture;

public class TestStarlingDistanceFieldStyle extends Sprite {
    [Embed(source="../assets/fonts/FontXML.fnt", mimeType="application/octet-stream")]
    public static const FontXml:Class;
    [Embed(source="../assets/image-assets/FontTexture.png")]
    public static const FontTexture:Class;

    public function TestStarlingDistanceFieldStyle() {
        //shared instance of DistanceFieldStyle does not work properly
        var distanceFieldStyle:DistanceFieldStyle=new DistanceFieldStyle();

        //setup font
        var texture:Texture = Texture.fromEmbeddedAsset(FontTexture);
        var xml:XML = XML(new FontXml());
        var bitmapFont:BitmapFont = new BitmapFont(texture, xml);
        var fontName:String=bitmapFont.name;
        TextField.registerCompositor(bitmapFont,fontName);

        var textFormat:TextFormat=new TextFormat(fontName,62,0xFF0000)

        var textField1:TextField = new TextField(500, 100, "I love Starling",textFormat);
        textField1.style=distanceFieldStyle;
        addChild(textField1);

        var textField2:TextField = new TextField(500, 100, "I love Starling",textFormat);
        textField2.y=100;
        //below line causes error: exception, information=TypeError: Error #2007: Parameter indexBuffer must be non-null.
        textField2.style=distanceFieldStyle; //works if changed to new DistanceFieldStyle();
        addChild(textField2);
    }
}
}

Obvious workaround is to use unique instance of DistanceFieldStyle for each TextField, but it should be possible to use shared instance of DistanceFieldStyle.

PrimaryFeather commented 7 years ago

A MeshStyle cannot be used on multiple objects simultaneously. It's mentioned here in the API reference, but I should add that information at the style property, too, probably.

The reason: a MeshStyle is not only a set of properties (like e.g. a TextFormat), but it's an extension of the actual Mesh, inherently connected with it.

I know this makes some things a little bothersome, but there's (currently) no way around that. You can use, however, MeshStyle.clone() to get an exact duplicate of a style. To synchronize two styles, you can use MeshStyle.copyFrom(). That should help for most issues.

Nevertheless, I should throw a better error message when a style is used on two meshes. I'll look into that!

PrimaryFeather commented 7 years ago

(That's also why I just labelled this Bug. This does not mean that having one style on separate meshes should be fixed.)

jarkkosyrjala commented 7 years ago

Thanks and sorry for not noticing the line in the API reference.

A style instance may only be used on one object at a time

PrimaryFeather commented 7 years ago

No need to apologize! I definitely need to emphasize this information more, and mention it at other places, as well. Thanks for making me aware of that!

PrimaryFeather commented 7 years ago

I updated the reference to make it easier to see that a style can only be used on one mesh. Furthermore, I fixed the error you were seeing: now, the previously used mesh simply reverts to a standard style.