Commit 9272db0e authored by wjf's avatar wjf

增加webgl优化

parent ac74cb04
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -386,7 +386,7 @@ export class Entity extends HashObject { ...@@ -386,7 +386,7 @@ export class Entity extends HashObject {
*/ */
getComponents(clazz: any): any[] { getComponents(clazz: any): any[] {
return this._components.filter((component: any) => { return this._components.filter((component: any) => {
return typeof clazz === 'string' ? component.constructor.__class__ === clazz : component instanceof clazz; return typeof clazz === 'string' ? component.constructor.name === clazz : component instanceof clazz;
}); });
} }
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
*/ */
import HashObject from "./HashObject"; import HashObject from "./HashObject";
import {Entity, } from "./Entity"; import { Entity, } from "./Entity";
import {EngineConfig} from "../engine-config"; import { EngineConfig } from "../engine-config";
const interactiveMap = [ const interactiveMap = [
'_dealGlobalTouchBegin', '_dealGlobalTouchBegin',
...@@ -80,36 +80,36 @@ export class ScillaComponent extends HashObject { ...@@ -80,36 +80,36 @@ export class ScillaComponent extends HashObject {
/** /**
* 当组件生效时 * 当组件生效时
*/ */
onEnable(){ onEnable() {
} }
/** /**
* 当组件失效时 * 当组件失效时
*/ */
onDisable(){ onDisable() {
} }
$onUpdate(t) { $onUpdate(t) {
this.onUpdate(t); this.onUpdate(t);
if(!this._firstUpdate){ if (!this._firstUpdate) {
this.invokeDelayCallback(t); this.invokeDelayCallback(t);
} }
this._firstUpdate = false; this._firstUpdate = false;
} }
private invokeDelayCallback(t){ private invokeDelayCallback(t) {
const removed = []; const removed = [];
for (let i = 0, li = this.delayCallbacks.length; i < li; i++) { for (let i = 0, li = this.delayCallbacks.length; i < li; i++) {
let {callback, once} = this.delayCallbacks[i]; let { callback, once } = this.delayCallbacks[i];
if(once){ if (once) {
removed.push(i); removed.push(i);
} }
callback.call(this, t); callback.call(this, t);
} }
for(let item of removed){ for (let item of removed) {
this.delayCallbacks.splice(item, 1); this.delayCallbacks.splice(item, 1);
} }
} }
...@@ -149,14 +149,14 @@ export class ScillaComponent extends HashObject { ...@@ -149,14 +149,14 @@ export class ScillaComponent extends HashObject {
* @param key * @param key
* @param oldValue * @param oldValue
*/ */
protected onModify(value, key, oldValue){ protected onModify(value, key, oldValue) {
} }
private getDelayCallback(callback){ private getDelayCallback(callback) {
let result; let result;
for(let item of this.delayCallbacks){ for (let item of this.delayCallbacks) {
if(item.callback == callback){ if (item.callback == callback) {
result = item; result = item;
break; break;
} }
...@@ -172,14 +172,14 @@ export class ScillaComponent extends HashObject { ...@@ -172,14 +172,14 @@ export class ScillaComponent extends HashObject {
callOnNextTick(callback, once = true) { callOnNextTick(callback, once = true) {
const item = this.getDelayCallback(callback); const item = this.getDelayCallback(callback);
if (!item) { if (!item) {
this.delayCallbacks.push({callback, once}); this.delayCallbacks.push({ callback, once });
} }
} }
cancelOnNextTick(callback){ cancelOnNextTick(callback) {
const item = this.getDelayCallback(callback); const item = this.getDelayCallback(callback);
const index = this.delayCallbacks.indexOf(item); const index = this.delayCallbacks.indexOf(item);
if(index >= 0){ if (index >= 0) {
this.delayCallbacks.splice(index, 1); this.delayCallbacks.splice(index, 1);
} }
} }
...@@ -233,9 +233,15 @@ export class ScillaComponent extends HashObject { ...@@ -233,9 +233,15 @@ export class ScillaComponent extends HashObject {
onGlobalTouchEnd(e) { onGlobalTouchEnd(e) {
} }
private _transform;
get transform(){ get transform() {
return this.entity.getComponent('components/base/Transform'); if (!this._transform) {
this._transform = this.entity.getComponent('Transform');
return this._transform
} else {
return this._transform
}
// return this.entity.getComponent('Transform');
} }
/** /**
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
import Bounds from "../support/Bounds"; import Bounds from "../support/Bounds";
import HashObject from "../core/HashObject"; import HashObject from "../core/HashObject";
import {createCanvas} from "./context/RenderContext"; // import {createCanvas} from "./context/RenderContext";
/** /**
* 纹理类 * 纹理类
...@@ -20,14 +20,36 @@ export default class Texture extends HashObject { ...@@ -20,14 +20,36 @@ export default class Texture extends HashObject {
this.bounds = new Bounds(); this.bounds = new Bounds();
} }
/**
* 原图img上的纹理坐标,归一处理,左上角顺时针开始
*/
uvs = [0, 65535, -1, -65536]
/** /**
* 设置图集中的坐标和尺寸 * 设置图集中的坐标和尺寸
* @param frame * @param frame
*/ */
setFrame(frame) { setFrame(frame) {
let {x, y, w, h} = frame; let { x, y, w, h } = frame;
this.bounds.setTo(x, y, w, h); this.bounds.setTo(x, y, w, h);
if (!this.img.complete && !(this.img instanceof HTMLCanvasElement)) return
let { width, height } = this.img;
var x0 = x / width;
var y0 = y / height;
var x1 = (x + w) / width;
var y1 = y / height;
var x2 = (x + w) / width;
var y2 = (y + h) / height;
var x3 = x / width;
var y3 = (y + h) / height;
this.uvs[0] = (((y0 * 65535) & 0xFFFF) << 16) | ((x0 * 65535) & 0xFFFF);
this.uvs[1] = (((y1 * 65535) & 0xFFFF) << 16) | ((x1 * 65535) & 0xFFFF);
this.uvs[2] = (((y2 * 65535) & 0xFFFF) << 16) | ((x2 * 65535) & 0xFFFF);
this.uvs[3] = (((y3 * 65535) & 0xFFFF) << 16) | ((x3 * 65535) & 0xFFFF);
} }
/** /**
...@@ -36,6 +58,12 @@ export default class Texture extends HashObject { ...@@ -36,6 +58,12 @@ export default class Texture extends HashObject {
*/ */
setImg(img) { setImg(img) {
this.img = img; this.img = img;
//暂时全放img
this.img._glTextures = {};
this.img._enabled = 0;
this.img._virtalBoundId = -1;
this.img.touched = 0;
} }
/** /**
...@@ -56,11 +84,11 @@ export default class Texture extends HashObject { ...@@ -56,11 +84,11 @@ export default class Texture extends HashObject {
* 产生一个缓存画布 * 产生一个缓存画布
*/ */
getCacheCanvas() { getCacheCanvas() {
const {width, height} = this.bounds; const { width, height } = this.bounds;
let canvas = this._cacheCanvas; let canvas = this._cacheCanvas;
if (!canvas) { if (!canvas) {
canvas = this._cacheCanvas = createCanvas(); canvas = this._cacheCanvas = document.createElement("canvas");
} }
canvas.width = width; canvas.width = width;
canvas.height = height; canvas.height = height;
...@@ -82,7 +110,7 @@ export default class Texture extends HashObject { ...@@ -82,7 +110,7 @@ export default class Texture extends HashObject {
* @param dh * @param dh
*/ */
drawToCanvas(context, dx = 0, dy = 0, sx?, sy?, dw?, dh?) { drawToCanvas(context, dx = 0, dy = 0, sx?, sy?, dw?, dh?) {
const {x, y, width, height} = this.bounds; const { x, y, width, height } = this.bounds;
context.drawImage(this.img, sx || x, sy || y, width, height, dx, dy, dw || width, dh || height); context.drawImage(this.img, sx || x, sy || y, width, height, dx, dy, dw || width, dh || height);
} }
...@@ -99,7 +127,7 @@ export default class Texture extends HashObject { ...@@ -99,7 +127,7 @@ export default class Texture extends HashObject {
/** /**
* 销毁缓存画布 * 销毁缓存画布
*/ */
destroyCacheCanvas(){ destroyCacheCanvas() {
this._cacheCanvas = null; this._cacheCanvas = null;
} }
} }
...@@ -112,7 +140,7 @@ export default class Texture extends HashObject { ...@@ -112,7 +140,7 @@ export default class Texture extends HashObject {
export function createTexture(img, frame?): Texture { export function createTexture(img, frame?): Texture {
const texture = new Texture(); const texture = new Texture();
texture.setImg(img); texture.setImg(img);
texture.setFrame(frame || {x: 0, y: 0, w: img.width, h: img.height}); texture.setFrame(frame || { x: 0, y: 0, w: img.width, h: img.height });
return texture; return texture;
} }
/**
* Created by rockyl on 2018/11/5.
*
* 渲染上下文
*/
import { updateScaleMode } from "./InteractContext";
import Bounds from "../../support/Bounds";
let _canvas, context, width, height;
let scaleX, scaleY, rotation = 0;
let _designWidth, _designHeight, _scaleMode, _modifyCanvasSize;
let shortcutCanvas;
let renderStyle = "canvas"
/**
* 缩放模式
*
* SHOW_ALL: 全可见
* FIXED_WIDTH: 宽度固定
* FIXED_HEIGHT: 高度固定
*/
export const ScaleMode = {
SHOW_ALL: 'showAll',
FIXED_WIDTH: 'fixedWidth',
FIXED_HEIGHT: 'fixedHeight',
};
/**
* 装配上下文
* @param options
*/
export function setupContext(options: any = {}) {
const { canvas, designWidth, designHeight, scaleMode = ScaleMode.SHOW_ALL, modifyCanvasSize = false } = options;
_designWidth = designWidth;
_designHeight = designHeight;
_scaleMode = scaleMode;
_modifyCanvasSize = modifyCanvasSize;
_canvas = canvas;
if (options.renderStyle == "webgl") {
renderStyle = "webgl"
//参数有需要时开放
var option = {
// alpha: true,
antialias: false,
// premultipliedAlpha: true,
stencil: true,
// preserveDrawingBuffer: false,
// powerPreference: false, //双显卡设备参数切换高性能,移动端暂时无用
}
context = canvas.getContext('webgl', option) ||
canvas.getContext('experimental-webgl', option);
if (!context) {
console.log("不支持webgl,回退canvas模式")
renderStyle = "canvas";
context = canvas.getContext('2d');
}
} else {
context = canvas.getContext('2d');
}
updateScaleModeSelf();
}
/**
* 获取渲染模式
*/
export function getRenderStyle() {
return renderStyle
}
/**
* 清空渲染上下文
*/
export function clear() {
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, width, height);
}
/**
* 获取渲染上下文
*/
export function getContext() {
return context;
}
/**
* 获取舞台尺寸
*/
export function getStageSize() {
return {
width,
height,
}
}
/**
* 获取舞台缩放
*/
export function getStageScale() {
return {
x: scaleX,
y: scaleY,
}
}
/**
* 获取舞台中心
*/
export function getStageCenter() {
return {
x: width / 2,
y: height / 2,
}
}
/**
* 创建canvas
*/
export function createCanvas() {
return document.createElement('canvas');
}
interface ShortcutParams {
imgType: string;
zoomToDom?: boolean;
quality?: number;
bounds?: Bounds;
}
/**
* 截图
* @param type 目标格式 0:Image, 1:DataURL
* @param params
*/
export async function shortcut(type: number = 0, params: ShortcutParams) {
let targetImg;
if (params.bounds || params.zoomToDom) {
const dataUrl = _canvas.toDataURL('image/png');
const img = await dataUrlToImage(dataUrl);
targetImg = await shortcutWithSize(img, type, params.imgType, params.quality, params.bounds, params.zoomToDom ? scaleX : 1);
} else {
targetImg = _canvas.toDataURL(params.imgType, params.quality);
}
return targetImg;
}
function dataUrlToImage(dataUrl) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = function () {
resolve(image);
};
image.onerror = function (e) {
reject(e);
};
image.src = dataUrl;
})
}
async function shortcutWithSize(img, type, imgType, quality?, bounds?: Bounds, scale = 1) {
if (!shortcutCanvas) {
shortcutCanvas = createCanvas();
}
const sx = bounds ? bounds.x || 0 : 0;
const sy = bounds ? bounds.y || 0 : 0;
const sw = bounds ? (bounds.width ? Math.min(bounds.width, width) : width) : width;
const sh = bounds ? (bounds.height ? Math.min(bounds.height, height) : height) : height;
const dw = sw * scale;
const dh = sh * scale;
shortcutCanvas.width = dw;
shortcutCanvas.height = dh;
const context = shortcutCanvas.getContext('2d');
context.drawImage(img, sx, sy, sw, sh, 0, 0, dw, dh);
const dataUrl = shortcutCanvas.toDataURL('image/' + imgType, quality);
switch (type) {
case 0:
return await dataUrlToImage(dataUrl);
case 1:
return dataUrl;
}
}
/**
* 更新缩放模式
*/
function updateScaleModeSelf() {
let parent = _canvas.parentElement;
let containerWidth = parent.clientWidth;
let containerHeight = parent.clientHeight;
const designWidth = _designWidth || containerWidth;
const designHeight = _designHeight || containerHeight;
scaleX = containerWidth / designWidth;
scaleY = containerHeight / designHeight;
switch (_scaleMode) {
case ScaleMode.SHOW_ALL:
width = designWidth;
height = designHeight;
break;
case ScaleMode.FIXED_WIDTH:
width = designWidth;
if (_modifyCanvasSize) {
height = designHeight;
} else {
height = containerHeight / scaleX;
}
scaleY = scaleX;
break;
case ScaleMode.FIXED_HEIGHT:
if (_modifyCanvasSize) {
width = designWidth;
} else {
width = containerWidth / scaleY;
}
height = designHeight;
scaleX = scaleY;
break;
}
updateScaleMode(scaleX, scaleY, rotation);
let styleWidth = _modifyCanvasSize ? designWidth * scaleX : containerWidth;
let styleHeight = _modifyCanvasSize ? designHeight * scaleY : containerHeight;
_canvas.width = width;
_canvas.height = height;
_canvas.style.display = 'block';
_canvas.style.width = styleWidth + 'px';
_canvas.style.height = styleHeight + 'px';
}
...@@ -6,10 +6,14 @@ export {ScillaComponent} from "./ScillaComponent"; ...@@ -6,10 +6,14 @@ export {ScillaComponent} from "./ScillaComponent";
export {Entity} from './Entity' export {Entity} from './Entity'
export {Scene} from './Scene' export {Scene} from './Scene'
export {ScillaEvent} from './ScillaEvent' export {ScillaEvent} from './ScillaEvent'
export {getContext, createCanvas, getStageSize, getStageScale, getStageCenter, shortcut, ScaleMode} from './context/RenderContext'; // export {getContext, createCanvas, getStageSize, getStageScale, getStageCenter, shortcut, ScaleMode} from './context/RenderContext';
export { getContext, getRenderStyle, createCanvas, getStageSize, getStageScale, getStageCenter, shortcut } from './context/RenderContextGL';
export {pagePosToCanvasPos, canvasPosToPagePos} from './context/InteractContext'; export {pagePosToCanvasPos, canvasPosToPagePos} from './context/InteractContext';
export * from './manager' export * from './manager'
export {default as Texture, createTexture} from './Texture' export {default as Texture, createTexture} from './Texture'
export * from './Sheet' export * from './Sheet'
export * from './FrameAnimation' export * from './FrameAnimation'
\ No newline at end of file
//导出webgl渲染器
export {default as WebGLRenderer} from "./webgl/WebGLRenderer";
\ No newline at end of file
...@@ -2,12 +2,13 @@ ...@@ -2,12 +2,13 @@
* Created by rockyl on 2018/11/23. * Created by rockyl on 2018/11/23.
*/ */
import {Entity, traverse, traversePostorder} from "./Entity"; import { Entity, traverse, traversePostorder } from "./Entity";
import {injectProp} from "../tools/utils"; import { injectProp } from "../tools/utils";
import {setupContext as setupInteractContext} from "./context/InteractContext"; import { setupContext as setupInteractContext } from "./context/InteractContext";
import {clear, ScaleMode, setupContext as setupRenderContext} from "./context/RenderContext"; // import {clear, ScaleMode, setupContext as setupRenderContext} from "./context/RenderContext";
import { clear, getRenderStyle, ScaleMode, setupContext as setupRenderContext } from "./context/RenderContextGL";
import './requestAnimationFrame'; import './requestAnimationFrame';
import WebglRenderer from "./webgl/WebGLRenderer";
/** /**
* 默认配置 * 默认配置
*/ */
...@@ -33,7 +34,7 @@ let lastFPS = 0; ...@@ -33,7 +34,7 @@ let lastFPS = 0;
export function setup(_options?) { export function setup(_options?) {
injectProp(options, _options); injectProp(options, _options);
const {canvas, designWidth, designHeight, scaleMode, modifyCanvasSize, touchEnabled} = options; const { canvas, designWidth, designHeight, scaleMode, modifyCanvasSize, touchEnabled,renderStyle } = options;
let canvasElement = typeof canvas == 'object' ? canvas : document.getElementById(canvas); let canvasElement = typeof canvas == 'object' ? canvas : document.getElementById(canvas);
...@@ -53,6 +54,7 @@ export function setup(_options?) { ...@@ -53,6 +54,7 @@ export function setup(_options?) {
designHeight, designHeight,
scaleMode, scaleMode,
modifyCanvasSize, modifyCanvasSize,
renderStyle
}); });
root = new Entity('root'); root = new Entity('root');
...@@ -103,7 +105,7 @@ export function getEntityPath(entity?: Entity): string { ...@@ -103,7 +105,7 @@ export function getEntityPath(entity?: Entity): string {
* 根据节点路径获取节点 * 根据节点路径获取节点
* @param path * @param path
*/ */
export function getEntityByPath(path?: string): Entity{ export function getEntityByPath(path?: string): Entity {
let target = root; let target = root;
if (path.length > 0) { if (path.length > 0) {
...@@ -166,12 +168,17 @@ function flush(tsNow): void { ...@@ -166,12 +168,17 @@ function flush(tsNow): void {
} }
const nextTicks = []; const nextTicks = [];
export function nextTick(func){ export function nextTick(func) {
nextTicks.push(func); nextTicks.push(func);
} }
function onFrameTick(tsNow) { function onFrameTick(tsNow) {
clear(); //循环前
if (getRenderStyle() == "webgl") {
WebglRenderer.ins.preRender();
} else {
clear();
}
const tsNow2 = Date.now(); const tsNow2 = Date.now();
lastFPS = Math.floor(1000 / (tsNow - tsLast)); lastFPS = Math.floor(1000 / (tsNow - tsLast));
tsLast = tsNow; tsLast = tsNow;
...@@ -188,10 +195,14 @@ function onFrameTick(tsNow) { ...@@ -188,10 +195,14 @@ function onFrameTick(tsNow) {
}); });
//const tsPass = Date.now() - tsNow; //const tsPass = Date.now() - tsNow;
while(nextTicks.length > 0){ while (nextTicks.length > 0) {
let func = nextTicks.shift(); let func = nextTicks.shift();
func(); func();
} }
//循环后
if (getRenderStyle() == "webgl") {
WebglRenderer.ins.postRender()
}
} }
/** /**
......
/**
* Base for a common object renderer that can be used as a system renderer plugin.
*
* @class
*/
export default class ObjectRenderer {
renderer
constructor(renderer) {
this.renderer = renderer
}
/**
* Starts the renderer and sets the shader
*
*/
start() {
// set the shader..
}
/**
* Stops the renderer
*
*/
stop() {
this.flush();
}
/**
* Stub method for rendering content and emptying the current batch.
*
*/
flush() {
// flush!
}
/**
* Renders an object
*
* @param {DisplayObject} object - The object to render.
*/
render(object) // eslint-disable-line no-unused-vars
{
// render the object
}
}
import { getContext, getStageSize } from "../../core/context/RenderContextGL"
import { GLTexture, VertexArrayObject } from "./glCore"
import MaskManager from './managers/MaskManager';
import StencilManager from './managers/StencilManager';
// import FilterManager from './managers/FilterManager';
import RenderTarget from './utils/RenderTarget';
import ObjectRenderer from './ObjectRenderer';
import TextureManager from './managers/TextureManager';
import TextureGarbageCollector from './managers/TextureGarbageCollector';
import WebGLState from './WebGLState';
import mapWebGLDrawModesTo from './utils/mapWebGLDrawModesTo';
import validateContext from './utils/validateContext';
import pluginTarget from './utils/pluginTarget';
import { RENDERER_TYPE } from './const';
import BatchRenderer from "./rendererPlugins/BatchRenderer"
import GraphicsRenderer from "./rendererPlugins/GraphicsRenderer"
let CONTEXT_UID = 0;
/**
* The WebGLRenderer draws the scene and all its content onto a webGL enabled canvas. This renderer
* should be used for browsers that support webGL. This Render works by automatically managing webGLBatchs.
* So no need for Sprite Batches or Sprite Clouds.
* Don't forget to add the view to your DOM or you will not see anything :)
*
* @class
* @memberof PIXI
* @extends SystemRenderer
*/
export default class WebGLRenderer {
gl: any;
type: number;
_backgroundColorRgba: number[];
maskManager: MaskManager;
stencilManager: StencilManager;
emptyRenderer: ObjectRenderer;
currentRenderer: any;
textureManager: any;
filterManager: any;
CONTEXT_UID: number;
state: WebGLState;
renderingToScreen: boolean;
boundTextures: any;
_activeShader: any;
_activeVao: any;
_activeRenderTarget: any;
drawModes: {};
_nextTextureLocation: number;
emptyTextures: any[];
textureGC: TextureGarbageCollector;
rootRenderTarget: RenderTarget;
uid: number;
private static instance: WebGLRenderer;
public static get ins(): WebGLRenderer {
if (!this.instance) {
this.instance = new WebGLRenderer();
}
return this.instance;
}
constructor() {
this.gl = getContext();
// this.legacy = this.options.legacy;
// if (this.legacy) {
// glCore.VertexArrayObject.FORCE_NATIVE = true;
// }
/**
* The type of this renderer as a standardised const
*
* @member {number}
* @see RENDERER_TYPE
*/
this.type = RENDERER_TYPE.WEBGL;
this.handleContextLost = this.handleContextLost.bind(this);
this.handleContextRestored = this.handleContextRestored.bind(this);
// this.view.addEventListener('webglcontextlost', this.handleContextLost, false);
// this.view.addEventListener('webglcontextrestored', this.handleContextRestored, false);
this._backgroundColorRgba = [0, 0, 0, 0];
/**
* Manages the masks using the stencil buffer.
*
* @member {MaskManager}
*/
this.maskManager = new MaskManager(this);
/**
* Manages the stencil buffer.
*
* @member {StencilManager}
*/
this.stencilManager = new StencilManager(this);
/**
* An empty renderer.
*
* @member {ObjectRenderer}
*/
this.emptyRenderer = new ObjectRenderer(this);
/**
* The currently active ObjectRenderer.
*
* @member {ObjectRenderer}
*/
this.currentRenderer = this.emptyRenderer;
/**
* Manages textures
* @member {TextureManager}
*/
this.textureManager = null;
/**
* Manages the filters.
*
* @member {FilterManager}
*/
this.filterManager = null;
this["initPlugins"]();
/**
* The current WebGL rendering context, it is created here
*
* @member {WebGLRenderingContext}
*/
// initialize the context so it is ready for the managers.
// if (this.options.context) {
// checks to see if a context is valid..
validateContext(this.gl);
// }
this.CONTEXT_UID = CONTEXT_UID++;
/**
* The currently active ObjectRenderer.
*
* @member {WebGLState}
*/
this.state = new WebGLState(this.gl);
this.renderingToScreen = true;
/**
* Holds the current state of textures bound to the GPU.
* @type {Array}
*/
this.boundTextures = null;
/**
* Holds the current shader
*
* @member {Shader}
*/
this._activeShader = null;
this._activeVao = null;
/**
* Holds the current render target
*
* @member {RenderTarget}
*/
this._activeRenderTarget = null;
this._initContext();
// map some webGL blend and drawmodes..
this.drawModes = mapWebGLDrawModesTo(this.gl);
this._nextTextureLocation = 0;
this.setBlendMode(0);
/**
* Fired after rendering finishes.
*
* @event WebGLRenderer#postrender
*/
/**
* Fired before rendering starts.
*
* @event WebGLRenderer#prerender
*/
/**
* Fired when the WebGL context is set.
*
* @event WebGLRenderer#context
* @param {WebGLRenderingContext} gl - WebGL context.
*/
}
/**
* Creates the WebGL context
*
* @private
*/
_initContext() {
const gl = this.gl;
// restore a context if it was previously lost
if (gl.isContextLost() && gl.getExtension('WEBGL_lose_context')) {
gl.getExtension('WEBGL_lose_context').restoreContext();
}
const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
this._activeShader = null;
this._activeVao = null;
this.boundTextures = new Array(maxTextures);
this.emptyTextures = new Array(maxTextures);
// create a texture manager...
this.textureManager = new TextureManager(this);
// this.filterManager = new FilterManager(this);
this.textureGC = new TextureGarbageCollector(this);
this.state.resetToDefault();
var wh = getStageSize();
this.rootRenderTarget = new RenderTarget(gl, wh.width, wh.height, null, /*this.resolution,*/ true);
this.rootRenderTarget.clearColor = this._backgroundColorRgba;
this.bindRenderTarget(this.rootRenderTarget);
// now lets fill up the textures with empty ones!
const emptyGLTexture = GLTexture.fromData(gl, null, 1, 1);
const tempObj = { _glTextures: {} };
tempObj._glTextures[this.CONTEXT_UID] = {};
for (let i = 0; i < maxTextures; i++) {
// const empty = new Texture();
const empty:any = new Image();//先用这个代替,以后优化
empty._glTextures={}
empty._glTextures[this.CONTEXT_UID] = emptyGLTexture;
this.boundTextures[i] = tempObj;
this.emptyTextures[i] = empty;
this.bindTexture(null, i);
}
// this.emit('context', gl);
//直接这里都执行了
console.log(this["plugins"])
this["plugins"].batch.onContextChange();
this["plugins"].graphics.onContextChange();
// setup the width/height properties and gl viewport
this.resize(wh.width, wh.height);
}
preRender(){
this["plugins"].batch.onPrerender();
this._nextTextureLocation = 0;
this.bindRenderTexture();
this.currentRenderer.start();
this._activeRenderTarget.clear();
}
/**
* Renders the object to its webGL view
*
* @param {DisplayObject} displayObject - the object to be rendered
* @param {RenderTexture} renderTexture - The render texture to render to.
* @param {boolean} [clear] - Should the canvas be cleared before the new render
* @param {Matrix} [transform] - A transform to apply to the render texture before rendering.
* @param {boolean} [skipUpdateTransform] - Should we skip the update transform pass?
*/
render(displayObject, renderTexture?, clear?, transform?, skipUpdateTransform?) {
this.setObjectRenderer(this["plugins"][displayObject.pluginName||"batch"]);
this["plugins"][displayObject.pluginName||"batch"].render(displayObject);
}
postRender(){
this.currentRenderer.flush();
this.textureGC.update();
}
/**
* Changes the current renderer to the one given in parameter
*
* @param {ObjectRenderer} objectRenderer - The object renderer to use.
*/
setObjectRenderer(objectRenderer) {
if (this.currentRenderer === objectRenderer) {
return;
}
this.currentRenderer.stop();
this.currentRenderer = objectRenderer;
this.currentRenderer.start();
}
/**
* This should be called if you wish to do some custom rendering
* It will basically render anything that may be batched up such as sprites
*
*/
flush() {
this.setObjectRenderer(this.emptyRenderer);
}
/**
* Resizes the webGL view to the specified width and height.
*
* @param {number} screenWidth - the new width of the screen
* @param {number} screenHeight - the new height of the screen
*/
resize(screenWidth, screenHeight) {
// if(width * this.resolution === this.width && height * this.resolution === this.height)return;
// SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight);
this.rootRenderTarget.resize(screenWidth, screenHeight);
if (this._activeRenderTarget === this.rootRenderTarget) {
this.rootRenderTarget.activate();
if (this._activeShader) {
this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true);
}
}
}
/**
* Resizes the webGL view to the specified width and height.
*
* @param {number} blendMode - the desired blend mode
*/
setBlendMode(blendMode) {
this.state.setBlendMode(blendMode);
}
/**
* Erases the active render target and fills the drawing area with a colour
*
* @param {number} [clearColor] - The colour
*/
clear(clearColor) {
this._activeRenderTarget.clear(clearColor);
}
/**
* Sets the transform of the active render target to the given matrix
*
* @param {Matrix} matrix - The transformation matrix
*/
setTransform(matrix) {
this._activeRenderTarget.transform = matrix;
}
/**
* Erases the render texture and fills the drawing area with a colour
*
* @param {RenderTexture} renderTexture - The render texture to clear
* @param {number} [clearColor] - The colour
* @return {WebGLRenderer} Returns itself.
*/
clearRenderTexture(renderTexture, clearColor) {
const baseTexture = renderTexture.baseTexture;
const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID];
if (renderTarget) {
renderTarget.clear(clearColor);
}
return this;
}
/**
* Binds a render texture for rendering
*
* @param {RenderTexture} renderTexture - The render texture to render
* @param {Matrix} transform - The transform to be applied to the render texture
* @return {WebGLRenderer} Returns itself.
*/
bindRenderTexture(renderTexture?, transform?) {
let renderTarget;
if (renderTexture) {
const baseTexture = renderTexture.baseTexture;
if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) {
// bind the current texture
this.textureManager.updateTexture(baseTexture, 0);
}
this.unbindTexture(baseTexture);
renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID];
renderTarget.setFrame(renderTexture.frame);
}
else {
renderTarget = this.rootRenderTarget;
}
renderTarget.transform = transform;
this.bindRenderTarget(renderTarget);
return this;
}
/**
* Changes the current render target to the one given in parameter
*
* @param {RenderTarget} renderTarget - the new render target
* @return {WebGLRenderer} Returns itself.
*/
bindRenderTarget(renderTarget) {
if (renderTarget !== this._activeRenderTarget) {
this._activeRenderTarget = renderTarget;
renderTarget.activate();
if (this._activeShader) {
this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true);
}
this.stencilManager.setMaskStack(renderTarget.stencilMaskStack);
}
return this;
}
/**
* Changes the current shader to the one given in parameter
*
* @param {Shader} shader - the new shader
* @param {boolean} [autoProject=true] - Whether automatically set the projection matrix
* @return {WebGLRenderer} Returns itself.
*/
bindShader(shader, autoProject) {
// TODO cache
if (this._activeShader !== shader) {
this._activeShader = shader;
shader.bind();
// `autoProject` normally would be a default parameter set to true
// but because of how Babel transpiles default parameters
// it hinders the performance of this method.
if (autoProject !== false) {
// automatically set the projection matrix
shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true);
}
}
return this;
}
/**
* Binds the texture. This will return the location of the bound texture.
* It may not be the same as the one you pass in. This is due to optimisation that prevents
* needless binding of textures. For example if the texture is already bound it will return the
* current location of the texture instead of the one provided. To bypass this use force location
*
* @param {Texture} texture - the new texture 为image标签先
* @param {number} location - the suggested texture location
* @param {boolean} forceLocation - force the location
* @return {number} bound texture location
*/
bindTexture(texture, location, forceLocation?) {
texture = texture || this.emptyTextures[location];
// texture = texture.baseTexture || texture;
// texture.touched = this.textureGC.count;
if (!forceLocation) {
// TODO - maybe look into adding boundIds.. save us the loop?
for (let i = 0; i < this.boundTextures.length; i++) {
if (this.boundTextures[i] === texture) {
return i;
}
}
if (location === undefined) {
this._nextTextureLocation++;
this._nextTextureLocation %= this.boundTextures.length;
location = this.boundTextures.length - this._nextTextureLocation - 1;
}
}
else {
location = location || 0;
}
const gl = this.gl;
const glTexture = texture._glTextures[this.CONTEXT_UID];
if (!glTexture) {
// this will also bind the texture..
this.textureManager.updateTexture(texture, location);
}
else {
// bind the current texture
this.boundTextures[location] = texture;
gl.activeTexture(gl.TEXTURE0 + location);
gl.bindTexture(gl.TEXTURE_2D, glTexture.texture);
}
return location;
}
/**
* unbinds the texture ...
*
* @param {Texture} texture - the texture to unbind
* @return {WebGLRenderer} Returns itself.
*/
unbindTexture(texture) {
const gl = this.gl;
texture = texture.baseTexture || texture;
for (let i = 0; i < this.boundTextures.length; i++) {
if (this.boundTextures[i] === texture) {
this.boundTextures[i] = this.emptyTextures[i];
gl.activeTexture(gl.TEXTURE0 + i);
gl.bindTexture(gl.TEXTURE_2D, this.emptyTextures[i]._glTextures[this.CONTEXT_UID].texture);
}
}
return this;
}
/**
* Creates a new VAO from this renderer's context and state.
*
* @return {VertexArrayObject} The new VAO.
*/
createVao() {
return new VertexArrayObject(this.gl, this.state.attribState);
}
/**
* Changes the current Vao to the one given in parameter
*
* @param {VertexArrayObject} vao - the new Vao
* @return {WebGLRenderer} Returns itself.
*/
bindVao(vao?) {
if (this._activeVao === vao) {
return this;
}
if (vao) {
vao.bind();
}
else if (this._activeVao) {
// TODO this should always be true i think?
this._activeVao.unbind();
}
this._activeVao = vao;
return this;
}
/**
* Resets the WebGL state so you can render things however you fancy!
*
* @return {WebGLRenderer} Returns itself.
*/
reset() {
this.setObjectRenderer(this.emptyRenderer);
this.bindVao(null);
this._activeShader = null;
this._activeRenderTarget = this.rootRenderTarget;
for (let i = 0; i < this.boundTextures.length; i++) {
this.boundTextures[i] = this.emptyTextures[i];
}
// bind the main frame buffer (the screen);
this.rootRenderTarget.activate();
this.state.resetToDefault();
return this;
}
/**
* Handles a lost webgl context
*
* @private
* @param {WebGLContextEvent} event - The context lost event.
*/
handleContextLost(event) {
event.preventDefault();
}
/**
* Handles a restored webgl context
*
* @private
*/
handleContextRestored() {
this.textureManager.removeAll();
this.filterManager.destroy(true);
this._initContext();
}
/**
* Removes everything from the renderer (event listeners, spritebatch, etc...)
*
* @param {boolean} [removeView=false] - Removes the Canvas element from the DOM.
* See: https://github.com/pixijs/js/issues/2233
*/
destroy(removeView) {
// this.destroyPlugins();
// remove listeners
// this.view.removeEventListener('webglcontextlost', this.handleContextLost);
// this.view.removeEventListener('webglcontextrestored', this.handleContextRestored);
this.textureManager.destroy();
// call base destroy
// super.destroy(removeView);
this.uid = 0;
// destroy the managers
this.maskManager.destroy();
this.stencilManager.destroy();
this.filterManager.destroy();
this.maskManager = null;
this.filterManager = null;
this.textureManager = null;
this.currentRenderer = null;
this.handleContextLost = null;
this.handleContextRestored = null;
this.gl.useProgram(null);
if (this.gl.getExtension('WEBGL_lose_context')) {
this.gl.getExtension('WEBGL_lose_context').loseContext();
}
this.gl = null;
// this = null;
}
}
/**
* Collection of installed plugins. These are included by default in PIXI, but can be excluded
* by creating a custom build. Consult the README for more information about creating custom
* builds and excluding plugins.
* @name WebGLRenderer#plugins
* @type {object}
* @readonly
* @property {accessibility.AccessibilityManager} accessibility Support tabbing interactive elements.
* @property {extract.WebGLExtract} extract Extract image data from renderer.
* @property {interaction.InteractionManager} interaction Handles mouse, touch and pointer events.
* @property {prepare.WebGLPrepare} prepare Pre-render display objects.
*/
/**
* Adds a plugin to the renderer.
*
* @method WebGLRenderer#registerPlugin
* @param {string} pluginName - The name of the plugin.
* @param {Function} ctor - The constructor function or class for the plugin.
*/
pluginTarget.mixin(WebGLRenderer);
WebGLRenderer["registerPlugin"]('batch', BatchRenderer);
WebGLRenderer["registerPlugin"]('graphics', GraphicsRenderer);
import mapWebGLBlendModesTo from './utils/mapWebGLBlendModesTo';
const BLEND = 0;
const DEPTH_TEST = 1;
const FRONT_FACE = 2;
const CULL_FACE = 3;
const BLEND_FUNC = 4;
/**
* A WebGL state machines
*
* @class
*/
export default class WebGLState {
activeState: Uint8Array;
defaultState: Uint8Array;
stackIndex: number;
stack: any[];
gl: any;
maxAttribs: any;
attribState: { tempAttribState: any[]; attribState: any[]; };
blendModes: any[];
nativeVaoExtension: any;
/**
* @param {WebGLRenderingContext} gl - The current WebGL rendering context
*/
constructor(gl) {
/**
* The current active state
*
* @member {Uint8Array}
*/
this.activeState = new Uint8Array(16);
/**
* The default state
*
* @member {Uint8Array}
*/
this.defaultState = new Uint8Array(16);
// default blend mode..
this.defaultState[0] = 1;
/**
* The current state index in the stack
*
* @member {number}
* @private
*/
this.stackIndex = 0;
/**
* The stack holding all the different states
*
* @member {Array<*>}
* @private
*/
this.stack = [];
/**
* The current WebGL rendering context
*
* @member {WebGLRenderingContext}
*/
this.gl = gl;
this.maxAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
this.attribState = {
tempAttribState: new Array(this.maxAttribs),
attribState: new Array(this.maxAttribs),
};
this.blendModes = mapWebGLBlendModesTo(gl);
// check we have vao..
this.nativeVaoExtension = (
gl.getExtension('OES_vertex_array_object')
|| gl.getExtension('MOZ_OES_vertex_array_object')
|| gl.getExtension('WEBKIT_OES_vertex_array_object')
);
}
/**
* Pushes a new active state
*/
push() {
// next state..
let state = this.stack[this.stackIndex];
if (!state) {
state = this.stack[this.stackIndex] = new Uint8Array(16);
}
++this.stackIndex;
// copy state..
// set active state so we can force overrides of gl state
for (let i = 0; i < this.activeState.length; i++) {
state[i] = this.activeState[i];
}
}
/**
* Pops a state out
*/
pop() {
const state = this.stack[--this.stackIndex];
this.setState(state);
}
/**
* Sets the current state
*
* @param {*} state - The state to set.
*/
setState(state) {
this.setBlend(state[BLEND]);
this.setDepthTest(state[DEPTH_TEST]);
this.setFrontFace(state[FRONT_FACE]);
this.setCullFace(state[CULL_FACE]);
this.setBlendMode(state[BLEND_FUNC]);
}
/**
* Enables or disabled blending.
*
* @param {boolean} value - Turn on or off webgl blending.
*/
setBlend(value) {
value = value ? 1 : 0;
if (this.activeState[BLEND] === value) {
return;
}
this.activeState[BLEND] = value;
this.gl[value ? 'enable' : 'disable'](this.gl.BLEND);
}
/**
* Sets the blend mode.
*
* @param {number} value - The blend mode to set to.
*/
setBlendMode(value) {
if (value === this.activeState[BLEND_FUNC]) {
return;
}
this.activeState[BLEND_FUNC] = value;
const mode = this.blendModes[value];
if (mode.length === 2) {
this.gl.blendFunc(mode[0], mode[1]);
}
else {
this.gl.blendFuncSeparate(mode[0], mode[1], mode[2], mode[3]);
}
}
/**
* Sets whether to enable or disable depth test.
*
* @param {boolean} value - Turn on or off webgl depth testing.
*/
setDepthTest(value) {
value = value ? 1 : 0;
if (this.activeState[DEPTH_TEST] === value) {
return;
}
this.activeState[DEPTH_TEST] = value;
this.gl[value ? 'enable' : 'disable'](this.gl.DEPTH_TEST);
}
/**
* Sets whether to enable or disable cull face.
*
* @param {boolean} value - Turn on or off webgl cull face.
*/
setCullFace(value) {
value = value ? 1 : 0;
if (this.activeState[CULL_FACE] === value) {
return;
}
this.activeState[CULL_FACE] = value;
this.gl[value ? 'enable' : 'disable'](this.gl.CULL_FACE);
}
/**
* Sets the gl front face.
*
* @param {boolean} value - true is clockwise and false is counter-clockwise
*/
setFrontFace(value) {
value = value ? 1 : 0;
if (this.activeState[FRONT_FACE] === value) {
return;
}
this.activeState[FRONT_FACE] = value;
this.gl.frontFace(this.gl[value ? 'CW' : 'CCW']);
}
/**
* Disables all the vaos in use
*
*/
resetAttributes() {
for (let i = 0; i < this.attribState.tempAttribState.length; i++) {
this.attribState.tempAttribState[i] = 0;
}
for (let i = 0; i < this.attribState.attribState.length; i++) {
this.attribState.attribState[i] = 0;
}
// im going to assume one is always active for performance reasons.
for (let i = 1; i < this.maxAttribs; i++) {
this.gl.disableVertexAttribArray(i);
}
}
// used
/**
* Resets all the logic and disables the vaos
*/
resetToDefault() {
// unbind any VAO if they exist..
if (this.nativeVaoExtension) {
this.nativeVaoExtension.bindVertexArrayOES(null);
}
// reset all attributes..
this.resetAttributes();
// set active state so we can force overrides of gl state
for (let i = 0; i < this.activeState.length; ++i) {
this.activeState[i] = 32;
}
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, false);
this.setState(this.defaultState);
}
}
/**
* Two Pi.
*
* @static
* @constant
* @memberof PIXI
* @type {number}
*/
export const PI_2 = Math.PI * 2;
/**
* Conversion factor for converting radians to degrees.
*
* @static
* @constant
* @memberof PIXI
* @type {number}
*/
export const RAD_TO_DEG = 180 / Math.PI;
/**
* Conversion factor for converting degrees to radians.
*
* @static
* @constant
* @memberof PIXI
* @type {number}
*/
export const DEG_TO_RAD = Math.PI / 180;
/**
* Constant to identify the Renderer Type.
*
* @static
* @constant
* @memberof PIXI
* @name RENDERER_TYPE
* @type {object}
* @property {number} UNKNOWN - Unknown render type.
* @property {number} WEBGL - WebGL render type.
* @property {number} CANVAS - Canvas render type.
*/
export const RENDERER_TYPE = {
UNKNOWN: 0,
WEBGL: 1,
CANVAS: 2,
};
/**
* Various blend modes supported by
*
* IMPORTANT - The WebGL renderer only supports the NORMAL, ADD, MULTIPLY and SCREEN blend modes.
* Anything else will silently act like NORMAL.
*
* @static
* @constant
* @memberof PIXI
* @name BLEND_MODES
* @type {object}
* @property {number} NORMAL
* @property {number} ADD
* @property {number} MULTIPLY
* @property {number} SCREEN
* @property {number} OVERLAY
* @property {number} DARKEN
* @property {number} LIGHTEN
* @property {number} COLOR_DODGE
* @property {number} COLOR_BURN
* @property {number} HARD_LIGHT
* @property {number} SOFT_LIGHT
* @property {number} DIFFERENCE
* @property {number} EXCLUSION
* @property {number} HUE
* @property {number} SATURATION
* @property {number} COLOR
* @property {number} LUMINOSITY
*/
export const BLEND_MODES = {
NORMAL: 0,
ADD: 1,
MULTIPLY: 2,
SCREEN: 3,
OVERLAY: 4,
DARKEN: 5,
LIGHTEN: 6,
COLOR_DODGE: 7,
COLOR_BURN: 8,
HARD_LIGHT: 9,
SOFT_LIGHT: 10,
DIFFERENCE: 11,
EXCLUSION: 12,
HUE: 13,
SATURATION: 14,
COLOR: 15,
LUMINOSITY: 16,
NORMAL_NPM: 17,
ADD_NPM: 18,
SCREEN_NPM: 19,
};
/**
* Various webgl draw modes. These can be used to specify which GL drawMode to use
* under certain situations and renderers.
*
* @static
* @constant
* @memberof PIXI
* @name DRAW_MODES
* @type {object}
* @property {number} POINTS
* @property {number} LINES
* @property {number} LINE_LOOP
* @property {number} LINE_STRIP
* @property {number} TRIANGLES
* @property {number} TRIANGLE_STRIP
* @property {number} TRIANGLE_FAN
*/
export const DRAW_MODES = {
POINTS: 0,
LINES: 1,
LINE_LOOP: 2,
LINE_STRIP: 3,
TRIANGLES: 4,
TRIANGLE_STRIP: 5,
TRIANGLE_FAN: 6,
};
/**
* The scale modes that are supported by
*
* The {@link settings.SCALE_MODE} scale mode affects the default scaling mode of future operations.
* It can be re-assigned to either LINEAR or NEAREST, depending upon suitability.
*
* @static
* @constant
* @memberof PIXI
* @name SCALE_MODES
* @type {object}
* @property {number} LINEAR Smooth scaling
* @property {number} NEAREST Pixelating scaling
*/
export const SCALE_MODES = {
LINEAR: 0,
NEAREST: 1,
};
/**
* The wrap modes that are supported by
*
* The {@link settings.WRAP_MODE} wrap mode affects the default wrapping mode of future operations.
* It can be re-assigned to either CLAMP or REPEAT, depending upon suitability.
* If the texture is non power of two then clamp will be used regardless as webGL can
* only use REPEAT if the texture is po2.
*
* This property only affects WebGL.
*
* @static
* @constant
* @name WRAP_MODES
* @memberof PIXI
* @type {object}
* @property {number} CLAMP - The textures uvs are clamped
* @property {number} REPEAT - The texture uvs tile and repeat
* @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring
*/
export const WRAP_MODES = {
CLAMP: 0,
REPEAT: 1,
MIRRORED_REPEAT: 2,
};
/**
* The gc modes that are supported by
*
* The {@link settings.GC_MODE} Garbage Collection mode for PixiJS textures is AUTO
* If set to GC_MODE, the renderer will occasionally check textures usage. If they are not
* used for a specified period of time they will be removed from the GPU. They will of course
* be uploaded again when they are required. This is a silent behind the scenes process that
* should ensure that the GPU does not get filled up.
*
* Handy for mobile devices!
* This property only affects WebGL.
*
* @static
* @constant
* @name GC_MODES
* @memberof PIXI
* @type {object}
* @property {number} AUTO - Garbage collection will happen periodically automatically
* @property {number} MANUAL - Garbage collection will need to be called manually
*/
export const GC_MODES = {
AUTO: 0,
MANUAL: 1,
};
/**
* Regexp for image type by extension.
*
* @static
* @constant
* @memberof PIXI
* @type {RegExp|string}
* @example `image.png`
*/
export const URL_FILE_EXTENSION = /\.(\w{3,4})(?:$|\?|#)/i;
/**
* Regexp for data URI.
* Based on: {@link https://github.com/ragingwind/data-uri-regex}
*
* @static
* @constant
* @name DATA_URI
* @memberof PIXI
* @type {RegExp|string}
* @example data:image/png;base64
*/
export const DATA_URI = /^\s*data:(?:([\w-]+)\/([\w+.-]+))?(?:;charset=([\w-]+))?(?:;(base64))?,(.*)/i;
/**
* Regexp for SVG size.
*
* @static
* @constant
* @name SVG_SIZE
* @memberof PIXI
* @type {RegExp|string}
* @example &lt;svg width="100" height="100"&gt;&lt;/svg&gt;
*/
export const SVG_SIZE = /<svg[^>]*(?:\s(width|height)=('|")(\d*(?:\.\d+)?)(?:px)?('|"))[^>]*(?:\s(width|height)=('|")(\d*(?:\.\d+)?)(?:px)?('|"))[^>]*>/i; // eslint-disable-line max-len
/**
* Constants that identify shapes, mainly to prevent `instanceof` calls.
*
* @static
* @constant
* @name SHAPES
* @memberof PIXI
* @type {object}
* @property {number} POLY Polygon
* @property {number} RECT Rectangle
* @property {number} CIRC Circle
* @property {number} ELIP Ellipse
* @property {number} RREC Rounded Rectangle
*/
export const SHAPES = {
POLY: 0,
RECT: 1,
CIRC: 2,
ELIP: 3,
RREC: 4,
};
/**
* Constants that specify float precision in shaders.
*
* @static
* @constant
* @name PRECISION
* @memberof PIXI
* @type {object}
* @property {string} LOW='lowp'
* @property {string} MEDIUM='mediump'
* @property {string} HIGH='highp'
*/
export const PRECISION = {
LOW: 'lowp',
MEDIUM: 'mediump',
HIGH: 'highp',
};
/**
* Constants that specify the transform type.
*
* @static
* @constant
* @name TRANSFORM_MODE
* @memberof PIXI
* @type {object}
* @property {number} STATIC
* @property {number} DYNAMIC
*/
export const TRANSFORM_MODE = {
STATIC: 0,
DYNAMIC: 1,
};
/**
* Constants that define the type of gradient on text.
*
* @static
* @constant
* @name TEXT_GRADIENT
* @memberof PIXI
* @type {object}
* @property {number} LINEAR_VERTICAL Vertical gradient
* @property {number} LINEAR_HORIZONTAL Linear gradient
*/
export const TEXT_GRADIENT = {
LINEAR_VERTICAL: 0,
LINEAR_HORIZONTAL: 1,
};
/**
* Represents the update priorities used by internal PIXI classes when registered with
* the {@link ticker.Ticker} object. Higher priority items are updated first and lower
* priority items, such as render, should go later.
*
* @static
* @constant
* @name UPDATE_PRIORITY
* @memberof PIXI
* @type {object}
* @property {number} INTERACTION=50 Highest priority, used for {@link interaction.InteractionManager}
* @property {number} HIGH=25 High priority updating, {@link VideoBaseTexture} and {@link extras.AnimatedSprite}
* @property {number} NORMAL=0 Default priority for ticker events, see {@link ticker.Ticker#add}.
* @property {number} LOW=-25 Low priority used for {@link Application} rendering.
* @property {number} UTILITY=-50 Lowest priority used for {@link prepare.BasePrepare} utility.
*/
export const UPDATE_PRIORITY = {
INTERACTION: 50,
HIGH: 25,
NORMAL: 0,
LOW: -25,
UTILITY: -50,
};
export class BatchBuffer {
vertices: ArrayBuffer;
float32View: Float32Array;
uint32View: Uint32Array;
positions: any;
uvs: any;
colors: any;
/**
* @param {number} size - The size of the buffer in bytes.
*/
constructor(size) {
this.vertices = new ArrayBuffer(size);
/**
* View on the vertices as a Float32Array for positions
*
* @member {Float32Array}
*/
this.float32View = new Float32Array(this.vertices);
/**
* View on the vertices as a Uint32Array for uvs
*
* @member {Float32Array}
*/
this.uint32View = new Uint32Array(this.vertices);
}
/**
* Destroys the buffer.
*
*/
public destroy() {
this.vertices = null;
this.positions = null;
this.uvs = null;
this.colors = null;
}
}
var EMPTY_ARRAY_BUFFER = new ArrayBuffer(0);
/**
* Helper class to create a webGL buffer
*
* @class
* @memberof glCore
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param type {gl.ARRAY_BUFFER | gl.ELEMENT_ARRAY_BUFFER} @mat
* @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
* @param drawType {gl.STATIC_DRAW|gl.DYNAMIC_DRAW|gl.STREAM_DRAW}
*/
export class GLBuffer {
gl: any;
buffer: any;
type: any;
drawType: any;
data: ArrayBuffer;
_updateID: number;
constructor(gl, type?, data?, drawType?) {
/**
* The current WebGL rendering context
*
* @member {WebGLRenderingContext}
*/
this.gl = gl;
/**
* The WebGL buffer, created upon instantiation
*
* @member {WebGLBuffer}
*/
this.buffer = gl.createBuffer();
/**
* The type of the buffer
*
* @member {gl.ARRAY_BUFFER|gl.ELEMENT_ARRAY_BUFFER}
*/
this.type = type || gl.ARRAY_BUFFER;
/**
* The draw type of the buffer
*
* @member {gl.STATIC_DRAW|gl.DYNAMIC_DRAW|gl.STREAM_DRAW}
*/
this.drawType = drawType || gl.STATIC_DRAW;
/**
* The data in the buffer, as a typed array
*
* @member {ArrayBuffer| SharedArrayBuffer|ArrayBufferView}
*/
this.data = EMPTY_ARRAY_BUFFER;
if (data) {
this.upload(data);
}
this._updateID = 0;
};
/**
* Uploads the buffer to the GPU
* @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data to upload
* @param offset {Number} if only a subset of the data should be uploaded, this is the amount of data to subtract
* @param dontBind {Boolean} whether to bind the buffer before uploading it
*/
public upload(data, offset?, dontBind?) {
// todo - needed?
if (!dontBind) this.bind();
var gl = this.gl;
data = data || this.data;
offset = offset || 0;
if (this.data.byteLength >= data.byteLength) {
gl.bufferSubData(this.type, offset, data);
}
else {
gl.bufferData(this.type, data, this.drawType);
}
this.data = data;
};
/**
* Binds the buffer
*
*/
public bind() {
var gl = this.gl;
gl.bindBuffer(this.type, this.buffer);
};
/**
* Destroys the buffer
*
*/
public destroy = function () {
this.gl.deleteBuffer(this.buffer);
};
public static createVertexBuffer(gl, data?, drawType?) {
return new GLBuffer(gl, gl.ARRAY_BUFFER, data, drawType);
};
public static createIndexBuffer(gl, data?, drawType?) {
return new GLBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, data, drawType);
};
public static create(gl, type, data, drawType) {
return new GLBuffer(gl, type, data, drawType);
};
}
import { GLTexture } from './GLTexture';
/**
* Helper class to create a webGL Framebuffer
*
* @class
* @memberof glCore
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param width {Number} the width of the drawing area of the frame buffer
* @param height {Number} the height of the drawing area of the frame buffer
*/
export class GLFramebuffer {
gl: any;
framebuffer: any;
stencil: any;
texture: any;
width: any;
height: any;
constructor(gl, width, height) {
/**
* The current WebGL rendering context
*
* @member {WebGLRenderingContext}
*/
this.gl = gl;
/**
* The frame buffer
*
* @member {WebGLFramebuffer}
*/
this.framebuffer = gl.createFramebuffer();
/**
* The stencil buffer
*
* @member {WebGLRenderbuffer}
*/
this.stencil = null;
/**
* The stencil buffer
*
* @member {glCore.GLTexture}
*/
this.texture = null;
/**
* The width of the drawing area of the buffer
*
* @member {Number}
*/
this.width = width || 100;
/**
* The height of the drawing area of the buffer
*
* @member {Number}
*/
this.height = height || 100;
};
/**
* Adds a texture to the frame buffer
* @param texture {glCore.GLTexture}
*/
public enableTexture(texture) {
var gl = this.gl;
this.texture = texture || new GLTexture(gl);
this.texture.bind();
//gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
this.bind();
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture.texture, 0);
};
/**
* Initialises the stencil buffer
*/
public enableStencil() {
if (this.stencil) return;
var gl = this.gl;
this.stencil = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencil);
// TODO.. this is depth AND stencil?
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.stencil);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, this.width, this.height);
};
/**
* Erases the drawing area and fills it with a colour
* @param r {Number} the red value of the clearing colour
* @param g {Number} the green value of the clearing colour
* @param b {Number} the blue value of the clearing colour
* @param a {Number} the alpha value of the clearing colour
*/
public clear(r, g, b, a) {
this.bind();
var gl = this.gl;
gl.clearColor(r, g, b, a);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
};
/**
* Binds the frame buffer to the WebGL context
*/
public bind() {
var gl = this.gl;
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
};
/**
* Unbinds the frame buffer to the WebGL context
*/
public unbind() {
var gl = this.gl;
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
};
/**
* Resizes the drawing area of the buffer to the given width and height
* @param width {Number} the new width
* @param height {Number} the new height
*/
public resize(width, height) {
var gl = this.gl;
this.width = width;
this.height = height;
if (this.texture) {
this.texture.uploadData(null, width, height);
}
if (this.stencil) {
// update the stencil buffer width and height
gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencil);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, width, height);
}
};
/**
* Destroys this buffer
*/
public destroy() {
var gl = this.gl;
//TODO
if (this.texture) {
this.texture.destroy();
}
gl.deleteFramebuffer(this.framebuffer);
this.gl = null;
this.stencil = null;
this.texture = null;
};
/**
* Creates a frame buffer with a texture containing the given data
* @static
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param width {Number} the width of the drawing area of the frame buffer
* @param height {Number} the height of the drawing area of the frame buffer
* @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
*/
public static createRGBA(gl, width, height, data?) {
var texture = GLTexture.fromData(gl, null, width, height);
texture.enableNearestScaling();
texture.enableWrapClamp();
//now create the framebuffer object and attach the texture to it.
var fbo = new GLFramebuffer(gl, width, height);
fbo.enableTexture(texture);
//fbo.enableStencil(); // get this back on soon!
//fbo.enableStencil(); // get this back on soon!
fbo.unbind();
return fbo;
};
/**
* Creates a frame buffer with a texture containing the given data
* @static
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param width {Number} the width of the drawing area of the frame buffer
* @param height {Number} the height of the drawing area of the frame buffer
* @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
*/
public static createFloat32(gl, width, height, data) {
// create a new texture..
var texture = GLTexture.fromData(gl, data, width, height);
texture.enableNearestScaling();
texture.enableWrapClamp();
//now create the framebuffer object and attach the texture to it.
var fbo = new GLFramebuffer(gl, width, height);
fbo.enableTexture(texture);
fbo.unbind();
return fbo;
};
}
import { compileProgram } from './shader/compileProgram';
import { extractAttributes } from './shader/extractAttributes';
import { extractUniforms } from './shader/extractUniforms';
import { setPrecision } from './shader/setPrecision';
import { generateUniformAccessObject } from './shader/generateUniformAccessObject';
/**
* Helper class to create a webGL Shader
*
* @class
* @memberof glCore
* @param gl {WebGLRenderingContext}
* @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
* @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.
* @param precision {string} The float precision of the shader. Options are 'lowp', 'mediump' or 'highp'.
* @param attributeLocations {object} A key value pair showing which location eact attribute should sit eg {position:0, uvs:1}
*/
export class GLShader {
gl: any;
program: any;
attributes: {};
uniformData: {};
uniforms: { data: {}; };
constructor(gl, vertexSrc, fragmentSrc, precision?, attributeLocations?) {
/**
* The current WebGL rendering context
*
* @member {WebGLRenderingContext}
*/
this.gl = gl;
if (precision) {
vertexSrc = setPrecision(vertexSrc, precision);
fragmentSrc = setPrecision(fragmentSrc, precision);
}
/**
* The shader program
*
* @member {WebGLProgram}
*/
// First compile the program..
this.program = compileProgram(gl, vertexSrc, fragmentSrc, attributeLocations);
/**
* The attributes of the shader as an object containing the following properties
* {
* type,
* size,
* location,
* pointer
* }
* @member {Object}
*/
// next extract the attributes
this.attributes = extractAttributes(gl, this.program);
this.uniformData = extractUniforms(gl, this.program);
/**
* The uniforms of the shader as an object containing the following properties
* {
* gl,
* data
* }
* @member {Object}
*/
this.uniforms = generateUniformAccessObject(gl, this.uniformData);
};
/**
* Uses this shader
*
* @return {glCore.GLShader} Returns itself.
*/
public bind() {
this.gl.useProgram(this.program);
return this;
};
/**
* Destroys this shader
* TODO
*/
public destroy() {
this.attributes = null;
this.uniformData = null;
this.uniforms = null;
var gl = this.gl;
gl.deleteProgram(this.program);
};
}
/**
* Helper class to create a WebGL Texture
*
* @class
* @memberof glCore
* @param gl {WebGLRenderingContext} The current WebGL context
* @param width {number} the width of the texture
* @param height {number} the height of the texture
* @param format {number} the pixel format of the texture. defaults to gl.RGBA
* @param type {number} the gl type of the texture. defaults to gl.UNSIGNED_BYTE
*/
export class GLTexture {
gl: any;
texture: any;
mipmap: boolean;
premultiplyAlpha: boolean;
width: any;
height: any;
format: any;
type: any;
constructor(gl, width?, height?, format?, type?) {
/**
* The current WebGL rendering context
*
* @member {WebGLRenderingContext}
*/
this.gl = gl;
/**
* The WebGL texture
*
* @member {WebGLTexture}
*/
this.texture = gl.createTexture();
/**
* If mipmapping was used for this texture, enable and disable with enableMipmap()
*
* @member {Boolean}
*/
// some settings..
this.mipmap = false;
/**
* Set to true to enable pre-multiplied alpha
*
* @member {Boolean}
*/
this.premultiplyAlpha = false;
/**
* The width of texture
*
* @member {Number}
*/
this.width = width || -1;
/**
* The height of texture
*
* @member {Number}
*/
this.height = height || -1;
/**
* The pixel format of the texture. defaults to gl.RGBA
*
* @member {Number}
*/
this.format = format || gl.RGBA;
/**
* The gl type of the texture. defaults to gl.UNSIGNED_BYTE
*
* @member {Number}
*/
this.type = type || gl.UNSIGNED_BYTE;
};
/**
* Uploads this texture to the GPU
* @param source {HTMLImageElement|ImageData|HTMLVideoElement} the source image of the texture
*/
public upload(source) {
this.bind();
var gl = this.gl;
//设置是否对纹理进行预乘透明通道
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);
var newWidth = source.videoWidth || source.width;
var newHeight = source.videoHeight || source.height;
if (newHeight !== this.height || newWidth !== this.width) {
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.format, this.type, source);
}
else {
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, this.format, this.type, source);
}
// if the source is a video, we need to use the videoWidth / videoHeight properties as width / height will be incorrect.
this.width = newWidth;
this.height = newHeight;
};
/**
* Use a data source and uploads this texture to the GPU
* @param data {TypedArray} the data to upload to the texture
* @param width {number} the new width of the texture
* @param height {number} the new height of the texture
*/
public uploadData = function (data, width, height) {
this.bind();
var gl = this.gl;
if (data instanceof Float32Array) {
if (!FLOATING_POINT_AVAILABLE) {
var ext = gl.getExtension("OES_texture_float");
if (ext) {
FLOATING_POINT_AVAILABLE = true;
}
else {
throw new Error('floating point textures not available');
}
}
this.type = gl.FLOAT;
}
else {
// TODO support for other types
this.type = this.type || gl.UNSIGNED_BYTE;
}
// what type of data?
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.premultiplyAlpha);
if (width !== this.width || height !== this.height) {
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, width, height, 0, this.format, this.type, data || null);
}
else {
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, this.format, this.type, data || null);
}
this.width = width;
this.height = height;
// texSubImage2D
};
/**
* Binds the texture
* @param location
*/
public bind(location?) {
var gl = this.gl;
if (location !== undefined) {
gl.activeTexture(gl.TEXTURE0 + location);
}
gl.bindTexture(gl.TEXTURE_2D, this.texture);
};
/**
* Unbinds the texture
*/
public unbind() {
var gl = this.gl;
gl.bindTexture(gl.TEXTURE_2D, null);
};
/**
* @param linear {Boolean} if we want to use linear filtering or nearest neighbour interpolation
*/
public minFilter(linear) {
var gl = this.gl;
this.bind();
if (this.mipmap) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linear ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);
}
else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, linear ? gl.LINEAR : gl.NEAREST);
}
};
/**
* @param linear {Boolean} if we want to use linear filtering or nearest neighbour interpolation
*/
public magFilter(linear) {
var gl = this.gl;
this.bind();
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, linear ? gl.LINEAR : gl.NEAREST);
};
/**
* Enables mipmapping
*/
public enableMipmap() {
var gl = this.gl;
this.bind();
this.mipmap = true;
gl.generateMipmap(gl.TEXTURE_2D);
};
/**
* Enables linear filtering
*/
public enableLinearScaling() {
this.minFilter(true);
this.magFilter(true);
};
/**
* Enables nearest neighbour interpolation
*/
public enableNearestScaling() {
this.minFilter(false);
this.magFilter(false);
};
/**
* Enables clamping on the texture so WebGL will not repeat it
*/
public enableWrapClamp() {
var gl = this.gl;
this.bind();
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
};
/**
* Enable tiling on the texture
*/
public enableWrapRepeat() {
var gl = this.gl;
this.bind();
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
};
public enableWrapMirrorRepeat() {
var gl = this.gl;
this.bind();
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);
};
/**
* Destroys this texture
*/
public destroy() {
var gl = this.gl;
//TODO
gl.deleteTexture(this.texture);
};
/**
* @static
* @param gl {WebGLRenderingContext} The current WebGL context
* @param source {HTMLImageElement|ImageData} the source image of the texture
* @param premultiplyAlpha {Boolean} If we want to use pre-multiplied alpha
*/
public static fromSource(gl, source, premultiplyAlpha?) {
var texture = new GLTexture(gl);
texture.premultiplyAlpha = premultiplyAlpha || false;
texture.upload(source);
return texture;
};
/**
* @static
* @param gl {WebGLRenderingContext} The current WebGL context
* @param data {TypedArray} the data to upload to the texture
* @param width {number} the new width of the texture
* @param height {number} the new height of the texture
*/
public static fromData(gl, data, width, height) {
//console.log(data, width, height);
var texture = new GLTexture(gl);
texture.uploadData(data, width, height);
return texture;
};
}
var FLOATING_POINT_AVAILABLE = false;
// import GroupD8 from '../math/GroupD8';
/**
* A standard object to store the Uvs of a texture
*
* @class
* @private
*/
export class TextureUvs
{
x0: number;
y0: number;
x1: number;
y1: number;
x2: number;
y2: number;
x3: number;
y3: number;
uvsUint32: Uint32Array;
/**
*
*/
constructor()
{
this.x0 = 0;
this.y0 = 0;
this.x1 = 1;
this.y1 = 0;
this.x2 = 1;
this.y2 = 1;
this.x3 = 0;
this.y3 = 1;
this.uvsUint32 = new Uint32Array(4);
this.uvsUint32[0] = (((this.y0 * 65535) & 0xFFFF) << 16) | ((this.x0 * 65535) & 0xFFFF);
this.uvsUint32[1] = (((this.y1 * 65535) & 0xFFFF) << 16) | ((this.x1 * 65535) & 0xFFFF);
this.uvsUint32[2] = (((this.y2 * 65535) & 0xFFFF) << 16) | ((this.x2 * 65535) & 0xFFFF);
this.uvsUint32[3] = (((this.y3 * 65535) & 0xFFFF) << 16) | ((this.x3 * 65535) & 0xFFFF);
}
/**
* Sets the texture Uvs based on the given frame information.
*
* @private
* @param {Rectangle} frame - The frame of the texture
* @param {Rectangle} baseFrame - The base frame of the texture
* @param {number} rotate - Rotation of frame, see {@link GroupD8}
*/
set(frame, baseFrame, rotate?)
{
const tw = baseFrame.width;
const th = baseFrame.height;
// if (rotate)
// {
// // width and height div 2 div baseFrame size
// const w2 = frame.width / 2 / tw;
// const h2 = frame.height / 2 / th;
// // coordinates of center
// const cX = (frame.x / tw) + w2;
// const cY = (frame.y / th) + h2;
// rotate = GroupD8.add(rotate, GroupD8.NW); // NW is top-left corner
// this.x0 = cX + (w2 * GroupD8.uX(rotate));
// this.y0 = cY + (h2 * GroupD8.uY(rotate));
// rotate = GroupD8.add(rotate, 2); // rotate 90 degrees clockwise
// this.x1 = cX + (w2 * GroupD8.uX(rotate));
// this.y1 = cY + (h2 * GroupD8.uY(rotate));
// rotate = GroupD8.add(rotate, 2);
// this.x2 = cX + (w2 * GroupD8.uX(rotate));
// this.y2 = cY + (h2 * GroupD8.uY(rotate));
// rotate = GroupD8.add(rotate, 2);
// this.x3 = cX + (w2 * GroupD8.uX(rotate));
// this.y3 = cY + (h2 * GroupD8.uY(rotate));
// }
// else
// {
this.x0 = frame.x / tw;
this.y0 = frame.y / th;
this.x1 = (frame.x + frame.width) / tw;
this.y1 = frame.y / th;
this.x2 = (frame.x + frame.width) / tw;
this.y2 = (frame.y + frame.height) / th;
this.x3 = frame.x / tw;
this.y3 = (frame.y + frame.height) / th;
// }
this.uvsUint32[0] = (((this.y0 * 65535) & 0xFFFF) << 16) | ((this.x0 * 65535) & 0xFFFF);
this.uvsUint32[1] = (((this.y1 * 65535) & 0xFFFF) << 16) | ((this.x1 * 65535) & 0xFFFF);
this.uvsUint32[2] = (((this.y2 * 65535) & 0xFFFF) << 16) | ((this.x2 * 65535) & 0xFFFF);
this.uvsUint32[3] = (((this.y3 * 65535) & 0xFFFF) << 16) | ((this.x3 * 65535) & 0xFFFF);
}
}
// state object//
import { setVertexAttribArrays } from './setVertexAttribArrays';
/**
* Helper class to work with WebGL VertexArrayObjects (vaos)
* Only works if WebGL extensions are enabled (they usually are)
*
* @class
* @memberof glCore
* @param gl {WebGLRenderingContext} The current WebGL rendering context
*/
export class VertexArrayObject {
nativeVaoExtension: any;
nativeState: any;
nativeVao: any;
gl: any;
attributes: any[];
indexBuffer: any;
dirty: boolean;
constructor(gl, state) {
this.nativeVaoExtension = null;
if (!VertexArrayObject.FORCE_NATIVE) {
this.nativeVaoExtension = gl.getExtension('OES_vertex_array_object') ||
gl.getExtension('MOZ_OES_vertex_array_object') ||
gl.getExtension('WEBKIT_OES_vertex_array_object');
}
this.nativeState = state;
if (this.nativeVaoExtension) {
this.nativeVao = this.nativeVaoExtension.createVertexArrayOES();
var maxAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
// VAO - overwrite the state..
this.nativeState = {
tempAttribState: new Array(maxAttribs),
attribState: new Array(maxAttribs)
};
}
/**
* The current WebGL rendering context
*
* @member {WebGLRenderingContext}
*/
this.gl = gl;
/**
* An array of attributes
*
* @member {Array}
*/
this.attributes = [];
/**
* @member {glCore.GLBuffer}
*/
this.indexBuffer = null;
/**
* A boolean flag
*
* @member {Boolean}
*/
this.dirty = false;
};
/**
* Binds the buffer
*/
public bind() {
if (this.nativeVao) {
this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao);
if (this.dirty) {
this.dirty = false;
this.activate();
return this;
}
if (this.indexBuffer) {
this.indexBuffer.bind();
}
}
else {
this.activate();
}
return this;
};
/**
* Unbinds the buffer
*/
public unbind() {
if (this.nativeVao) {
this.nativeVaoExtension.bindVertexArrayOES(null);
}
return this;
};
/**
* Uses this vao
*/
public activate() {
var gl = this.gl;
var lastBuffer = null;
for (var i = 0; i < this.attributes.length; i++) {
var attrib = this.attributes[i];
if (lastBuffer !== attrib.buffer) {
attrib.buffer.bind();
lastBuffer = attrib.buffer;
}
gl.vertexAttribPointer(attrib.attribute.location,
attrib.attribute.size,
attrib.type || gl.FLOAT,
attrib.normalized || false,
attrib.stride || 0,
attrib.start || 0);
}
setVertexAttribArrays(gl, this.attributes, this.nativeState);
if (this.indexBuffer) {
this.indexBuffer.bind();
}
return this;
};
/**
*
* @param buffer {gl.GLBuffer}
* @param attribute {*}
* @param type {String}
* @param normalized {Boolean}
* @param stride {Number}
* @param start {Number}
*/
public addAttribute(buffer, attribute, type?, normalized?, stride?, start?) {
this.attributes.push({
buffer: buffer,
attribute: attribute,
location: attribute.location,
type: type || this.gl.FLOAT,
normalized: normalized || false,
stride: stride || 0,
start: start || 0
});
this.dirty = true;
return this;
};
/**
*
* @param buffer {gl.GLBuffer}
*/
public addIndex(buffer/*, options*/) {
this.indexBuffer = buffer;
this.dirty = true;
return this;
};
/**
* Unbinds this vao and disables it
*/
public clear() {
// var gl = this.gl;
// TODO - should this function unbind after clear?
// for now, no but lets see what happens in the real world!
if (this.nativeVao) {
this.nativeVaoExtension.bindVertexArrayOES(this.nativeVao);
}
this.attributes.length = 0;
this.indexBuffer = null;
return this;
};
/**
* @param type {Number}
* @param size {Number}
* @param start {Number}
*/
public draw(type, size?, start?) {
var gl = this.gl;
if (this.indexBuffer) {
gl.drawElements(type, size || this.indexBuffer.data.length, gl.UNSIGNED_SHORT, (start || 0) * 2);
}
else {
// TODO need a better way to calculate size..
gl.drawArrays(type, start || 0, size || this.getSize());
}
return this;
};
/**
* Destroy this vao
*/
public destroy() {
// lose references
this.gl = null;
this.indexBuffer = null;
this.attributes = null;
this.nativeState = null;
if (this.nativeVao) {
this.nativeVaoExtension.deleteVertexArrayOES(this.nativeVao);
}
this.nativeVaoExtension = null;
this.nativeVao = null;
};
public getSize() {
var attrib = this.attributes[0];
return attrib.buffer.data.length / ((attrib.stride / 4) || attrib.attribute.size);
};
/**
* Some devices behave a bit funny when using the newer extensions (im looking at you ipad 2!)
* If you find on older devices that things have gone a bit weird then set this to true.
*/
/**
* Lets the VAO know if you should use the WebGL extension or the native methods.
* Some devices behave a bit funny when using the newer extensions (im looking at you ipad 2!)
* If you find on older devices that things have gone a bit weird then set this to true.
* @static
* @property {Boolean} FORCE_NATIVE
*/
public static FORCE_NATIVE = false;
}
import { createContext } from './createContext';
const fragTemplate = [
'precision mediump float;',
'void main(void){',
'float test = 0.1;',
'%forloop%',
'gl_FragColor = vec4(0.0);',
'}',
].join('\n');
export function checkMaxIfStatmentsInShader(maxIfs, gl) {
const createTempContext = !gl;
// @if DEBUG
if (maxIfs === 0) {
throw new Error('Invalid value of `0` passed to `checkMaxIfStatementsInShader`');
}
// @endif
if (createTempContext) {
const tinyCanvas = document.createElement('canvas');
tinyCanvas.width = 1;
tinyCanvas.height = 1;
gl = createContext(tinyCanvas);
}
const shader = gl.createShader(gl.FRAGMENT_SHADER);
while (true) // eslint-disable-line no-constant-condition
{
const fragmentSrc = fragTemplate.replace(/%forloop%/gi, generateIfTestSrc(maxIfs));
gl.shaderSource(shader, fragmentSrc);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
maxIfs = (maxIfs / 2) | 0;
}
else {
// valid!
break;
}
}
if (createTempContext) {
// get rid of context
if (gl.getExtension('WEBGL_lose_context')) {
gl.getExtension('WEBGL_lose_context').loseContext();
}
}
return maxIfs;
}
function generateIfTestSrc(maxIfs) {
let src = '';
for (let i = 0; i < maxIfs; ++i) {
if (i > 0) {
src += '\nelse ';
}
if (i < maxIfs - 1) {
src += `if(test == ${i}.0){}`;
}
}
return src;
}
/**
* Helper class to create a webGL Context
*
* @class
* @memberof glCore
* @param canvas {HTMLCanvasElement} the canvas element that we will get the context from
* @param options {Object} An options object that gets passed in to the canvas element containing the context attributes,
* see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext for the options available
* @return {WebGLRenderingContext} the WebGL context
*/
export function createContext(canvas, options?) {
var gl = canvas.getContext('webgl', options) ||
canvas.getContext('experimental-webgl', options);
if (!gl) {
// fail, not able to get a context
throw new Error('This browser does not support webGL. Try using the canvas renderer');
}
return gl;
};
\ No newline at end of file
/**
* Generic Mask Stack data structure
*
* @function createIndicesForQuads
* @private
* @param {number} size - Number of quads
* @return {Uint16Array} indices
*/
export function createIndicesForQuads(size)
{
// the total number of indices in our array, there are 6 points per quad.
const totalIndices = size * 6;
const indices = new Uint16Array(totalIndices);
// fill the indices with the quads to draw
for (let i = 0, j = 0; i < totalIndices; i += 6, j += 4)
{
indices[i + 0] = j + 0;
indices[i + 1] = j + 1;
indices[i + 2] = j + 2;
indices[i + 3] = j + 0;
indices[i + 4] = j + 2;
indices[i + 5] = j + 3;
}
return indices;
}
import { GLShader } from './GLShader';
//顶点着色器程序
const VSHADER_SOURCE =
" precision highp float;" +
"attribute vec2 aVertexPosition;" +
"attribute vec2 aTextureCoord;" +
"attribute vec4 aColor;" +
"attribute float aTextureId;" +
"uniform mat3 projectionMatrix;" +
"uniform mat3 modelMatrix;" +
"varying vec2 vTextureCoord;" +
"varying vec4 vColor;" +
"varying float vTextureId;" +
"void main(void){" +
"gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);" +
// "gl_Position = vec4((projectionMatrix *modelMatrix* vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);" +
"vTextureCoord = aTextureCoord;" +
"vTextureId = aTextureId;" +
"vColor = aColor;" +
"}";
const fragTemplate = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
'varying vec4 vColor;',
'varying float vTextureId;',
'uniform sampler2D uSamplers[%count%];',
'void main(void){',
'vec4 color;',
'float textureId = floor(vTextureId+0.5);',
'%forloop%',
'gl_FragColor = color * vColor;',
'}',
].join('\n');
export function generateMultiTextureShader(gl, maxTextures) {
// const vertexSrc = readFileSync(join(__dirname, './texture.vert'), 'utf8');
let fragmentSrc = fragTemplate;
fragmentSrc = fragmentSrc.replace(/%count%/gi, maxTextures);
fragmentSrc = fragmentSrc.replace(/%forloop%/gi, generateSampleSrc(maxTextures));
// console.log(fragmentSrc)
const shader = new GLShader(gl, VSHADER_SOURCE, fragmentSrc);
const sampleValues = [];
for (let i = 0; i < maxTextures; i++) {
sampleValues[i] = i;
}
shader.bind();
shader.uniforms["uSamplers"] = sampleValues;
// console.log(fragmentSrc)
return shader;
}
function generateSampleSrc(maxTextures) {
let src = '';
src += '\n';
src += '\n';
for (let i = 0; i < maxTextures; i++) {
if (i > 0) {
src += '\nelse ';
}
if (i < maxTextures - 1) {
src += `if(textureId == ${i}.0)`;
}
src += '\n{';
src += `\n\tcolor = texture2D(uSamplers[${i}], vTextureCoord);`;
src += '\n}';
}
src += '\n';
src += '\n';
return src;
}
// export { default as GroupD8 } from './GroupD8';
export { GLTexture } from './GLTexture';
export { GLBuffer } from './GLBuffer';
export { VertexArrayObject } from './VertexArrayObject';
export { GLFramebuffer } from "./GLFramebuffer";
export { GLShader } from "./GLShader";
export { TextureUvs } from "./TextureUvs";
export { checkMaxIfStatmentsInShader } from "./checkMaxIfStatmentsInShader"
// var GL_MAP = {};
/**
* @param gl {WebGLRenderingContext} The current WebGL context
* @param attribs {*}
* @param state {*}
*/
export function setVertexAttribArrays(gl, attribs, state?) {
var i;
if (state) {
var tempAttribState = state.tempAttribState,
attribState = state.attribState;
for (i = 0; i < tempAttribState.length; i++) {
tempAttribState[i] = false;
}
// set the new attribs
for (i = 0; i < attribs.length; i++) {
tempAttribState[attribs[i].attribute.location] = true;
}
for (i = 0; i < attribState.length; i++) {
if (attribState[i] !== tempAttribState[i]) {
attribState[i] = tempAttribState[i];
if (state.attribState[i]) {
gl.enableVertexAttribArray(i);
}
else {
gl.disableVertexAttribArray(i);
}
}
}
}
else {
for (i = 0; i < attribs.length; i++) {
var attrib = attribs[i];
gl.enableVertexAttribArray(attrib.attribute.location);
}
}
};
\ No newline at end of file
/**
* @class
* @memberof glCore.shader
* @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram}
* @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
* @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.
* @param attributeLocations {Object} An attribute location map that lets you manually set the attribute locations
* @return {WebGLProgram} the shader program
*/
export function compileProgram(gl, vertexSrc, fragmentSrc, attributeLocations?) {
var glVertShader = compileShader(gl, gl.VERTEX_SHADER, vertexSrc);
var glFragShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSrc);
var program = gl.createProgram();
gl.attachShader(program, glVertShader);
gl.attachShader(program, glFragShader);
// optionally, set the attributes manually for the program rather than letting WebGL decide..
if (attributeLocations) {
for (var i in attributeLocations) {
gl.bindAttribLocation(program, attributeLocations[i], i);
}
}
gl.linkProgram(program);
// if linking fails, then log and cleanup
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('Error: Could not initialize shader.');
console.error('gl.VALIDATE_STATUS', gl.getProgramParameter(program, gl.VALIDATE_STATUS));
console.error('gl.getError()', gl.getError());
// if there is a program info log, log it
if (gl.getProgramInfoLog(program) !== '') {
console.warn('Warning: gl.getProgramInfoLog()', gl.getProgramInfoLog(program));
}
gl.deleteProgram(program);
program = null;
}
// clean up some shaders
gl.deleteShader(glVertShader);
gl.deleteShader(glFragShader);
return program;
};
/**
* @private
* @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram}
* @param type {Number} the type, can be either VERTEX_SHADER or FRAGMENT_SHADER
* @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
* @return {WebGLShader} the shader
*/
var compileShader = function (gl, type, src) {
var shader = gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.log(gl.getShaderInfoLog(shader));
return null;
}
return shader;
};
/**
* @class
* @memberof glCore.shader
* @param type {String} Type of value
* @param size {Number}
*/
export function defaultValue(type, size) {
switch (type) {
case 'float':
return 0;
case 'vec2':
return new Float32Array(2 * size);
case 'vec3':
return new Float32Array(3 * size);
case 'vec4':
return new Float32Array(4 * size);
case 'int':
case 'sampler2D':
return 0;
case 'ivec2':
return new Int32Array(2 * size);
case 'ivec3':
return new Int32Array(3 * size);
case 'ivec4':
return new Int32Array(4 * size);
case 'bool':
return false;
case 'bvec2':
return booleanArray(2 * size);
case 'bvec3':
return booleanArray(3 * size);
case 'bvec4':
return booleanArray(4 * size);
case 'mat2':
return new Float32Array([1, 0,
0, 1]);
case 'mat3':
return new Float32Array([1, 0, 0,
0, 1, 0,
0, 0, 1]);
case 'mat4':
return new Float32Array([1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1]);
}
};
var booleanArray = function (size) {
var array = new Array(size);
for (var i = 0; i < array.length; i++) {
array[i] = false;
}
return array;
};
import { mapType } from './mapType';
import { mapSize } from './mapSize';
/**
* Extracts the attributes
* @class
* @memberof glCore.shader
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param program {WebGLProgram} The shader program to get the attributes from
* @return attributes {Object}
*/
export function extractAttributes(gl, program) {
var attributes = {};
var totalAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
for (var i = 0; i < totalAttributes; i++) {
var attribData = gl.getActiveAttrib(program, i);
var type = mapType(gl, attribData.type);
attributes[attribData.name] = {
type: type,
size: mapSize(type),
location: gl.getAttribLocation(program, attribData.name),
//TODO - make an attribute object
pointer: function (type = gl.FLOAT, normalized = false, stride = 0, start = 0) {
// console.log(this.location)
gl.vertexAttribPointer(this.location, this.size, type, normalized, stride, start);
}
};
}
return attributes;
};
import { mapType } from './mapType';
import { defaultValue } from './defaultValue';
/**
* Extracts the uniforms
* @class
* @memberof glCore.shader
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param program {WebGLProgram} The shader program to get the uniforms from
* @return uniforms {Object}
*/
export function extractUniforms(gl, program) {
var uniforms = {};
var totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
for (var i = 0; i < totalUniforms; i++) {
var uniformData = gl.getActiveUniform(program, i);
var name = uniformData.name.replace(/\[.*?\]/, "");
var type = mapType(gl, uniformData.type);
uniforms[name] = {
type: type,
size: uniformData.size,
location: gl.getUniformLocation(program, name),
value: defaultValue(type, uniformData.size)
};
}
return uniforms;
};
/**
* Extracts the attributes
* @class
* @memberof glCore.shader
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param uniforms {Array} @mat ?
* @return attributes {Object}
*/
export function generateUniformAccessObject(gl, uniformData) {
// this is the object we will be sending back.
// an object hierachy will be created for structs
var uniforms = { data: {} };
uniforms["gl"] = gl;
var uniformKeys = Object.keys(uniformData);
for (var i = 0; i < uniformKeys.length; i++) {
var fullName = uniformKeys[i];
var nameTokens = fullName.split('.');
var name = nameTokens[nameTokens.length - 1];
var uniformGroup = getUniformGroup(nameTokens, uniforms);
var uniform = uniformData[fullName];
uniformGroup.data[name] = uniform;
uniformGroup.gl = gl;
Object.defineProperty(uniformGroup, name, {
get: generateGetter(name),
set: generateSetter(name, uniform)
});
}
return uniforms;
};
var generateGetter = function (name) {
return function () {
return this.data[name].value;
};
};
var GLSL_SINGLE_SETTERS = {
float: function setSingleFloat(gl, location, value) { gl.uniform1f(location, value); },
vec2: function setSingleVec2(gl, location, value) { gl.uniform2f(location, value[0], value[1]); },
vec3: function setSingleVec3(gl, location, value) { gl.uniform3f(location, value[0], value[1], value[2]); },
vec4: function setSingleVec4(gl, location, value) { gl.uniform4f(location, value[0], value[1], value[2], value[3]); },
int: function setSingleInt(gl, location, value) { gl.uniform1i(location, value); },
ivec2: function setSingleIvec2(gl, location, value) { gl.uniform2i(location, value[0], value[1]); },
ivec3: function setSingleIvec3(gl, location, value) { gl.uniform3i(location, value[0], value[1], value[2]); },
ivec4: function setSingleIvec4(gl, location, value) { gl.uniform4i(location, value[0], value[1], value[2], value[3]); },
bool: function setSingleBool(gl, location, value) { gl.uniform1i(location, value); },
bvec2: function setSingleBvec2(gl, location, value) { gl.uniform2i(location, value[0], value[1]); },
bvec3: function setSingleBvec3(gl, location, value) { gl.uniform3i(location, value[0], value[1], value[2]); },
bvec4: function setSingleBvec4(gl, location, value) { gl.uniform4i(location, value[0], value[1], value[2], value[3]); },
mat2: function setSingleMat2(gl, location, value) { gl.uniformMatrix2fv(location, false, value); },
mat3: function setSingleMat3(gl, location, value) { gl.uniformMatrix3fv(location, false, value); },
mat4: function setSingleMat4(gl, location, value) { gl.uniformMatrix4fv(location, false, value); },
sampler2D: function setSingleSampler2D(gl, location, value) { gl.uniform1i(location, value); },
};
var GLSL_ARRAY_SETTERS = {
float: function setFloatArray(gl, location, value) { gl.uniform1fv(location, value); },
vec2: function setVec2Array(gl, location, value) { gl.uniform2fv(location, value); },
vec3: function setVec3Array(gl, location, value) { gl.uniform3fv(location, value); },
vec4: function setVec4Array(gl, location, value) { gl.uniform4fv(location, value); },
int: function setIntArray(gl, location, value) { gl.uniform1iv(location, value); },
ivec2: function setIvec2Array(gl, location, value) { gl.uniform2iv(location, value); },
ivec3: function setIvec3Array(gl, location, value) { gl.uniform3iv(location, value); },
ivec4: function setIvec4Array(gl, location, value) { gl.uniform4iv(location, value); },
bool: function setBoolArray(gl, location, value) { gl.uniform1iv(location, value); },
bvec2: function setBvec2Array(gl, location, value) { gl.uniform2iv(location, value); },
bvec3: function setBvec3Array(gl, location, value) { gl.uniform3iv(location, value); },
bvec4: function setBvec4Array(gl, location, value) { gl.uniform4iv(location, value); },
sampler2D: function setSampler2DArray(gl, location, value) { gl.uniform1iv(location, value); },
};
function generateSetter(name, uniform) {
return function (value) {
this.data[name].value = value;
var location = this.data[name].location;
if (uniform.size === 1) {
GLSL_SINGLE_SETTERS[uniform.type](this.gl, location, value);
}
else {
// glslSetArray(gl, location, type, value) {
GLSL_ARRAY_SETTERS[uniform.type](this.gl, location, value);
}
};
}
function getUniformGroup(nameTokens, uniform) {
var cur = uniform;
for (var i = 0; i < nameTokens.length - 1; i++) {
var o = cur[nameTokens[i]] || { data: {} };
cur[nameTokens[i]] = o;
cur = o;
}
return cur;
}
export { compileProgram } from './compileProgram';
export { defaultValue } from './defaultValue';
export { extractAttributes } from './extractAttributes';
export { extractUniforms } from './extractUniforms';
export { generateUniformAccessObject } from './generateUniformAccessObject';
export { setPrecision } from './setPrecision';
export { mapSize } from './mapSize';
export { mapType } from './mapType';
/**
* @class
* @memberof glCore.shader
* @param type {String}
* @return {Number}
*/
export function mapSize(type) {
return GLSL_TO_SIZE[type];
};
var GLSL_TO_SIZE = {
'float': 1,
'vec2': 2,
'vec3': 3,
'vec4': 4,
'int': 1,
'ivec2': 2,
'ivec3': 3,
'ivec4': 4,
'bool': 1,
'bvec2': 2,
'bvec3': 3,
'bvec4': 4,
'mat2': 4,
'mat3': 9,
'mat4': 16,
'sampler2D': 1
};
\ No newline at end of file
export function mapType(gl, type) {
if (!GL_TABLE) {
var typeNames = Object.keys(GL_TO_GLSL_TYPES);
GL_TABLE = {};
for (var i = 0; i < typeNames.length; ++i) {
var tn = typeNames[i];
GL_TABLE[gl[tn]] = GL_TO_GLSL_TYPES[tn];
}
}
return GL_TABLE[type];
};
var GL_TABLE = null;
var GL_TO_GLSL_TYPES = {
'FLOAT': 'float',
'FLOAT_VEC2': 'vec2',
'FLOAT_VEC3': 'vec3',
'FLOAT_VEC4': 'vec4',
'INT': 'int',
'INT_VEC2': 'ivec2',
'INT_VEC3': 'ivec3',
'INT_VEC4': 'ivec4',
'BOOL': 'bool',
'BOOL_VEC2': 'bvec2',
'BOOL_VEC3': 'bvec3',
'BOOL_VEC4': 'bvec4',
'FLOAT_MAT2': 'mat2',
'FLOAT_MAT3': 'mat3',
'FLOAT_MAT4': 'mat4',
'SAMPLER_2D': 'sampler2D'
};
/**
* Sets the float precision on the shader. If the precision is already present this function will do nothing
* @param {string} src the shader source
* @param {string} precision The float precision of the shader. Options are 'lowp', 'mediump' or 'highp'.
*
* @return {string} modified shader source
*/
export function setPrecision(src, precision) {
if (src.substring(0, 9) !== 'precision') {
return 'precision ' + precision + ' float;\n' + src;
}
return src;
};
\ No newline at end of file
// import AlphaMaskFilter from '../filters/spriteMask/SpriteMaskFilter';
/**
* @class
*/
export default class MaskManager {
renderer: any;
scissor: boolean;
scissorData: any;
scissorRenderTarget: any;
enableScissor: boolean;
/**
* @param {WebGLRenderer} renderer - The renderer this manager works for.
*/
constructor(renderer) {
this.renderer = renderer
// TODO - we don't need both!
this.scissor = false;
this.scissorData = null;
this.scissorRenderTarget = null;
this.enableScissor = true;
// this.alphaMaskPool = [];
// this.alphaMaskIndex = 0;
}
/**
* Applies the Mask and adds it to the current filter stack.
*
* @param {DisplayObject} target - Display Object to push the mask to
* @param {Sprite|Graphics} maskData - The masking data.
*/
pushMask(target, maskData) {
// TODO the root check means scissor rect will not
// be used on render textures more info here:
if (this.enableScissor
&& !this.scissor
&& this.renderer._activeRenderTarget.root
&& !this.renderer.stencilManager.stencilMaskStack.length
&& maskData.maskType == "aaaa") {//Scissor还有问题,再处理
const matrix = maskData.transform.getMatrix();
let rot = Math.atan2(matrix.b, matrix.a);
// use the nearest degree!
rot = Math.round(rot * (180 / Math.PI));
if (rot % 90) {
this.pushStencilMask(maskData);
}
else {
this.pushScissorMask(target, maskData);
}
}
else {
this.pushStencilMask(maskData);
}
}
/**
* Removes the last mask from the mask stack and doesn't return it.
*
* @param {DisplayObject} target - Display Object to pop the mask from
* @param {Sprite|Graphics} maskData - The masking data.
*/
popMask(target, maskData) {
if (this.enableScissor && !this.renderer.stencilManager.stencilMaskStack.length) {
this.popScissorMask(target, maskData);
}
else {
this.popStencilMask(target, maskData);
}
}
/**
* Applies the Mask and adds it to the current filter stack.
*
* @param {RenderTarget} target - Display Object to push the sprite mask to
* @param {Sprite} maskData - Sprite to be used as the mask
*/
// pushSpriteMask(target, maskData)
// {
// let alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex];
// if (!alphaMaskFilter)
// {
// alphaMaskFilter = this.alphaMaskPool[this.alphaMaskIndex] = [new AlphaMaskFilter(maskData)];
// }
// alphaMaskFilter[0].resolution = this.renderer.resolution;
// alphaMaskFilter[0].maskSprite = maskData;
// // TODO - may cause issues!
// target.filterArea = maskData.getBounds(true);
// this.renderer.filterManager.pushFilter(target, alphaMaskFilter);
// this.alphaMaskIndex++;
// }
/**
* Removes the last filter from the filter stack and doesn't return it.
*
*/
// popSpriteMask()
// {
// this.renderer.filterManager.popFilter();
// this.alphaMaskIndex--;
// }
/**
* Applies the Mask and adds it to the current filter stack.
*
* @param {Sprite|Graphics} maskData - The masking data.
*/
pushStencilMask(maskData) {
this.renderer.currentRenderer.stop();
this.renderer.stencilManager.pushStencil(maskData);
}
/**
* Removes the last filter from the filter stack and doesn't return it.
*
*/
popStencilMask(target, maskData) {
this.renderer.currentRenderer.stop();
this.renderer.stencilManager.popStencil();
}
/**
*
* @param {DisplayObject} target - Display Object to push the mask to
* @param {Graphics} maskData - The masking data.
*/
pushScissorMask(target, maskData) {
maskData.renderable = true;
const renderTarget = this.renderer._activeRenderTarget;
const bounds = maskData.scissorMaskBounds();
this.fit(bounds,renderTarget.size);
this.renderer.gl.enable(this.renderer.gl.SCISSOR_TEST);
this.renderer.gl.scissor(
bounds.x,
(renderTarget.root ? renderTarget.size.height - bounds.y - bounds.height : bounds.y),
bounds.width,
bounds.height
);
this.scissorRenderTarget = renderTarget;
this.scissorData = maskData;
this.scissor = true;
}
/**
*
*
*/
popScissorMask(target, maskData) {
// this.scissorRenderTarget = null;
// this.scissorData = null;
this.scissor = false;
// must be scissor!
const gl = this.renderer.gl;
gl.disable(gl.SCISSOR_TEST);
}
destroy() {
}
fit(bounds,rectangle) {
if (bounds.x < rectangle.x) {
bounds.width += bounds.x;
if (bounds.width < 0) {
bounds.width = 0;
}
bounds.x = rectangle.x;
}
if (bounds.y < rectangle.y) {
bounds.height += bounds.y;
if (bounds.height < 0) {
bounds.height = 0;
}
bounds.y = rectangle.y;
}
if (bounds.x + bounds.width > rectangle.x + rectangle.width) {
bounds.width = rectangle.width - bounds.x;
if (bounds.width < 0) {
bounds.width = 0;
}
}
if (bounds.y + bounds.height > rectangle.y + rectangle.height) {
bounds.height = rectangle.height - bounds.y;
if (bounds.height < 0) {
bounds.height = 0;
}
}
}
}
/**
* @class
*/
export default class StencilManager {
renderer: any;
stencilMaskStack: any;
/**
* @param {WebGLRenderer} renderer - The renderer this manager works for.
*/
constructor(renderer) {
this.renderer = renderer
this.stencilMaskStack = null;
}
/**
* Changes the mask stack that is used by this manager.
*
* @param {Graphics[]} stencilMaskStack - The mask stack
*/
setMaskStack(stencilMaskStack) {
this.stencilMaskStack = stencilMaskStack;
const gl = this.renderer.gl;
if (stencilMaskStack.length === 0) {
gl.disable(gl.STENCIL_TEST);
}
else {
gl.enable(gl.STENCIL_TEST);
}
}
/**
* Applies the Mask and adds it to the current stencil stack. @alvin
*
* @param {Graphics} graphics - The mask
*/
pushStencil(graphics) {
this.renderer.setObjectRenderer(this.renderer.plugins.graphics);
this.renderer._activeRenderTarget.attachStencilBuffer();
const gl = this.renderer.gl;
const prevMaskCount = this.stencilMaskStack.length;
if (prevMaskCount === 0) {
gl.enable(gl.STENCIL_TEST);
}
this.stencilMaskStack.push(graphics);
// Increment the refference stencil value where the new mask overlaps with the old ones.
if(graphics.maskVisible){
//如果显示遮罩
gl.colorMask(true, true, true, true);
}else{
gl.colorMask(false, false, false, false);
}
// gl.colorMask(true, true, true, true);
gl.stencilFunc(gl.EQUAL, prevMaskCount, this._getBitwiseMask());
gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
this.renderer.plugins.graphics.render(graphics);
this._useCurrent();
}
/**
* Removes the last mask from the stencil stack. @alvin
*/
popStencil() {
this.renderer.setObjectRenderer(this.renderer.plugins.graphics);
const gl = this.renderer.gl;
const graphics = this.stencilMaskStack.pop();
if (this.stencilMaskStack.length === 0) {
// the stack is empty!
gl.disable(gl.STENCIL_TEST);
gl.clear(gl.STENCIL_BUFFER_BIT);
gl.clearStencil(0);
}
else {
// Decrement the refference stencil value where the popped mask overlaps with the other ones
gl.colorMask(false, false, false, false);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);
this.renderer.plugins.graphics.render(graphics);
this._useCurrent();
}
}
/**
* Setup renderer to use the current stencil data.
*/
_useCurrent() {
const gl = this.renderer.gl;
gl.colorMask(true, true, true, true);
gl.stencilFunc(gl.EQUAL, this.stencilMaskStack.length, this._getBitwiseMask());
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
}
/**
* Fill 1s equal to the number of acitve stencil masks.
*
* @return {number} The bitwise mask.
*/
_getBitwiseMask() {
return (1 << this.stencilMaskStack.length) - 1;
}
/**
* Destroys the mask stack.
*
*/
destroy() {
this.renderer = null;
this.stencilMaskStack.stencilStack = null;
}
}
import { GC_MODES } from '../const';
import settings from '../settings';
/**
* TextureGarbageCollector. This class manages the GPU and ensures that it does not get clogged
* up with textures that are no longer being used.
*
* @class
* @memberof PIXI
*/
export default class TextureGarbageCollector {
renderer: any;
count: number;
checkCount: number;
maxIdle: number;
checkCountMax: number;
mode: number;
/**
* @param {WebGLRenderer} renderer - The renderer this manager works for.
*/
constructor(renderer) {
this.renderer = renderer;
this.count = 0;
this.checkCount = 0;
this.maxIdle = settings.GC_MAX_IDLE;
this.checkCountMax = settings.GC_MAX_CHECK_COUNT;
this.mode = settings.GC_MODE;
}
/**
* Checks to see when the last time a texture was used
* if the texture has not been used for a specified amount of time it will be removed from the GPU
*/
update() {
this.count++;
if (this.mode === GC_MODES.MANUAL) {
return;
}
this.checkCount++;
if (this.checkCount > this.checkCountMax) {
this.checkCount = 0;
this.run();
}
}
/**
* Checks to see when the last time a texture was used
* if the texture has not been used for a specified amount of time it will be removed from the GPU
*/
run() {
const tm = this.renderer.textureManager;
const managedTextures = tm._managedTextures;
let wasRemoved = false;
for (let i = 0; i < managedTextures.length; i++) {
const texture = managedTextures[i];
// only supports non generated textures at the moment!
if (!texture._glRenderTargets && this.count - texture.touched > this.maxIdle) {
tm.destroyTexture(texture, true);
managedTextures[i] = null;
wasRemoved = true;
}
}
if (wasRemoved) {
let j = 0;
for (let i = 0; i < managedTextures.length; i++) {
if (managedTextures[i] !== null) {
managedTextures[j++] = managedTextures[i];
}
}
managedTextures.length = j;
}
}
/**
* Removes all the textures within the specified displayObject and its children from the GPU
*
* @param {DisplayObject} displayObject - the displayObject to remove the textures from.
*/
unload(displayObject) {
const tm = this.renderer.textureManager;
// only destroy non generated textures
if (displayObject._texture && displayObject._texture._glRenderTargets) {
tm.destroyTexture(displayObject._texture, true);
}
for (let i = displayObject.children.length - 1; i >= 0; i--) {
this.unload(displayObject.children[i]);
}
}
}
import { GLTexture } from '../glCore';
import { WRAP_MODES, SCALE_MODES } from '../const';
import RenderTarget from '../utils/RenderTarget';
import removeItems from '../utils/removeItems';
import {isPow2} from "../utils"
/**
* Helper class to create a webGL Texture
*
* @class
*/
export default class TextureManager {
renderer: any;
gl: any;
_managedTextures: any[];
/**
* @param {WebGLRenderer} renderer - A reference to the current renderer
*/
constructor(renderer) {
/**
* A reference to the current renderer
*
* @member {PIXI.WebGLRenderer}
*/
this.renderer = renderer;
/**
* The current WebGL rendering context
*
* @member {WebGLRenderingContext}
*/
this.gl = renderer.gl;
/**
* Track textures in the renderer so we can no longer listen to them on destruction.
*
* @member {Array<*>}
* @private
*/
this._managedTextures = [];
}
/**
* Binds a texture.
*
*/
bindTexture() {
// empty
}
/**
* Gets a texture.
*
*/
getTexture() {
// empty
}
/**
* Updates and/or Creates a WebGL texture for the renderer's context.
*
* @param {PIXI.BaseTexture|PIXI.Texture} texture - the texture to update
* @param {number} location - the location the texture will be bound to.
* @return {GLTexture} The gl texture.
*/
updateTexture(texture, location) {
// assume it good!
// texture = texture.baseTexture || texture;
const gl = this.gl;
const isRenderTexture = !!texture._glRenderTargets;
// if (!texture.hasLoaded) {
// return null;
// }
if(!texture.complete&&!(texture instanceof HTMLCanvasElement)){
return null;
}
const boundTextures = this.renderer.boundTextures;
// if the location is undefined then this may have been called by n event.
// this being the case the texture may already be bound to a slot. As a texture can only be bound once
// we need to find its current location if it exists.
if (location === undefined) {
location = 0;
// TODO maybe we can use texture bound ids later on...
// check if texture is already bound..
for (let i = 0; i < boundTextures.length; ++i) {
if (boundTextures[i] === texture) {
location = i;
break;
}
}
}
boundTextures[location] = texture;
gl.activeTexture(gl.TEXTURE0 + location);
let glTexture = texture._glTextures[this.renderer.CONTEXT_UID];
if (!glTexture) {
// if (isRenderTexture) {
// const renderTarget = new RenderTarget(
// this.gl,
// texture.width,
// texture.height,
// texture.scaleMode,
// texture.resolution
// );
// renderTarget.resize(texture.width, texture.height);
// texture._glRenderTargets[this.renderer.CONTEXT_UID] = renderTarget;
// glTexture = renderTarget.texture;
// }
// else {
glTexture = new GLTexture(this.gl, null, null, null, null);
glTexture.bind(location);
glTexture.premultiplyAlpha = true;//必设,否则带透明度的纹理渲染会出问题
// glTexture.upload(texture.source);
glTexture.upload(texture);
// }
texture._glTextures[this.renderer.CONTEXT_UID] = glTexture;
// texture.on('update', this.updateTexture, this);
// texture.on('dispose', this.destroyTexture, this);
this._managedTextures.push(texture);
if (isPow2(texture.width)&&isPow2(texture.height)) {
// if (texture.mipmap) {
// glTexture.enableMipmap();
// }
// if (texture.wrapMode === WRAP_MODES.CLAMP) {
// glTexture.enableWrapClamp();
// }
// else if (texture.wrapMode === WRAP_MODES.REPEAT) {
// glTexture.enableWrapRepeat();
// }
// else {
// glTexture.enableWrapMirrorRepeat();
// }
glTexture.enableMipmap();
glTexture.enableWrapClamp();
}
else {
glTexture.enableWrapClamp();
}
// if (texture.scaleMode === SCALE_MODES.NEAREST) {
// glTexture.enableNearestScaling();
// }
// else {
glTexture.enableLinearScaling();
// }
}
// the texture already exists so we only need to update it..
// else if (isRenderTexture) {
// texture._glRenderTargets[this.renderer.CONTEXT_UID].resize(texture.width, texture.height);
// }
else {
glTexture.upload(texture);
}
return glTexture;
}
/**
* Deletes the texture from WebGL
*
* @param {PIXI.BaseTexture|PIXI.Texture} texture - the texture to destroy
* @param {boolean} [skipRemove=false] - Whether to skip removing the texture from the TextureManager.
*/
destroyTexture(texture, skipRemove) {
texture = texture.baseTexture || texture;
if (!texture.hasLoaded) {
return;
}
const uid = this.renderer.CONTEXT_UID;
const glTextures = texture._glTextures;
const glRenderTargets = texture._glRenderTargets;
if (glTextures[uid]) {
this.renderer.unbindTexture(texture);
glTextures[uid].destroy();
// texture.off('update', this.updateTexture, this);
// texture.off('dispose', this.destroyTexture, this);
delete glTextures[uid];
if (!skipRemove) {
const i = this._managedTextures.indexOf(texture);
if (i !== -1) {
removeItems(this._managedTextures, i, 1);
}
}
}
if (glRenderTargets && glRenderTargets[uid]) {
glRenderTargets[uid].destroy();
delete glRenderTargets[uid];
}
}
/**
* Deletes all the textures from WebGL
*/
removeAll() {
// empty all the old gl textures as they are useless now
for (let i = 0; i < this._managedTextures.length; ++i) {
const texture = this._managedTextures[i];
if (texture._glTextures[this.renderer.CONTEXT_UID]) {
delete texture._glTextures[this.renderer.CONTEXT_UID];
}
}
}
/**
* Destroys this manager and removes all its textures
*/
destroy() {
// destroy managed textures
for (let i = 0; i < this._managedTextures.length; ++i) {
const texture = this._managedTextures[i];
this.destroyTexture(texture, true);
// texture.off('update', this.updateTexture, this);
// texture.off('dispose', this.destroyTexture, this);
}
this._managedTextures = null;
}
}
import ObjectRenderer from '../ObjectRenderer';
import WebGLRenderer from '../WebGLRenderer';
import createIndicesForQuads from '../utils/createIndicesForQuads';
import { generateMultiTextureShader } from '../utils/generateMultiTextureShader';
import { checkMaxIfStatmentsInShader } from '../glCore/checkMaxIfStatmentsInShader';
import { BatchBuffer } from '../glCore/BatchBuffer';
import settings from '../settings';
import { /*premultiplyBlendMode,*/ premultiplyTint } from '../utils';
import { nextPow2, log2 } from "../utils";
import { GLBuffer } from '../glCore/GLBuffer';
let TICK = 0;
let TEXTURE_TICK = 0;
/**
* Renderer dedicated to drawing and batching sprites.
*
* @class
* @private
* @extends ObjectRenderer
*/
export default class BatchRenderer extends ObjectRenderer {
vertSize: number;
vertByteSize: number;
size: number;
buffers: any[];
indices: Uint16Array;
shader: any;
currentIndex: number;
groups: any[];
sprites: any[];
vertexBuffers: any[];
vaos: any[];
vaoMax: number;
vertexCount: number;
MAX_TEXTURES: number;
indexBuffer: GLBuffer;
vao: any;
currentBlendMode: number;
boundTextures: any[];
/**
* @param {WebGLRenderer} renderer - The renderer this sprite batch works for.
*/
constructor(renderer) {
super(renderer);
/**
* Number of values sent in the vertex buffer.
* aVertexPosition(2), aTextureCoord(1), aColor(1), aTextureId(1) = 5
*
* @member {number}
*/
this.vertSize = 5;
/**
* The size of the vertex information in bytes.
*
* @member {number}
*/
this.vertByteSize = this.vertSize * 4;
/**
* The number of images in the SpriteRenderer before it flushes.
*
* @member {number}
*/
this.size = settings.SPRITE_BATCH_SIZE; // 2000 is a nice balance between mobile / desktop
// the total number of bytes in our batch
// let numVerts = this.size * 4 * this.vertByteSize;
this.buffers = [];
for (let i = 1; i <= nextPow2(this.size); i *= 2) {
this.buffers.push(new BatchBuffer(i * 4 * this.vertByteSize));
}
/**
* Holds the indices of the geometry (quads) to draw
*
* @member {Uint16Array}
*/
this.indices = createIndicesForQuads(this.size);
/**
* The default shaders that is used if a sprite doesn't have a more specific one.
* there is a shader for each number of textures that can be rendererd.
* These shaders will also be generated on the fly as required.
* @member {Shader[]}
*/
this.shader = null;
this.currentIndex = 0;
this.groups = [];
for (let k = 0; k < this.size; k++) {
this.groups[k] = { textures: [], textureCount: 0, ids: [], size: 0, start: 0, blend: 0 };
}
this.sprites = [];
this.vertexBuffers = [];
this.vaos = [];
this.vaoMax = 2;
this.vertexCount = 0;
// this.renderer.on('prerender', this.onPrerender, this);
}
/**
* Sets up the renderer context and necessary buffers.
*
* @private
*/
onContextChange() {
const gl = this.renderer.gl;
if (this.renderer.legacy) {
this.MAX_TEXTURES = 1;
}
else {
// step 1: first check max textures the GPU can handle.
this.MAX_TEXTURES = Math.min(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS), settings.SPRITE_MAX_TEXTURES);
// step 2: check the maximum number of if statements the shader can have too..
this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl);
}
this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES);
// create a couple of buffers
this.indexBuffer = GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW);
// we use the second shader as the first one depending on your browser may omit aTextureId
// as it is not used by the shader so is optimized out.
this.renderer.bindVao(null);
const attrs = this.shader.attributes;
for (let i = 0; i < this.vaoMax; i++) {
/* eslint-disable max-len */
const vertexBuffer = this.vertexBuffers[i] = GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW);
/* eslint-enable max-len */
// build the vao object that will render..
const vao = this.renderer.createVao()
.addIndex(this.indexBuffer)
.addAttribute(vertexBuffer, attrs.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0)
.addAttribute(vertexBuffer, attrs.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4)
.addAttribute(vertexBuffer, attrs.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4);
if (attrs.aTextureId) {
vao.addAttribute(vertexBuffer, attrs.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4);
}
this.vaos[i] = vao;
}
this.vao = this.vaos[0];
this.currentBlendMode = 99999;
this.boundTextures = new Array(this.MAX_TEXTURES);
}
/**
* Called before the renderer starts rendering.
*
*/
onPrerender() {
this.vertexCount = 0;
}
/**
* Renders the sprite object.
*
* @param {Sprite} sprite - the sprite to render when using this spritebatch
*/
render(sprite) {
// TODO set blend modes..
// check texture..
if (this.currentIndex >= this.size) {
this.flush();
}
// get the uvs for the texture
// if the uvs have not updated then no point rendering just yet!
if (!sprite.texture && !sprite.cacheCanvas) {
return;
}
// push a texture.
// increment the batchsize
this.sprites[this.currentIndex++] = sprite;
}
/**
* Renders the content and empties the current batch.
*
*/
flush() {
if (this.currentIndex === 0) {
return;
}
const gl = this.renderer.gl;
const MAX_TEXTURES = this.MAX_TEXTURES;
const np2 = nextPow2(this.currentIndex);
const log22 = log2(np2);
const buffer = this.buffers[log22];
const sprites = this.sprites;
const groups = this.groups;
const float32View = buffer.float32View;
const uint32View = buffer.uint32View;
const boundTextures = this.boundTextures;
const rendererBoundTextures = this.renderer.boundTextures;
const touch = this.renderer.textureGC.count;
let index = 0;
let nextTexture;
let currentTexture;
let groupCount = 1;
let textureCount = 0;
let currentGroup = groups[0];
let vertexData;
let uvs;
// let blendMode = premultiplyBlendMode[
// sprites[0]._texture.baseTexture.premultipliedAlpha ? 1 : 0][sprites[0].blendMode];
currentGroup.textureCount = 0;
currentGroup.start = 0;
// currentGroup.blend = blendMode;
TICK++;
let i;
// copy textures..
for (i = 0; i < MAX_TEXTURES; ++i) {
const bt = rendererBoundTextures[i];
if (bt._enabled === TICK) {
boundTextures[i] = this.renderer.emptyTextures[i];
continue;
}
boundTextures[i] = bt;
bt._virtalBoundId = i;
bt._enabled = TICK;
}
TICK++;
for (i = 0; i < this.currentIndex; ++i) {
// upload the sprite elemetns...
// they have all ready been calculated so we just need to push them into the buffer.
const sprite = sprites[i];
sprites[i] = null;
// nextTexture = sprite._texture.baseTexture;
// nextTexture = sprite.texture.img;//需要判断图集是否同一 或者是缓存的canvas,缓存canvas的uvs固定默认 当存在滤镜的时候还要重新考虑
nextTexture = sprite.texture ? sprite.texture.img : sprite.cacheCanvas
//混合模式暂时不用
/* const spriteBlendMode = premultiplyBlendMode[Number(nextTexture.premultipliedAlpha)][sprite.blendMode];
if (blendMode !== spriteBlendMode)
{
// finish a group..
blendMode = spriteBlendMode;
// force the batch to break!
currentTexture = null;
textureCount = MAX_TEXTURES;
TICK++;
}*/
if (currentTexture !== nextTexture) {
currentTexture = nextTexture;
if (nextTexture._enabled !== TICK) {
if (textureCount === MAX_TEXTURES) {
TICK++;
currentGroup.size = i - currentGroup.start;
textureCount = 0;
currentGroup = groups[groupCount++];
// currentGroup.blend = blendMode;
currentGroup.textureCount = 0;
currentGroup.start = i;
}
nextTexture.touched = touch;
if (nextTexture._virtalBoundId === -1) {
for (let j = 0; j < MAX_TEXTURES; ++j) {
const tIndex = (j + TEXTURE_TICK) % MAX_TEXTURES;
const t = boundTextures[tIndex];
if (t._enabled !== TICK) {
TEXTURE_TICK++;
t._virtalBoundId = -1;
nextTexture._virtalBoundId = tIndex;
boundTextures[tIndex] = nextTexture;
break;
}
}
}
nextTexture._enabled = TICK;
currentGroup.textureCount++;
currentGroup.ids[textureCount] = nextTexture._virtalBoundId;
currentGroup.textures[textureCount++] = nextTexture;
}
}
vertexData = sprite.vertexData;
// TODO this sum does not need to be set each frame..
// uvs = sprite.texture.uvs/*.uvsUint32;*/
uvs = sprite.texture ? sprite.texture.uvs : [0, 65535, -1, -65536]
// if (this.renderer.roundPixels)
// {
// const resolution = this.renderer.resolution;
// // xy
// float32View[index] = ((vertexData[0] * resolution) | 0) / resolution;
// float32View[index + 1] = ((vertexData[1] * resolution) | 0) / resolution;
// // xy
// float32View[index + 5] = ((vertexData[2] * resolution) | 0) / resolution;
// float32View[index + 6] = ((vertexData[3] * resolution) | 0) / resolution;
// // xy
// float32View[index + 10] = ((vertexData[4] * resolution) | 0) / resolution;
// float32View[index + 11] = ((vertexData[5] * resolution) | 0) / resolution;
// // xy
// float32View[index + 15] = ((vertexData[6] * resolution) | 0) / resolution;
// float32View[index + 16] = ((vertexData[7] * resolution) | 0) / resolution;
// }
// else
// {
// xy
float32View[index] = vertexData[0];
float32View[index + 1] = vertexData[1];
// xy
float32View[index + 5] = vertexData[2];
float32View[index + 6] = vertexData[3];
// xy
float32View[index + 10] = vertexData[4];
float32View[index + 11] = vertexData[5];
// xy
float32View[index + 15] = vertexData[6];
float32View[index + 16] = vertexData[7];
// }
uint32View[index + 2] = uvs[0];
uint32View[index + 7] = uvs[1];
uint32View[index + 12] = uvs[2];
uint32View[index + 17] = uvs[3];
/* eslint-disable max-len */
//颜色暂时计算,到时候修改
var _tintRGB = 16777215
if (sprite._tintRGB) {
var num = parseInt(sprite.borderColor.slice(1), 16);
_tintRGB = (num >> 16) + (num & 0xff00) + ((num & 0xff) << 16);
}
const alpha = Math.min(sprite.transform.renderAlpha*sprite.alpha, 1.0);
// we dont call extra function if alpha is 1.0, that's faster
const argb = alpha < 1.0 /*&& nextTexture.premultipliedAlpha*/ ? premultiplyTint(/*sprite._tintRGB*/_tintRGB, alpha)
: /*sprite._tintRGB*/_tintRGB + (alpha * 255 << 24);
uint32View[index + 3] = uint32View[index + 8] = uint32View[index + 13] = uint32View[index + 18] = argb;
float32View[index + 4] = float32View[index + 9] = float32View[index + 14] = float32View[index + 19] = nextTexture._virtalBoundId;
/* eslint-enable max-len */
index += 20;
}
currentGroup.size = i - currentGroup.start;
if (!settings.CAN_UPLOAD_SAME_BUFFER) {
// this is still needed for IOS performance..
// it really does not like uploading to the same buffer in a single frame!
if (this.vaoMax <= this.vertexCount) {
this.vaoMax++;
const attrs = this.shader.attributes;
/* eslint-disable max-len */
const vertexBuffer = this.vertexBuffers[this.vertexCount] = GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW);
/* eslint-enable max-len */
// build the vao object that will render..
const vao = this.renderer.createVao()
.addIndex(this.indexBuffer)
.addAttribute(vertexBuffer, attrs.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0)
.addAttribute(vertexBuffer, attrs.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4)
.addAttribute(vertexBuffer, attrs.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4);
if (attrs.aTextureId) {
vao.addAttribute(vertexBuffer, attrs.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4);
}
this.vaos[this.vertexCount] = vao;
}
this.renderer.bindVao(this.vaos[this.vertexCount]);
this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, false);
this.vertexCount++;
}
else {
// lets use the faster option, always use buffer number 0
this.vertexBuffers[this.vertexCount].upload(buffer.vertices, 0, true);
}
for (i = 0; i < MAX_TEXTURES; ++i) {
rendererBoundTextures[i]._virtalBoundId = -1;
}
// render the groups..
for (i = 0; i < groupCount; ++i) {
const group = groups[i];
const groupTextureCount = group.textureCount;
for (let j = 0; j < groupTextureCount; j++) {
currentTexture = group.textures[j];
// reset virtual ids..
// lets do a quick check..
if (rendererBoundTextures[group.ids[j]] !== currentTexture) {
this.renderer.bindTexture(currentTexture, group.ids[j], true);
}
else if (currentTexture instanceof HTMLCanvasElement && currentTexture["dirty"]) {
// this.renderer.bindTexture(currentTexture, group.ids[j], true);
this.renderer.textureManager.updateTexture(currentTexture, group.ids[j]);
currentTexture["dirty"] = false
}
// reset the virtualId..
currentTexture._virtalBoundId = -1;
}
// set the blend mode..
// this.renderer.state.setBlendMode(group.blend);
gl.drawElements(gl.TRIANGLES, group.size * 6, gl.UNSIGNED_SHORT, group.start * 6 * 2);
}
// reset elements for the next flush
this.currentIndex = 0;
}
/**
* Starts a new sprite batch.
*/
start() {
this.renderer.bindShader(this.shader);
if (settings.CAN_UPLOAD_SAME_BUFFER) {
// bind buffer #0, we don't need others
this.renderer.bindVao(this.vaos[this.vertexCount]);
this.vertexBuffers[this.vertexCount].bind();
}
}
/**
* Stops and flushes the current batch.
*
*/
stop() {
this.flush();
}
/**
* Destroys the SpriteRenderer.
*
*/
destroy() {
// for (let i = 0; i < this.vaoMax; i++)
// {
// if (this.vertexBuffers[i])
// {
// this.vertexBuffers[i].destroy();
// }
// if (this.vaos[i])
// {
// this.vaos[i].destroy();
// }
// }
// if (this.indexBuffer)
// {
// this.indexBuffer.destroy();
// }
// this.renderer.off('prerender', this.onPrerender, this);
// super.destroy();
// if (this.shader)
// {
// this.shader.destroy();
// this.shader = null;
// }
// this.vertexBuffers = null;
// this.vaos = null;
// this.indexBuffer = null;
// this.indices = null;
// this.sprites = null;
// for (let i = 0; i < this.buffers.length; ++i)
// {
// this.buffers[i].destroy();
// }
}
}
// WebGLRenderer["registerPlugin"]('batch', BatchRenderer);
// import { hex2rgb } from '../../utils';
// import { SHAPES } from '../../const';
import ObjectRenderer from '../ObjectRenderer';
// import WebGLRenderer from '../../renderers/webgl/WebGLRenderer';
// import WebGLGraphicsData from './WebGLGraphicsData';
import PrimitiveShader from './PrimitiveShader';
import { hex2rgb } from "../utils";
import { GLBuffer, VertexArrayObject } from "../glCore"
/**
* Renders the graphics object.
*暂时为遮罩处理用,shader和vao特定的
* @class
* @extends ObjectRenderer
*/
export default class GraphicsRenderer extends ObjectRenderer {
graphicsDataPool: any[];
primitiveShader: any;
gl: any;
CONTEXT_UID: number;
renderer: any;
buffer: GLBuffer;
indexBuffer: GLBuffer;
vao: any;
/**
* @param {WebGLRenderer} renderer - The renderer this object renderer works for.
*/
constructor(renderer) {
super(renderer);
this.graphicsDataPool = [];
this.primitiveShader = null;
this.gl = renderer.gl;
// easy access!
this.CONTEXT_UID = 0;
this.buffer = GLBuffer.createVertexBuffer(this.gl);
this.indexBuffer = GLBuffer.createIndexBuffer(this.gl);
}
/**
* Called when there is a WebGL context change
*
* @private
*
*/
onContextChange() {
this.gl = this.renderer.gl;
this.CONTEXT_UID = this.renderer.CONTEXT_UID;
this.primitiveShader = new PrimitiveShader(this.gl);
}
/**
* Destroys this renderer.
*
*/
// destroy()
// {
// ObjectRenderer.prototype.destroy.call(this);
// for (let i = 0; i < this.graphicsDataPool.length; ++i)
// {
// this.graphicsDataPool[i].destroy();
// }
// this.graphicsDataPool = null;
// }
/**
* Renders a graphics object.
*
* @param {Graphics} graphics - The graphics object to render.
*/
render(graphics) {
const renderer = this.renderer;
const gl = renderer.gl;
var glPoints;
var glIndices;
graphics.calculateMaskVertices();
glPoints = new Float32Array(graphics.verts);
glIndices = new Uint16Array(graphics.indices);
const shader = this.primitiveShader;
renderer.bindShader(shader);
if (!this.vao) {
this.vao = new VertexArrayObject(gl, this.renderer.state.attribsState)
.addIndex(this.indexBuffer)
.addAttribute(this.buffer, shader.attributes.aVertexPosition, gl.FLOAT, false, 4 * 2, 0)
// .addAttribute(this.buffer, shader.attributes.aColor, gl.FLOAT, false, 4 * 6, 2 * 4);
}
shader.uniforms.translationMatrix = graphics.transform.getMatrix(true).toArray(true);
shader.uniforms.tint = hex2rgb(parseInt(graphics.fillColor.slice(1), 16));
shader.uniforms.alpha = graphics.alpha * graphics.transform.renderAlpha;
renderer.bindVao(this.vao);
this.buffer.upload(glPoints);
this.indexBuffer.upload(glIndices);
this.vao.draw(gl.TRIANGLE_STRIP, graphics.indices.length);
// renderer.state.setBlendMode(graphics.blendMode);
}
}
// WebGLRenderer.registerPlugin('graphics', GraphicsRenderer);
import Shader from './Shader';
/**
* This shader is used to draw simple primitive shapes for {@link Graphics}.
*
* @class
* @extends Shader
*/
export default class PrimitiveShader extends Shader {
/**
* 注释掉的aColor暂时不需要,不考虑混色,简单粗暴颜色和透明度
* @param {WebGLRenderingContext} gl - The webgl shader manager this shader works for.
*/
constructor(gl) {
super(gl,
// vertex shader
[
'attribute vec2 aVertexPosition;',
// 'attribute vec4 aColor;',
'uniform mat3 translationMatrix;',
'uniform mat3 projectionMatrix;',
'uniform float alpha;',
'uniform vec3 tint;',
'varying vec4 vColor;',
'void main(void){',
' gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',
// ' vColor = aColor * vec4(tint * alpha, alpha);',
'vColor = vec4(tint * alpha, alpha);',//考虑和vColor = vec4(tint,alpha)的区别
'}',
].join('\n'),
// fragment shader
[
'varying vec4 vColor;',
'void main(void){',
' gl_FragColor = vColor;',
// ' gl_FragColor = vec4(1.0,0.0,0.0,1.0);',
'}',
].join('\n')
);
}
}
import { GLShader } from '../glCore';
import settings from '../settings';
function checkPrecision(src, def)
{
if (src instanceof Array)
{
if (src[0].substring(0, 9) !== 'precision')
{
const copy = src.slice(0);
copy.unshift(`precision ${def} float;`);
return copy;
}
}
else if (src.trim().substring(0, 9) !== 'precision')
{
return `precision ${def} float;\n${src}`;
}
return src;
}
/**
* Wrapper class, webGL Shader
* Adds precision string if vertexSrc or fragmentSrc have no mention of it.
*
* @class
* @extends GLShader
*/
export default class Shader extends GLShader
{
/**
*
* @param {WebGLRenderingContext} gl - The current WebGL rendering context
* @param {string|string[]} vertexSrc - The vertex shader source as an array of strings.
* @param {string|string[]} fragmentSrc - The fragment shader source as an array of strings.
* @param {object} [attributeLocations] - A key value pair showing which location eact attribute should sit.
e.g. {position:0, uvs:1}.
* @param {string} [precision] - The float precision of the shader. Options are 'lowp', 'mediump' or 'highp'.
*/
constructor(gl, vertexSrc, fragmentSrc, attributeLocations?, precision?)
{
super(gl, checkPrecision(vertexSrc, precision || settings.PRECISION_VERTEX),
checkPrecision(fragmentSrc, precision || settings.PRECISION_FRAGMENT), undefined, attributeLocations);
}
}
import maxRecommendedTextures from './utils/maxRecommendedTextures';
import canUploadSameBuffer from './utils/canUploadSameBuffer';
/**
* User's customizable globals for overriding the default PIXI settings, such
* as a renderer's default resolution, framerate, float percision, etc.
* @example
* // Use the native window resolution as the default resolution
* // will support high-density displays when rendering
* settings.RESOLUTION = window.devicePixelRatio.
*
* // Disable interpolation when scaling, will make texture be pixelated
* settings.SCALE_MODE = SCALE_MODES.NEAREST;
* @namespace settings
*/
export default {
/**
* Target frames per millisecond.
*
* @static
* @memberof settings
* @type {number}
* @default 0.06
*/
TARGET_FPMS: 0.06,
/**
* If set to true WebGL will attempt make textures mimpaped by default.
* Mipmapping will only succeed if the base texture uploaded has power of two dimensions.
*
* @static
* @memberof settings
* @type {boolean}
* @default true
*/
MIPMAP_TEXTURES: true,
/**
* Default resolution / device pixel ratio of the renderer.
*
* @static
* @memberof settings
* @type {number}
* @default 1
*/
RESOLUTION: window.devicePixelRatio || 1,
/**
* Default filter resolution.
*
* @static
* @memberof settings
* @type {number}
* @default 1
*/
// FILTER_RESOLUTION: 1,
/**
* The maximum textures that this device supports.
*
* @static
* @memberof settings
* @type {number}
* @default 32
*/
SPRITE_MAX_TEXTURES: maxRecommendedTextures(32),
// TODO: maybe change to SPRITE.BATCH_SIZE: 2000
// TODO: maybe add PARTICLE.BATCH_SIZE: 15000
/**
* The default sprite batch size.
*
* The default aims to balance desktop and mobile devices.
*
* @static
* @memberof settings
* @type {number}
* @default 4096
*/
SPRITE_BATCH_SIZE: 2000,
/**
* The prefix that denotes a URL is for a retina asset.
*
* @static
* @memberof settings
* @type {RegExp}
* @example `@2x`
* @default /@([0-9\.]+)x/
*/
RETINA_PREFIX: /@([0-9\.]+)x/,
/**
* The default render options if none are supplied to {@link WebGLRenderer}
* or {@link CanvasRenderer}.
*
* @static
* @constant
* @memberof settings
* @type {object}
* @property {HTMLCanvasElement} view=null
* @property {number} resolution=1
* @property {boolean} antialias=false
* @property {boolean} forceFXAA=false
* @property {boolean} autoResize=false
* @property {boolean} transparent=false
* @property {number} backgroundColor=0x000000
* @property {boolean} clearBeforeRender=true
* @property {boolean} preserveDrawingBuffer=false
* @property {boolean} roundPixels=false
* @property {number} width=800
* @property {number} height=600
* @property {boolean} legacy=false
*/
RENDER_OPTIONS: {
view: null,
antialias: false,
forceFXAA: false,
autoResize: false,
transparent: false,
backgroundColor: 0x000000,
clearBeforeRender: true,
preserveDrawingBuffer: false,
roundPixels: false,
width: 800,
height: 600,
legacy: false,
},
/**
* Default transform type.
*
* @static
* @memberof settings
* @type {TRANSFORM_MODE}
* @default TRANSFORM_MODE.STATIC
*/
TRANSFORM_MODE: 0,
/**
* Default Garbage Collection mode.
*
* @static
* @memberof settings
* @type {GC_MODES}
* @default GC_MODES.AUTO
*/
GC_MODE: 0,
/**
* Default Garbage Collection max idle.
*
* @static
* @memberof settings
* @type {number}
* @default 3600
*/
GC_MAX_IDLE: 60 * 60,
/**
* Default Garbage Collection maximum check count.
*
* @static
* @memberof settings
* @type {number}
* @default 600
*/
GC_MAX_CHECK_COUNT: 60 * 10,
/**
* Default wrap modes that are supported by
*
* @static
* @memberof settings
* @type {WRAP_MODES}
* @default WRAP_MODES.CLAMP
*/
WRAP_MODE: 0,
/**
* The scale modes that are supported by
*
* @static
* @memberof settings
* @type {SCALE_MODES}
* @default SCALE_MODES.LINEAR
*/
SCALE_MODE: 0,
/**
* Default specify float precision in vertex shader.
*
* @static
* @memberof settings
* @type {PRECISION}
* @default PRECISION.HIGH
*/
PRECISION_VERTEX: 'highp',
/**
* Default specify float precision in fragment shader.
*
* @static
* @memberof settings
* @type {PRECISION}
* @default PRECISION.MEDIUM
*/
PRECISION_FRAGMENT: 'mediump',
/**
* Can we upload the same buffer in a single frame?
*
* @static
* @constant
* @memberof settings
* @type {boolean}
*/
CAN_UPLOAD_SAME_BUFFER: canUploadSameBuffer(),
/**
* Default Mesh `canvasPadding`.
*
* @see mesh.Mesh#canvasPadding
* @static
* @constant
* @memberof settings
* @type {number}
*/
MESH_CANVAS_PADDING: 0,
};
/**
* 批处理buffer数据类
*/
export default class Buffer {
/**
* 顶点类型化数组
*/
vertices: ArrayBuffer;
/**
* View on the vertices as a Float32Array for positions
* @member {Float32Array}
*/
float32View: Float32Array;
/**
* View on the vertices as a Uint32Array for uvs
* @member {Uint32Array}
*/
uint32View: Uint32Array;
positions: any;
uvs: any;
colors: any;
/**
* @param {number} size - The size of the buffer in bytes.
*/
constructor(size) {
this.vertices = new ArrayBuffer(size);
this.float32View = new Float32Array(this.vertices);
this.uint32View = new Uint32Array(this.vertices);
}
/**
* Destroys the buffer.
*
*/
destroy() {
this.vertices = null;
this.positions = null;
this.uvs = null;
this.colors = null;
}
}
var apple_phone = /iPhone/i,
apple_ipod = /iPod/i,
apple_tablet = /iPad/i,
android_phone = /(?=.*\bAndroid\b)(?=.*\bMobile\b)/i, // Match 'Android' AND 'Mobile'
android_tablet = /Android/i,
amazon_phone = /(?=.*\bAndroid\b)(?=.*\bSD4930UR\b)/i,
amazon_tablet = /(?=.*\bAndroid\b)(?=.*\b(?:KFOT|KFTT|KFJWI|KFJWA|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|KFARWI|KFASWI|KFSAWI|KFSAWA)\b)/i,
windows_phone = /Windows Phone/i,
windows_tablet = /(?=.*\bWindows\b)(?=.*\bARM\b)/i, // Match 'Windows' AND 'ARM'
other_blackberry = /BlackBerry/i,
other_blackberry_10 = /BB10/i,
other_opera = /Opera Mini/i,
other_chrome = /(CriOS|Chrome)(?=.*\bMobile\b)/i,
other_firefox = /(?=.*\bFirefox\b)(?=.*\bMobile\b)/i, // Match 'Firefox' AND 'Mobile'
seven_inch = new RegExp(
'(?:' + // Non-capturing group
'Nexus 7' + // Nexus 7
'|' + // OR
'BNTV250' + // B&N Nook Tablet 7 inch
'|' + // OR
'Kindle Fire' + // Kindle Fire
'|' + // OR
'Silk' + // Kindle Fire, Silk Accelerated
'|' + // OR
'GT-P1000' + // Galaxy Tab 7 inch
')', // End non-capturing group
'i'); // Case-insensitive matching
var match = function (regex, userAgent) {
return regex.test(userAgent);
};
var IsMobileClass = function (userAgent?) {
var obj:any={};
var ua = userAgent || navigator.userAgent;
// Facebook mobile app's integrated browser adds a bunch of strings that
// match everything. Strip it out if it exists.
var tmp = ua.split('[FBAN');
if (typeof tmp[1] !== 'undefined') {
ua = tmp[0];
}
// Twitter mobile app's integrated browser on iPad adds a "Twitter for
// iPhone" string. Same probable happens on other tablet platforms.
// This will confuse detection so strip it out if it exists.
tmp = ua.split('Twitter');
if (typeof tmp[1] !== 'undefined') {
ua = tmp[0];
}
obj.apple = {
phone: match(apple_phone, ua),
ipod: match(apple_ipod, ua),
tablet: !match(apple_phone, ua) && match(apple_tablet, ua),
device: match(apple_phone, ua) || match(apple_ipod, ua) || match(apple_tablet, ua)
};
obj.amazon = {
phone: match(amazon_phone, ua),
tablet: !match(amazon_phone, ua) && match(amazon_tablet, ua),
device: match(amazon_phone, ua) || match(amazon_tablet, ua)
};
obj.android = {
phone: match(amazon_phone, ua) || match(android_phone, ua),
tablet: !match(amazon_phone, ua) && !match(android_phone, ua) && (match(amazon_tablet, ua) || match(android_tablet, ua)),
device: match(amazon_phone, ua) || match(amazon_tablet, ua) || match(android_phone, ua) || match(android_tablet, ua)
};
obj.windows = {
phone: match(windows_phone, ua),
tablet: match(windows_tablet, ua),
device: match(windows_phone, ua) || match(windows_tablet, ua)
};
obj.other = {
blackberry: match(other_blackberry, ua),
blackberry10: match(other_blackberry_10, ua),
opera: match(other_opera, ua),
firefox: match(other_firefox, ua),
chrome: match(other_chrome, ua),
device: match(other_blackberry, ua) || match(other_blackberry_10, ua) || match(other_opera, ua) || match(other_firefox, ua) || match(other_chrome, ua)
};
obj.seven_inch = match(seven_inch, ua);
obj.any = obj.apple.device || obj.android.device || obj.windows.device || obj.other.device || obj.seven_inch;
// excludes 'other' devices and ipods, targeting touchscreen phones
obj.phone = obj.apple.phone || obj.android.phone || obj.windows.phone;
// excludes 7 inch devices, classifying as phone or tablet is left to the user
obj.tablet = obj.apple.tablet || obj.android.tablet || obj.windows.tablet;
// if (typeof window === 'undefined') {
// return this;
// }
return obj
};
export const Device =IsMobileClass()
// import { Rectangle, Matrix } from '../../../math';
import { Bounds, Matrix } from "../../../support";
import { SCALE_MODES } from '../const';
import settings from '../settings';
import { GLFramebuffer,GLTexture } from '../glCore';
import { getStageSize } from "../../../core/context/RenderContextGL"
/**
* @class
*/
export default class RenderTarget {
/**
* The current WebGL drawing context.
* @member {WebGLRenderingContext}
*/
gl: WebGLRenderingContext;
/**
* A frame buffer
*/
frameBuffer: GLFramebuffer;
/**
* The texture
*/
texture: GLTexture;
/**
* The background colour of this render target, as an array of [r,g,b,a] values
*/
clearColor: number[];
/**
* The size of the object as a rectangle
*/
size: Bounds;
/**
* The projection matrix
*/
projectionMatrix: Matrix;
transform: any;
frame: any;
defaultFrame: any;
destinationFrame: any;
sourceFrame: any;
stencilBuffer: any;
stencilMaskStack: any[];
filterData: any;
filterPoolKey: string;
scaleMode: any;
root: any;
/**
* @param {WebGLRenderingContext} gl - The current WebGL drawing context
* @param {number} [width=0] - the horizontal range of the filter
* @param {number} [height=0] - the vertical range of the filter
* @param {number} [scaleMode=settings.SCALE_MODE] - See {@link SCALE_MODES} for possible values
* @param {number} [resolution=1] - The current resolution / device pixel ratio
* @param {boolean} [root=false] - Whether this object is the root element or not
*/
constructor(gl, width, height, scaleMode?, /*resolution,*/ root?) {
// TODO Resolution could go here ( eg low res blurs )
this.gl = gl;
// next time to create a frame buffer and texture
this.frameBuffer = null;
this.texture = null;
this.clearColor = [0, 0, 0, 0];
// this.size = new Rectangle(0, 0, 1, 1);
this.size = new Bounds(0, 0, 1, 1);
/**
* The current resolution / device pixel ratio
*
* @member {number}
* @default 1
*/
// this.resolution = resolution || settings.RESOLUTION;
this.projectionMatrix = new Matrix();
/**
* The object's transform
*
* @member {Matrix}
*/
this.transform = null;
/**
* The frame.
*
* @member {Rectangle}
*/
this.frame = null;
/**
* The stencil buffer stores masking data for the render target
*
* @member {glCore.GLBuffer}
*/
// this.defaultFrame = new Rectangle();
this.defaultFrame = new Bounds();
this.destinationFrame = null;
this.sourceFrame = null;
/**
* The stencil buffer stores masking data for the render target
*
* @member {glCore.GLBuffer}
*/
this.stencilBuffer = null;
/**
* The data structure for the stencil masks
*
* @member {Graphics[]}
*/
this.stencilMaskStack = [];
/**
* Stores filter data for the render target
*
* @member {object[]}
*/
this.filterData = null;
/**
* The key for pooled texture of FilterSystem
* @private
* @member {string}
*/
this.filterPoolKey = '';
/**
* The scale mode.
*
* @member {number}
* @default settings.SCALE_MODE
* @see SCALE_MODES
*/
this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE;
/**
* Whether this object is the root element or not
*
* @member {boolean}
*/
this.root = root;
if (!this.root) {
this.frameBuffer = GLFramebuffer.createRGBA(gl, 100, 100);
if (this.scaleMode === SCALE_MODES.NEAREST) {
this.frameBuffer.texture.enableNearestScaling();
}
else {
this.frameBuffer.texture.enableLinearScaling();
}
/*
A frame buffer needs a target to render to..
create a texture and bind it attach it to the framebuffer..
*/
// this is used by the base texture
this.texture = this.frameBuffer.texture;
}
else {
// make it a null framebuffer..
this.frameBuffer = new GLFramebuffer(gl, 100, 100);
this.frameBuffer.framebuffer = null;
}
this.setFrame();
this.resize(width, height);
}
/**
* Clears the filter texture.
*
* @param {number[]} [clearColor=this.clearColor] - Array of [r,g,b,a] to clear the framebuffer
*/
clear(clearColor) {
const cc = clearColor || this.clearColor;
this.frameBuffer.clear(cc[0], cc[1], cc[2], cc[3]);// r,g,b,a);
}
/**
* Binds the stencil buffer.
*
*/
attachStencilBuffer() {
// TODO check if stencil is done?
/**
* The stencil buffer is used for masking in pixi
* lets create one and then add attach it to the framebuffer..
*/
if (!this.root) {
this.frameBuffer.enableStencil();
}
}
/**
* Sets the frame of the render target.
*
* @param {Rectangle} destinationFrame - The destination frame.
* @param {Rectangle} sourceFrame - The source frame.
*/
setFrame(destinationFrame?, sourceFrame?) {
this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame;
this.sourceFrame = sourceFrame || this.sourceFrame || this.destinationFrame;
}
/**
* Binds the buffers and initialises the viewport.
*
*/
activate() {
// TOOD refactor usage of frame..
const gl = this.gl;
var wh = getStageSize();
this.setFrame(new Bounds(0, 0, wh.width, wh.height))
// make sure the texture is unbound!
this.frameBuffer.bind();
this.calculateProjection(this.destinationFrame, this.sourceFrame);
if (this.transform) {
// this.projectionMatrix.append(this.transform);
}
// TODO add a check as them may be the same!
// if (this.destinationFrame !== this.sourceFrame) {
// gl.enable(gl.SCISSOR_TEST);
// gl.scissor(
// this.destinationFrame.x | 0,
// this.destinationFrame.y | 0,
// (this.destinationFrame.width /* this.resolution*/) | 0,
// (this.destinationFrame.height /* this.resolution*/) | 0
// );
// }
// else {
gl.disable(gl.SCISSOR_TEST);
// }
// var wh = getStageSize();
// TODO - does not need to be updated all the time??
// gl.viewport(
// this.destinationFrame.x | 0,
// this.destinationFrame.y | 0,
// (this.destinationFrame.width /* this.resolution*/) | 0,
// (this.destinationFrame.height /* this.resolution*/) | 0
// );
gl.viewport(
0,
0,
wh.width,
wh.height
);
}
/**
* Updates the projection matrix based on a projection frame (which is a rectangle)
*
* @param {Rectangle} destinationFrame - The destination frame.
* @param {Rectangle} sourceFrame - The source frame.
*/
calculateProjection(destinationFrame, sourceFrame?) {
const pm = this.projectionMatrix;
sourceFrame = sourceFrame || destinationFrame;
pm.identity();
// TODO: make dest scale source
if (!this.root) {
pm.a = 1 / destinationFrame.width * 2;
pm.d = 1 / destinationFrame.height * 2;
pm.tx = -1 - (sourceFrame.x * pm.a);
pm.ty = -1 - (sourceFrame.y * pm.d);
}
else {
pm.a = 1 / destinationFrame.width * 2;
pm.d = -1 / destinationFrame.height * 2;
pm.tx = -1 - (sourceFrame.x * pm.a);
pm.ty = 1 - (sourceFrame.y * pm.d);
}
}
/**
* Resizes the texture to the specified width and height
*
* @param {number} width - the new width of the texture
* @param {number} height - the new height of the texture
*/
resize(width, height) {
width = width | 0;
height = height | 0;
if (this.size.width === width && this.size.height === height) {
return;
}
this.size.width = width;
this.size.height = height;
this.defaultFrame.width = width;
this.defaultFrame.height = height;
this.frameBuffer.resize(width /* this.resolution*/, height /* this.resolution*/);
const projectionFrame = this.frame || this.size;
this.calculateProjection(projectionFrame);
}
/**
* Destroys the render target.
*
*/
destroy() {
this.frameBuffer.destroy();
this.frameBuffer = null;
this.texture = null;
}
}
export default function canUploadSameBuffer() {
// Uploading the same buffer multiple times in a single frame can cause perf issues.
// Apparent on IOS so only check for that at the moment
// this check may become more complex if this issue pops up elsewhere.
const ios = !!navigator.platform && (/iPad|iPhone|iPod/).test(navigator.platform);
return !ios;
}
/**
* Generic Mask Stack data structure
*
* @function createIndicesForQuads
* @private
* @param {number} size - Number of quads
* @return {Uint16Array} indices
*/
export default function createIndicesForQuads(size)
{
// the total number of indices in our array, there are 6 points per quad.
const totalIndices = size * 6;
const indices = new Uint16Array(totalIndices);
// fill the indices with the quads to draw
for (let i = 0, j = 0; i < totalIndices; i += 6, j += 4)
{
indices[i + 0] = j + 0;
indices[i + 1] = j + 1;
indices[i + 2] = j + 2;
indices[i + 3] = j + 0;
indices[i + 4] = j + 2;
indices[i + 5] = j + 3;
}
return indices;
}
import { GLShader } from '../glCore/GLShader';
//顶点着色器程序
const VSHADER_SOURCE =
" precision highp float;" +
"attribute vec2 aVertexPosition;" +
"attribute vec2 aTextureCoord;" +
"attribute vec4 aColor;" +
"attribute float aTextureId;" +
"uniform mat3 projectionMatrix;" +
// "uniform mat3 modelMatrix;" +
"varying vec2 vTextureCoord;" +
"varying vec4 vColor;" +
"varying float vTextureId;" +
"void main(void){" +
"gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);" +
// "gl_Position = vec4((projectionMatrix *modelMatrix* vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);" +
"vTextureCoord = aTextureCoord;" +
"vTextureId = aTextureId;" +
"vColor = aColor;" +
"}";
const fragTemplate = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
'varying vec4 vColor;',
'varying float vTextureId;',
'uniform sampler2D uSamplers[%count%];',
'void main(void){',
'vec4 color;',
'float textureId = floor(vTextureId+0.5);',
'%forloop%',
'gl_FragColor = color * vColor;',
'}',
].join('\n');
export function generateMultiTextureShader(gl, maxTextures) {
// const vertexSrc = readFileSync(join(__dirname, './texture.vert'), 'utf8');
let fragmentSrc = fragTemplate;
fragmentSrc = fragmentSrc.replace(/%count%/gi, maxTextures);
fragmentSrc = fragmentSrc.replace(/%forloop%/gi, generateSampleSrc(maxTextures));
// console.log(fragmentSrc)
const shader = new GLShader(gl, VSHADER_SOURCE, fragmentSrc);
const sampleValues = [];
for (let i = 0; i < maxTextures; i++) {
sampleValues[i] = i;
}
shader.bind();
shader.uniforms["uSamplers"] = sampleValues;
// console.log(fragmentSrc)
return shader;
}
function generateSampleSrc(maxTextures) {
let src = '';
src += '\n';
src += '\n';
for (let i = 0; i < maxTextures; i++) {
if (i > 0) {
src += '\nelse ';
}
if (i < maxTextures - 1) {
src += `if(textureId == ${i}.0)`;
}
src += '\n{';
src += `\n\tcolor = texture2D(uSamplers[${i}], vTextureCoord);`;
src += '\n}';
}
src += '\n';
src += '\n';
return src;
}
/**
* premultiplies tint
*
* @memberof utils
* @param {number} tint integet RGB
* @param {number} alpha floating point alpha (0.0-1.0)
* @returns {number} tint multiplied by alpha
*/
export function premultiplyTint(tint, alpha) {
if (alpha === 1.0) {
return (alpha * 255 << 24) + tint;
}
if (alpha === 0.0) {
return 0;
}
let R = ((tint >> 16) & 0xFF);
let G = ((tint >> 8) & 0xFF);
let B = (tint & 0xFF);
R = ((R * alpha) + 0.5) | 0;
G = ((G * alpha) + 0.5) | 0;
B = ((B * alpha) + 0.5) | 0;
return (alpha * 255 << 24) + (R << 16) + (G << 8) + B;
}
export function nextPow2(v) {
v += v === 0;
--v;
v |= v >>> 1;
v |= v >>> 2;
v |= v >>> 4;
v |= v >>> 8;
v |= v >>> 16;
return v + 1;
}
export function log2(v: number) {
var r, shift;
r = Number(v > 0xFFFF) << 4; v >>>= r;
shift = Number(v > 0xFF) << 3; v >>>= shift; r |= shift;
shift = Number(v > 0xF) << 2; v >>>= shift; r |= shift;
shift = Number(v > 0x3) << 1; v >>>= shift; r |= shift;
return r | (v >> 1);
}
export function isPow2(v) {
return !(v & (v - 1)) && (!!v);
}
/**
* Converts a hex color number to an [R, G, B] array
*
* @memberof utils
* @function hex2rgb
* @param {number} hex - The number to convert
* @param {number[]} [out=[]] If supplied, this array will be used rather than returning a new one
* @return {number[]} An array representing the [R, G, B] of the color.
*/
export function hex2rgb(hex, out?)
{
out = out || [];
out[0] = ((hex >> 16) & 0xFF) / 255;
out[1] = ((hex >> 8) & 0xFF) / 255;
out[2] = (hex & 0xFF) / 255;
return out;
}
\ No newline at end of file
import { BLEND_MODES } from '../const';
/**
* Maps gl blend combinations to WebGL.
*
* @function mapWebGLBlendModesTo
* @private
* @param {WebGLRenderingContext} gl - The rendering context.
* @param {string[]} [array=[]] - The array to output into.
* @return {string[]} Mapped modes.
*/
export default function mapWebGLBlendModesTo(gl, array = [])
{
// TODO - premultiply alpha would be different.
// add a boolean for that!
array[BLEND_MODES.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.ADD] = [gl.ONE, gl.DST_ALPHA];
array[BLEND_MODES.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.SCREEN] = [gl.ONE, gl.ONE_MINUS_SRC_COLOR];
array[BLEND_MODES.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.DARKEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.LIGHTEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.COLOR_DODGE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.COLOR_BURN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.HARD_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.SOFT_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.DIFFERENCE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.EXCLUSION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.HUE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.SATURATION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.COLOR] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.LUMINOSITY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
// not-premultiplied blend modes
array[BLEND_MODES.NORMAL_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
array[BLEND_MODES.ADD_NPM] = [gl.SRC_ALPHA, gl.DST_ALPHA, gl.ONE, gl.DST_ALPHA];
array[BLEND_MODES.SCREEN_NPM] = [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_COLOR, gl.ONE, gl.ONE_MINUS_SRC_COLOR];
return array;
}
import { DRAW_MODES } from '../const';
/**
* Generic Mask Stack data structure.
*
* @memberof PIXI
* @function mapWebGLDrawModesToPixi
* @private
* @param {WebGLRenderingContext} gl - The current WebGL drawing context
* @param {object} [object={}] - The object to map into
* @return {object} The mapped draw modes.
*/
export default function mapWebGLDrawModesTo(gl, object = {})
{
object[DRAW_MODES.POINTS] = gl.POINTS;
object[DRAW_MODES.LINES] = gl.LINES;
object[DRAW_MODES.LINE_LOOP] = gl.LINE_LOOP;
object[DRAW_MODES.LINE_STRIP] = gl.LINE_STRIP;
object[DRAW_MODES.TRIANGLES] = gl.TRIANGLES;
object[DRAW_MODES.TRIANGLE_STRIP] = gl.TRIANGLE_STRIP;
object[DRAW_MODES.TRIANGLE_FAN] = gl.TRIANGLE_FAN;
return object;
}
import {Device} from './Device';
export default function maxRecommendedTextures(max)
{
if (Device.tablet || Device.phone)
{
// check if the res is iphone 6 or higher..
return 4;
}
// desktop should be ok
return max;
}
/**
* Mixins functionality to make an object have "plugins".
*
* @example
* function MyObject() {}
*
* pluginTarget.mixin(MyObject);
*
* @mixin
* @memberof PIXI.utils
* @param {object} obj - The object to mix into.
*/
function pluginTarget(obj)
{
obj.__plugins = {};
/**
* Adds a plugin to an object
*
* @param {string} pluginName - The events that should be listed.
* @param {Function} ctor - The constructor function for the plugin.
*/
obj.registerPlugin = function registerPlugin(pluginName, ctor)
{
obj.__plugins[pluginName] = ctor;
};
/**
* Instantiates all the plugins of this object
*
*/
obj.prototype.initPlugins = function initPlugins()
{
this.plugins = this.plugins || {};
for (const o in obj.__plugins)
{
this.plugins[o] = new (obj.__plugins[o])(this);
}
};
/**
* Removes all the plugins of this object
*
*/
obj.prototype.destroyPlugins = function destroyPlugins()
{
for (const o in this.plugins)
{
this.plugins[o].destroy();
this.plugins[o] = null;
}
this.plugins = null;
};
}
export default {
/**
* Mixes in the properties of the pluginTarget into another object
*
* @param {object} obj - The obj to mix into
*/
mixin: function mixin(obj)
{
pluginTarget(obj);
},
};
/**
* Remove a range of items from an array
*
* @function removeItems
* @param {Array<*>} arr The target array
* @param {number} startIdx The index to begin removing from (inclusive)
* @param {number} removeCount How many items to remove
*/
export default function removeItems(arr, startIdx, removeCount) {
var i, length = arr.length
if (startIdx >= length || removeCount === 0) {
return
}
removeCount = (startIdx + removeCount > length ? length - startIdx : removeCount)
var len = length - removeCount
for (i = startIdx; i < len; ++i) {
arr[i] = arr[i + removeCount]
}
arr.length = len
}
\ No newline at end of file
export default function validateContext(gl)
{
const attributes = gl.getContextAttributes();
// this is going to be fairly simple for now.. but at least we have room to grow!
if (!attributes.stencil)
{
/* eslint-disable no-console */
console.warn('Provided WebGL context does not have a stencil buffer, masks may not render correctly');
/* eslint-enable no-console */
}
}
...@@ -22,7 +22,7 @@ export default class Matrix { ...@@ -22,7 +22,7 @@ export default class Matrix {
d; d;
tx; tx;
ty; ty;
/** /**
* 释放一个Matrix实例到对象池 * 释放一个Matrix实例到对象池
* @param matrix 需要回收的 matrix * @param matrix 需要回收的 matrix
...@@ -181,7 +181,7 @@ export default class Matrix { ...@@ -181,7 +181,7 @@ export default class Matrix {
//angle = angle / DEG_TO_RAD; //angle = angle / DEG_TO_RAD;
let u = Math.cos(radian); let u = Math.cos(radian);
let v = Math.sin(radian); let v = Math.sin(radian);
const {a, b, c, d, tx, ty} = this; const { a, b, c, d, tx, ty } = this;
this.a = a * u - b * v; this.a = a * u - b * v;
this.b = a * v + b * u; this.b = a * v + b * u;
this.c = c * u - d * v; this.c = c * u - d * v;
...@@ -237,7 +237,7 @@ export default class Matrix { ...@@ -237,7 +237,7 @@ export default class Matrix {
* @returns Object 由应用矩阵转换所产生的点。 * @returns Object 由应用矩阵转换所产生的点。
*/ */
transformPoint(pointX, pointY, resultPoint) { transformPoint(pointX, pointY, resultPoint) {
const {a, b, c, d, tx, ty} = this; const { a, b, c, d, tx, ty } = this;
let x = a * pointX + c * pointY + tx; let x = a * pointX + c * pointY + tx;
let y = b * pointX + d * pointY + ty; let y = b * pointX + d * pointY + ty;
if (resultPoint) { if (resultPoint) {
...@@ -245,7 +245,7 @@ export default class Matrix { ...@@ -245,7 +245,7 @@ export default class Matrix {
resultPoint.y = y; resultPoint.y = y;
return resultPoint; return resultPoint;
} }
return {x, y}; return { x, y };
} }
/** /**
...@@ -256,7 +256,7 @@ export default class Matrix { ...@@ -256,7 +256,7 @@ export default class Matrix {
* @param resultPoint 框架建议尽可能减少创建对象次数来优化性能,可以从外部传入一个复用的Point对象来存储结果,若不传入将创建一个新的Point对象返回。 * @param resultPoint 框架建议尽可能减少创建对象次数来优化性能,可以从外部传入一个复用的Point对象来存储结果,若不传入将创建一个新的Point对象返回。
*/ */
deltaTransformPoint(pointX, pointY, resultPoint) { deltaTransformPoint(pointX, pointY, resultPoint) {
const {a, b, c, d} = this; const { a, b, c, d } = this;
let x = a * pointX + c * pointY; let x = a * pointX + c * pointY;
let y = b * pointX + d * pointY; let y = b * pointX + d * pointY;
...@@ -265,7 +265,7 @@ export default class Matrix { ...@@ -265,7 +265,7 @@ export default class Matrix {
resultPoint.y = y; resultPoint.y = y;
return resultPoint; return resultPoint;
} }
return {x, y}; return { x, y };
} }
/** /**
...@@ -554,5 +554,38 @@ export default class Matrix { ...@@ -554,5 +554,38 @@ export default class Matrix {
target.ty = ty; target.ty = ty;
} }
/**
* Creates an array from the current Matrix object.与glsl中的mat3对应,注意行列主序执行transpose;
*
* @param {boolean} transpose - Whether we need to transpose the matrix or not
* @param {Float32Array} [out=new Float32Array(9)] - If provided the array will be assigned to out
* @return {number[]} the newly created array which contains the matrix
*/
public toArray(transpose = false, out?) {
const array = out || new Float32Array(9);
if (transpose) {
array[0] = this.a;
array[1] = this.b;
array[2] = 0;
array[3] = this.c;
array[4] = this.d;
array[5] = 0;
array[6] = this.tx;
array[7] = this.ty;
array[8] = 1;
} else {
array[0] = this.a;
array[1] = this.c;
array[2] = this.tx;
array[3] = this.b;
array[4] = this.d;
array[5] = this.ty;
array[6] = 0;
array[7] = 0;
array[8] = 1;
}
return array;
}
} }
\ No newline at end of file
export declare type color = string;
export declare type resource = any;
export declare type raw = any;
/**
* Created by rockyl on 2018/7/11.
*
* 资源管理
* 加载资源
*/
import { FrameAnimation } from '../core/FrameAnimation';
import { Sheet } from '../core/Sheet';
import { Texture } from "../core";
/**
* 设置资源根路径
* @param path
*/
export declare function setResPath(path: any): void;
/**
* 加载一批资源
* @param items 资源数组: ['aaa.png', {uuid: 'bbb', url: 'alias.png'}]
* @param progress 进度回调,参数为加载百分比
* @return Promise<Array<any>> 资源组
*/
export declare function loadResItems(items: Array<any | string>, progress?: (percentage: number) => void): Promise<Array<any>>;
/**
* 加载任意网络资源
* @param url url
* @param uuid
* @param type 类型(json|text|arraybuffer|blob)
* @param cache
* @param config
* @param options 请求配置
* @return Promise<any> 资源
*/
export declare function loadAny(url: any, uuid?: any, cache?: boolean, config?: any, options?: {}, type?: string): Promise<any>;
/**
* 加载文本资源
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadTxt(url: any, uuid?: any, cache?: boolean, config?: any): Promise<string>;
/**
* 加载json资源
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadJson(url: any, uuid?: any, cache?: boolean, config?: any): Promise<any>;
/**
* 加载json5资源
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadJson5(url: any, uuid?: any, cache?: boolean, config?: any): Promise<any>;
/**
* 加载图集资源
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadSheet(url: any, uuid?: any, cache?: boolean, config?: any): Promise<Sheet>;
/**
* 加载散列的图集
* @param url
* @param uuid
* @param cache
* @param config
*/
export declare function loadSheetDisperse(url: any, uuid?: any, cache?: boolean, config?: any): Promise<Sheet>;
/**
* 加载文图字资源
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadFont(url: any, uuid?: any, cache?: boolean, config?: any): Promise<Sheet>;
/**
* 加载帧动画资源(多个)
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadAnim(url: any, uuid?: any, cache?: boolean, config?: any): Promise<FrameAnimation[]>;
/**
* 加载图片资源
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadImage(url: any, uuid?: any, cache?: boolean, config?: any): Promise<any>;
/**
* 加载blob图片资源
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadImageFromBlob(url: any, uuid?: any, cache?: boolean, config?: any): Promise<any>;
/**
* 加载纹理资源
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadTexture(url: any, uuid?: any, cache?: boolean, config?: any): Promise<Texture>;
/**
* 加载blob纹理资源
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadTextureFromBlob(url: any, uuid?: any, cache?: boolean, config?: any): Promise<Texture>;
/**
* 缓存资源
* @param res
* @param url
* @param uuid
*/
export declare function cacheRes(res: any, url: any, uuid?: any): void;
/**
* 增加加载器
* @param ext 需加载的文件后缀
* @param loader 加载方法,返回携带最终资源的Promise
*/
export declare function addLoader(ext: any, loader: any): void;
/**
* 获取资源
* @param uuid
*/
export declare function getRes(uuid: any): any;
/**
* 销毁资源
* @param uuidOrUuids
*/
export declare function destroyRes(uuidOrUuids: any): void;
/**
* 销毁全部资源
*/
export declare function destroyAllRes(): void;
/**
* 获取所有uuid值
*/
export declare function getAllResUuids(): string[];
/**
* Created by rockyl on 2018/11/5.
*/
import HashObject from "./HashObject";
import { ScillaComponent } from "./ScillaComponent";
/**
* 节点遍历(先序遍历)
* @param target 目标节点
* @param hitChild 遇到子节点回调
* @param level 深度,默认全部遍历
* @param includeSelf 是否包括自身
* @param fullCallback 子节点遍历完后回调
* @param params 其他参数
*/
export declare function traverse(target: Entity, hitChild: (child: Entity, ...params: any[]) => boolean, level?: number, includeSelf?: boolean, fullCallback?: (current: Entity) => void, ...params: any[]): void;
/**
* 节点遍历(后序遍历且倒序)
* @param target 目标节点
* @param hitChild 遇到子节点回调
* @param level 深度,默认全部遍历
* @param includeSelf 是否包括自身
* @param fullCallback 子节点遍历完后回调
* @param params 其他参数
*/
export declare function traversePostorder(target: Entity, hitChild: (child: Entity, ...params: any[]) => boolean, level?: number, includeSelf?: boolean, fullCallback?: (current: Entity) => void, ...params: any[]): boolean;
/**
* 节点冒泡
* @param target 目标节点
* @param hitParent 遇到父节点回调
* @param includeSelf 是否包括自身
* @param params 其他参数
*/
export declare function bubbling(target: Entity, hitParent: (parent: Entity, ...params: any[]) => boolean, includeSelf?: boolean, ...params: any[]): void;
/**
* 实体类
* 实体类只是单纯的父子节点逻辑,不含有其他逻辑
*/
export declare class Entity extends HashObject {
name: string;
protected _uuid: string;
protected _isFree: boolean;
protected _enabled: boolean;
protected _parent: Entity;
protected _children: Entity[];
protected _components: ScillaComponent[];
constructor(name?: any, uuid?: any);
readonly uuid: string;
/**
* 是否有效状态
*/
enabled: boolean;
_invokeEnabledState(enabled: any): void;
readonly isParentActive: boolean;
readonly isActive: boolean;
/**
* 是否游离状态
*/
readonly isFree: boolean;
/**
* 使游离
*/
_free(): void;
/**
* 使约束
*/
_restrict(): void;
/**
* 获取父节点
*/
readonly parent: Entity;
/**
* 是否含有子节点
* @param child
*/
containsChild(child: Entity): boolean;
/**
* 添加子节点时
* @param child
* @private
*/
protected _onChildAdded(child: Entity): void;
/**
* 子节点被移除时
* @param child
* @private
*/
_onChildRemoved(child: Entity): void;
/**
* 添加子节点,重复添加则会加到最后
* @param child
*/
addChild(child: Entity): void;
/**
* 添加子节点到指定索引,重复添加可作为顺序交换
* @param child
* @param index
*/
addChildAt(child: Entity, index: any): void;
/**
* 移除节点
* @param child
*/
removeChild(child: Entity): void;
/**
* 移除指定索引的节点
* @param index
*/
removeChildAt(index: any): void;
/**
* 根据节点获取索引
* @param child
*/
getChildIndex(child: Entity): number;
/**
* 获取指定索引的节点
* @param index
*/
getChildByIndex(index: any): Entity;
/**
* 移除所有子节点
*/
removeChildren(): void;
/**
* 获取所有子节点
*/
readonly children: Entity[];
/**
* 增加组件
* @param component
*/
addComponent(component: ScillaComponent): void;
/**
* 在指定索引增加组件,重复添加可作为顺序交换
* @param component
* @param index
*/
addComponentAt(component: ScillaComponent, index: any): void;
/**
* 移除组件
* @param component
*/
removeComponent(component: ScillaComponent): void;
/**
* 移除所有组件
*/
removeAllComponents(): void;
/**
* 获取指定类的组件列表
* @param clazz
*/
getComponents(clazz: any): any[];
/**
* 获取指定类的组件
* @param clazz
*/
getComponent(clazz: any): any;
/**
* 获取所有组件
*/
readonly components: ScillaComponent[];
/**
* 遍历所有组件
* @param func
*/
forEachComponent(func: (component: any) => boolean): void;
/**
* 当组件生效时
*/
onEnable(): void;
/**
* 当组件失效时
*/
onDisable(): void;
/**
* 当始终更新时
* @param t
*/
onUpdate(t: any): void;
/**
* 当子节点遍历结束后
*/
afterUpdate(): void;
/**
* 当交互时
* @param type
* @param event
*/
onInteract(type: any, event: any): boolean;
/**
* 当添加组件时
* @param component
*/
onAddComponent(component: ScillaComponent): void;
/**
* 唤醒组件
* @param component
*/
awakeComponent(component: any): void;
/**
* 当移除组件时
* @param component
*/
onRemoveComponent(component: ScillaComponent): void;
/**
* 睡眠组件
* @param component
*/
sleepComponent(component: any): void;
/**
* 向下广播
* 如果某组件调用后返回true,将结束整条链
* @param method 方法名
* @param level 深度,默认全部遍历
* @param params 参数
*/
broadcast(method: any, level?: number, ...params: any[]): void;
/**
* 向上冒泡
* 如果某组件调用后返回true,将结束整条链
* @param method 方法名
* @param params 参数
*/
bubbling(method: any, ...params: any[]): void;
/**
* 调用实体上的组件的方法
* @param hitEntity 遇到的实体
* @param method 方法名
* @param params 参数
*/
private invokeOnEntity;
}
/**
* Created by rockyl on 2018-11-30.
*/
/**
* 获取一个帧动画资源
* @param name
*/
export declare function getFrameAnimation(name: any): FrameAnimation;
/**
* 放置帧动画图片和数据
* @param img
* @param data
*/
export declare function putFrameAnim(img: any, data: any): void;
/**
* 帧动画资源
*/
export interface FrameAnimation {
/**
* 填充帧数据
* @param name
*/
fillMcData(name: any): any;
/**
* 获取帧率
*/
readonly fps: number;
/**
* 获取所有帧标签
*/
readonly labels: any[];
/**
* 获取帧数
*/
readonly frameCount: number;
/**
* 根据名字获取帧标签
* @param name
*/
getLabel(name: any): any;
/**
* 获取帧
* @param frameIndex
*/
getFrame(frameIndex: any): any;
/**
* 销毁自身
*/
destroy(): any;
}
/**
* 帧动画资源实现
*/
export declare class FrameAnimationImpl implements FrameAnimation {
private readonly _name;
private _animData;
constructor(name: any);
readonly name: string;
fillMcData(name: any): void;
readonly fps: number;
readonly labels: any[];
readonly frameCount: number;
getLabel(name: any): any;
getFrame(frameIndex: any): any;
destroy(): void;
}
/**
* Created by rockyl on 2018/11/5.
*/
/**
* 哈希对象
*/
export default class HashObject {
_hashCode: any;
constructor();
readonly hashCode: any;
}
/**
* Created by rockyl on 2018-12-03.
*/
import { Entity } from "./Entity";
export declare class Scene {
name: string;
root: Entity;
resourceGroups: any;
config: any;
initByConfig(config: any): void;
loadResGroup(name: any, progress?: any): Promise<void>;
}
/**
* Created by rockyl on 2018/11/5.
*/
import HashObject from "./HashObject";
import { Entity } from "./Entity";
/**
* 组件基类
*/
export declare class ScillaComponent extends HashObject {
/**
* 所依附的实体
*/
entity: Entity;
protected delayCallbacks: any[];
private _firstUpdate;
protected _enabled: boolean;
/**
* 是否有效状态
*/
enabled: boolean;
/**
* 装配实体
* @param entity
*/
_setup(entity: Entity): void;
/**
* 卸载实体
*/
_unSetup(): void;
/**
* 当组件被创建时
*/
onCreate(): void;
/**
* 当组件被唤醒时
*/
onAwake(): void;
/**
* 当组件生效时
*/
onEnable(): void;
/**
* 当组件失效时
*/
onDisable(): void;
$onUpdate(t: any): void;
private invokeDelayCallback;
/**
* 当时钟更新时
* @param t 从引擎开始到当前的毫秒数
*/
onUpdate(t: any): void;
/**
* 当子节点的时钟更新结束后
*/
afterUpdate(): void;
/**
* 当组件沉睡时
*/
onSleep(): void;
/**
* 当组件被销毁时
*/
onDestroy(): void;
/**
* 当被监听的属性被修改时
* @param value
* @param key
* @param oldValue
*/
protected onModify(value: any, key: any, oldValue: any): void;
private getDelayCallback;
/**
* 执行延迟回调
* @param callback
* @param once 是否只执行一次
*/
callOnNextTick(callback: any, once?: boolean): void;
cancelOnNextTick(callback: any): void;
/**
* 当交互时
* @param type
* @param event
*/
onInteract(type: any, event: any): any;
_dealGlobalTouchBegin(e: any): void;
_dealGlobalTouchMove(e: any): void;
_dealGlobalTouchEnd(e: any): void;
/**
* 当全局触摸开始
* @param e
*/
onGlobalTouchBegin(e: any): void;
/**
* 当全触摸移动
* @param e
*/
onGlobalTouchMove(e: any): void;
/**
* 当全触摸结束
* @param e
*/
onGlobalTouchEnd(e: any): void;
readonly transform: any;
/**
* 向下广播
* 如果某组件调用后返回true,将结束整条链
* @param method 方法名
* @param level 深度,默认全部遍历
* @param params 参数
*/
broadcast(method: any, level?: number, ...params: any[]): void;
/**
* 向上冒泡
* 如果某组件调用后返回true,将结束整条链
* @param method 方法名
* @param params 参数
*/
bubbling(method: any, ...params: any[]): void;
}
/**
* Created by rockyl on 2018-11-27.
*/
/**
* 单一事件类
* 一对多形式的订阅分发机制
*/
export declare class ScillaEvent {
private _subscribers;
constructor();
private findListener;
/**
* 添加侦听
* @param callback
* @param thisObj
* @param priority
* @param params
*/
addListener(callback: any, thisObj?: any, priority?: number, ...params: any[]): void;
/**
* 添加单次侦听
* @param callback
* @param thisObj
* @param priority
* @param params
*/
once(callback: any, thisObj?: any, priority?: number, ...params: any[]): void;
/**
* 移除侦听
* @param callback
*/
removeListener(callback: any): void;
/**
* 是否已经侦听
* @param callback
*/
hasListener(callback: any): boolean;
/**
* 调用派发
* @param paramsNew
*/
invoke(...paramsNew: any[]): void;
}
/**
* Created by rockyl on 2018-11-30.
*/
import HashObject from "../core/HashObject";
/**
* 图集
*/
export declare class Sheet extends HashObject {
/**
* 图集原图
*/
img: any;
/**
* 图集分割配置
*/
frames: any;
private _textureCache;
constructor(img?: any, frames?: any);
/**
* 生成全部纹理
*/
generateAll(): void;
/**
* 生成一个纹理
* @param name
* @param force
*/
generateTexture(name: any, force?: boolean): any;
/**
* 是否有这个纹理
* @param name
*/
hasTexture(name: any): boolean;
/**
* 获取纹理
* @param name
*/
getTexture(name: any): any;
/**
* 获取全部存在的纹理
*/
getAllTextures(): any;
/**
* 销毁自身
*/
destroy(): void;
}
/**
* Created by rockyl on 2018/7/12.
*/
import Bounds from "../support/Bounds";
import HashObject from "../core/HashObject";
/**
* 纹理类
*/
export default class Texture extends HashObject {
img: any;
bounds: Bounds;
_cacheCanvas: any;
constructor();
/**
* 原图img上的纹理坐标,归一处理,左上角顺时针开始
*/
uvs: number[];
/**
* 设置图集中的坐标和尺寸
* @param frame
*/
setFrame(frame: any): void;
/**
* 设置图片
* @param img
*/
setImg(img: any): void;
/**
* 获取纹理宽度
*/
readonly width: any;
/**
* 获取纹理高度
*/
readonly height: any;
/**
* 产生一个缓存画布
*/
getCacheCanvas(): any;
/**
* 绘制到一个画布上
* @param context
* @param dx
* @param dy
* @param sx
* @param sy
* @param dw
* @param dh
*/
drawToCanvas(context: any, dx?: number, dy?: number, sx?: any, sy?: any, dw?: any, dh?: any): void;
/**
* 销毁自身
*/
destroy(): void;
/**
* 销毁缓存画布
*/
destroyCacheCanvas(): void;
}
/**
* 快捷创建纹理
* @param img
* @param frame
*/
export declare function createTexture(img: any, frame?: any): Texture;
/**
* Created by rockyl on 2018/11/7.
*
* 交互上下文
*/
/**
* 装配上下文
* @param options
*/
export declare function setupContext(options?: any): void;
/**
* 更新缩放模式
* @param scaleX
* @param scaleY
* @param rotation
*/
export declare function updateScaleMode(scaleX: any, scaleY: any, rotation: any): void;
/**
* 页面坐标转画布坐标
* @param pageX
* @param pageY
* @param identifier
* @param isLocalPos
*/
export declare function pagePosToCanvasPos(pageX: any, pageY: any, identifier?: any, isLocalPos?: boolean): {
x: number;
y: number;
identifier: any;
};
/**
* 画布坐标转页面坐标
* @param x
* @param y
*/
export declare function canvasPosToPagePos(x: any, y: any): {
x: any;
y: any;
};
/**
* Created by rockyl on 2018/11/5.
*
* 渲染上下文
*/
import Bounds from "../../support/Bounds";
/**
* 缩放模式
*
* SHOW_ALL: 全可见
* FIXED_WIDTH: 宽度固定
* FIXED_HEIGHT: 高度固定
*/
export declare const ScaleMode: {
SHOW_ALL: string;
FIXED_WIDTH: string;
FIXED_HEIGHT: string;
};
/**
* 装配上下文
* @param options
*/
export declare function setupContext(options?: any): void;
/**
* 清空渲染上下文
*/
export declare function clear(): void;
/**
* 获取渲染上下文
*/
export declare function getContext(): any;
/**
* 获取舞台尺寸
*/
export declare function getStageSize(): {
width: any;
height: any;
};
/**
* 获取舞台缩放
*/
export declare function getStageScale(): {
x: any;
y: any;
};
/**
* 获取舞台中心
*/
export declare function getStageCenter(): {
x: number;
y: number;
};
/**
* 创建canvas
*/
export declare function createCanvas(): HTMLCanvasElement;
interface ShortcutParams {
imgType: string;
zoomToDom?: boolean;
quality?: number;
bounds?: Bounds;
}
/**
* 截图
* @param type 目标格式 0:Image, 1:DataURL
* @param params
*/
export declare function shortcut(type: number, params: ShortcutParams): Promise<any>;
export {};
/**
* Created by rockyl on 2018/11/5.
*
* 渲染上下文
*/
import Bounds from "../../support/Bounds";
/**
* 缩放模式
*
* SHOW_ALL: 全可见
* FIXED_WIDTH: 宽度固定
* FIXED_HEIGHT: 高度固定
*/
export declare const ScaleMode: {
SHOW_ALL: string;
FIXED_WIDTH: string;
FIXED_HEIGHT: string;
};
/**
* 装配上下文
* @param options
*/
export declare function setupContext(options?: any): void;
/**
* 获取渲染模式
*/
export declare function getRenderStyle(): string;
/**
* 清空渲染上下文
*/
export declare function clear(): void;
/**
* 获取渲染上下文
*/
export declare function getContext(): any;
/**
* 获取舞台尺寸
*/
export declare function getStageSize(): {
width: any;
height: any;
};
/**
* 获取舞台缩放
*/
export declare function getStageScale(): {
x: any;
y: any;
};
/**
* 获取舞台中心
*/
export declare function getStageCenter(): {
x: number;
y: number;
};
/**
* 创建canvas
*/
export declare function createCanvas(): HTMLCanvasElement;
interface ShortcutParams {
imgType: string;
zoomToDom?: boolean;
quality?: number;
bounds?: Bounds;
}
/**
* 截图
* @param type 目标格式 0:Image, 1:DataURL
* @param params
*/
export declare function shortcut(type: number, params: ShortcutParams): Promise<any>;
export {};
/**
* Created by rockyl on 2018/11/5.
*/
export { ScillaComponent } from "./ScillaComponent";
export { Entity } from './Entity';
export { Scene } from './Scene';
export { ScillaEvent } from './ScillaEvent';
export { getContext, getRenderStyle, createCanvas, getStageSize, getStageScale, getStageCenter, shortcut } from './context/RenderContextGL';
export { pagePosToCanvasPos, canvasPosToPagePos } from './context/InteractContext';
export * from './manager';
export { default as Texture, createTexture } from './Texture';
export * from './Sheet';
export * from './FrameAnimation';
export { default as WebGLRenderer } from "./webgl/WebGLRenderer";
/**
* Created by rockyl on 2018/11/23.
*/
import { Entity } from "./Entity";
import './requestAnimationFrame';
/**
* 装配引擎
* @param _options
*/
export declare function setup(_options?: any): void;
/**
* 开始引擎
*/
export declare function start(): void;
/**
* 暂停引擎
*/
export declare function pause(): void;
/**
* 获取根Entity
*/
export declare function getRoot(): Entity;
/**
* 获取节点路径
* @param entity
*/
export declare function getEntityPath(entity?: Entity): string;
/**
* 根据节点路径获取节点
* @param path
*/
export declare function getEntityByPath(path?: string): Entity;
/**
* 获取当前帧率
*/
export declare function getFPS(): number;
export declare function nextTick(func: any): void;
/**
* Created by Administrator on 2017/7/12.
*/
declare var lastTime: number;
declare var vendors: string[];
/**
* Base for a common object renderer that can be used as a system renderer plugin.
*
* @class
*/
export default class ObjectRenderer {
renderer: any;
constructor(renderer: any);
/**
* Starts the renderer and sets the shader
*
*/
start(): void;
/**
* Stops the renderer
*
*/
stop(): void;
/**
* Stub method for rendering content and emptying the current batch.
*
*/
flush(): void;
/**
* Renders an object
*
* @param {DisplayObject} object - The object to render.
*/
render(object: any): void;
}
import { VertexArrayObject } from "./glCore";
import MaskManager from './managers/MaskManager';
import StencilManager from './managers/StencilManager';
import RenderTarget from './utils/RenderTarget';
import ObjectRenderer from './ObjectRenderer';
import TextureGarbageCollector from './managers/TextureGarbageCollector';
import WebGLState from './WebGLState';
/**
* The WebGLRenderer draws the scene and all its content onto a webGL enabled canvas. This renderer
* should be used for browsers that support webGL. This Render works by automatically managing webGLBatchs.
* So no need for Sprite Batches or Sprite Clouds.
* Don't forget to add the view to your DOM or you will not see anything :)
*
* @class
* @memberof PIXI
* @extends SystemRenderer
*/
export default class WebGLRenderer {
gl: any;
type: number;
_backgroundColorRgba: number[];
maskManager: MaskManager;
stencilManager: StencilManager;
emptyRenderer: ObjectRenderer;
currentRenderer: any;
textureManager: any;
filterManager: any;
CONTEXT_UID: number;
state: WebGLState;
renderingToScreen: boolean;
boundTextures: any;
_activeShader: any;
_activeVao: any;
_activeRenderTarget: any;
drawModes: {};
_nextTextureLocation: number;
emptyTextures: any[];
textureGC: TextureGarbageCollector;
rootRenderTarget: RenderTarget;
uid: number;
private static instance;
static readonly ins: WebGLRenderer;
constructor();
/**
* Creates the WebGL context
*
* @private
*/
_initContext(): void;
preRender(): void;
/**
* Renders the object to its webGL view
*
* @param {DisplayObject} displayObject - the object to be rendered
* @param {RenderTexture} renderTexture - The render texture to render to.
* @param {boolean} [clear] - Should the canvas be cleared before the new render
* @param {Matrix} [transform] - A transform to apply to the render texture before rendering.
* @param {boolean} [skipUpdateTransform] - Should we skip the update transform pass?
*/
render(displayObject: any, renderTexture?: any, clear?: any, transform?: any, skipUpdateTransform?: any): void;
postRender(): void;
/**
* Changes the current renderer to the one given in parameter
*
* @param {ObjectRenderer} objectRenderer - The object renderer to use.
*/
setObjectRenderer(objectRenderer: any): void;
/**
* This should be called if you wish to do some custom rendering
* It will basically render anything that may be batched up such as sprites
*
*/
flush(): void;
/**
* Resizes the webGL view to the specified width and height.
*
* @param {number} screenWidth - the new width of the screen
* @param {number} screenHeight - the new height of the screen
*/
resize(screenWidth: any, screenHeight: any): void;
/**
* Resizes the webGL view to the specified width and height.
*
* @param {number} blendMode - the desired blend mode
*/
setBlendMode(blendMode: any): void;
/**
* Erases the active render target and fills the drawing area with a colour
*
* @param {number} [clearColor] - The colour
*/
clear(clearColor: any): void;
/**
* Sets the transform of the active render target to the given matrix
*
* @param {Matrix} matrix - The transformation matrix
*/
setTransform(matrix: any): void;
/**
* Erases the render texture and fills the drawing area with a colour
*
* @param {RenderTexture} renderTexture - The render texture to clear
* @param {number} [clearColor] - The colour
* @return {WebGLRenderer} Returns itself.
*/
clearRenderTexture(renderTexture: any, clearColor: any): this;
/**
* Binds a render texture for rendering
*
* @param {RenderTexture} renderTexture - The render texture to render
* @param {Matrix} transform - The transform to be applied to the render texture
* @return {WebGLRenderer} Returns itself.
*/
bindRenderTexture(renderTexture?: any, transform?: any): this;
/**
* Changes the current render target to the one given in parameter
*
* @param {RenderTarget} renderTarget - the new render target
* @return {WebGLRenderer} Returns itself.
*/
bindRenderTarget(renderTarget: any): this;
/**
* Changes the current shader to the one given in parameter
*
* @param {Shader} shader - the new shader
* @param {boolean} [autoProject=true] - Whether automatically set the projection matrix
* @return {WebGLRenderer} Returns itself.
*/
bindShader(shader: any, autoProject: any): this;
/**
* Binds the texture. This will return the location of the bound texture.
* It may not be the same as the one you pass in. This is due to optimisation that prevents
* needless binding of textures. For example if the texture is already bound it will return the
* current location of the texture instead of the one provided. To bypass this use force location
*
* @param {Texture} texture - the new texture 为image标签先
* @param {number} location - the suggested texture location
* @param {boolean} forceLocation - force the location
* @return {number} bound texture location
*/
bindTexture(texture: any, location: any, forceLocation?: any): any;
/**
* unbinds the texture ...
*
* @param {Texture} texture - the texture to unbind
* @return {WebGLRenderer} Returns itself.
*/
unbindTexture(texture: any): this;
/**
* Creates a new VAO from this renderer's context and state.
*
* @return {VertexArrayObject} The new VAO.
*/
createVao(): VertexArrayObject;
/**
* Changes the current Vao to the one given in parameter
*
* @param {VertexArrayObject} vao - the new Vao
* @return {WebGLRenderer} Returns itself.
*/
bindVao(vao?: any): this;
/**
* Resets the WebGL state so you can render things however you fancy!
*
* @return {WebGLRenderer} Returns itself.
*/
reset(): this;
/**
* Handles a lost webgl context
*
* @private
* @param {WebGLContextEvent} event - The context lost event.
*/
handleContextLost(event: any): void;
/**
* Handles a restored webgl context
*
* @private
*/
handleContextRestored(): void;
/**
* Removes everything from the renderer (event listeners, spritebatch, etc...)
*
* @param {boolean} [removeView=false] - Removes the Canvas element from the DOM.
* See: https://github.com/pixijs/js/issues/2233
*/
destroy(removeView: any): void;
}
/**
* A WebGL state machines
*
* @memberof PIXI
* @class
*/
export default class WebGLState {
activeState: Uint8Array;
defaultState: Uint8Array;
stackIndex: number;
stack: any[];
gl: any;
maxAttribs: any;
attribState: {
tempAttribState: any[];
attribState: any[];
};
blendModes: any[];
nativeVaoExtension: any;
/**
* @param {WebGLRenderingContext} gl - The current WebGL rendering context
*/
constructor(gl: any);
/**
* Pushes a new active state
*/
push(): void;
/**
* Pops a state out
*/
pop(): void;
/**
* Sets the current state
*
* @param {*} state - The state to set.
*/
setState(state: any): void;
/**
* Enables or disabled blending.
*
* @param {boolean} value - Turn on or off webgl blending.
*/
setBlend(value: any): void;
/**
* Sets the blend mode.
*
* @param {number} value - The blend mode to set to.
*/
setBlendMode(value: any): void;
/**
* Sets whether to enable or disable depth test.
*
* @param {boolean} value - Turn on or off webgl depth testing.
*/
setDepthTest(value: any): void;
/**
* Sets whether to enable or disable cull face.
*
* @param {boolean} value - Turn on or off webgl cull face.
*/
setCullFace(value: any): void;
/**
* Sets the gl front face.
*
* @param {boolean} value - true is clockwise and false is counter-clockwise
*/
setFrontFace(value: any): void;
/**
* Disables all the vaos in use
*
*/
resetAttributes(): void;
/**
* Resets all the logic and disables the vaos
*/
resetToDefault(): void;
}
/**
* Two Pi.
*
* @static
* @constant
* @memberof PIXI
* @type {number}
*/
export declare const PI_2: number;
/**
* Conversion factor for converting radians to degrees.
*
* @static
* @constant
* @memberof PIXI
* @type {number}
*/
export declare const RAD_TO_DEG: number;
/**
* Conversion factor for converting degrees to radians.
*
* @static
* @constant
* @memberof PIXI
* @type {number}
*/
export declare const DEG_TO_RAD: number;
/**
* Constant to identify the Renderer Type.
*
* @static
* @constant
* @memberof PIXI
* @name RENDERER_TYPE
* @type {object}
* @property {number} UNKNOWN - Unknown render type.
* @property {number} WEBGL - WebGL render type.
* @property {number} CANVAS - Canvas render type.
*/
export declare const RENDERER_TYPE: {
UNKNOWN: number;
WEBGL: number;
CANVAS: number;
};
/**
* Various blend modes supported by
*
* IMPORTANT - The WebGL renderer only supports the NORMAL, ADD, MULTIPLY and SCREEN blend modes.
* Anything else will silently act like NORMAL.
*
* @static
* @constant
* @memberof PIXI
* @name BLEND_MODES
* @type {object}
* @property {number} NORMAL
* @property {number} ADD
* @property {number} MULTIPLY
* @property {number} SCREEN
* @property {number} OVERLAY
* @property {number} DARKEN
* @property {number} LIGHTEN
* @property {number} COLOR_DODGE
* @property {number} COLOR_BURN
* @property {number} HARD_LIGHT
* @property {number} SOFT_LIGHT
* @property {number} DIFFERENCE
* @property {number} EXCLUSION
* @property {number} HUE
* @property {number} SATURATION
* @property {number} COLOR
* @property {number} LUMINOSITY
*/
export declare const BLEND_MODES: {
NORMAL: number;
ADD: number;
MULTIPLY: number;
SCREEN: number;
OVERLAY: number;
DARKEN: number;
LIGHTEN: number;
COLOR_DODGE: number;
COLOR_BURN: number;
HARD_LIGHT: number;
SOFT_LIGHT: number;
DIFFERENCE: number;
EXCLUSION: number;
HUE: number;
SATURATION: number;
COLOR: number;
LUMINOSITY: number;
NORMAL_NPM: number;
ADD_NPM: number;
SCREEN_NPM: number;
};
/**
* Various webgl draw modes. These can be used to specify which GL drawMode to use
* under certain situations and renderers.
*
* @static
* @constant
* @memberof PIXI
* @name DRAW_MODES
* @type {object}
* @property {number} POINTS
* @property {number} LINES
* @property {number} LINE_LOOP
* @property {number} LINE_STRIP
* @property {number} TRIANGLES
* @property {number} TRIANGLE_STRIP
* @property {number} TRIANGLE_FAN
*/
export declare const DRAW_MODES: {
POINTS: number;
LINES: number;
LINE_LOOP: number;
LINE_STRIP: number;
TRIANGLES: number;
TRIANGLE_STRIP: number;
TRIANGLE_FAN: number;
};
/**
* The scale modes that are supported by
*
* The {@link settings.SCALE_MODE} scale mode affects the default scaling mode of future operations.
* It can be re-assigned to either LINEAR or NEAREST, depending upon suitability.
*
* @static
* @constant
* @memberof PIXI
* @name SCALE_MODES
* @type {object}
* @property {number} LINEAR Smooth scaling
* @property {number} NEAREST Pixelating scaling
*/
export declare const SCALE_MODES: {
LINEAR: number;
NEAREST: number;
};
/**
* The wrap modes that are supported by
*
* The {@link settings.WRAP_MODE} wrap mode affects the default wrapping mode of future operations.
* It can be re-assigned to either CLAMP or REPEAT, depending upon suitability.
* If the texture is non power of two then clamp will be used regardless as webGL can
* only use REPEAT if the texture is po2.
*
* This property only affects WebGL.
*
* @static
* @constant
* @name WRAP_MODES
* @memberof PIXI
* @type {object}
* @property {number} CLAMP - The textures uvs are clamped
* @property {number} REPEAT - The texture uvs tile and repeat
* @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring
*/
export declare const WRAP_MODES: {
CLAMP: number;
REPEAT: number;
MIRRORED_REPEAT: number;
};
/**
* The gc modes that are supported by
*
* The {@link settings.GC_MODE} Garbage Collection mode for PixiJS textures is AUTO
* If set to GC_MODE, the renderer will occasionally check textures usage. If they are not
* used for a specified period of time they will be removed from the GPU. They will of course
* be uploaded again when they are required. This is a silent behind the scenes process that
* should ensure that the GPU does not get filled up.
*
* Handy for mobile devices!
* This property only affects WebGL.
*
* @static
* @constant
* @name GC_MODES
* @memberof PIXI
* @type {object}
* @property {number} AUTO - Garbage collection will happen periodically automatically
* @property {number} MANUAL - Garbage collection will need to be called manually
*/
export declare const GC_MODES: {
AUTO: number;
MANUAL: number;
};
/**
* Regexp for image type by extension.
*
* @static
* @constant
* @memberof PIXI
* @type {RegExp|string}
* @example `image.png`
*/
export declare const URL_FILE_EXTENSION: RegExp;
/**
* Regexp for data URI.
* Based on: {@link https://github.com/ragingwind/data-uri-regex}
*
* @static
* @constant
* @name DATA_URI
* @memberof PIXI
* @type {RegExp|string}
* @example data:image/png;base64
*/
export declare const DATA_URI: RegExp;
/**
* Regexp for SVG size.
*
* @static
* @constant
* @name SVG_SIZE
* @memberof PIXI
* @type {RegExp|string}
* @example &lt;svg width="100" height="100"&gt;&lt;/svg&gt;
*/
export declare const SVG_SIZE: RegExp;
/**
* Constants that identify shapes, mainly to prevent `instanceof` calls.
*
* @static
* @constant
* @name SHAPES
* @memberof PIXI
* @type {object}
* @property {number} POLY Polygon
* @property {number} RECT Rectangle
* @property {number} CIRC Circle
* @property {number} ELIP Ellipse
* @property {number} RREC Rounded Rectangle
*/
export declare const SHAPES: {
POLY: number;
RECT: number;
CIRC: number;
ELIP: number;
RREC: number;
};
/**
* Constants that specify float precision in shaders.
*
* @static
* @constant
* @name PRECISION
* @memberof PIXI
* @type {object}
* @property {string} LOW='lowp'
* @property {string} MEDIUM='mediump'
* @property {string} HIGH='highp'
*/
export declare const PRECISION: {
LOW: string;
MEDIUM: string;
HIGH: string;
};
/**
* Constants that specify the transform type.
*
* @static
* @constant
* @name TRANSFORM_MODE
* @memberof PIXI
* @type {object}
* @property {number} STATIC
* @property {number} DYNAMIC
*/
export declare const TRANSFORM_MODE: {
STATIC: number;
DYNAMIC: number;
};
/**
* Constants that define the type of gradient on text.
*
* @static
* @constant
* @name TEXT_GRADIENT
* @memberof PIXI
* @type {object}
* @property {number} LINEAR_VERTICAL Vertical gradient
* @property {number} LINEAR_HORIZONTAL Linear gradient
*/
export declare const TEXT_GRADIENT: {
LINEAR_VERTICAL: number;
LINEAR_HORIZONTAL: number;
};
/**
* Represents the update priorities used by internal PIXI classes when registered with
* the {@link ticker.Ticker} object. Higher priority items are updated first and lower
* priority items, such as render, should go later.
*
* @static
* @constant
* @name UPDATE_PRIORITY
* @memberof PIXI
* @type {object}
* @property {number} INTERACTION=50 Highest priority, used for {@link interaction.InteractionManager}
* @property {number} HIGH=25 High priority updating, {@link VideoBaseTexture} and {@link extras.AnimatedSprite}
* @property {number} NORMAL=0 Default priority for ticker events, see {@link ticker.Ticker#add}.
* @property {number} LOW=-25 Low priority used for {@link Application} rendering.
* @property {number} UTILITY=-50 Lowest priority used for {@link prepare.BasePrepare} utility.
*/
export declare const UPDATE_PRIORITY: {
INTERACTION: number;
HIGH: number;
NORMAL: number;
LOW: number;
UTILITY: number;
};
export declare class BatchBuffer {
vertices: ArrayBuffer;
float32View: Float32Array;
uint32View: Uint32Array;
positions: any;
uvs: any;
colors: any;
/**
* @param {number} size - The size of the buffer in bytes.
*/
constructor(size: any);
/**
* Destroys the buffer.
*
*/
destroy(): void;
}
/**
* Helper class to create a webGL buffer
*
* @class
* @memberof glCore
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param type {gl.ARRAY_BUFFER | gl.ELEMENT_ARRAY_BUFFER} @mat
* @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
* @param drawType {gl.STATIC_DRAW|gl.DYNAMIC_DRAW|gl.STREAM_DRAW}
*/
export declare class GLBuffer {
gl: any;
buffer: any;
type: any;
drawType: any;
data: ArrayBuffer;
_updateID: number;
constructor(gl: any, type?: any, data?: any, drawType?: any);
/**
* Uploads the buffer to the GPU
* @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data to upload
* @param offset {Number} if only a subset of the data should be uploaded, this is the amount of data to subtract
* @param dontBind {Boolean} whether to bind the buffer before uploading it
*/
upload(data: any, offset?: any, dontBind?: any): void;
/**
* Binds the buffer
*
*/
bind(): void;
/**
* Destroys the buffer
*
*/
destroy: () => void;
static createVertexBuffer(gl: any, data?: any, drawType?: any): GLBuffer;
static createIndexBuffer(gl: any, data?: any, drawType?: any): GLBuffer;
static create(gl: any, type: any, data: any, drawType: any): GLBuffer;
}
/**
* Helper class to create a webGL Framebuffer
*
* @class
* @memberof glCore
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param width {Number} the width of the drawing area of the frame buffer
* @param height {Number} the height of the drawing area of the frame buffer
*/
export declare class GLFramebuffer {
gl: any;
framebuffer: any;
stencil: any;
texture: any;
width: any;
height: any;
constructor(gl: any, width: any, height: any);
/**
* Adds a texture to the frame buffer
* @param texture {glCore.GLTexture}
*/
enableTexture(texture: any): void;
/**
* Initialises the stencil buffer
*/
enableStencil(): void;
/**
* Erases the drawing area and fills it with a colour
* @param r {Number} the red value of the clearing colour
* @param g {Number} the green value of the clearing colour
* @param b {Number} the blue value of the clearing colour
* @param a {Number} the alpha value of the clearing colour
*/
clear(r: any, g: any, b: any, a: any): void;
/**
* Binds the frame buffer to the WebGL context
*/
bind(): void;
/**
* Unbinds the frame buffer to the WebGL context
*/
unbind(): void;
/**
* Resizes the drawing area of the buffer to the given width and height
* @param width {Number} the new width
* @param height {Number} the new height
*/
resize(width: any, height: any): void;
/**
* Destroys this buffer
*/
destroy(): void;
/**
* Creates a frame buffer with a texture containing the given data
* @static
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param width {Number} the width of the drawing area of the frame buffer
* @param height {Number} the height of the drawing area of the frame buffer
* @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
*/
static createRGBA(gl: any, width: any, height: any, data?: any): GLFramebuffer;
/**
* Creates a frame buffer with a texture containing the given data
* @static
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param width {Number} the width of the drawing area of the frame buffer
* @param height {Number} the height of the drawing area of the frame buffer
* @param data {ArrayBuffer| SharedArrayBuffer|ArrayBufferView} an array of data
*/
static createFloat32(gl: any, width: any, height: any, data: any): GLFramebuffer;
}
/**
* Helper class to create a webGL Shader
*
* @class
* @memberof glCore
* @param gl {WebGLRenderingContext}
* @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
* @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.
* @param precision {string} The float precision of the shader. Options are 'lowp', 'mediump' or 'highp'.
* @param attributeLocations {object} A key value pair showing which location eact attribute should sit eg {position:0, uvs:1}
*/
export declare class GLShader {
gl: any;
program: any;
attributes: {};
uniformData: {};
uniforms: {
data: {};
};
constructor(gl: any, vertexSrc: any, fragmentSrc: any, precision?: any, attributeLocations?: any);
/**
* Uses this shader
*
* @return {glCore.GLShader} Returns itself.
*/
bind(): this;
/**
* Destroys this shader
* TODO
*/
destroy(): void;
}
/**
* Helper class to create a WebGL Texture
*
* @class
* @memberof glCore
* @param gl {WebGLRenderingContext} The current WebGL context
* @param width {number} the width of the texture
* @param height {number} the height of the texture
* @param format {number} the pixel format of the texture. defaults to gl.RGBA
* @param type {number} the gl type of the texture. defaults to gl.UNSIGNED_BYTE
*/
export declare class GLTexture {
gl: any;
texture: any;
mipmap: boolean;
premultiplyAlpha: boolean;
width: any;
height: any;
format: any;
type: any;
constructor(gl: any, width?: any, height?: any, format?: any, type?: any);
/**
* Uploads this texture to the GPU
* @param source {HTMLImageElement|ImageData|HTMLVideoElement} the source image of the texture
*/
upload(source: any): void;
/**
* Use a data source and uploads this texture to the GPU
* @param data {TypedArray} the data to upload to the texture
* @param width {number} the new width of the texture
* @param height {number} the new height of the texture
*/
uploadData: (data: any, width: any, height: any) => void;
/**
* Binds the texture
* @param location
*/
bind(location?: any): void;
/**
* Unbinds the texture
*/
unbind(): void;
/**
* @param linear {Boolean} if we want to use linear filtering or nearest neighbour interpolation
*/
minFilter(linear: any): void;
/**
* @param linear {Boolean} if we want to use linear filtering or nearest neighbour interpolation
*/
magFilter(linear: any): void;
/**
* Enables mipmapping
*/
enableMipmap(): void;
/**
* Enables linear filtering
*/
enableLinearScaling(): void;
/**
* Enables nearest neighbour interpolation
*/
enableNearestScaling(): void;
/**
* Enables clamping on the texture so WebGL will not repeat it
*/
enableWrapClamp(): void;
/**
* Enable tiling on the texture
*/
enableWrapRepeat(): void;
enableWrapMirrorRepeat(): void;
/**
* Destroys this texture
*/
destroy(): void;
/**
* @static
* @param gl {WebGLRenderingContext} The current WebGL context
* @param source {HTMLImageElement|ImageData} the source image of the texture
* @param premultiplyAlpha {Boolean} If we want to use pre-multiplied alpha
*/
static fromSource(gl: any, source: any, premultiplyAlpha?: any): GLTexture;
/**
* @static
* @param gl {WebGLRenderingContext} The current WebGL context
* @param data {TypedArray} the data to upload to the texture
* @param width {number} the new width of the texture
* @param height {number} the new height of the texture
*/
static fromData(gl: any, data: any, width: any, height: any): GLTexture;
}
/**
* A standard object to store the Uvs of a texture
*
* @class
* @private
*/
export declare class TextureUvs {
x0: number;
y0: number;
x1: number;
y1: number;
x2: number;
y2: number;
x3: number;
y3: number;
uvsUint32: Uint32Array;
/**
*
*/
constructor();
/**
* Sets the texture Uvs based on the given frame information.
*
* @private
* @param {Rectangle} frame - The frame of the texture
* @param {Rectangle} baseFrame - The base frame of the texture
* @param {number} rotate - Rotation of frame, see {@link GroupD8}
*/
set(frame: any, baseFrame: any, rotate?: any): void;
}
/**
* Helper class to work with WebGL VertexArrayObjects (vaos)
* Only works if WebGL extensions are enabled (they usually are)
*
* @class
* @memberof glCore
* @param gl {WebGLRenderingContext} The current WebGL rendering context
*/
export declare class VertexArrayObject {
nativeVaoExtension: any;
nativeState: any;
nativeVao: any;
gl: any;
attributes: any[];
indexBuffer: any;
dirty: boolean;
constructor(gl: any, state: any);
/**
* Binds the buffer
*/
bind(): this;
/**
* Unbinds the buffer
*/
unbind(): this;
/**
* Uses this vao
*/
activate(): this;
/**
*
* @param buffer {gl.GLBuffer}
* @param attribute {*}
* @param type {String}
* @param normalized {Boolean}
* @param stride {Number}
* @param start {Number}
*/
addAttribute(buffer: any, attribute: any, type?: any, normalized?: any, stride?: any, start?: any): this;
/**
*
* @param buffer {gl.GLBuffer}
*/
addIndex(buffer: any): this;
/**
* Unbinds this vao and disables it
*/
clear(): this;
/**
* @param type {Number}
* @param size {Number}
* @param start {Number}
*/
draw(type: any, size?: any, start?: any): this;
/**
* Destroy this vao
*/
destroy(): void;
getSize(): number;
/**
* Some devices behave a bit funny when using the newer extensions (im looking at you ipad 2!)
* If you find on older devices that things have gone a bit weird then set this to true.
*/
/**
* Lets the VAO know if you should use the WebGL extension or the native methods.
* Some devices behave a bit funny when using the newer extensions (im looking at you ipad 2!)
* If you find on older devices that things have gone a bit weird then set this to true.
* @static
* @property {Boolean} FORCE_NATIVE
*/
static FORCE_NATIVE: boolean;
}
export declare function checkMaxIfStatmentsInShader(maxIfs: any, gl: any): any;
/**
* Helper class to create a webGL Context
*
* @class
* @memberof glCore
* @param canvas {HTMLCanvasElement} the canvas element that we will get the context from
* @param options {Object} An options object that gets passed in to the canvas element containing the context attributes,
* see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext for the options available
* @return {WebGLRenderingContext} the WebGL context
*/
export declare function createContext(canvas: any, options?: any): any;
/**
* Generic Mask Stack data structure
*
* @function createIndicesForQuads
* @private
* @param {number} size - Number of quads
* @return {Uint16Array} indices
*/
export declare function createIndicesForQuads(size: any): Uint16Array;
import { GLShader } from './GLShader';
export declare function generateMultiTextureShader(gl: any, maxTextures: any): GLShader;
export { GLTexture } from './GLTexture';
export { GLBuffer } from './GLBuffer';
export { VertexArrayObject } from './VertexArrayObject';
export { GLFramebuffer } from "./GLFramebuffer";
export { GLShader } from "./GLShader";
export { TextureUvs } from "./TextureUvs";
export { checkMaxIfStatmentsInShader } from "./checkMaxIfStatmentsInShader";
/**
* @param gl {WebGLRenderingContext} The current WebGL context
* @param attribs {*}
* @param state {*}
*/
export declare function setVertexAttribArrays(gl: any, attribs: any, state?: any): void;
/**
* @class
* @memberof glCore.shader
* @param gl {WebGLRenderingContext} The current WebGL context {WebGLProgram}
* @param vertexSrc {string|string[]} The vertex shader source as an array of strings.
* @param fragmentSrc {string|string[]} The fragment shader source as an array of strings.
* @param attributeLocations {Object} An attribute location map that lets you manually set the attribute locations
* @return {WebGLProgram} the shader program
*/
export declare function compileProgram(gl: any, vertexSrc: any, fragmentSrc: any, attributeLocations?: any): any;
/**
* @class
* @memberof glCore.shader
* @param type {String} Type of value
* @param size {Number}
*/
export declare function defaultValue(type: any, size: any): false | any[] | 0 | Float32Array | Int32Array;
/**
* Extracts the attributes
* @class
* @memberof glCore.shader
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param program {WebGLProgram} The shader program to get the attributes from
* @return attributes {Object}
*/
export declare function extractAttributes(gl: any, program: any): {};
/**
* Extracts the uniforms
* @class
* @memberof glCore.shader
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param program {WebGLProgram} The shader program to get the uniforms from
* @return uniforms {Object}
*/
export declare function extractUniforms(gl: any, program: any): {};
/**
* Extracts the attributes
* @class
* @memberof glCore.shader
* @param gl {WebGLRenderingContext} The current WebGL rendering context
* @param uniforms {Array} @mat ?
* @return attributes {Object}
*/
export declare function generateUniformAccessObject(gl: any, uniformData: any): {
data: {};
};
export { compileProgram } from './compileProgram';
export { defaultValue } from './defaultValue';
export { extractAttributes } from './extractAttributes';
export { extractUniforms } from './extractUniforms';
export { generateUniformAccessObject } from './generateUniformAccessObject';
export { setPrecision } from './setPrecision';
export { mapSize } from './mapSize';
export { mapType } from './mapType';
/**
* @class
* @memberof glCore.shader
* @param type {String}
* @return {Number}
*/
export declare function mapSize(type: any): any;
export declare function mapType(gl: any, type: any): any;
/**
* Sets the float precision on the shader. If the precision is already present this function will do nothing
* @param {string} src the shader source
* @param {string} precision The float precision of the shader. Options are 'lowp', 'mediump' or 'highp'.
*
* @return {string} modified shader source
*/
export declare function setPrecision(src: any, precision: any): any;
/**
* @class
*/
export default class MaskManager {
renderer: any;
scissor: boolean;
scissorData: any;
scissorRenderTarget: any;
enableScissor: boolean;
/**
* @param {WebGLRenderer} renderer - The renderer this manager works for.
*/
constructor(renderer: any);
/**
* Applies the Mask and adds it to the current filter stack.
*
* @param {DisplayObject} target - Display Object to push the mask to
* @param {Sprite|Graphics} maskData - The masking data.
*/
pushMask(target: any, maskData: any): void;
/**
* Removes the last mask from the mask stack and doesn't return it.
*
* @param {DisplayObject} target - Display Object to pop the mask from
* @param {Sprite|Graphics} maskData - The masking data.
*/
popMask(target: any, maskData: any): void;
/**
* Applies the Mask and adds it to the current filter stack.
*
* @param {RenderTarget} target - Display Object to push the sprite mask to
* @param {Sprite} maskData - Sprite to be used as the mask
*/
/**
* Removes the last filter from the filter stack and doesn't return it.
*
*/
/**
* Applies the Mask and adds it to the current filter stack.
*
* @param {Sprite|Graphics} maskData - The masking data.
*/
pushStencilMask(maskData: any): void;
/**
* Removes the last filter from the filter stack and doesn't return it.
*
*/
popStencilMask(target: any, maskData: any): void;
/**
*
* @param {DisplayObject} target - Display Object to push the mask to
* @param {Graphics} maskData - The masking data.
*/
pushScissorMask(target: any, maskData: any): void;
/**
*
*
*/
popScissorMask(target: any, maskData: any): void;
destroy(): void;
fit(bounds: any, rectangle: any): void;
}
/**
* @class
*/
export default class StencilManager {
renderer: any;
stencilMaskStack: any;
/**
* @param {WebGLRenderer} renderer - The renderer this manager works for.
*/
constructor(renderer: any);
/**
* Changes the mask stack that is used by this manager.
*
* @param {Graphics[]} stencilMaskStack - The mask stack
*/
setMaskStack(stencilMaskStack: any): void;
/**
* Applies the Mask and adds it to the current stencil stack. @alvin
*
* @param {Graphics} graphics - The mask
*/
pushStencil(graphics: any): void;
/**
* Removes the last mask from the stencil stack. @alvin
*/
popStencil(): void;
/**
* Setup renderer to use the current stencil data.
*/
_useCurrent(): void;
/**
* Fill 1s equal to the number of acitve stencil masks.
*
* @return {number} The bitwise mask.
*/
_getBitwiseMask(): number;
/**
* Destroys the mask stack.
*
*/
destroy(): void;
}
/**
* TextureGarbageCollector. This class manages the GPU and ensures that it does not get clogged
* up with textures that are no longer being used.
*
* @class
* @memberof PIXI
*/
export default class TextureGarbageCollector {
renderer: any;
count: number;
checkCount: number;
maxIdle: number;
checkCountMax: number;
mode: number;
/**
* @param {WebGLRenderer} renderer - The renderer this manager works for.
*/
constructor(renderer: any);
/**
* Checks to see when the last time a texture was used
* if the texture has not been used for a specified amount of time it will be removed from the GPU
*/
update(): void;
/**
* Checks to see when the last time a texture was used
* if the texture has not been used for a specified amount of time it will be removed from the GPU
*/
run(): void;
/**
* Removes all the textures within the specified displayObject and its children from the GPU
*
* @param {DisplayObject} displayObject - the displayObject to remove the textures from.
*/
unload(displayObject: any): void;
}
/**
* Helper class to create a webGL Texture
*
* @class
*/
export default class TextureManager {
renderer: any;
gl: any;
_managedTextures: any[];
/**
* @param {WebGLRenderer} renderer - A reference to the current renderer
*/
constructor(renderer: any);
/**
* Binds a texture.
*
*/
bindTexture(): void;
/**
* Gets a texture.
*
*/
getTexture(): void;
/**
* Updates and/or Creates a WebGL texture for the renderer's context.
*
* @param {PIXI.BaseTexture|PIXI.Texture} texture - the texture to update
* @param {number} location - the location the texture will be bound to.
* @return {GLTexture} The gl texture.
*/
updateTexture(texture: any, location: any): any;
/**
* Deletes the texture from WebGL
*
* @param {PIXI.BaseTexture|PIXI.Texture} texture - the texture to destroy
* @param {boolean} [skipRemove=false] - Whether to skip removing the texture from the TextureManager.
*/
destroyTexture(texture: any, skipRemove: any): void;
/**
* Deletes all the textures from WebGL
*/
removeAll(): void;
/**
* Destroys this manager and removes all its textures
*/
destroy(): void;
}
import ObjectRenderer from '../ObjectRenderer';
import { GLBuffer } from '../glCore/GLBuffer';
/**
* Renderer dedicated to drawing and batching sprites.
*
* @class
* @private
* @extends ObjectRenderer
*/
export default class BatchRenderer extends ObjectRenderer {
vertSize: number;
vertByteSize: number;
size: number;
buffers: any[];
indices: Uint16Array;
shader: any;
currentIndex: number;
groups: any[];
sprites: any[];
vertexBuffers: any[];
vaos: any[];
vaoMax: number;
vertexCount: number;
MAX_TEXTURES: number;
indexBuffer: GLBuffer;
vao: any;
currentBlendMode: number;
boundTextures: any[];
/**
* @param {WebGLRenderer} renderer - The renderer this sprite batch works for.
*/
constructor(renderer: any);
/**
* Sets up the renderer context and necessary buffers.
*
* @private
*/
onContextChange(): void;
/**
* Called before the renderer starts rendering.
*
*/
onPrerender(): void;
/**
* Renders the sprite object.
*
* @param {Sprite} sprite - the sprite to render when using this spritebatch
*/
render(sprite: any): void;
/**
* Renders the content and empties the current batch.
*
*/
flush(): void;
/**
* Starts a new sprite batch.
*/
start(): void;
/**
* Stops and flushes the current batch.
*
*/
stop(): void;
/**
* Destroys the SpriteRenderer.
*
*/
destroy(): void;
}
import ObjectRenderer from '../ObjectRenderer';
import { GLBuffer } from "../glCore";
/**
* Renders the graphics object.
*暂时为遮罩处理用,shader和vao特定的
* @class
* @extends ObjectRenderer
*/
export default class GraphicsRenderer extends ObjectRenderer {
graphicsDataPool: any[];
primitiveShader: any;
gl: any;
CONTEXT_UID: number;
renderer: any;
buffer: GLBuffer;
indexBuffer: GLBuffer;
vao: any;
/**
* @param {WebGLRenderer} renderer - The renderer this object renderer works for.
*/
constructor(renderer: any);
/**
* Called when there is a WebGL context change
*
* @private
*
*/
onContextChange(): void;
/**
* Destroys this renderer.
*
*/
/**
* Renders a graphics object.
*
* @param {Graphics} graphics - The graphics object to render.
*/
render(graphics: any): void;
}
import Shader from './Shader';
/**
* This shader is used to draw simple primitive shapes for {@link Graphics}.
*
* @class
* @extends Shader
*/
export default class PrimitiveShader extends Shader {
/**
* 注释掉的aColor暂时不需要,不考虑混色,简单粗暴颜色和透明度
* @param {WebGLRenderingContext} gl - The webgl shader manager this shader works for.
*/
constructor(gl: any);
}
import { GLShader } from '../glCore';
/**
* Wrapper class, webGL Shader
* Adds precision string if vertexSrc or fragmentSrc have no mention of it.
*
* @class
* @extends GLShader
*/
export default class Shader extends GLShader {
/**
*
* @param {WebGLRenderingContext} gl - The current WebGL rendering context
* @param {string|string[]} vertexSrc - The vertex shader source as an array of strings.
* @param {string|string[]} fragmentSrc - The fragment shader source as an array of strings.
* @param {object} [attributeLocations] - A key value pair showing which location eact attribute should sit.
e.g. {position:0, uvs:1}.
* @param {string} [precision] - The float precision of the shader. Options are 'lowp', 'mediump' or 'highp'.
*/
constructor(gl: any, vertexSrc: any, fragmentSrc: any, attributeLocations?: any, precision?: any);
}
declare const _default: {
/**
* Target frames per millisecond.
*
* @static
* @memberof settings
* @type {number}
* @default 0.06
*/
TARGET_FPMS: number;
/**
* If set to true WebGL will attempt make textures mimpaped by default.
* Mipmapping will only succeed if the base texture uploaded has power of two dimensions.
*
* @static
* @memberof settings
* @type {boolean}
* @default true
*/
MIPMAP_TEXTURES: boolean;
/**
* Default resolution / device pixel ratio of the renderer.
*
* @static
* @memberof settings
* @type {number}
* @default 1
*/
RESOLUTION: number;
/**
* Default filter resolution.
*
* @static
* @memberof settings
* @type {number}
* @default 1
*/
/**
* The maximum textures that this device supports.
*
* @static
* @memberof settings
* @type {number}
* @default 32
*/
SPRITE_MAX_TEXTURES: any;
/**
* The default sprite batch size.
*
* The default aims to balance desktop and mobile devices.
*
* @static
* @memberof settings
* @type {number}
* @default 4096
*/
SPRITE_BATCH_SIZE: number;
/**
* The prefix that denotes a URL is for a retina asset.
*
* @static
* @memberof settings
* @type {RegExp}
* @example `@2x`
* @default /@([0-9\.]+)x/
*/
RETINA_PREFIX: RegExp;
/**
* The default render options if none are supplied to {@link WebGLRenderer}
* or {@link CanvasRenderer}.
*
* @static
* @constant
* @memberof settings
* @type {object}
* @property {HTMLCanvasElement} view=null
* @property {number} resolution=1
* @property {boolean} antialias=false
* @property {boolean} forceFXAA=false
* @property {boolean} autoResize=false
* @property {boolean} transparent=false
* @property {number} backgroundColor=0x000000
* @property {boolean} clearBeforeRender=true
* @property {boolean} preserveDrawingBuffer=false
* @property {boolean} roundPixels=false
* @property {number} width=800
* @property {number} height=600
* @property {boolean} legacy=false
*/
RENDER_OPTIONS: {
view: any;
antialias: boolean;
forceFXAA: boolean;
autoResize: boolean;
transparent: boolean;
backgroundColor: number;
clearBeforeRender: boolean;
preserveDrawingBuffer: boolean;
roundPixels: boolean;
width: number;
height: number;
legacy: boolean;
};
/**
* Default transform type.
*
* @static
* @memberof settings
* @type {TRANSFORM_MODE}
* @default TRANSFORM_MODE.STATIC
*/
TRANSFORM_MODE: number;
/**
* Default Garbage Collection mode.
*
* @static
* @memberof settings
* @type {GC_MODES}
* @default GC_MODES.AUTO
*/
GC_MODE: number;
/**
* Default Garbage Collection max idle.
*
* @static
* @memberof settings
* @type {number}
* @default 3600
*/
GC_MAX_IDLE: number;
/**
* Default Garbage Collection maximum check count.
*
* @static
* @memberof settings
* @type {number}
* @default 600
*/
GC_MAX_CHECK_COUNT: number;
/**
* Default wrap modes that are supported by
*
* @static
* @memberof settings
* @type {WRAP_MODES}
* @default WRAP_MODES.CLAMP
*/
WRAP_MODE: number;
/**
* The scale modes that are supported by
*
* @static
* @memberof settings
* @type {SCALE_MODES}
* @default SCALE_MODES.LINEAR
*/
SCALE_MODE: number;
/**
* Default specify float precision in vertex shader.
*
* @static
* @memberof settings
* @type {PRECISION}
* @default PRECISION.HIGH
*/
PRECISION_VERTEX: string;
/**
* Default specify float precision in fragment shader.
*
* @static
* @memberof settings
* @type {PRECISION}
* @default PRECISION.MEDIUM
*/
PRECISION_FRAGMENT: string;
/**
* Can we upload the same buffer in a single frame?
*
* @static
* @constant
* @memberof settings
* @type {boolean}
*/
CAN_UPLOAD_SAME_BUFFER: boolean;
/**
* Default Mesh `canvasPadding`.
*
* @see mesh.Mesh#canvasPadding
* @static
* @constant
* @memberof settings
* @type {number}
*/
MESH_CANVAS_PADDING: number;
};
/**
* User's customizable globals for overriding the default PIXI settings, such
* as a renderer's default resolution, framerate, float percision, etc.
* @example
* // Use the native window resolution as the default resolution
* // will support high-density displays when rendering
* settings.RESOLUTION = window.devicePixelRatio.
*
* // Disable interpolation when scaling, will make texture be pixelated
* settings.SCALE_MODE = SCALE_MODES.NEAREST;
* @namespace settings
*/
export default _default;
/**
* 批处理buffer数据类
*/
export default class Buffer {
/**
* 顶点类型化数组
*/
vertices: ArrayBuffer;
/**
* View on the vertices as a Float32Array for positions
* @member {Float32Array}
*/
float32View: Float32Array;
/**
* View on the vertices as a Uint32Array for uvs
* @member {Uint32Array}
*/
uint32View: Uint32Array;
positions: any;
uvs: any;
colors: any;
/**
* @param {number} size - The size of the buffer in bytes.
*/
constructor(size: any);
/**
* Destroys the buffer.
*
*/
destroy(): void;
}
export declare const Device: any;
import { Bounds, Matrix } from "../../../support";
import { GLFramebuffer, GLTexture } from '../glCore';
/**
* @class
*/
export default class RenderTarget {
/**
* The current WebGL drawing context.
* @member {WebGLRenderingContext}
*/
gl: WebGLRenderingContext;
/**
* A frame buffer
*/
frameBuffer: GLFramebuffer;
/**
* The texture
*/
texture: GLTexture;
/**
* The background colour of this render target, as an array of [r,g,b,a] values
*/
clearColor: number[];
/**
* The size of the object as a rectangle
*/
size: Bounds;
/**
* The projection matrix
*/
projectionMatrix: Matrix;
transform: any;
frame: any;
defaultFrame: any;
destinationFrame: any;
sourceFrame: any;
stencilBuffer: any;
stencilMaskStack: any[];
filterData: any;
filterPoolKey: string;
scaleMode: any;
root: any;
/**
* @param {WebGLRenderingContext} gl - The current WebGL drawing context
* @param {number} [width=0] - the horizontal range of the filter
* @param {number} [height=0] - the vertical range of the filter
* @param {number} [scaleMode=settings.SCALE_MODE] - See {@link SCALE_MODES} for possible values
* @param {number} [resolution=1] - The current resolution / device pixel ratio
* @param {boolean} [root=false] - Whether this object is the root element or not
*/
constructor(gl: any, width: any, height: any, scaleMode?: any, /*resolution,*/ root?: any);
/**
* Clears the filter texture.
*
* @param {number[]} [clearColor=this.clearColor] - Array of [r,g,b,a] to clear the framebuffer
*/
clear(clearColor: any): void;
/**
* Binds the stencil buffer.
*
*/
attachStencilBuffer(): void;
/**
* Sets the frame of the render target.
*
* @param {Rectangle} destinationFrame - The destination frame.
* @param {Rectangle} sourceFrame - The source frame.
*/
setFrame(destinationFrame?: any, sourceFrame?: any): void;
/**
* Binds the buffers and initialises the viewport.
*
*/
activate(): void;
/**
* Updates the projection matrix based on a projection frame (which is a rectangle)
*
* @param {Rectangle} destinationFrame - The destination frame.
* @param {Rectangle} sourceFrame - The source frame.
*/
calculateProjection(destinationFrame: any, sourceFrame?: any): void;
/**
* Resizes the texture to the specified width and height
*
* @param {number} width - the new width of the texture
* @param {number} height - the new height of the texture
*/
resize(width: any, height: any): void;
/**
* Destroys the render target.
*
*/
destroy(): void;
}
export default function canUploadSameBuffer(): boolean;
/**
* Generic Mask Stack data structure
*
* @function createIndicesForQuads
* @private
* @param {number} size - Number of quads
* @return {Uint16Array} indices
*/
export default function createIndicesForQuads(size: any): Uint16Array;
import { GLShader } from '../glCore/GLShader';
export declare function generateMultiTextureShader(gl: any, maxTextures: any): GLShader;
/**
* premultiplies tint
*
* @memberof utils
* @param {number} tint integet RGB
* @param {number} alpha floating point alpha (0.0-1.0)
* @returns {number} tint multiplied by alpha
*/
export declare function premultiplyTint(tint: any, alpha: any): any;
export declare function nextPow2(v: any): any;
export declare function log2(v: number): number;
export declare function isPow2(v: any): boolean;
/**
* Converts a hex color number to an [R, G, B] array
*
* @memberof utils
* @function hex2rgb
* @param {number} hex - The number to convert
* @param {number[]} [out=[]] If supplied, this array will be used rather than returning a new one
* @return {number[]} An array representing the [R, G, B] of the color.
*/
export declare function hex2rgb(hex: any, out?: any): any;
/**
* Maps gl blend combinations to WebGL.
*
* @function mapWebGLBlendModesTo
* @private
* @param {WebGLRenderingContext} gl - The rendering context.
* @param {string[]} [array=[]] - The array to output into.
* @return {string[]} Mapped modes.
*/
export default function mapWebGLBlendModesTo(gl: any, array?: any[]): any[];
/**
* Generic Mask Stack data structure.
*
* @memberof PIXI
* @function mapWebGLDrawModesToPixi
* @private
* @param {WebGLRenderingContext} gl - The current WebGL drawing context
* @param {object} [object={}] - The object to map into
* @return {object} The mapped draw modes.
*/
export default function mapWebGLDrawModesTo(gl: any, object?: {}): {};
export default function maxRecommendedTextures(max: any): any;
declare const _default: {
/**
* Mixes in the properties of the pluginTarget into another object
*
* @param {object} obj - The obj to mix into
*/
mixin: (obj: any) => void;
};
export default _default;
/**
* Remove a range of items from an array
*
* @function removeItems
* @param {Array<*>} arr The target array
* @param {number} startIdx The index to begin removing from (inclusive)
* @param {number} removeCount How many items to remove
*/
export default function removeItems(arr: any, startIdx: any, removeCount: any): void;
export default function validateContext(gl: any): void;
/**
* Created by rockyl on 2018-12-04.
*/
export * from './interpreter';
/**
* 启动场景
* @param name
* @param progress
*/
export declare function launchScene(name: any, progress?: any): Promise<void>;
/**
* 装载场景
* @param scene
*/
export declare function mountScene(scene: any): void;
/**
* 卸载场景
* @param scene
*/
export declare function unmountScene(scene: any): void;
/**
* 加载预制资源
* @param url url
* @param uuid 唯一名
* @param cache 是否缓存
* @param config
* @return Promise<any> 资源
*/
export declare function loadPrefab(url: any, uuid?: any, cache?: boolean, config?: any): Promise<any>;
/**
* Created by rockyl on 2018-12-03.
*
* 配置文件解释器
*/
import { Entity, Scene } from "../core";
export declare function registerDef(name: any, def: any): void;
/**
* 装配场景
* @param scene
* @param root
*/
export declare function setupScene(scene: Scene, root: Entity): Scene;
/**
* 清空实体
* @param entity
*/
export declare function cleanEntity(entity: Entity): void;
/**
* 装配预制体
* @param config
*/
export declare function instantiate(config: any): Entity;
export declare function injectComponentProperties(component: any, config: any, pid?: any): void;
/**
* 实例化组件
* @param entity
* @param config
*/
export declare function instantiateComponent(entity: Entity, config: any): any;
/**
* Created by rockyl on 2018-12-05.
*/
export declare const EngineConfig: {
lineHeightRatio: number;
entityEnabled: boolean;
componentEnabled: boolean;
awakeComponentWhenAdded: boolean;
sleepComponentWhenRemoved: boolean;
drawRenderRect: boolean;
imgCrossOrigin: boolean;
};
export declare function modifyEngineConfig(_options: any): void;
/**
* 投影或者发光滤镜
* @class ShadowFilter
* @public
* @since 1.0.0
*/
export declare class ShadowFilter {
/**
* 颜色值
* @property color
* @public
* @readonly
* @since 1.0.0
* @default black
* @type {string}
*/
color: string;
/**
* x方向投影距离
* @property offsetX
* @public
* @readonly
* @since 1.0.0
* @default 2
* @type {number}
*/
offsetX: number;
/**
* y方向投影距离
* @property offsetY
* @public
* @readonly
* @since 1.0.0
* @default 2
* @type {number}
*/
offsetY: number;
/**
* 模糊值
* @property blur
* @public
* @readonly
* @since 1.0.0
* @default 2
* @type {number}
*/
blur: number;
/**
* 滤镜类型 只读
* @property color
* @public
* @readonly
* @since 1.0.0
* @default Shadow
* @type {string}
*/
type: string;
/**
* @method ShadowFilter
* @param {string} color
* @param {number} offsetX
* @param {number} offsetY
* @param {number} blur
*/
constructor(color?: string, offsetX?: number, offsetY?: number, blur?: number);
/**
*获取滤镜的字符串表现形式以方便比较两个滤镜是否效果一样
* @method toString
* @public
* @since 1.0.0
* @return {string}
*/
toString(): string;
/**
* 绘画滤镜效果
* @method drawFilter
* @public
* @since 1.0.0
* @param {ImageData} imageData
*/
drawFilter(imageData?: ImageData): void;
destroy(): void;
}
/**
* 普通变色滤镜
* @class ColorFilter
* @public
* @since 1.0.0
*/
export declare class ColorFilter {
/**
* @property redMultiplier
* @public
* @since 1.0.0
* @readonly
* @type {number}
*/
redMultiplier: number;
/**
* @property redOffset
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
redOffset: number;
/**
* @property greenMultiplier
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
greenMultiplier: number;
/**
* @property greenOffset
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
greenOffset: number;
/**
* @property blueMultiplier
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
blueMultiplier: number;
/**
* @property blueOffset
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
blueOffset: number;
/**
* @property alphaMultiplier
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
alphaMultiplier: number;
/**
* @property alphaOffset
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
alphaOffset: number;
/**
* @property type
* @public
* @readonly
* @since 1.0.0
* @type {string}
*/
type: string;
/**
* @method ColorFilter
* @param {number} colorArrays 颜色值数据
*/
constructor(colorArrays: number[]);
/**
* 绘画滤镜效果
* @method drawFilter
* @param {ImageData} imageData
* @since 1.0.0
* @public
*/
drawFilter(imageData?: ImageData): void;
/**
*获取滤镜的字符串表现形式以方便比较两个滤镜是否效果一样
* @method toString
* @public
* @since 1.0.0
* @return {string}
*/
toString(): string;
destroy(): void;
}
/**
* 矩阵变色滤镜
* @class ColorMatrixFilter
* @public
* @since 1.0.0
*/
export declare class ColorMatrixFilter {
/**
* @property brightness
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
brightness: number;
/**
* @property contrast
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
contrast: number;
/**
* @property saturation
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
saturation: number;
/**
* @property hue
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
hue: number;
/**
* 滤镜类型 只读
* @property type
* @public
* @readonly
* @since 1.0.0
* @type {string}
*/
type: string;
private colorMatrix;
/**
* @method ColorMatrixFilter
* @param {number} brightness
* @param {number} contrast
* @param {number} saturation
* @param {number} hue
* @public
* @since 1.0.0
*/
constructor(brightness: number, contrast: number, saturation: number, hue: number);
/**
* 绘画滤镜效果
* @method drawFilter
* @param {ImageData} imageData
* @since 1.0.0
* @public
*/
drawFilter(imageData?: ImageData): void;
static DELTA_INDEX: number[];
private _multiplyMatrix;
private _cleanValue;
/**
*获取滤镜的字符串表现形式以方便比较两个滤镜是否效果一样
* @method toString
* @public
* @since 1.0.0
* @return {string}
*/
toString(): string;
destroy(): void;
}
/**
* 模糊滤镜
* @class BlurFilter
* @public
* @since 1.0.0
*/
export declare class BlurFilter {
/**
* 滤镜类型 只读
* @property type
* @public
* @readonly
* @since 1.0.0
* @type {string}
*/
type: string;
/**
* 水平模糊量
* @property blurX
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
blurX: number;
/**
* 垂直模糊量
* @property blurY
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
blurY: number;
/**
* 模糊品质
* @property quality
* @public
* @readonly
* @since 1.0.0
* @type {number}
*/
quality: number;
/**
* @method BlurFilter
* @public
* @since 1.0.0
* @param {number} blurX
* @param {number} blurY
* @param {number} quality
*/
constructor(blurX?: number, blurY?: number, quality?: number);
/**
*获取滤镜的字符串表现形式以方便比较两个滤镜是否效果一样
* @method toString
* @public
* @since 1.0.0
* @return {string}
*/
toString(): string;
private static SHG_TABLE;
private static MUL_TABLE;
/**
* 绘画滤镜效果
* @method drawFilter
* @param {ImageData} imageData
* @since 1.0.0
* @public
*/
drawFilter(imageData?: ImageData): boolean;
destroy(): void;
}
export { ShadowFilter } from './Filters';
export { ColorFilter } from './Filters';
export { ColorMatrixFilter } from './Filters';
export { BlurFilter } from './Filters';
/**
* Created by rockyl on 2018/11/15.
*/
export * from './core';
export * from './editor';
export * from './assets-manager';
export * from './support';
export * from './tools';
export * from './filter';
export * from './engine-config';
export * from './ReType';
/**
* Created by rockyl on 2018/11/7.
*
*/
/**
* 边界类
*/
export default class Bounds {
x: any;
y: any;
width: any;
height: any;
constructor(x?: number, y?: number, width?: number, height?: number);
left: any;
top: any;
right: any;
bottom: any;
contains(x: any, y: any): boolean;
setTo(x: any, y: any, width: any, height: any): void;
copyFrom(target: any): void;
clone(): Bounds;
inflate(dx: any, dy: any): void;
isEmpty(): boolean;
setEmpty(): void;
intersects(toIntersect: any): boolean;
containsBounds(bounds: any): boolean;
equals(toCompare: any): boolean;
toString(): string;
}
/**
* Created by rockyl on 2018-12-07.
*/
/**
* 颜色
*/
export default class Color {
enableAlpha: any;
format: any;
private _hue;
private _saturation;
private _value;
private _valueStr;
private _alpha;
constructor(value?: any);
value: any;
set(prop: any, value: any): void;
get(prop: any): any;
toRgb(): {
r: number;
g: number;
b: number;
};
fromString(value: any): void;
compare(color: any): boolean;
doOnChange(): void;
}
/**
* Created by rockyl on 2018-11-25.
*/
/**
* Minimal `EventEmitter` interface that is molded against the Node.js
* `EventEmitter` interface.
*
* @constructor
* @public
*/
export default class EventEmitter {
_events: any;
_eventsCount: any;
off: any;
addListener: any;
static readonly prefixed: string;
constructor();
/**
* Return an array listing the events for which the emitter has registered
* listeners.
*
* @returns {Array}
* @public
*/
eventNames(): any[];
/**
* Return the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Array} The registered listeners.
* @public
*/
listeners(event: any): any[];
/**
* Return the number of listeners listening to a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Number} The number of listeners.
* @public
*/
listenerCount(event: any): any;
/**
* Calls each of the listeners registered for a given event.
*
* @param {(String|Symbol)} event The event name.
* @returns {Boolean} `true` if the event had listeners, else `false`.
* @public
*/
emit(event: any, a1?: any, a2?: any, a3?: any, a4?: any, a5?: any): boolean;
/**
* Add a listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
on(event: any, fn: any, context: any): any;
/**
* Add a one-time listener for a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn The listener function.
* @param {*} [context=this] The context to invoke the listener with.
* @returns {EventEmitter} `this`.
* @public
*/
once(event: any, fn: any, context: any): any;
/**
* Remove the listeners of a given event.
*
* @param {(String|Symbol)} event The event name.
* @param {Function} fn Only remove the listeners that match this function.
* @param {*} context Only remove the listeners that have this context.
* @param {Boolean} once Only remove one-time listeners.
* @returns {EventEmitter} `this`.
* @public
*/
removeListener(event: any, fn: any, context: any, once: any): this;
/**
* Remove all listeners, or those of the specified event.
*
* @param {(String|Symbol)} [event] The event name.
* @returns {EventEmitter} `this`.
* @public
*/
removeAllListeners(event: any): this;
}
/**
* Created by rockyl on 2019-01-04.
*/
export default class LocalStorage {
ID: string;
constructor(ID: string);
getName(key: string, prefix?: string): string;
getItem(key: string, prefix?: string): string;
setItem(key: string, value: string, prefix?: string): void;
getItemObj(key: string, defaultObj?: any, prefix?: string): any;
setItemObj(key: string, itemObj: any, prefix?: string): void;
}
/**
* Created by rockyl on 2018/11/6.
*
* 矩阵 3x3
*/
/**
* Matrix 类表示一个转换矩阵,它确定如何将点从一个坐标空间映射到另一个坐标空间。
* 您可以对一个显示对象执行不同的图形转换,方法是设置 Matrix 对象的属性,将该 Matrix
* 对象应用于显示对象的 matrix 属性。这些转换函数包括平移(x 和 y 重新定位)、旋转、缩放和倾斜。
*/
export default class Matrix {
a: any;
b: any;
c: any;
d: any;
tx: any;
ty: any;
/**
* 释放一个Matrix实例到对象池
* @param matrix 需要回收的 matrix
*/
static release(matrix: any): void;
/**
* 从对象池中取出或创建一个新的Matrix对象。
*/
static create(): any;
/**
* 使用指定参数创建一个 Matrix 对象
* @param a 缩放或旋转图像时影响像素沿 x 轴定位的值。
* @param b 旋转或倾斜图像时影响像素沿 y 轴定位的值。
* @param c 旋转或倾斜图像时影响像素沿 x 轴定位的值。
* @param d 缩放或旋转图像时影响像素沿 y 轴定位的值。
* @param tx 沿 x 轴平移每个点的距离。
* @param ty 沿 y 轴平移每个点的距离。
*/
constructor(a?: number, b?: number, c?: number, d?: number, tx?: number, ty?: number);
/**
* 返回一个新的 Matrix 对象,它是此矩阵的克隆,带有与所含对象完全相同的副本。
*/
clone(): any;
/**
* 将某个矩阵与当前矩阵连接,从而将这两个矩阵的几何效果有效地结合在一起。在数学术语中,将两个矩阵连接起来与使用矩阵乘法将它们结合起来是相同的。
* @param other 要连接到源矩阵的矩阵。
*/
concat(other: any): void;
/**
* 将源 Matrix 对象中的所有矩阵数据复制到调用方 Matrix 对象中。
* @param other 要拷贝的目标矩阵
*/
copyFrom(other: any): this;
/**
* 为每个矩阵属性设置一个值,该值将导致矩阵无转换。通过应用恒等矩阵转换的对象将与原始对象完全相同。
* 调用 identity() 方法后,生成的矩阵具有以下属性:a=1、b=0、c=0、d=1、tx=0 和 ty=0。
*/
identity(): void;
/**
* 执行原始矩阵的逆转换。
* 您可以将一个逆矩阵应用于对象来撤消在应用原始矩阵时执行的转换。
*/
invert(): void;
/**
* @private
*/
$invertInto(target: any): void;
/**
* 对 Matrix 对象应用旋转转换。
* rotate() 方法将更改 Matrix 对象的 a、b、c 和 d 属性。
* @param radian 以弧度为单位的旋转角度。
*/
rotate(radian: any): void;
/**
* 对矩阵应用缩放转换。x 轴乘以 sx,y 轴乘以 sy。
* scale() 方法将更改 Matrix 对象的 a 和 d 属性。
* @param sx 用于沿 x 轴缩放对象的乘数。
* @param sy 用于沿 y 轴缩放对象的乘数。
*/
scale(sx: any, sy: any): void;
/**
* 将 Matrix 的成员设置为指定值
* @param a 缩放或旋转图像时影响像素沿 x 轴定位的值。
* @param b 旋转或倾斜图像时影响像素沿 y 轴定位的值。
* @param c 旋转或倾斜图像时影响像素沿 x 轴定位的值。
* @param d 缩放或旋转图像时影响像素沿 y 轴定位的值。
* @param tx 沿 x 轴平移每个点的距离。
* @param ty 沿 y 轴平移每个点的距离。
*/
setTo(a: any, b: any, c: any, d: any, tx: any, ty: any): this;
/**
* 返回将 Matrix 对象表示的几何转换应用于指定点所产生的结果。
* @param pointX 想要获得其矩阵转换结果的点的x坐标。
* @param pointY 想要获得其矩阵转换结果的点的y坐标。
* @param resultPoint 框架建议尽可能减少创建对象次数来优化性能,可以从外部传入一个复用的Point对象来存储结果,若不传入将创建一个新的Point对象返回。
* @returns Object 由应用矩阵转换所产生的点。
*/
transformPoint(pointX: any, pointY: any, resultPoint: any): any;
/**
* 如果给定预转换坐标空间中的点,则此方法返回发生转换后该点的坐标。
* 与使用 transformPoint() 方法应用的标准转换不同,deltaTransformPoint() 方法的转换不考虑转换参数 tx 和 ty。
* @param pointX 想要获得其矩阵转换结果的点的x坐标。
* @param pointY 想要获得其矩阵转换结果的点的y坐标。
* @param resultPoint 框架建议尽可能减少创建对象次数来优化性能,可以从外部传入一个复用的Point对象来存储结果,若不传入将创建一个新的Point对象返回。
*/
deltaTransformPoint(pointX: any, pointY: any, resultPoint: any): any;
/**
* 沿 x 和 y 轴平移矩阵,由 dx 和 dy 参数指定。
* @param dx 沿 x 轴向右移动的量(以像素为单位)。
* @param dy 沿 y 轴向下移动的量(以像素为单位)。
*/
translate(dx: any, dy: any): void;
/**
* 是否与另一个矩阵数据相等
* @param other 要比较的另一个矩阵对象。
* @returns 是否相等,ture表示相等。
*/
equals(other: any): boolean;
/**
* 前置矩阵
* @param a 缩放或旋转图像时影响像素沿 x 轴定位的值
* @param b 缩放或旋转图像时影响像素沿 y 轴定位的值
* @param c 缩放或旋转图像时影响像素沿 x 轴定位的值
* @param d 缩放或旋转图像时影响像素沿 y 轴定位的值
* @param tx 沿 x 轴平移每个点的距离
* @param ty 沿 y 轴平移每个点的距离
* @returns 矩阵自身
*/
prepend(a: any, b: any, c: any, d: any, tx: any, ty: any): this;
/**
* 后置矩阵
* @param a 缩放或旋转图像时影响像素沿 x 轴定位的值
* @param b 缩放或旋转图像时影响像素沿 y 轴定位的值
* @param c 缩放或旋转图像时影响像素沿 x 轴定位的值
* @param d 缩放或旋转图像时影响像素沿 y 轴定位的值
* @param tx 沿 x 轴平移每个点的距离
* @param ty 沿 y 轴平移每个点的距离
* @returns 矩阵自身
*/
append(a: any, b: any, c: any, d: any, tx: any, ty: any): this;
/**
* 返回将 Matrix 对象表示的几何转换应用于指定点所产生的结果。
* @returns 一个字符串,它包含 Matrix 对象的属性值:a、b、c、d、tx 和 ty。
*/
toString(): string;
/**
* 包括用于缩放、旋转和转换的参数。当应用于矩阵时,该方法会基于这些参数设置矩阵的值。
* @param scaleX 水平缩放所用的系数
* @param scaleY 垂直缩放所用的系数
* @param rotation 旋转量(以弧度为单位)
* @param tx 沿 x 轴向右平移(移动)的像素数
* @param ty 沿 y 轴向下平移(移动)的像素数
*/
createBox(scaleX: any, scaleY: any, rotation?: number, tx?: number, ty?: number): void;
/**
* 创建 Graphics 类的 beginGradientFill() 和 lineGradientStyle() 方法所需的矩阵的特定样式。
* 宽度和高度被缩放为 scaleX/scaleY 对,而 tx/ty 值偏移了宽度和高度的一半。
* @param width 渐变框的宽度
* @param height 渐变框的高度
* @param rotation 旋转量(以弧度为单位)
* @param tx 沿 x 轴向右平移的距离(以像素为单位)。此值将偏移 width 参数的一半
* @param ty 沿 y 轴向下平移的距离(以像素为单位)。此值将偏移 height 参数的一半
*/
createGradientBox(width: any, height: any, rotation?: number, tx?: number, ty?: number): void;
/**
* @private
*/
$transformBounds(bounds: any): void;
/**
* @private
*/
getDeterminant(): number;
/**
* @private
*/
$getScaleX(): any;
/**
* @private
*/
$getScaleY(): any;
/**
* @private
*/
$getSkewX(): number;
/**
* @private
*/
$getSkewY(): number;
/**
* @private
*/
$updateScaleAndRotation(scaleX: any, scaleY: any, skewX: any, skewY: any): void;
/**
* @private
* target = other * this
*/
$preMultiplyInto(other: any, target: any): void;
/**
* Creates an array from the current Matrix object.与glsl中的mat3对应,注意行列主序执行transpose;
*
* @param {boolean} transpose - Whether we need to transpose the matrix or not
* @param {Float32Array} [out=new Float32Array(9)] - If provided the array will be assigned to out
* @return {number[]} the newly created array which contains the matrix
*/
toArray(transpose?: boolean, out?: any): any;
}
/**
* Created by rockyl on 2018/8/1.
*
* 对象池
*/
export declare function register(name: any, newFunc: any, initFunc: any): void;
export declare function get(name: any, ...params: any[]): any;
export declare function recycle(name: any, instance: any): void;
/**
* 尺寸
*/
export default class Size {
width: number;
height: number;
onChange: any;
constructor(width?: number, height?: number);
setNaN(): void;
isEmpty(): void;
set(width?: any, height?: any): void;
clone(): Size;
copyFrom(target: any): void;
onModify(value: any, key: any, oldValue: any): void;
}
/**
* Created by rockyl on 2018-11-29.
*/
export declare enum FontStyle {
/**
* 正常
*/
NORMAL = "normal",
/**
* 斜体
*/
ITALIC = "italic",
/**
* 倾斜
*/
OBLIQUE = "oblique"
}
export declare enum FontVariant {
/**
* 正常
*/
NORMAL = "normal",
/**
* 小型大写
*/
SMALL_CAPS = "small-caps"
}
export declare enum FontWeight {
/**
* 正常
*/
NORMAL = "normal",
/**
* 粗体
*/
BOLD = "bold",
/**
* 更粗
*/
BOLDER = "bolder",
/**
* 更细
*/
LIGHTER = "lighter"
}
/**
* 文本样式
*/
export declare class TextStyle {
private readonly _callback;
onChange: any;
/**
* 字体样式
*/
fontStyle: FontStyle;
/**
* 字体倾斜
*/
fontVariant: FontVariant;
/**
* 字体宽度
*/
fontWeight: FontWeight;
/**
* 字体尺寸
*/
fontSize: number;
/**
* 字体名称
*/
fontFamily: string;
onModify(value: any, key: any, oldValue: any): void;
}
/**
* Created by rockyl on 2018/11/8.
*
*/
import { ScillaComponent } from "../core";
import HashObject from "../core/HashObject";
declare enum STATUS {
IDLE = 0,
PENDING = 1,
DO_SET = 2,
DO_TO = 3,
DO_WAIT = 4,
DO_CALL = 5
}
export interface ITweenPlugin {
}
export interface TweenOptions {
loop?: number;
autoPlay?: boolean;
initFields?: string[];
clazz?: any;
fields?: string[];
}
/**
* 补间动画
* @param target
* @param override
* @param options
* @param plugins
*/
export declare function createTween(target: ScillaComponent, override?: boolean, options?: TweenOptions, plugins?: any[]): Tween;
/**
* 移除对象上所有的Tween实例
* @param target
*/
export declare function killTweens(target: ScillaComponent): void;
export declare class Tween extends HashObject {
target: ScillaComponent;
loop: number;
queue: any[];
loopCounting: number;
step: number;
status: STATUS;
t: any;
startTime: any;
plugins: ITweenPlugin[];
clazz: any;
fields: any;
autoPlay: boolean;
initProps: any;
fromProps: any;
toProps: any;
ease: Function;
duration: number;
constructor(target: ScillaComponent, options?: TweenOptions, plugins?: any[]);
onUpdate: (t: any) => void;
private getInitProps;
set(props: any): this;
to(props: any, duration?: any, ease?: any): this;
wait(duration: any): this;
call(func: any, thisObj?: any, params?: any): this;
play(override?: boolean, delay?: number, resetLoopCounting?: boolean): void;
private _doPlay;
stop(): void;
_set(props: any): void;
_to(props: any, duration: any, ease: any): void;
_wait(duration: any): void;
_call(func: any, thisObj: any, params: any): void;
_start(resetLoopCounting?: boolean): void;
_readyStart: (t: any) => void;
_doStart(): void;
_doNextAction: () => void;
}
export {};
/**
* Created by rockyl on 2018/11/6.
*
*/
/**
* 创建2D矢量
* @param x
* @param y
*/
export declare function createVector2D(x?: number, y?: number): any;
/**
* 回收2D矢量
* @param target
*/
export declare function releaseVector2D(target: any): void;
/**
* 2D矢量
*/
export default class Vector2D {
_x: any;
_y: any;
onChange: any;
static readonly zero: Vector2D;
constructor(x?: number, y?: number, onChange?: any);
x: any;
y: any;
setXY(x?: number, y?: number): this;
copyFrom(v2: any): this;
clone(): Vector2D;
zero(): this;
readonly isZero: boolean;
normalize(): this;
readonly isNormalized: boolean;
truncate(max: any): this;
reverse(): this;
dotProd(v2: any): number;
crossProd(v2: any): number;
distSQ(v2: any): number;
distance(v2: any): number;
add(v2: any): this;
subtract(v2: any): this;
multiply(value: any): this;
divide(value: any): this;
angle: any;
radian: any;
equals(v2: any): boolean;
length: any;
readonly lengthSQ: number;
readonly slope: number;
toString(): string;
static corner(v1: any, v2: any): number;
}
/**
* Created by rockyl on 2018/11/15.
*
* 支撑类库
*/
export { default as Bounds } from './Bounds';
export { default as Vector2D, createVector2D, releaseVector2D } from './Vector2D';
export { createTween, Tween } from './Tween';
export { default as Matrix } from './Matrix';
export { default as Size } from './Size';
export { default as LocalStorage } from './LocalStorage';
export { TextStyle } from './TextStyle';
export { default as EventEmitter } from './EventEmitter';
/**
* Created by rockyl on 2018/11/9.
*
* 装饰器
*/
/**
* 属性修改时触发
* @param onChange
*/
export declare function fieldChanged(onChange: any): (target: any, key: string) => void;
/**
* 属性变脏时设置宿主的dirty属性为true
*/
export declare const dirtyFieldDetector: (target: any, key: string) => void;
/**
* 属性变脏时触发onModify方法
*/
export declare const dirtyFieldTrigger: (target: any, key: string) => void;
/**
* Created by rockyl on 2018/11/8.
*
* 缓动函数集合,使用不同的缓动函数使得动画按照对应的方程进行
*/
export declare enum Ease {
quadIn = "quadIn",
quadOut = "quadOut",
quadInOut = "quadInOut",
cubicIn = "cubicIn",
cubicOut = "cubicOut",
cubicInOut = "cubicInOut",
quartIn = "quartIn",
quartOut = "quartOut",
quartInOut = "quartInOut",
quintIn = "quintIn",
quintOut = "quintOut",
quintInOut = "quintInOut",
sineIn = "sineIn",
sineOut = "sineOut",
sineInOut = "sineInOut",
backIn = "backIn",
backOut = "backOut",
backInOut = "backInOut",
circIn = "circIn",
circOut = "circOut",
circInOut = "circInOut",
bounceIn = "bounceIn",
bounceOut = "bounceOut",
bounceInOut = "bounceInOut",
elasticIn = "elasticIn",
elasticOut = "elasticOut",
elasticInOut = "elasticInOut"
}
export declare function get(amount: any): (t: any) => any;
export declare function getPowIn(pow: any): (t: any) => number;
export declare function getPowOut(pow: any): (t: any) => number;
export declare function getPowInOut(pow: any): (t: any) => number;
export declare const quadIn: (t: any) => number;
export declare const quadOut: (t: any) => number;
export declare const quadInOut: (t: any) => number;
export declare const cubicIn: (t: any) => number;
export declare const cubicOut: (t: any) => number;
export declare const cubicInOut: (t: any) => number;
export declare const quartIn: (t: any) => number;
export declare const quartOut: (t: any) => number;
export declare const quartInOut: (t: any) => number;
export declare const quintIn: (t: any) => number;
export declare const quintOut: (t: any) => number;
export declare const quintInOut: (t: any) => number;
export declare function sineIn(t: any): number;
export declare function sineOut(t: any): number;
export declare function sineInOut(t: any): number;
export declare function getBackIn(amount: any): (t: any) => number;
export declare const backIn: (t: any) => number;
export declare function getBackOut(amount: any): (t: any) => number;
export declare const backOut: (t: any) => number;
export declare function getBackInOut(amount: any): (t: any) => number;
export declare const backInOut: (t: any) => number;
export declare function circIn(t: any): number;
export declare function circOut(t: any): number;
export declare function circInOut(t: any): number;
export declare function bounceIn(t: any): number;
export declare function bounceOut(t: any): number;
export declare function bounceInOut(t: any): number;
export declare function getElasticIn(amplitude: any, period: any): (t: any) => any;
export declare const elasticIn: (t: any) => any;
export declare function getElasticOut(amplitude: any, period: any): (t: any) => any;
export declare const elasticOut: (t: any) => any;
export declare function getElasticInOut(amplitude: any, period: any): (t: any) => number;
export declare const elasticInOut: (t: any) => number;
/**
* Created by rockyl on 2018/11/16.
*/
import * as decorators from './decorators';
import * as ease from './ease';
import * as math from './math';
import * as utils from './utils';
import * as timeUtils from './time';
import { Ease } from "./ease";
export { decorators, ease, Ease, math, utils, timeUtils, };
/**
* Created by rockyl on 2018/11/8.
*
* 数学工具
*/
/**
* 线性插值
* @param begin number
* @param end number
* @param t number
* @param allowOutOfBounds
* @return number
*/
export declare function lerp(begin: any, end: any, t: any, allowOutOfBounds?: boolean): any;
/**
* 线性插值对象
* @param begin
* @param end
* @param t
* @param clazz
* @param fields
* @param allowOutOfBounds
* @return
*/
export declare function lerpObj(begin: any, end: any, t: any, clazz: any, fields: any, allowOutOfBounds?: boolean): any;
/**
* 随机生成一个整数
* @param max
* @param min
*/
export declare function makeRandomInt(max: number, min?: number): number;
/**
* 打乱一个数组
* @param arr
* @returns {any}
*/
export declare function mixArray(arr: any): Array<any>;
/**
* Created by rockyl on 2019-01-01.
*/
/**
* 时间戳转日期
* @param ts
*/
export declare function ts2Date(ts: any): Date;
export declare function dateToDateString(date: Date, format?: string): string;
export declare function dateToTimeString(date: Date, format?: string): string;
export declare function dateToString(date: Date, dayFormat: any, timeFormat: any): string;
export declare function tsToTimeString(ts: any, format?: string): string;
export declare function secondFormat(second: number, format?: string, placeZero?: boolean): string;
/**
* Created by rockyl on 2018/11/9.
*
* 常用工具
*/
export declare function injectProp(target: any, data?: any, callback?: Function, ignoreMethod?: boolean, ignoreNull?: boolean): boolean;
export declare function objectStringify(obj: any): string;
export declare function waitPromise(duration: any): Promise<void>;
export declare function format(formatStr: string, ...params: any[]): string;
export declare function formatApply(formatStr: string, params: any[]): string;
export declare function supplement(value: number, count: number): string;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment