{"version":3,"file":"GlBackBufferSystem.mjs","sources":["../../../../src/rendering/renderers/gl/GlBackBufferSystem.ts"],"sourcesContent":["import { ExtensionType } from '../../../extensions/Extensions';\nimport { warn } from '../../../utils/logging/warn';\nimport { Geometry } from '../shared/geometry/Geometry';\nimport { Shader } from '../shared/shader/Shader';\nimport { State } from '../shared/state/State';\nimport { TextureSource } from '../shared/texture/sources/TextureSource';\nimport { Texture } from '../shared/texture/Texture';\nimport { GlProgram } from './shader/GlProgram';\n\nimport type { RenderOptions } from '../shared/system/AbstractRenderer';\nimport type { System } from '../shared/system/System';\nimport type { WebGLRenderer } from './WebGLRenderer';\n\nconst bigTriangleGeometry = new Geometry({\n    attributes: {\n        aPosition: [\n            -1.0, -1.0, // Bottom left corner\n            3.0, -1.0, // Bottom right corner, extending beyond right edge\n            -1.0, 3.0 // Top left corner, extending beyond top edge\n        ],\n    },\n});\n\n/**\n * The options for the back buffer system.\n * @category rendering\n * @property {boolean} [useBackBuffer=false] - if true will use the back buffer where required\n * @property {boolean} [antialias=false] - if true will ensure the texture is antialiased\n * @advanced\n */\nexport interface GlBackBufferOptions\n{\n    /**\n     * if true will use the back buffer where required\n     * @default false\n     */\n    useBackBuffer?: boolean;\n    /** if true will ensure the texture is antialiased */\n    antialias?: boolean;\n}\n\n/**\n * For blend modes you need to know what pixels you are actually drawing to. For this to be possible in WebGL\n * we need to render to a texture and then present that texture to the screen. This system manages that process.\n *\n * As the main scene is rendered to a texture, it means we can sample it and copy its pixels,\n * something not possible on the main canvas.\n *\n * If antialiasing is set to to true and useBackBuffer is set to true, then the back buffer will be antialiased.\n * and the main gl context will not.\n *\n * You only need to activate this back buffer if you are using a blend mode that requires it.\n *\n * to activate is simple, you pass `useBackBuffer:true` to your render options\n * @category rendering\n * @advanced\n */\nexport class GlBackBufferSystem implements System<GlBackBufferOptions>\n{\n    /** @ignore */\n    public static extension = {\n        type: [\n            ExtensionType.WebGLSystem,\n        ],\n        name: 'backBuffer',\n        priority: 1\n    } as const;\n\n    /** default options for the back buffer system */\n    public static defaultOptions: GlBackBufferOptions = {\n        /** if true will use the back buffer where required */\n        useBackBuffer: false,\n    };\n\n    /** if true, the back buffer is used */\n    public useBackBuffer = false;\n\n    private _backBufferTexture: Texture;\n    private readonly _renderer: WebGLRenderer;\n    private _targetTexture: TextureSource;\n    private _useBackBufferThisRender = false;\n    private _antialias: boolean;\n    private _state: State;\n    private _bigTriangleShader: Shader;\n\n    constructor(renderer: WebGLRenderer)\n    {\n        this._renderer = renderer;\n    }\n\n    public init(options: GlBackBufferOptions = {})\n    {\n        const { useBackBuffer, antialias } = { ...GlBackBufferSystem.defaultOptions, ...options };\n\n        this.useBackBuffer = useBackBuffer;\n\n        this._antialias = antialias;\n\n        if (!this._renderer.context.supports.msaa)\n        {\n            warn('antialiasing, is not supported on when using the back buffer');\n\n            this._antialias = false;\n        }\n\n        this._state = State.for2d();\n\n        const bigTriangleProgram = new GlProgram({\n            vertex: `\n                attribute vec2 aPosition;\n                out vec2 vUv;\n\n                void main() {\n                    gl_Position = vec4(aPosition, 0.0, 1.0);\n\n                    vUv = (aPosition + 1.0) / 2.0;\n\n                    // flip dem UVs\n                    vUv.y = 1.0 - vUv.y;\n                }`,\n            fragment: `\n                in vec2 vUv;\n                out vec4 finalColor;\n\n                uniform sampler2D uTexture;\n\n                void main() {\n                    finalColor = texture(uTexture, vUv);\n                }`,\n            name: 'big-triangle',\n        });\n\n        this._bigTriangleShader = new Shader({\n            glProgram: bigTriangleProgram,\n            resources: {\n                uTexture: Texture.WHITE.source,\n            },\n        });\n    }\n\n    /**\n     * This is called before the RenderTargetSystem is started. This is where\n     * we replace the target with the back buffer if required.\n     * @param options - The options for this render.\n     */\n    protected renderStart(options: RenderOptions)\n    {\n        const renderTarget = this._renderer.renderTarget.getRenderTarget(options.target);\n\n        this._useBackBufferThisRender = this.useBackBuffer && !!renderTarget.isRoot;\n\n        if (this._useBackBufferThisRender)\n        {\n            const renderTarget = this._renderer.renderTarget.getRenderTarget(options.target);\n\n            this._targetTexture = renderTarget.colorTexture;\n\n            options.target = this._getBackBufferTexture(renderTarget.colorTexture);\n        }\n    }\n\n    protected renderEnd()\n    {\n        this._presentBackBuffer();\n    }\n\n    private _presentBackBuffer()\n    {\n        const renderer = this._renderer;\n\n        renderer.renderTarget.finishRenderPass();\n\n        if (!this._useBackBufferThisRender) return;\n\n        renderer.renderTarget.bind(this._targetTexture, false);\n\n        this._bigTriangleShader.resources.uTexture = this._backBufferTexture.source;\n\n        renderer.encoder.draw({\n            geometry: bigTriangleGeometry,\n            shader: this._bigTriangleShader,\n            state: this._state,\n        });\n    }\n\n    private _getBackBufferTexture(targetSourceTexture: TextureSource)\n    {\n        this._backBufferTexture = this._backBufferTexture || new Texture({\n            source: new TextureSource({\n                width: targetSourceTexture.width,\n                height: targetSourceTexture.height,\n                resolution: targetSourceTexture._resolution,\n                antialias: this._antialias,\n            }),\n        });\n\n        // this will not resize if its the same size already! No extra check required\n        this._backBufferTexture.source.resize(\n            targetSourceTexture.width,\n            targetSourceTexture.height,\n            targetSourceTexture._resolution,\n        );\n\n        return this._backBufferTexture;\n    }\n\n    /** destroys the back buffer */\n    public destroy()\n    {\n        if (this._backBufferTexture)\n        {\n            this._backBufferTexture.destroy();\n            this._backBufferTexture = null;\n        }\n    }\n}\n"],"names":["renderTarget"],"mappings":"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"}