Initial
This commit is contained in:
105
resources/app/client/pixi/webgl/helpers/framebuffer-snapshot.js
Normal file
105
resources/app/client/pixi/webgl/helpers/framebuffer-snapshot.js
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* Provide the necessary methods to get a snapshot of the framebuffer into a render texture.
|
||||
* Class meant to be used as a singleton.
|
||||
* Created with the precious advices of dev7355608.
|
||||
*/
|
||||
class FramebufferSnapshot {
|
||||
constructor() {
|
||||
/**
|
||||
* The RenderTexture that is the render destination for the framebuffer snapshot.
|
||||
* @type {PIXI.RenderTexture}
|
||||
*/
|
||||
this.framebufferTexture = FramebufferSnapshot.#createRenderTexture();
|
||||
|
||||
// Listen for resize events
|
||||
canvas.app.renderer.on("resize", () => this.#hasResized = true);
|
||||
}
|
||||
|
||||
/**
|
||||
* To know if we need to update the texture.
|
||||
* @type {boolean}
|
||||
*/
|
||||
#hasResized = true;
|
||||
|
||||
/**
|
||||
* A placeholder for temporary copy.
|
||||
* @type {PIXI.Rectangle}
|
||||
*/
|
||||
#tempSourceFrame = new PIXI.Rectangle();
|
||||
|
||||
/* ---------------------------------------- */
|
||||
|
||||
/**
|
||||
* Get the framebuffer texture snapshot.
|
||||
* @param {PIXI.Renderer} renderer The renderer for this context.
|
||||
* @returns {PIXI.RenderTexture} The framebuffer snapshot.
|
||||
*/
|
||||
getFramebufferTexture(renderer) {
|
||||
// Need resize?
|
||||
if ( this.#hasResized ) {
|
||||
CachedContainer.resizeRenderTexture(renderer, this.framebufferTexture);
|
||||
this.#hasResized = false;
|
||||
}
|
||||
|
||||
// Flush batched operations before anything else
|
||||
renderer.batch.flush();
|
||||
|
||||
const fb = renderer.framebuffer.current;
|
||||
const vf = this.#tempSourceFrame.copyFrom(renderer.renderTexture.viewportFrame);
|
||||
|
||||
// Inverted Y in the case of canvas
|
||||
if ( !fb ) vf.y = renderer.view.height - (vf.y + vf.height);
|
||||
|
||||
// Empty viewport
|
||||
if ( !(vf.width > 0 && vf.height > 0) ) return PIXI.Texture.WHITE;
|
||||
|
||||
// Computing bounds of the source
|
||||
let srcX = vf.x;
|
||||
let srcY = vf.y;
|
||||
let srcX2 = srcX + vf.width;
|
||||
let srcY2 = srcY + vf.height;
|
||||
|
||||
// Inverted Y in the case of canvas
|
||||
if ( !fb ) {
|
||||
srcY = renderer.view.height - 1 - srcY;
|
||||
srcY2 = srcY - vf.height;
|
||||
}
|
||||
|
||||
// Computing bounds of the destination
|
||||
let dstX = 0;
|
||||
let dstY = 0;
|
||||
let dstX2 = vf.width;
|
||||
let dstY2 = vf.height;
|
||||
|
||||
// Preparing the gl context
|
||||
const gl = renderer.gl;
|
||||
const framebufferSys = renderer.framebuffer;
|
||||
const currentFramebuffer = framebufferSys.current;
|
||||
|
||||
// Binding our render texture to the framebuffer
|
||||
framebufferSys.bind(this.framebufferTexture.framebuffer, framebufferSys.viewport);
|
||||
// Current framebuffer is binded as a read framebuffer (to prepare the blit)
|
||||
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fb?.glFramebuffers[framebufferSys.CONTEXT_UID].framebuffer);
|
||||
// Blit current framebuffer into our render texture
|
||||
gl.blitFramebuffer(srcX, srcY, srcX2, srcY2, dstX, dstY, dstX2, dstY2, gl.COLOR_BUFFER_BIT, gl.NEAREST);
|
||||
// Restore original behavior
|
||||
framebufferSys.bind(currentFramebuffer, framebufferSys.viewport);
|
||||
|
||||
return this.framebufferTexture;
|
||||
}
|
||||
|
||||
/* ---------------------------------------- */
|
||||
|
||||
/**
|
||||
* Create a render texture, provide a render method and an optional clear color.
|
||||
* @returns {PIXI.RenderTexture} A reference to the created render texture.
|
||||
*/
|
||||
static #createRenderTexture() {
|
||||
const renderer = canvas.app?.renderer;
|
||||
return PIXI.RenderTexture.create({
|
||||
width: renderer?.screen.width ?? window.innerWidth,
|
||||
height: renderer?.screen.height ?? window.innerHeight,
|
||||
resolution: renderer.resolution ?? PIXI.settings.RESOLUTION
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user