Skip to content

Commit

Permalink
Merge branch 'pixijs-dev' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeljherrmann committed Jun 16, 2022
2 parents 7bc0f71 + 5e900b7 commit 60ab3b3
Show file tree
Hide file tree
Showing 24 changed files with 272 additions and 278 deletions.
3 changes: 2 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 29 additions & 19 deletions packages/canvas-extract/src/CanvasExtract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ export class CanvasExtract
* Creates a Canvas element, renders this target to it and then returns it.
* @param target - A displayObject or renderTexture
* to convert. If left empty will use the main renderer
* @param frame - The frame the extraction is restricted to.
* @returns A Canvas element with the texture rendered on.
*/
public canvas(target?: DisplayObject | RenderTexture): HTMLCanvasElement
public canvas(target?: DisplayObject | RenderTexture, frame?: Rectangle): HTMLCanvasElement
{
const renderer = this.renderer;
let context;
let resolution;
let frame;
let renderTexture;

if (target)
Expand All @@ -88,22 +88,28 @@ export class CanvasExtract
{
context = (renderTexture.baseTexture as BaseRenderTexture)._canvasRenderTarget.context;
resolution = (renderTexture.baseTexture as BaseRenderTexture)._canvasRenderTarget.resolution;
frame = renderTexture.frame;
frame = frame ?? renderTexture.frame;
}
else
{
context = renderer.rootContext;
resolution = renderer.resolution;
frame = TEMP_RECT;
frame.width = this.renderer.width;
frame.height = this.renderer.height;

if (!frame)
{
frame = TEMP_RECT;
frame.width = renderer.width;
frame.height = renderer.height;
}
}

const width = Math.floor((frame.width * resolution) + 1e-4);
const height = Math.floor((frame.height * resolution) + 1e-4);
const x = Math.round(frame.x * resolution);
const y = Math.round(frame.y * resolution);
const width = Math.round(frame.width * resolution);
const height = Math.round(frame.height * resolution);

const canvasBuffer = new CanvasRenderTarget(width, height, 1);
const canvasData = context.getImageData(frame.x * resolution, frame.y * resolution, width, height);
const canvasData = context.getImageData(x, y, width, height);

canvasBuffer.context.putImageData(canvasData, 0, 0);

Expand All @@ -116,14 +122,14 @@ export class CanvasExtract
* order, with integer values between 0 and 255 (included).
* @param target - A displayObject or renderTexture
* to convert. If left empty will use the main renderer
* @param frame - The frame the extraction is restricted to.
* @returns One-dimensional array containing the pixel data of the entire texture
*/
public pixels(target?: DisplayObject | RenderTexture): Uint8ClampedArray
public pixels(target?: DisplayObject | RenderTexture, frame?: Rectangle): Uint8ClampedArray
{
const renderer = this.renderer;
let context;
let resolution;
let frame;
let renderTexture;

if (target)
Expand All @@ -142,21 +148,25 @@ export class CanvasExtract
{
context = (renderTexture.baseTexture as BaseRenderTexture)._canvasRenderTarget.context;
resolution = (renderTexture.baseTexture as BaseRenderTexture)._canvasRenderTarget.resolution;
frame = renderTexture.frame;
frame = frame ?? renderTexture.frame;
}
else
{
context = renderer.rootContext;
resolution = renderer.resolution;
frame = TEMP_RECT;
frame.width = renderer.width;
frame.height = renderer.height;

if (!frame)
{
frame = TEMP_RECT;
frame.width = renderer.width;
frame.height = renderer.height;
}
}

const x = frame.x * resolution;
const y = frame.y * resolution;
const width = frame.width * resolution;
const height = frame.height * resolution;
const x = Math.round(frame.x * resolution);
const y = Math.round(frame.y * resolution);
const width = Math.round(frame.width * resolution);
const height = Math.round(frame.height * resolution);

return context.getImageData(x, y, width, height).data;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/mask/MaskData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface IMaskTarget extends IFilterTarget
isSprite?: boolean;
worldTransform: Matrix;
isFastRect?(): boolean;
getBounds(skipUpdate?: boolean): Rectangle;
getBounds(skipUpdate?: boolean, rect?: Rectangle): Rectangle;
render(renderer: Renderer): void;
}
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/mask/MaskSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export class MaskSystem implements ISystem
switch (maskData.type)
{
case MASK_TYPES.SCISSOR:
this.renderer.scissor.pop();
this.renderer.scissor.pop(maskData);
break;
case MASK_TYPES.STENCIL:
this.renderer.stencil.pop(maskData.maskObject);
Expand Down
16 changes: 9 additions & 7 deletions packages/core/src/mask/ScissorSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { MaskData } from './MaskData';
import { Matrix, Rectangle } from '@pixi/math';

const tempMatrix = new Matrix();
const rectPool: Rectangle[] = [];

/**
* System plugin to the renderer to manage scissor masking.
Expand Down Expand Up @@ -53,19 +54,14 @@ export class ScissorSystem extends AbstractMaskSystem
const { maskObject } = maskData;
const { renderer } = this;
const renderTextureSystem = renderer.renderTexture;

maskObject.renderable = true;

const rect = maskObject.getBounds(true);
const rect = maskObject.getBounds(true, rectPool.pop() ?? new Rectangle());

this.roundFrameToPixels(rect,
renderTextureSystem.current ? renderTextureSystem.current.resolution : renderer.resolution,
renderTextureSystem.sourceFrame,
renderTextureSystem.destinationFrame,
renderer.projection.transform);

maskObject.renderable = false;

if (prevData)
{
rect.fit(prevData);
Expand Down Expand Up @@ -179,11 +175,17 @@ export class ScissorSystem extends AbstractMaskSystem
* last mask in the stack.
*
* This can also be called when you directly modify the scissor box and want to restore PixiJS state.
* @param maskData - The mask data.
*/
pop(): void
pop(maskData?: MaskData): void
{
const { gl } = this.renderer;

if (maskData)
{
rectPool.push(maskData._scissorRectLocal);
}

if (this.getStackLength() > 0)
{
this._useCurrent();
Expand Down
5 changes: 3 additions & 2 deletions packages/events/src/EventBoundary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -497,9 +497,10 @@ export class EventBoundary

if (displayObject._mask)
{
const mask = displayObject._mask as any;
const maskObject = ((displayObject._mask as any).isMaskData
? (displayObject._mask as any).maskObject : displayObject._mask);

if (!(mask.containsPoint && mask.containsPoint(location)))
if (maskObject && !maskObject.containsPoint?.(location))
{
return true;
}
Expand Down
81 changes: 32 additions & 49 deletions packages/extract/src/Extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const BYTES_PER_PIXEL = 4;
/**
* this interface is used to extract only a single pixel of Render Texture or Display Object
* if you use this Interface all fields is required
* @deprecated
* @example
* test: PixelExtractOptions = { x: 15, y: 20, resolution: 4, width: 10, height: 10 }
*/
Expand Down Expand Up @@ -91,13 +92,13 @@ export class Extract implements IRendererPlugin
* Creates a Canvas element, renders this target to it and then returns it.
* @param target - A displayObject or renderTexture
* to convert. If left empty will use the main renderer
* @param frame - The frame the extraction is restricted to.
* @returns - A Canvas element with the texture rendered on.
*/
public canvas(target: DisplayObject | RenderTexture): HTMLCanvasElement
public canvas(target: DisplayObject | RenderTexture, frame?: Rectangle): HTMLCanvasElement
{
const renderer = this.renderer;
let resolution;
let frame;
let flipY = false;
let renderTexture;
let generated = false;
Expand All @@ -118,25 +119,27 @@ export class Extract implements IRendererPlugin
if (renderTexture)
{
resolution = renderTexture.baseTexture.resolution;
frame = renderTexture.frame;
frame = frame ?? renderTexture.frame;
flipY = false;
renderer.renderTexture.bind(renderTexture);
}
else
{
resolution = this.renderer.resolution;

flipY = true;
resolution = renderer.resolution;

frame = TEMP_RECT;
frame.width = this.renderer.width;
frame.height = this.renderer.height;
if (!frame)
{
frame = TEMP_RECT;
frame.width = renderer.width;
frame.height = renderer.height;
}

flipY = true;
renderer.renderTexture.bind(null);
}

const width = Math.floor((frame.width * resolution) + 1e-4);
const height = Math.floor((frame.height * resolution) + 1e-4);
const width = Math.round(frame.width * resolution);
const height = Math.round(frame.height * resolution);

let canvasBuffer = new CanvasRenderTarget(width, height, 1);

Expand All @@ -146,8 +149,8 @@ export class Extract implements IRendererPlugin
const gl = renderer.gl;

gl.readPixels(
frame.x * resolution,
frame.y * resolution,
Math.round(frame.x * resolution),
Math.round(frame.y * resolution),
width,
height,
gl.RGBA,
Expand Down Expand Up @@ -190,14 +193,13 @@ export class Extract implements IRendererPlugin
* order, with integer values between 0 and 255 (included).
* @param target - A displayObject or renderTexture
* to convert. If left empty will use the main renderer
* @param options
* @param frame - The frame the extraction is restricted to.
* @returns - One-dimensional array containing the pixel data of the entire texture
*/
public pixels(target?: DisplayObject | RenderTexture, options?: PixelExtractOptions): Uint8Array
public pixels(target?: DisplayObject | RenderTexture, frame?: Rectangle | PixelExtractOptions): Uint8Array
{
const renderer = this.renderer;
let resolution;
let frame;
let renderTexture;
let generated = false;

Expand All @@ -207,7 +209,7 @@ export class Extract implements IRendererPlugin
{
renderTexture = target;
}
else if (target instanceof DisplayObject)
else
{
renderTexture = this.renderer.generateTexture(target);
generated = true;
Expand All @@ -216,54 +218,35 @@ export class Extract implements IRendererPlugin

if (renderTexture)
{
if (options)
{
resolution = options.resolution;
frame = renderTexture.frame;

// bind the buffer
renderer.renderTexture.bind(renderTexture);
}
else
{
resolution = renderTexture.baseTexture.resolution;
frame = renderTexture.frame;

// bind the buffer
renderer.renderTexture.bind(renderTexture);
}
}
else if (options)
{
resolution = options.resolution;

frame = TEMP_RECT;
frame.width = options.width;
frame.height = options.height;
renderer.renderTexture.bind(null);
resolution = renderTexture.baseTexture.resolution;
frame = frame ?? renderTexture.frame;
renderer.renderTexture.bind(renderTexture);
}
else
{
resolution = renderer.resolution;

frame = TEMP_RECT;
frame.width = renderer.width;
frame.height = renderer.height;
if (!frame)
{
frame = TEMP_RECT;
frame.width = renderer.width;
frame.height = renderer.height;
}

renderer.renderTexture.bind(null);
}

const width = frame.width * resolution;
const height = frame.height * resolution;
const width = Math.round(frame.width * resolution);
const height = Math.round(frame.height * resolution);

const webglPixels = new Uint8Array(BYTES_PER_PIXEL * width * height);

// read pixels to the array
const gl = renderer.gl;

gl.readPixels(
frame.x * resolution,
frame.y * resolution,
Math.round(frame.x * resolution),
Math.round(frame.y * resolution),
width,
height,
gl.RGBA,
Expand Down
7 changes: 4 additions & 3 deletions packages/extract/test/Extract.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Sprite } from '@pixi/sprite';
import { expect } from 'chai';
import { skipHello } from '@pixi/utils';
import { Texture, RenderTexture, BatchRenderer, Renderer } from '@pixi/core';
import { Extract, PixelExtractOptions } from '@pixi/extract';
import { Extract } from '@pixi/extract';
import { Rectangle } from '@pixi/math';

skipHello();

Expand Down Expand Up @@ -57,13 +58,13 @@ describe('Extract', () =>
const extract = renderer.plugins.extract as Extract;
const renderTexture = RenderTexture.create({ width: 10, height: 10 });
const sprite = new Sprite(Texture.WHITE);
const test: PixelExtractOptions = { x: 1, y: 2, resolution: 5, width: 10, height: 10 };
const frame = new Rectangle(1, 2, 5, 6);

renderer.render(sprite, { renderTexture });

expect(extract.canvas(renderTexture)).to.be.an.instanceof(HTMLCanvasElement);
expect(extract.base64(renderTexture)).to.be.a('string');
expect(extract.pixels(renderTexture, test)).to.be.instanceOf(Uint8Array);
expect(extract.pixels(renderTexture, frame)).to.be.instanceOf(Uint8Array);
expect(extract.image(renderTexture)).to.be.instanceOf(HTMLImageElement);

renderer.destroy();
Expand Down
3 changes: 1 addition & 2 deletions packages/graphics/src/Graphics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -826,11 +826,10 @@ export class Graphics extends Container
this.finishPoly();

const geometry = this._geometry;
const hasuint32 = renderer.context.supports.uint32Indices;
// batch part..
// batch it!

geometry.updateBatches(hasuint32);
geometry.updateBatches();

if (geometry.batchable)
{
Expand Down

0 comments on commit 60ab3b3

Please sign in to comment.