diff --git a/src/openfl/display/Graphics.hx b/src/openfl/display/Graphics.hx index 069e5071f9..86a9428f9a 100644 --- a/src/openfl/display/Graphics.hx +++ b/src/openfl/display/Graphics.hx @@ -99,6 +99,7 @@ import js.html.CanvasRenderingContext2D; #end @:noCompletion private var __bitmap:BitmapData; @:noCompletion private var __bitmapScale:Float; + @:noCompletion private var __hasTilemap:Bool; @:noCompletion private function new(owner:DisplayObject) { @@ -200,6 +201,27 @@ import js.html.CanvasRenderingContext2D; if (alpha > 0) __visible = true; } + /** + * Fills the drawing area with a tilemap. + * @param tilemap the tilemap to fill. + */ + public function beginTilemapFill(tilemap:Tilemap):Void + { + tilemap.__update(false, true); + + var xSign = tilemap.width < 0 ? -1 : 1; + var ySign = tilemap.height < 0 ? -1 : 1; + + __inflateBounds(tilemap.x - __strokePadding * xSign, tilemap.y - __strokePadding * ySign); + __inflateBounds(tilemap.x + tilemap.width + __strokePadding * xSign, tilemap.y + tilemap.height + __strokePadding * ySign); + + __commands.beginTilemapFill(tilemap); + + __dirty = true; + __visible = true; + __hasTilemap = true; + } + /** Specifies a gradient fill used by subsequent calls to other Graphics methods (such as `lineTo()` or `drawCircle()`) for @@ -654,6 +676,7 @@ import js.html.CanvasRenderingContext2D; var path:GraphicsPath; var trianglePath:GraphicsTrianglePath; var quadPath:GraphicsQuadPath; + var tilemapFill:GraphicsTilemapFill; for (graphics in graphicsData) { @@ -728,6 +751,9 @@ import js.html.CanvasRenderingContext2D; case QUAD_PATH: quadPath = cast graphics; drawQuads(quadPath.rects, quadPath.indices, quadPath.transforms); + case TILEMAP: + tilemapFill = cast graphics; + beginTilemapFill(tilemapFill.tilemap); } } } diff --git a/src/openfl/display/GraphicsTilemapFill.hx b/src/openfl/display/GraphicsTilemapFill.hx new file mode 100644 index 0000000000..d015861766 --- /dev/null +++ b/src/openfl/display/GraphicsTilemapFill.hx @@ -0,0 +1,44 @@ +package openfl.display; + +#if !flash +import openfl.display._internal.GraphicsDataType; +import openfl.display._internal.GraphicsFillType; +import openfl.geom.Matrix; + +/** + Defines a bitmap fill. The bitmap can be smoothed, repeated or tiled to + fill the area; or manipulated using a transformation matrix. + Use a GraphicsBitmapFill object with the `Graphics.drawGraphicsData()` + method. Drawing a GraphicsBitmapFill object is the equivalent of calling + the `Graphics.beginBitmapFill()` method. +**/ +#if !openfl_debug +@:fileXml('tags="haxe,release"') +@:noDebug +#end +@:final class GraphicsTilemapFill implements IGraphicsData implements IGraphicsFill +{ + /** + The tilemap to fill. + **/ + public var tilemap:Tilemap; + + @:noCompletion private var __graphicsDataType(default, null):GraphicsDataType; + @:noCompletion private var __graphicsFillType(default, null):GraphicsFillType; + + /** + Creates a new GraphicsBitmapFill object. + + @param tilemap A tilemap that contains tiles to render. + **/ + public function new(tilemap:Tilemap = null) + { + this.tilemap = tilemap; + + this.__graphicsDataType = TILEMAP; + this.__graphicsFillType = TILEMAP_FILL; + } +} +// #else +// typedef GraphicsBitmapFill = Dynamic; +#end diff --git a/src/openfl/display/_internal/Context3DGraphics.hx b/src/openfl/display/_internal/Context3DGraphics.hx index ea65cc59eb..55072e286b 100644 --- a/src/openfl/display/_internal/Context3DGraphics.hx +++ b/src/openfl/display/_internal/Context3DGraphics.hx @@ -37,6 +37,7 @@ class Context3DGraphics private static var blankBitmapData = new BitmapData(1, 1, false, 0); private static var maskRender:Bool; private static var tempColorTransform = new ColorTransform(1, 1, 1, 1, 0, 0, 0, 0); + private static var __tileRenderer:OpenGLRenderer; private static function buildBuffer(graphics:Graphics, renderer:OpenGLRenderer):Void { @@ -84,6 +85,12 @@ class Context3DGraphics } } + case BEGIN_TILEMAP_FILL: + var c = data.readBeginTilemapFill(); + c.tilemap; + // Context3DTilemap.buildBuffer(c.tilemap, renderer); + // data.skip(type); + case DRAW_QUADS: // TODO: Other fill types @@ -428,6 +435,9 @@ class Context3DGraphics return false; } + case BEGIN_TILEMAP_FILL: + data.skip(type); + case DRAW_RECT: if (hasColorFill) { @@ -532,7 +542,7 @@ class Context3DGraphics var width = graphics.__width; var height = graphics.__height; - if (bounds != null && width >= 1 && height >= 1) + if (bounds != null && ((width >= 1 && height >= 1) || graphics.__hasTilemap)) { if (graphics.__hardwareDirty || (graphics.__quadBuffer == null && graphics.__vertexBuffer == null && graphics.__vertexBufferUVT == null)) @@ -599,6 +609,29 @@ class Context3DGraphics fill = null; + case BEGIN_TILEMAP_FILL: + var c = data.readBeginTilemapFill(); + // giving the tilemap it's own renderer MAY allow for less gl events to switch between the states made by the Context3DGraphics and Context3DTilemap + if (__tileRenderer == null) __tileRenderer = new OpenGLRenderer(renderer.__context3D); + + __tileRenderer.__stage = renderer.__stage; + __tileRenderer.__allowSmoothing = c.tilemap.smoothing; + __tileRenderer.__overrideBlendMode = c.tilemap.blendMode; + __tileRenderer.__pixelRatio = renderer.__pixelRatio; + __tileRenderer.__worldTransform = c.tilemap.transform.matrix; + __tileRenderer.__worldAlpha = 1 / c.tilemap.__worldAlpha; + __tileRenderer.__resize(Math.ceil(c.tilemap.width), Math.ceil(c.tilemap.height)); + + var tilemapTransform = c.tilemap.__renderTransform; + var newTransform = Matrix.__pool.get(); + newTransform.copyFrom(tilemapTransform); + newTransform.concat(graphics.__owner.__transform); + c.tilemap.__renderTransform = newTransform; + + Context3DTilemap.renderDrawable(c.tilemap, __tileRenderer); + Matrix.__pool.release(newTransform); + c.tilemap.__renderTransform = tilemapTransform; + case DRAW_QUADS: if (bitmap != null) { diff --git a/src/openfl/display/_internal/DrawCommandBuffer.hx b/src/openfl/display/_internal/DrawCommandBuffer.hx index 3afcbf573b..4c31e2483e 100644 --- a/src/openfl/display/_internal/DrawCommandBuffer.hx +++ b/src/openfl/display/_internal/DrawCommandBuffer.hx @@ -159,6 +159,14 @@ class DrawCommandBuffer b.push(smooth); } + public function beginTilemapFill(tilemap:Tilemap):Void + { + prepareWrite(); + + types.push(BEGIN_TILEMAP_FILL); + o.push(tilemap); + } + public function beginFill(color:Int, alpha:Float):Void { prepareWrite(); diff --git a/src/openfl/display/_internal/DrawCommandReader.hx b/src/openfl/display/_internal/DrawCommandReader.hx index f5b711851a..128f00eb47 100644 --- a/src/openfl/display/_internal/DrawCommandReader.hx +++ b/src/openfl/display/_internal/DrawCommandReader.hx @@ -62,6 +62,9 @@ class DrawCommandReader case BEGIN_SHADER_FILL: oPos += 1; // shaderBuffer + case BEGIN_TILEMAP_FILL: + oPos += 1; // Tilemap + case CUBIC_CURVE_TO: fPos += 6; // controlX1, controlY1, controlX2, controlY2, anchorX, anchorY @@ -191,6 +194,13 @@ class DrawCommandReader return new BeginShaderFillView(this); } + public inline function readBeginTilemapFill():BeginTilemapFillView + { + advance(); + prev = BEGIN_TILEMAP_FILL; + return new BeginTilemapFillView(this); + } + public inline function readCubicCurveTo():CubicCurveToView { advance(); @@ -466,6 +476,21 @@ abstract BeginShaderFillView(DrawCommandReader) } } +abstract BeginTilemapFillView(DrawCommandReader) +{ + public inline function new(d:DrawCommandReader) + { + this = d; + } + + public var tilemap(get, never):Tilemap; + + private inline function get_tilemap():Tilemap + { + return cast this.obj(0); + } +} + abstract CubicCurveToView(DrawCommandReader) { public inline function new(d:DrawCommandReader) diff --git a/src/openfl/display/_internal/DrawCommandType.hx b/src/openfl/display/_internal/DrawCommandType.hx index 223e647552..37388588f4 100644 --- a/src/openfl/display/_internal/DrawCommandType.hx +++ b/src/openfl/display/_internal/DrawCommandType.hx @@ -7,6 +7,7 @@ enum DrawCommandType BEGIN_FILL; BEGIN_GRADIENT_FILL; BEGIN_SHADER_FILL; + BEGIN_TILEMAP_FILL; CUBIC_CURVE_TO; CURVE_TO; DRAW_CIRCLE; diff --git a/src/openfl/display/_internal/GraphicsDataType.hx b/src/openfl/display/_internal/GraphicsDataType.hx index 81abaa2b51..0cca904ff3 100644 --- a/src/openfl/display/_internal/GraphicsDataType.hx +++ b/src/openfl/display/_internal/GraphicsDataType.hx @@ -11,4 +11,5 @@ package openfl.display._internal; var QUAD_PATH = 6; var TRIANGLE_PATH = 7; var SHADER = 8; + var TILEMAP = 9; } diff --git a/src/openfl/display/_internal/GraphicsFillType.hx b/src/openfl/display/_internal/GraphicsFillType.hx index 8b3e1a5622..91b7621821 100644 --- a/src/openfl/display/_internal/GraphicsFillType.hx +++ b/src/openfl/display/_internal/GraphicsFillType.hx @@ -7,4 +7,5 @@ package openfl.display._internal; var BITMAP_FILL = 2; var END_FILL = 3; var SHADER_FILL = 4; + var TILEMAP_FILL = 5; }