mirror of
https://github.com/photonstorm/phaser
synced 2024-11-25 22:20:44 +00:00
Create WebGLFramebufferWrapper to encapsulate state.
This commit is contained in:
parent
b591c3674a
commit
68671f0d8a
1 changed files with 184 additions and 0 deletions
184
src/renderer/webgl/wrappers/WebGLFramebufferWrapper.js
Normal file
184
src/renderer/webgl/wrappers/WebGLFramebufferWrapper.js
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
var Class = require('../../../utils/Class');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible errors that can be thrown by `gl.checkFramebufferStatus()`.
|
||||||
|
*/
|
||||||
|
var errors = {
|
||||||
|
36054: 'Incomplete Attachment',
|
||||||
|
36055: 'Missing Attachment',
|
||||||
|
36057: 'Incomplete Dimensions',
|
||||||
|
36061: 'Framebuffer Unsupported'
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @classdesc
|
||||||
|
* Wrapper for a WebGL frame buffer,
|
||||||
|
* containing all the information that was used to create it.
|
||||||
|
*
|
||||||
|
* A WebGLFramebuffer should never be exposed outside the WebGLRenderer,
|
||||||
|
* so the WebGLRenderer can handle context loss and other events
|
||||||
|
* without other systems having to be aware of it.
|
||||||
|
* Always use WebGLFramebufferWrapper instead.
|
||||||
|
*
|
||||||
|
* @method Phaser.Renderer.WebGL.WebGLRenderer#createFramebuffer
|
||||||
|
* @since 3.80.0
|
||||||
|
*
|
||||||
|
* @param {WebGLRenderingContext} gl - The WebGLRenderingContext to create the WebGLFramebuffer for.
|
||||||
|
* @param {number} width - If `addDepthStencilBuffer` is true, this controls the width of the depth stencil.
|
||||||
|
* @param {number} height - If `addDepthStencilBuffer` is true, this controls the height of the depth stencil.
|
||||||
|
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} renderTexture - The color texture where the color pixels are written.
|
||||||
|
* @param {boolean} [addDepthStencilBuffer=false] - Create a Renderbuffer for the depth stencil?
|
||||||
|
*/
|
||||||
|
var WebGLFramebufferWrapper = new Class({
|
||||||
|
initialize: function WebGLFramebufferWrapper (renderer, width, height, renderTexture, addDepthStencilBuffer)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The WebGLFramebuffer being wrapped by this class.
|
||||||
|
*
|
||||||
|
* @name Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper#webGLFramebuffer
|
||||||
|
* @type {?WebGLFramebuffer}
|
||||||
|
* @default null
|
||||||
|
* @since 3.80.0
|
||||||
|
*/
|
||||||
|
this.webGLFramebuffer = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The WebGLRenderer instance that owns this WebGLFramebufferWrapper.
|
||||||
|
*
|
||||||
|
* @name Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper#renderer
|
||||||
|
* @type {Phaser.Renderer.WebGL.WebGLRenderer}
|
||||||
|
* @since 3.80.0
|
||||||
|
*/
|
||||||
|
this.renderer = renderer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Width of the depth stencil.
|
||||||
|
*
|
||||||
|
* @name Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper#width
|
||||||
|
* @type {number}
|
||||||
|
* @since 3.80.0
|
||||||
|
*/
|
||||||
|
this.width = width;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Height of the depth stencil.
|
||||||
|
*
|
||||||
|
* @name Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper#height
|
||||||
|
* @type {number}
|
||||||
|
* @since 3.80.0
|
||||||
|
*/
|
||||||
|
this.height = height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The color texture where the color pixels are written.
|
||||||
|
*
|
||||||
|
* @name Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper#renderTexture
|
||||||
|
* @type {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper}
|
||||||
|
* @since 3.80.0
|
||||||
|
*/
|
||||||
|
this.renderTexture = renderTexture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Renderbuffer for the depth stencil?
|
||||||
|
*
|
||||||
|
* @name Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper#addDepthStencilBuffer
|
||||||
|
* @type {boolean}
|
||||||
|
* @default false
|
||||||
|
* @since 3.80.0
|
||||||
|
*/
|
||||||
|
this.addDepthStencilBuffer = !!addDepthStencilBuffer;
|
||||||
|
|
||||||
|
this.createResource();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a WebGLFramebuffer from the given parameters.
|
||||||
|
*
|
||||||
|
* This is called automatically by the constructor. It may also be
|
||||||
|
* called again if the WebGLFramebuffer needs re-creating.
|
||||||
|
*
|
||||||
|
* @method Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper#createResource
|
||||||
|
* @since 3.80.0
|
||||||
|
*/
|
||||||
|
createResource: function ()
|
||||||
|
{
|
||||||
|
var renderer = this.renderer;
|
||||||
|
var gl = renderer.gl;
|
||||||
|
var renderTexture = this.renderTexture;
|
||||||
|
var complete = 0;
|
||||||
|
var framebuffer = gl.createFramebuffer();
|
||||||
|
|
||||||
|
// This property must exist before calling `setFramebuffer`.
|
||||||
|
this.webGLFramebuffer = framebuffer;
|
||||||
|
|
||||||
|
renderer.setFramebuffer(this);
|
||||||
|
|
||||||
|
renderTexture.isRenderTexture = true;
|
||||||
|
renderTexture.isAlphaPremultiplied = false;
|
||||||
|
|
||||||
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, renderTexture.webGLTexture, 0);
|
||||||
|
|
||||||
|
complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
||||||
|
|
||||||
|
if (complete !== gl.FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
throw new Error('Framebuffer status: ' + (errors[complete] || complete));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.addDepthStencilBuffer)
|
||||||
|
{
|
||||||
|
var depthStencilBuffer = gl.createRenderbuffer();
|
||||||
|
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
|
||||||
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, this.width, this.height);
|
||||||
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.setFramebuffer(null);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys this WebGLFramebufferWrapper.
|
||||||
|
*
|
||||||
|
* @method Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper#destroy
|
||||||
|
* @since 3.80.0
|
||||||
|
*/
|
||||||
|
destroy: function ()
|
||||||
|
{
|
||||||
|
if (this.webGLFramebuffer === null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var gl = this.renderer.gl;
|
||||||
|
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, this.webGLFramebuffer);
|
||||||
|
|
||||||
|
this.renderTexture = null;
|
||||||
|
|
||||||
|
// Check for a color attachment and remove it
|
||||||
|
var colorAttachment = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||||
|
|
||||||
|
if (colorAttachment !== null)
|
||||||
|
{
|
||||||
|
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
|
||||||
|
|
||||||
|
gl.deleteTexture(colorAttachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for a depth-stencil attachment and remove it
|
||||||
|
var depthStencilAttachment = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
|
||||||
|
|
||||||
|
if (depthStencilAttachment !== null)
|
||||||
|
{
|
||||||
|
gl.deleteRenderbuffer(depthStencilAttachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||||
|
|
||||||
|
gl.deleteFramebuffer(this.webGLFramebuffer);
|
||||||
|
|
||||||
|
this.webGLFramebuffer = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = WebGLFramebufferWrapper;
|
Loading…
Reference in a new issue