- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
import { hex2string, hex2rgb, EventEmitter, deprecation } from '@pixi/utils';
import { Matrix, Rectangle } from '@pixi/math';
import { RENDERER_TYPE } from '@pixi/constants';
import { settings } from '@pixi/settings';
import { RenderTexture } from './renderTexture/RenderTexture';
import type { SCALE_MODES, MSAA_QUALITY } from '@pixi/constants';
import type { ISystemConstructor } from './ISystem';
import type { IRenderingContext } from './IRenderingContext';
import type { IRenderableContainer, IRenderableObject } from './IRenderableObject';
const tempMatrix = new Matrix();
export interface IRendererOptions extends GlobalMixins.IRendererOptions
{
width?: number;
height?: number;
view?: HTMLCanvasElement;
useContextAlpha?: boolean | 'notMultiplied';
/**
* Use `backgroundAlpha` instead.
* @deprecated
*/
transparent?: boolean;
autoDensity?: boolean;
antialias?: boolean;
resolution?: number;
preserveDrawingBuffer?: boolean;
clearBeforeRender?: boolean;
backgroundColor?: number;
backgroundAlpha?: number;
powerPreference?: WebGLPowerPreference;
context?: IRenderingContext;
}
export interface IRendererPlugins
{
[key: string]: any;
}
export interface IRendererRenderOptions
{
renderTexture?: RenderTexture;
clear?: boolean;
transform?: Matrix;
skipUpdateTransform?: boolean;
}
export interface IGenerateTextureOptions
{
scaleMode?: SCALE_MODES;
resolution?: number;
region?: Rectangle;
multisample?: MSAA_QUALITY;
}
/**
* The AbstractRenderer is the base for a PixiJS Renderer. It is extended by the {@link PIXI.CanvasRenderer}
* and {@link PIXI.Renderer} which can be used for rendering a PixiJS scene.
* @abstract
* @class
* @extends PIXI.utils.EventEmitter
* @memberof PIXI
*/
export abstract class AbstractRenderer extends EventEmitter
{
public resolution: number;
public clearBeforeRender?: boolean;
public readonly options: IRendererOptions;
public readonly type: RENDERER_TYPE;
public readonly screen: Rectangle;
public readonly view: HTMLCanvasElement;
public readonly plugins: IRendererPlugins;
public readonly useContextAlpha: boolean | 'notMultiplied';
public readonly autoDensity: boolean;
public readonly preserveDrawingBuffer: boolean;
protected _backgroundColor: number;
protected _backgroundColorString: string;
_backgroundColorRgba: number[];
_lastObjectRendered: IRenderableObject;
/**
* @param type - The renderer type.
* @param [options] - The optional renderer parameters.
* @param {number} [options.width=800] - The width of the screen.
* @param {number} [options.height=600] - The height of the screen.
* @param {HTMLCanvasElement} [options.view] - The canvas to use as a view, optional.
* @param {boolean} [options.useContextAlpha=true] - Pass-through value for canvas' context `alpha` property.
* If you want to set transparency, please use `backgroundAlpha`. This option is for cases where the
* canvas needs to be opaque, possibly for performance reasons on some older devices.
* @param {boolean} [options.autoDensity=false] - Resizes renderer view in CSS pixels to allow for
* resolutions other than 1.
* @param {boolean} [options.antialias=false] - Sets antialias
* @param {number} [options.resolution=PIXI.settings.RESOLUTION] - The resolution / device pixel ratio of the renderer.
* @param {boolean} [options.preserveDrawingBuffer=false] - Enables drawing buffer preservation,
* enable this if you need to call toDataUrl on the WebGL context.
* @param {boolean} [options.clearBeforeRender=true] - This sets if the renderer will clear the canvas or
* not before the new render pass.
* @param {number} [options.backgroundColor=0x000000] - The background color of the rendered area
* (shown if not transparent).
* @param {number} [options.backgroundAlpha=1] - Value from 0 (fully transparent) to 1 (fully opaque).
*/
constructor(type: RENDERER_TYPE = RENDERER_TYPE.UNKNOWN, options?: IRendererOptions)
{
super();
// Add the default render options
options = Object.assign({}, settings.RENDER_OPTIONS, options);
/**
* The supplied constructor options.
* @member {object}
* @readonly
*/
this.options = options;
/**
* The type of the renderer.
* @member {number}
* @default PIXI.RENDERER_TYPE.UNKNOWN
* @see PIXI.RENDERER_TYPE
*/
this.type = type;
/**
* Measurements of the screen. (0, 0, screenWidth, screenHeight).
*
* Its safe to use as filterArea or hitArea for the whole stage.
* @member {PIXI.Rectangle}
*/
this.screen = new Rectangle(0, 0, options.width, options.height);
/**
* The canvas element that everything is drawn to.
* @member {HTMLCanvasElement}
*/
this.view = options.view || settings.ADAPTER.createCanvas();
/**
* The resolution / device pixel ratio of the renderer.
* @member {number}
* @default PIXI.settings.RESOLUTION
*/
this.resolution = options.resolution || settings.RESOLUTION;
/**
* Pass-thru setting for the canvas' context `alpha` property. This is typically
* not something you need to fiddle with. If you want transparency, use `backgroundAlpha`.
* @member {boolean}
*/
this.useContextAlpha = options.useContextAlpha;
/**
* Whether CSS dimensions of canvas view should be resized to screen dimensions automatically.
* @member {boolean}
*/
this.autoDensity = !!options.autoDensity;
/**
* The value of the preserveDrawingBuffer flag affects whether or not the contents of
* the stencil buffer is retained after rendering.
* @member {boolean}
*/
this.preserveDrawingBuffer = options.preserveDrawingBuffer;
/**
* This sets if the CanvasRenderer will clear the canvas or not before the new render pass.
* If the scene is NOT transparent PixiJS will use a canvas sized fillRect operation every
* frame to set the canvas background color. If the scene is transparent PixiJS will use clearRect
* to clear the canvas every frame. Disable this by setting this to false. For example, if
* your game has a canvas filling background image you often don't need this set.
* @member {boolean}
* @default
*/
this.clearBeforeRender = options.clearBeforeRender;
/**
* The background color as a number.
* @member {number}
* @protected
*/
this._backgroundColor = 0x000000;
/**
* The background color as an [R, G, B, A] array.
* @member {number[]}
* @protected
*/
this._backgroundColorRgba = [0, 0, 0, 1];
/**
* The background color as a string.
* @member {string}
* @protected
*/
this._backgroundColorString = '#000000';
this.backgroundColor = options.backgroundColor || this._backgroundColor; // run bg color setter
this.backgroundAlpha = options.backgroundAlpha;
// @deprecated
if (options.transparent !== undefined)
{
// #if _DEBUG
deprecation('6.0.0', 'Option transparent is deprecated, please use backgroundAlpha instead.');
// #endif
this.useContextAlpha = options.transparent;
this.backgroundAlpha = options.transparent ? 0 : 1;
}
/**
* The last root object that the renderer tried to render.
* @member {PIXI.DisplayObject}
* @protected
*/
this._lastObjectRendered = null;
/**
* Collection of plugins.
* @readonly
* @member {object}
*/
this.plugins = {};
}
/**
* Initialize the plugins.
* @protected
* @param {object} staticMap - The dictionary of statically saved plugins.
*/
initPlugins(staticMap: IRendererPlugins): void
{
for (const o in staticMap)
{
this.plugins[o] = new (staticMap[o])(this);
}
}
/**
* Same as view.width, actual number of pixels in the canvas by horizontal.
* @member {number}
* @readonly
* @default 800
*/
get width(): number
{
return this.view.width;
}
/**
* Same as view.height, actual number of pixels in the canvas by vertical.
* @member {number}
* @readonly
* @default 600
*/
get height(): number
{
return this.view.height;
}
/**
* Resizes the screen and canvas as close as possible to the specified width and height.
* Canvas dimensions are multiplied by resolution and rounded to the nearest integers.
* The new canvas dimensions divided by the resolution become the new screen dimensions.
* @param desiredScreenWidth - The desired width of the screen.
* @param desiredScreenHeight - The desired height of the screen.
*/
resize(desiredScreenWidth: number, desiredScreenHeight: number): void
{
this.view.width = Math.round(desiredScreenWidth * this.resolution);
this.view.height = Math.round(desiredScreenHeight * this.resolution);
const screenWidth = this.view.width / this.resolution;
const screenHeight = this.view.height / this.resolution;
this.screen.width = screenWidth;
this.screen.height = screenHeight;
if (this.autoDensity)
{
this.view.style.width = `${screenWidth}px`;
this.view.style.height = `${screenHeight}px`;
}
/**
* Fired after view has been resized.
* @event PIXI.Renderer#resize
* @param {number} screenWidth - The new width of the screen.
* @param {number} screenHeight - The new height of the screen.
*/
this.emit('resize', screenWidth, screenHeight);
}
/**
* Useful function that returns a texture of the display object that can then be used to create sprites
* This can be quite useful if your displayObject is complicated and needs to be reused multiple times.
* @method PIXI.AbstractRenderer#generateTexture
* @param displayObject - The displayObject the object will be generated from.
* @param {object} options - Generate texture options.
* @param {PIXI.SCALE_MODES} options.scaleMode - The scale mode of the texture.
* @param {number} options.resolution - The resolution / device pixel ratio of the texture being generated.
* @param {PIXI.Rectangle} options.region - The region of the displayObject, that shall be rendered,
* if no region is specified, defaults to the local bounds of the displayObject.
* @param {PIXI.MSAA_QUALITY} options.multisample - The number of samples of the frame buffer.
* @returns A texture of the graphics object.
*/
generateTexture(displayObject: IRenderableObject, options?: IGenerateTextureOptions): RenderTexture;
/**
* Please use the options argument instead.
* @method PIXI.AbstractRenderer#generateTexture
* @deprecated Since 6.1.0
* @param displayObject - The displayObject the object will be generated from.
* @param scaleMode - The scale mode of the texture.
* @param resolution - The resolution / device pixel ratio of the texture being generated.
* @param region - The region of the displayObject, that shall be rendered,
* if no region is specified, defaults to the local bounds of the displayObject.
* @returns A texture of the graphics object.
*/
generateTexture(
displayObject: IRenderableObject,
scaleMode?: SCALE_MODES,
resolution?: number,
region?: Rectangle): RenderTexture;
/**
* @ignore
*/
generateTexture(displayObject: IRenderableObject,
options: IGenerateTextureOptions | SCALE_MODES = {},
resolution?: number, region?: Rectangle): RenderTexture
{
// @deprecated parameters spread, use options instead
if (typeof options === 'number')
{
// #if _DEBUG
deprecation('6.1.0', 'generateTexture options (scaleMode, resolution, region) are now object options.');
// #endif
options = { scaleMode: options, resolution, region };
}
const { region: manualRegion, ...textureOptions } = options;
region = manualRegion || (displayObject as IRenderableContainer).getLocalBounds(null, true);
// minimum texture size is 1x1, 0x0 will throw an error
if (region.width === 0) region.width = 1;
if (region.height === 0) region.height = 1;
const renderTexture = RenderTexture.create(
{
width: region.width,
height: region.height,
...textureOptions,
});
tempMatrix.tx = -region.x;
tempMatrix.ty = -region.y;
this.render(displayObject, {
renderTexture,
clear: false,
transform: tempMatrix,
skipUpdateTransform: !!displayObject.parent
});
return renderTexture;
}
/**
* Adds a new system to the renderer.
* @param ClassRef - Class reference
* @param name - Property name for system
* @returns Return instance of renderer
*/
abstract addSystem(ClassRef: ISystemConstructor, name: string): this;
abstract render(displayObject: IRenderableObject, options?: IRendererRenderOptions): void;
/**
* Removes everything from the renderer and optionally removes the Canvas DOM element.
* @param [removeView=false] - Removes the Canvas element from the DOM.
*/
destroy(removeView?: boolean): void
{
for (const o in this.plugins)
{
this.plugins[o].destroy();
this.plugins[o] = null;
}
if (removeView && this.view.parentNode)
{
this.view.parentNode.removeChild(this.view);
}
const thisAny = this as any;
// null-ing all objects, that's a tradition!
thisAny.plugins = null;
thisAny.type = RENDERER_TYPE.UNKNOWN;
thisAny.view = null;
thisAny.screen = null;
thisAny._tempDisplayObjectParent = null;
thisAny.options = null;
this._backgroundColorRgba = null;
this._backgroundColorString = null;
this._lastObjectRendered = null;
}
/**
* The background color to fill if not transparent
* @member {number}
*/
get backgroundColor(): number
{
return this._backgroundColor;
}
set backgroundColor(value: number)
{
this._backgroundColor = value;
this._backgroundColorString = hex2string(value);
hex2rgb(value, this._backgroundColorRgba);
}
/**
* The background color alpha. Setting this to 0 will make the canvas transparent.
* @member {number}
*/
get backgroundAlpha(): number
{
return this._backgroundColorRgba[3];
}
set backgroundAlpha(value: number)
{
this._backgroundColorRgba[3] = value;
}
}