dragonbones-runtime
Version:
the tools to build dragonbones file for diffrent framework
177 lines (149 loc) • 6.64 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
* WebGLRenderTarget类
* 一个WebGL渲染目标,拥有一个frame buffer和texture
*/
export class WebGLRenderTarget extends HashObject {
private gl: WebGLRenderingContext;
// 存储着绘制结果的texture
// 某些场景下是否需要一个切换方法?
public texture: WebGLTexture;
private frameBuffer: WebGLFramebuffer;
private stencilBuffer: WebGLRenderbuffer;
// render target 的尺寸,与texture和stencil buffer的尺寸一致
public width: number;
public height: number;
// 清除色
public clearColor = [0, 0, 0, 0];
public constructor(gl: WebGLRenderingContext, width: number, height: number) {
super();
this.gl = gl;
// 如果尺寸为 0 chrome会报警
this.width = width || 1;
this.height = height || 1;
}
/**
* 重置render target的尺寸
*/
public resize(width: number, height: number): void {
let gl = this.gl;
this.width = width;
this.height = height;
if (this.frameBuffer) {
// 设置texture尺寸
gl.bindTexture(gl.TEXTURE_2D, this.texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
// gl.bindTexture(gl.TEXTURE_2D, null);
}
if (this.stencilBuffer) {
gl.deleteRenderbuffer(this.stencilBuffer);
this.stencilBuffer = null;
}
}
/**
* 激活此render target
*/
public activate(): void {
let gl = this.gl;
gl.bindFramebuffer(gl.FRAMEBUFFER, this.getFrameBuffer());
}
// 是否启用frame buffer, 默认为true
public useFrameBuffer: boolean = true;
/**
* 获取frame buffer
*/
private getFrameBuffer(): WebGLFramebuffer {
if (!this.useFrameBuffer) {
return null;
}
return this.frameBuffer;
}
public initFrameBuffer(): void {
if (!this.frameBuffer) {
let gl = this.gl;
// 创建材质
this.texture = this.createTexture();
// 创建frame buffer
this.frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);
// 绑定材质
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0);
}
}
/**
* 创建材质
* TODO 创建材质的方法可以合并
*/
private createTexture(): WebGLTexture {
let gl = this.gl;
let texture: WebGLTexture = gl.createTexture();
texture["glContext"] = gl;
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
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);
return texture;
}
/**
* 清除render target颜色缓存
*/
public clear(bind?: boolean) {
let gl = this.gl;
if (bind) {
this.activate();
}
gl.colorMask(true, true, true, true);
gl.clearColor(this.clearColor[0], this.clearColor[1], this.clearColor[2], this.clearColor[3]);
gl.clear(gl.COLOR_BUFFER_BIT);
}
public enabledStencil(): void {
if (!this.frameBuffer || this.stencilBuffer) {
return;
}
let gl = this.gl;
// 设置render buffer的尺寸
gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);// 是否需要强制绑定?
// 绑定stencil buffer
this.stencilBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, this.stencilBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, this.width, this.height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.stencilBuffer);
// 此处不解绑是否会造成bug?
// gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
public dispose():void {
WebGLUtils.deleteWebGLTexture(this.texture);
}
}
}