dragonbones-runtime
Version:
the tools to build dragonbones file for diffrent framework
295 lines (264 loc) • 10.7 kB
text/typescript
//////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2014-present, Egret Technology.
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Egret nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////
namespace egret.web {
/**
* @private
* draw类型,所有的绘图操作都会缓存在drawData中,每个drawData都是一个drawable对象
* $renderWebGL方法依据drawable对象的类型,调用不同的绘制方法
*/
export const enum DRAWABLE_TYPE {
TEXTURE,
RECT,
PUSH_MASK,
POP_MASK,
BLEND,
RESIZE_TARGET,
CLEAR_COLOR,
ACT_BUFFER,
ENABLE_SCISSOR,
DISABLE_SCISSOR,
SMOOTHING
}
/**
* @private
* 绘制指令管理器
* 用来维护drawData数组
*/
export class WebGLDrawCmdManager {
/**
* 用于缓存绘制命令的数组
*/
public drawData = [];
public drawDataLen = 0;
public constructor() {
}
/**
* 压入绘制矩形指令
*/
public pushDrawRect():void {
if(this.drawDataLen == 0 || this.drawData[this.drawDataLen - 1].type != DRAWABLE_TYPE.RECT) {
let data = this.drawData[this.drawDataLen] || {};
data.type = DRAWABLE_TYPE.RECT;
data.count = 0;
this.drawData[this.drawDataLen] = data;
this.drawDataLen++;
}
this.drawData[this.drawDataLen - 1].count += 2;
}
/**
* 压入绘制texture指令
*/
public pushDrawTexture(texture:any, count:number = 2, filter?:any, textureWidth?:number, textureHeight?:number):void {
if(filter) {
// 目前有滤镜的情况下不会合并绘制
let data = this.drawData[this.drawDataLen] || {};
data.type = DRAWABLE_TYPE.TEXTURE;
data.texture = texture;
data.filter = filter;
data.count = count;
data.textureWidth = textureWidth;
data.textureHeight = textureHeight;
this.drawData[this.drawDataLen] = data;
this.drawDataLen++;
} else {
if (this.drawDataLen == 0 || this.drawData[this.drawDataLen - 1].type != DRAWABLE_TYPE.TEXTURE || texture != this.drawData[this.drawDataLen - 1].texture || this.drawData[this.drawDataLen - 1].filter) {
let data = this.drawData[this.drawDataLen] || {};
data.type = DRAWABLE_TYPE.TEXTURE;
data.texture = texture;
data.count = 0;
this.drawData[this.drawDataLen] = data;
this.drawDataLen++;
}
this.drawData[this.drawDataLen - 1].count += count;
}
}
public pushChangeSmoothing(texture:WebGLTexture, smoothing:boolean):void {
texture["smoothing"] = smoothing;
let data = this.drawData[this.drawDataLen] || {};
data.type = DRAWABLE_TYPE.SMOOTHING;
data.texture = texture;
data.smoothing = smoothing;
this.drawData[this.drawDataLen] = data;
this.drawDataLen++;
}
/**
* 压入pushMask指令
*/
public pushPushMask(count:number = 1):void {
let data = this.drawData[this.drawDataLen] || {};
data.type = DRAWABLE_TYPE.PUSH_MASK;
data.count = count * 2;
this.drawData[this.drawDataLen] = data;
this.drawDataLen++;
}
/**
* 压入popMask指令
*/
public pushPopMask(count:number = 1):void {
let data = this.drawData[this.drawDataLen] || {};
data.type = DRAWABLE_TYPE.POP_MASK;
data.count = count * 2;
this.drawData[this.drawDataLen] = data;
this.drawDataLen++;
}
/**
* 压入混色指令
*/
public pushSetBlend(value:string):void {
let len = this.drawDataLen;
// 有无遍历到有效绘图操作
let drawState = false;
for(let i = len - 1; i >= 0; i--) {
let data = this.drawData[i];
if(data){
if(data.type == DRAWABLE_TYPE.TEXTURE || data.type == DRAWABLE_TYPE.RECT) {
drawState = true;
}
// 如果与上一次blend操作之间无有效绘图,上一次操作无效
if(!drawState && data.type == DRAWABLE_TYPE.BLEND) {
this.drawData.splice(i, 1);
this.drawDataLen--;
continue;
}
// 如果与上一次blend操作重复,本次操作无效
if(data.type == DRAWABLE_TYPE.BLEND) {
if(data.value == value) {
return;
} else {
break;
}
}
}
}
let _data = this.drawData[this.drawDataLen] || {};
_data.type = DRAWABLE_TYPE.BLEND;
_data.value = value;
this.drawData[this.drawDataLen] = _data;
this.drawDataLen++;
}
/*
* 压入resize render target命令
*/
public pushResize(buffer:WebGLRenderBuffer, width:number, height:number) {
let data = this.drawData[this.drawDataLen] || {};
data.type = DRAWABLE_TYPE.RESIZE_TARGET;
data.buffer = buffer;
data.width = width;
data.height = height;
this.drawData[this.drawDataLen] = data;
this.drawDataLen++;
}
/*
* 压入clear color命令
*/
public pushClearColor() {
let data = this.drawData[this.drawDataLen] || {};
data.type = DRAWABLE_TYPE.CLEAR_COLOR;
this.drawData[this.drawDataLen] = data;
this.drawDataLen++;
}
/**
* 压入激活buffer命令
*/
public pushActivateBuffer(buffer:WebGLRenderBuffer) {
let len = this.drawDataLen;
// 有无遍历到有效绘图操作
let drawState = false;
for(let i = len - 1; i >= 0; i--) {
let data = this.drawData[i];
if(data){
if(data.type != DRAWABLE_TYPE.BLEND && data.type != DRAWABLE_TYPE.ACT_BUFFER) {
drawState = true;
}
// 如果与上一次buffer操作之间无有效绘图,上一次操作无效
if(!drawState && data.type == DRAWABLE_TYPE.ACT_BUFFER) {
this.drawData.splice(i, 1);
this.drawDataLen--;
continue;
}
// 如果与上一次buffer操作重复,本次操作无效
// if(data.type == DRAWABLE_TYPE.ACT_BUFFER) {
// if(data.buffer == buffer) {
// return;
// } else {
// break;
// }
// }
}
}
let _data = this.drawData[this.drawDataLen] || {};
_data.type = DRAWABLE_TYPE.ACT_BUFFER;
_data.buffer = buffer;
_data.width = buffer.rootRenderTarget.width;
_data.height = buffer.rootRenderTarget.height;
this.drawData[this.drawDataLen] = _data;
this.drawDataLen++;
}
/*
* 压入enabel scissor命令
*/
public pushEnableScissor(x:number, y:number, width:number, height:number) {
let data = this.drawData[this.drawDataLen] || {};
data.type = DRAWABLE_TYPE.ENABLE_SCISSOR;
data.x = x;
data.y = y;
data.width = width;
data.height = height;
this.drawData[this.drawDataLen] = data;
this.drawDataLen++;
}
/*
* 压入disable scissor命令
*/
public pushDisableScissor() {
let data = this.drawData[this.drawDataLen] || {};
data.type = DRAWABLE_TYPE.DISABLE_SCISSOR;
this.drawData[this.drawDataLen] = data;
this.drawDataLen++;
}
/**
* 清空命令数组
*/
public clear():void {
for(let i = 0; i < this.drawDataLen; i++) {
let data = this.drawData[i];
data.type = 0;
data.count = 0;
data.texture = null;
data.filter = null;
data.uv = null;
data.value = "";
data.buffer = null;
data.width = 0;
data.height = 0;
}
this.drawDataLen = 0;
}
}
}