Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 73 additions & 95 deletions flixel/FlxCamera.hx
Original file line number Diff line number Diff line change
Expand Up @@ -571,16 +571,15 @@ class FlxCamera extends FlxBasic
static var renderPoint:FlxPoint = FlxPoint.get();

static var renderRect:FlxRect = FlxRect.get();

@:noCompletion
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These shouldn't be exposed by default, I think they'll just confuse 99% of devs and should be reserved for internal use or people who know what they are messing with, eventually we should try and separate the "backend" rendering features from the front-end camera object functionality, but for now, let's leave this


public function startQuadBatch(graphic:FlxGraphic, colored:Bool, hasColorOffsets:Bool = false, ?blend:BlendMode, smooth:Bool = false, ?shader:FlxShader)
{
#if FLX_RENDER_TRIANGLE
return startTrianglesBatch(graphic, smooth, colored, blend);
#else
var itemToReturn = null;
var blendInt:Int = FlxDrawBaseItem.blendToInt(blend);

if (_currentDrawItem != null
&& _currentDrawItem.type == FlxDrawItemType.TILES
&& _headTiles.graphics == graphic
Expand All @@ -593,7 +592,7 @@ class FlxCamera extends FlxBasic
{
return _headTiles;
}

if (_storageTilesHead != null)
{
itemToReturn = _storageTilesHead;
Expand All @@ -609,35 +608,34 @@ class FlxCamera extends FlxBasic
// TODO: catch this error when the dev actually messes up, not in the draw phase
if (graphic.isDestroyed)
throw 'Cannot queue ${graphic.key}. This sprite was destroyed.';

itemToReturn.graphics = graphic;
itemToReturn.antialiasing = smooth;
itemToReturn.colored = colored;
itemToReturn.hasColorOffsets = hasColorOffsets;
itemToReturn.blending = blendInt;
itemToReturn.blend = blend;
itemToReturn.shader = shader;

itemToReturn.nextTyped = _headTiles;
_headTiles = itemToReturn;

if (_headOfDrawStack == null)
{
_headOfDrawStack = itemToReturn;
}

if (_currentDrawItem != null)
{
_currentDrawItem.next = itemToReturn;
}

_currentDrawItem = itemToReturn;

return itemToReturn;
#end
}

@:noCompletion

public function startTrianglesBatch(graphic:FlxGraphic, smoothing:Bool = false, isColored:Bool = false, ?blend:BlendMode, ?hasColorOffsets:Bool, ?shader:FlxShader):FlxDrawTrianglesItem
{
var blendInt:Int = FlxDrawBaseItem.blendToInt(blend);
Expand All @@ -649,24 +647,21 @@ class FlxCamera extends FlxBasic
&& _headTriangles.colored == isColored
&& _headTriangles.blending == blendInt
&& _headTriangles.blend == blend
#if !flash
&& _headTriangles.hasColorOffsets == hasColorOffsets
&& _headTriangles.shader == shader
#end
)
{
return _headTriangles;
}

return getNewDrawTrianglesItem(graphic, smoothing, isColored, blend, hasColorOffsets, shader);
}

@:noCompletion

public function getNewDrawTrianglesItem(graphic:FlxGraphic, smoothing:Bool = false, isColored:Bool = false, ?blend:BlendMode, ?hasColorOffsets:Bool, ?shader:FlxShader):FlxDrawTrianglesItem
{
var itemToReturn:FlxDrawTrianglesItem = null;
var blendInt:Int = FlxDrawBaseItem.blendToInt(blend);

if (_storageTrianglesHead != null)
{
itemToReturn = _storageTrianglesHead;
Expand All @@ -678,41 +673,43 @@ class FlxCamera extends FlxBasic
{
itemToReturn = new FlxDrawTrianglesItem();
}


// TODO: catch this error when the dev actually messes up, not in the draw phase
if (graphic.isDestroyed)
throw 'Cannot queue ${graphic.key}. This sprite was destroyed.';

Comment on lines +677 to +680
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you share a case that this guards against? Since this is function is supposed to be used internally I imagine there's a better place to check this

itemToReturn.graphics = graphic;
itemToReturn.antialiasing = smoothing;
itemToReturn.colored = isColored;
itemToReturn.blending = blendInt;
itemToReturn.blend = blend;
#if !flash
itemToReturn.hasColorOffsets = hasColorOffsets;
itemToReturn.shader = shader;
#end


itemToReturn.nextTyped = _headTriangles;
_headTriangles = itemToReturn;

if (_headOfDrawStack == null)
{
_headOfDrawStack = itemToReturn;
}

if (_currentDrawItem != null)
{
_currentDrawItem.next = itemToReturn;
}

_currentDrawItem = itemToReturn;

return itemToReturn;
}

@:allow(flixel.system.frontEnds.CameraFrontEnd)
function clearDrawStack():Void
{
var currTiles = _headTiles;
var newTilesHead;

while (currTiles != null)
{
newTilesHead = currTiles.nextTyped;
Expand All @@ -721,10 +718,10 @@ class FlxCamera extends FlxBasic
_storageTilesHead = currTiles;
currTiles = newTilesHead;
}

var currTriangles:FlxDrawTrianglesItem = _headTriangles;
var newTrianglesHead:FlxDrawTrianglesItem;

while (currTriangles != null)
{
newTrianglesHead = currTriangles.nextTyped;
Expand All @@ -733,13 +730,13 @@ class FlxCamera extends FlxBasic
_storageTrianglesHead = currTriangles;
currTriangles = newTrianglesHead;
}

_currentDrawItem = null;
_headOfDrawStack = null;
_headTiles = null;
_headTriangles = null;
}

@:allow(flixel.system.frontEnds.CameraFrontEnd)
function render():Void
{
Expand All @@ -750,7 +747,7 @@ class FlxCamera extends FlxBasic
currItem = currItem.next;
}
}

public function drawPixels(?frame:FlxFrame, ?pixels:BitmapData, matrix:FlxMatrix, ?transform:ColorTransform, ?blend:BlendMode, ?smoothing:Bool = false,
?shader:FlxShader):Void
{
Expand All @@ -771,18 +768,18 @@ class FlxCamera extends FlxBasic
}
else
{
var isColored = (transform != null #if !html5 && transform.hasRGBMultipliers() #end);
var hasColorOffsets:Bool = (transform != null && transform.hasRGBAOffsets());

final isColored = (transform != null #if !html5 && transform.hasRGBMultipliers() #end);
final hasColorOffsets = (transform != null && transform.hasRGBAOffsets());
#if FLX_RENDER_TRIANGLE
var drawItem:FlxDrawTrianglesItem = startTrianglesBatch(frame.parent, smoothing, isColored, blend);
final drawItem = startTrianglesBatch(frame.parent, smoothing, isColored, blend, hasColorOffsets, shader);
#else
var drawItem = startQuadBatch(frame.parent, isColored, hasColorOffsets, blend, smoothing, shader);
final drawItem = startQuadBatch(frame.parent, isColored, hasColorOffsets, blend, smoothing, shader);
#end
drawItem.addQuad(frame, matrix, transform);
}
}

public function copyPixels(?frame:FlxFrame, ?pixels:BitmapData, ?sourceRect:Rectangle, destPoint:Point, ?transform:ColorTransform, ?blend:BlendMode,
?smoothing:Bool = false, ?shader:FlxShader):Void
{
Expand Down Expand Up @@ -814,70 +811,59 @@ class FlxCamera extends FlxBasic
{
_helperMatrix.identity();
_helperMatrix.translate(destPoint.x + frame.offset.x, destPoint.y + frame.offset.y);

var isColored = (transform != null && transform.hasRGBMultipliers());
var hasColorOffsets:Bool = (transform != null && transform.hasRGBAOffsets());

#if !FLX_RENDER_TRIANGLE
var drawItem = startQuadBatch(frame.parent, isColored, hasColorOffsets, blend, smoothing, shader);
final isColored = (transform != null #if !html5 && transform.hasRGBMultipliers() #end);
final hasColorOffsets = (transform != null && transform.hasRGBAOffsets());
#if FLX_RENDER_TRIANGLE
final drawItem = startTrianglesBatch(frame.parent, smoothing, isColored, blend, hasColorOffsets, shader);
#else
var drawItem:FlxDrawTrianglesItem = startTrianglesBatch(frame.parent, smoothing, isColored, blend);
final drawItem = startQuadBatch(frame.parent, isColored, hasColorOffsets, blend, smoothing, shader);
#end
drawItem.addQuad(frame, _helperMatrix, transform);
}
}

public function drawTriangles(graphic:FlxGraphic, vertices:DrawData<Float>, indices:DrawData<Int>, uvtData:DrawData<Float>, ?colors:DrawData<Int>,
public function drawTriangles(graphic:FlxGraphic, vertices:DrawData<Float>, indices:DrawData<Int>, uvtData:DrawData<Float>, ?colors:DrawData<FlxColor>,
?position:FlxPoint, ?blend:BlendMode, repeat:Bool = false, smoothing:Bool = false, ?transform:ColorTransform, ?shader:FlxShader):Void
{
final cameraBounds = _bounds.set(viewMarginLeft, viewMarginTop, viewWidth, viewHeight);

if (FlxG.renderBlit)
{
if (position == null)
position = renderPoint.set();

_bounds.set(0, 0, width, height);

var verticesLength:Int = vertices.length;
var currentVertexPosition:Int = 0;

var tempX:Float, tempY:Float;
var i:Int = 0;
var bounds = renderRect.set();
drawVertices.splice(0, drawVertices.length);


drawVertices.length = 0;
final verticesLength = Std.int(vertices.length / 2) * 2;
Copy link
Member

@Geokureli Geokureli Sep 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know of a case where we would need to round to the nearest multiple? is it possible to add an incorrect multiple? if so we shouldn't allow that, assume it was a mistake and throw an error then, rather than accounting for it everywhere.

Also, are you sure that in the case where vertices is not the correct length, will this code not malfunction? I imagine it would hit an out of range error

This goes for all cases

final bounds = renderRect.set();
var i = 0;

while (i < verticesLength)
{
tempX = position.x + vertices[i];
tempY = position.y + vertices[i + 1];

drawVertices[currentVertexPosition++] = tempX;
drawVertices[currentVertexPosition++] = tempY;

final tempX = position.x + vertices[i];
final tempY = position.y + vertices[i + 1];
drawVertices.push(tempX);
drawVertices.push(tempY);
if (i == 0)
{
bounds.set(tempX, tempY, 0, 0);
}
else
{
FlxDrawTrianglesItem.inflateBounds(bounds, tempX, tempY);
}


i += 2;
}

position.putWeak();

if (!_bounds.overlaps(bounds))
{
drawVertices.splice(drawVertices.length - verticesLength, verticesLength);
}
else

if (bounds.overlaps(cameraBounds) && Std.int(indices.length / 3) != 0)
{
trianglesSprite.graphics.clear();
trianglesSprite.graphics.beginBitmapFill(graphic.bitmap, null, repeat, smoothing);
trianglesSprite.graphics.drawTriangles(drawVertices, indices, uvtData);
trianglesSprite.graphics.endFill();

// TODO: check this block of code for cases, when zoom < 1 (or initial zoom?)...
if (_useBlitMatrix)
_helperMatrix.copyFrom(_blitMatrix);
Expand All @@ -886,12 +872,13 @@ class FlxCamera extends FlxBasic
_helperMatrix.identity();
_helperMatrix.translate(-viewMarginLeft, -viewMarginTop);
}

buffer.draw(trianglesSprite, _helperMatrix);

buffer.draw(trianglesSprite, _helperMatrix, transform);

#if FLX_DEBUG
if (FlxG.debugger.drawDebug)
{
var gfx:Graphics = FlxSpriteUtil.flashGfx;
final gfx = FlxSpriteUtil.flashGfx;
gfx.clear();
gfx.lineStyle(1, FlxColor.BLUE, 0.5);
gfx.drawTriangles(drawVertices, indices);
Expand All @@ -900,26 +887,17 @@ class FlxCamera extends FlxBasic
#end
// End of TODO...
}

bounds.put();
}
else
{
_bounds.set(0, 0, width, height);
var isColored:Bool = (colors != null && colors.length != 0);

#if !flash
var hasColorOffsets:Bool = (transform != null && transform.hasRGBAOffsets());
isColored = isColored || (transform != null && transform.hasRGBMultipliers());
var drawItem:FlxDrawTrianglesItem = startTrianglesBatch(graphic, smoothing, isColored, blend, hasColorOffsets, shader);
drawItem.addTriangles(vertices, indices, uvtData, colors, position, _bounds, transform);
#else
var drawItem:FlxDrawTrianglesItem = startTrianglesBatch(graphic, smoothing, isColored, blend);
drawItem.addTriangles(vertices, indices, uvtData, colors, position, _bounds);
#end
final isColored = (transform != null #if !html5 && transform.hasRGBMultipliers() #end) || (colors != null && colors.length != 0);
final hasColorOffsets = (transform != null && transform.hasRGBAOffsets());

final drawItem = startTrianglesBatch(graphic, smoothing, isColored, blend, hasColorOffsets, shader);
drawItem.addTriangles(vertices, indices, uvtData, colors, position, cameraBounds, transform);
}
}

/**
* Helper method preparing debug rectangle for rendering in blit render mode
* @param rect rectangle to prepare for rendering
Expand Down
Loading