diff --git a/src/mol-gl/shader-code.ts b/src/mol-gl/shader-code.ts index 3778ba8ff85859b8e29edc6842d3b1d04d4187c9..10307aa1f6d6ba1f9ddd143ce89d5887743e5e61 100644 --- a/src/mol-gl/shader-code.ts +++ b/src/mol-gl/shader-code.ts @@ -6,7 +6,7 @@ import { ValueCell } from 'mol-util'; import { idFactory } from 'mol-util/id-factory'; -import { WebGLExtensions } from './webgl/context'; +import { WebGLExtensions } from './webgl/extensions'; import { isWebGL2, GLRenderingContext } from './webgl/compat'; export type DefineKind = 'boolean' | 'string' | 'number' diff --git a/src/mol-gl/webgl/compat.ts b/src/mol-gl/webgl/compat.ts index ed2da5c59020e868963163349595c8ef5e22098c..60a7e1cad3bca5cf6e3231fd576a924629889cef 100644 --- a/src/mol-gl/webgl/compat.ts +++ b/src/mol-gl/webgl/compat.ts @@ -227,7 +227,7 @@ export interface COMPAT_depth_texture { } export function getDepthTexture(gl: GLRenderingContext): COMPAT_depth_texture | null { - if(isWebGL2(gl)) { + if (isWebGL2(gl)) { return { UNSIGNED_INT_24_8: gl.UNSIGNED_INT_24_8 } diff --git a/src/mol-gl/webgl/context.ts b/src/mol-gl/webgl/context.ts index 92b32ef54ac611799bf9c73f24c0b28abfe7ebae..fa3f2d19fb8c82b48c1406518731e59c1ae8e601 100644 --- a/src/mol-gl/webgl/context.ts +++ b/src/mol-gl/webgl/context.ts @@ -6,10 +6,12 @@ import { createProgramCache, ProgramCache } from './program' import { createShaderCache, ShaderCache } from './shader' -import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, getVertexArrayObject, isWebGL2, COMPAT_element_index_uint, getElementIndexUint, COMPAT_texture_float, getTextureFloat, COMPAT_texture_float_linear, getTextureFloatLinear, COMPAT_blend_minmax, getBlendMinMax, getFragDepth, COMPAT_frag_depth, COMPAT_color_buffer_float, getColorBufferFloat, COMPAT_draw_buffers, getDrawBuffers, getShaderTextureLod, COMPAT_shader_texture_lod, getDepthTexture, COMPAT_depth_texture } from './compat'; +import { GLRenderingContext, isWebGL2 } from './compat'; import { createFramebufferCache, FramebufferCache, checkFramebufferStatus } from './framebuffer'; import { Scheduler } from 'mol-task'; import { isDebugMode } from 'mol-util/debug'; +import { createExtensions, WebGLExtensions } from './extensions'; +import { WebGLState, createState } from './state'; export function getGLContext(canvas: HTMLCanvasElement, contextAttributes?: WebGLContextAttributes): GLRenderingContext | null { function getContext(contextId: 'webgl' | 'experimental-webgl' | 'webgl2') { @@ -149,90 +151,6 @@ export function createImageData(buffer: ArrayLike<number>, width: number, height // -export type WebGLExtensions = { - instancedArrays: COMPAT_instanced_arrays - standardDerivatives: COMPAT_standard_derivatives - blendMinMax: COMPAT_blend_minmax - textureFloat: COMPAT_texture_float - textureFloatLinear: COMPAT_texture_float_linear - elementIndexUint: COMPAT_element_index_uint - depthTexture: COMPAT_depth_texture - - vertexArrayObject: COMPAT_vertex_array_object | null - fragDepth: COMPAT_frag_depth | null - colorBufferFloat: COMPAT_color_buffer_float | null - drawBuffers: COMPAT_draw_buffers | null - shaderTextureLod: COMPAT_shader_texture_lod | null -} - -function createExtensions(gl: GLRenderingContext): WebGLExtensions { - const instancedArrays = getInstancedArrays(gl) - if (instancedArrays === null) { - throw new Error('Could not find support for "instanced_arrays"') - } - const standardDerivatives = getStandardDerivatives(gl) - if (standardDerivatives === null) { - throw new Error('Could not find support for "standard_derivatives"') - } - const blendMinMax = getBlendMinMax(gl) - if (blendMinMax === null) { - throw new Error('Could not find support for "blend_minmax"') - } - const textureFloat = getTextureFloat(gl) - if (textureFloat === null) { - throw new Error('Could not find support for "texture_float"') - } - const textureFloatLinear = getTextureFloatLinear(gl) - if (textureFloatLinear === null) { - throw new Error('Could not find support for "texture_float_linear"') - } - const elementIndexUint = getElementIndexUint(gl) - if (elementIndexUint === null) { - throw new Error('Could not find support for "element_index_uint"') - } - const depthTexture = getDepthTexture(gl) - if (depthTexture === null) { - throw new Error('Could not find support for "depth_texture"') - } - - const vertexArrayObject = getVertexArrayObject(gl) - if (vertexArrayObject === null) { - console.log('Could not find support for "vertex_array_object"') - } - const fragDepth = getFragDepth(gl) - if (fragDepth === null) { - console.log('Could not find support for "frag_depth"') - } - const colorBufferFloat = getColorBufferFloat(gl) - if (colorBufferFloat === null) { - console.log('Could not find support for "color_buffer_float"') - } - const drawBuffers = getDrawBuffers(gl) - if (drawBuffers === null) { - console.log('Could not find support for "draw_buffers"') - } - const shaderTextureLod = getShaderTextureLod(gl) - if (shaderTextureLod === null) { - console.log('Could not find support for "shader_texture_lod"') - } - - return { - instancedArrays, - standardDerivatives, - blendMinMax, - textureFloat, - textureFloatLinear, - elementIndexUint, - depthTexture, - - vertexArrayObject, - fragDepth, - colorBufferFloat, - drawBuffers, - shaderTextureLod, - } -} - export type WebGLStats = { bufferCount: number framebufferCount: number @@ -259,165 +177,7 @@ function createStats(): WebGLStats { } } -export type WebGLState = { - currentProgramId: number - currentMaterialId: number - currentRenderItemId: number - - /** - * specifies which WebGL capability to enable - * - `gl.BLEND`: blending of the computed fragment color values - * - `gl.CULL_FACE`: culling of polygons - * - `gl.DEPTH_TEST`: depth comparisons and updates to the depth buffer - * - `gl.DITHER`: dithering of color components before they get written to the color buffer - * - `gl.POLYGON_OFFSET_FILL`: adding an offset to depth values of polygon's fragments - * - `gl.SAMPLE_ALPHA_TO_COVERAGE`: computation of a temporary coverage value determined by the alpha value - * - `gl.SAMPLE_COVERAGE`: ANDing the fragment's coverage with the temporary coverage value - * - `gl.SCISSOR_TEST`: scissor test that discards fragments that are outside of the scissor rectangle - * - `gl.STENCIL_TEST`: stencil testing and updates to the stencil buffer - */ - enable: (cap: number) => void - /** - * specifies which WebGL capability to disable - * - `gl.BLEND`: blending of the computed fragment color values - * - `gl.CULL_FACE`: culling of polygons - * - `gl.DEPTH_TEST`: depth comparisons and updates to the depth buffer - * - `gl.DITHER`: dithering of color components before they get written to the color buffer - * - `gl.POLYGON_OFFSET_FILL`: adding an offset to depth values of polygon's fragments - * - `gl.SAMPLE_ALPHA_TO_COVERAGE`: computation of a temporary coverage value determined by the alpha value - * - `gl.SAMPLE_COVERAGE`: ANDing the fragment's coverage with the temporary coverage value - * - `gl.SCISSOR_TEST`: scissor test that discards fragments that are outside of the scissor rectangle - * - `gl.STENCIL_TEST`: stencil testing and updates to the stencil buffer - */ - disable: (cap: number) => void - - /** specifies whether polygons are front- or back-facing by setting a winding orientation */ - frontFace: (mode: number) => void - /** specifies whether or not front- and/or back-facing polygons can be culled */ - cullFace: (mode: number) => void - /** sets whether writing into the depth buffer is enabled or disabled */ - depthMask: (flag: boolean) => void - /** sets which color components to enable or to disable */ - colorMask: (red: boolean, green: boolean, blue: boolean, alpha: boolean) => void - /** specifies the color values used when clearing color buffers, used when calling `gl.clear`, clamped to [0, 1] */ - clearColor: (red: number, green: number, blue: number, alpha: number) => void - - /** defines which function is used for blending pixel arithmetic */ - blendFunc: (src: number, dst: number) => void - /** defines which function is used for blending pixel arithmetic for RGB and alpha components separately */ - blendFuncSeparate: (srcRGB: number, dstRGB: number, srcAlpha: number, dstAlpha: number) => void - - /** set both the RGB blend equation and alpha blend equation to a single equation, determines how a new pixel is combined with an existing */ - blendEquation: (mode: number) => void - /** set the RGB blend equation and alpha blend equation separately, determines how a new pixel is combined with an existing */ - blendEquationSeparate: (modeRGB: number, modeAlpha: number) => void -} - -function createState(gl: GLRenderingContext): WebGLState { - const enabledCapabilities: { [k: number]: boolean } = {} - - let currentFrontFace = gl.getParameter(gl.FRONT_FACE) - let currentCullFace = gl.getParameter(gl.CULL_FACE_MODE) - let currentDepthMask = gl.getParameter(gl.DEPTH_WRITEMASK) - let currentColorMask = gl.getParameter(gl.COLOR_WRITEMASK) - let currentClearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE) - - let currentBlendSrcRGB = gl.getParameter(gl.BLEND_SRC_RGB) - let currentBlendDstRGB = gl.getParameter(gl.BLEND_DST_RGB) - let currentBlendSrcAlpha = gl.getParameter(gl.BLEND_SRC_ALPHA) - let currentBlendDstAlpha = gl.getParameter(gl.BLEND_DST_ALPHA) - - let currentBlendEqRGB = gl.getParameter(gl.BLEND_EQUATION_RGB) - let currentBlendEqAlpha = gl.getParameter(gl.BLEND_EQUATION_ALPHA) - - return { - currentProgramId: -1, - currentMaterialId: -1, - currentRenderItemId: -1, - - enable: (cap: number) => { - if (enabledCapabilities[cap] !== true ) { - gl.enable(cap) - enabledCapabilities[cap] = true - } - }, - disable: (cap: number) => { - if (enabledCapabilities[cap] !== false) { - gl.disable(cap) - enabledCapabilities[cap] = false - } - }, - frontFace: (mode: number) => { - if (mode !== currentFrontFace) { - gl.frontFace(mode) - currentFrontFace = mode - } - }, - cullFace: (mode: number) => { - if (mode !== currentCullFace) { - gl.cullFace(mode) - currentCullFace = mode - } - }, - depthMask: (flag: boolean) => { - if (flag !== currentDepthMask) { - gl.depthMask(flag) - currentDepthMask = flag - } - }, - colorMask: (red: boolean, green: boolean, blue: boolean, alpha: boolean) => { - if (red !== currentColorMask[0] || green !== currentColorMask[1] || blue !== currentColorMask[2] || alpha !== currentColorMask[3]) - gl.colorMask(red, green, blue, alpha) - currentColorMask[0] = red - currentColorMask[1] = green - currentColorMask[2] = blue - currentColorMask[3] = alpha - }, - clearColor: (red: number, green: number, blue: number, alpha: number) => { - if (red !== currentClearColor[0] || green !== currentClearColor[1] || blue !== currentClearColor[2] || alpha !== currentClearColor[3]) - gl.clearColor(red, green, blue, alpha) - currentClearColor[0] = red - currentClearColor[1] = green - currentClearColor[2] = blue - currentClearColor[3] = alpha - }, - - blendFunc: (src: number, dst: number) => { - if (src !== currentBlendSrcRGB || dst !== currentBlendDstRGB || src !== currentBlendSrcAlpha || dst !== currentBlendDstAlpha) { - gl.blendFunc(src, dst) - currentBlendSrcRGB = src - currentBlendDstRGB = dst - currentBlendSrcAlpha = src - currentBlendDstAlpha = dst - } - }, - blendFuncSeparate: (srcRGB: number, dstRGB: number, srcAlpha: number, dstAlpha: number) => { - if (srcRGB !== currentBlendSrcRGB || dstRGB !== currentBlendDstRGB || srcAlpha !== currentBlendSrcAlpha || dstAlpha !== currentBlendDstAlpha) { - gl.blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha) - currentBlendSrcRGB = srcRGB - currentBlendDstRGB = dstRGB - currentBlendSrcAlpha = srcAlpha - currentBlendDstAlpha = dstAlpha - } - }, - - blendEquation: (mode: number) => { - if (mode !== currentBlendEqRGB || mode !== currentBlendEqAlpha) { - gl.blendEquation(mode) - currentBlendEqRGB = mode - currentBlendEqAlpha = mode - } - }, - blendEquationSeparate: (modeRGB: number, modeAlpha: number) => { - if (modeRGB !== currentBlendEqRGB || modeAlpha !== currentBlendEqAlpha) { - gl.blendEquationSeparate(modeRGB, modeAlpha) - currentBlendEqRGB = modeRGB - currentBlendEqAlpha = modeAlpha - } - } - } -} /** A WebGL context object, including the rendering context, resource caches and counts */ export interface WebGLContext { diff --git a/src/mol-gl/webgl/extensions.ts b/src/mol-gl/webgl/extensions.ts new file mode 100644 index 0000000000000000000000000000000000000000..dbc00402875c50d25ad2157828aadc5cd81f994d --- /dev/null +++ b/src/mol-gl/webgl/extensions.ts @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, getVertexArrayObject, COMPAT_element_index_uint, getElementIndexUint, COMPAT_texture_float, getTextureFloat, COMPAT_texture_float_linear, getTextureFloatLinear, COMPAT_blend_minmax, getBlendMinMax, getFragDepth, COMPAT_frag_depth, COMPAT_color_buffer_float, getColorBufferFloat, COMPAT_draw_buffers, getDrawBuffers, getShaderTextureLod, COMPAT_shader_texture_lod, getDepthTexture, COMPAT_depth_texture } from './compat'; + +export type WebGLExtensions = { + instancedArrays: COMPAT_instanced_arrays + standardDerivatives: COMPAT_standard_derivatives + blendMinMax: COMPAT_blend_minmax + textureFloat: COMPAT_texture_float + textureFloatLinear: COMPAT_texture_float_linear + elementIndexUint: COMPAT_element_index_uint + depthTexture: COMPAT_depth_texture + + vertexArrayObject: COMPAT_vertex_array_object | null + fragDepth: COMPAT_frag_depth | null + colorBufferFloat: COMPAT_color_buffer_float | null + drawBuffers: COMPAT_draw_buffers | null + shaderTextureLod: COMPAT_shader_texture_lod | null +} + +export function createExtensions(gl: GLRenderingContext): WebGLExtensions { + const instancedArrays = getInstancedArrays(gl) + if (instancedArrays === null) { + throw new Error('Could not find support for "instanced_arrays"') + } + const standardDerivatives = getStandardDerivatives(gl) + if (standardDerivatives === null) { + throw new Error('Could not find support for "standard_derivatives"') + } + const blendMinMax = getBlendMinMax(gl) + if (blendMinMax === null) { + throw new Error('Could not find support for "blend_minmax"') + } + const textureFloat = getTextureFloat(gl) + if (textureFloat === null) { + throw new Error('Could not find support for "texture_float"') + } + const textureFloatLinear = getTextureFloatLinear(gl) + if (textureFloatLinear === null) { + throw new Error('Could not find support for "texture_float_linear"') + } + const elementIndexUint = getElementIndexUint(gl) + if (elementIndexUint === null) { + throw new Error('Could not find support for "element_index_uint"') + } + const depthTexture = getDepthTexture(gl) + if (depthTexture === null) { + throw new Error('Could not find support for "depth_texture"') + } + + const vertexArrayObject = getVertexArrayObject(gl) + if (vertexArrayObject === null) { + console.log('Could not find support for "vertex_array_object"') + } + const fragDepth = getFragDepth(gl) + if (fragDepth === null) { + console.log('Could not find support for "frag_depth"') + } + const colorBufferFloat = getColorBufferFloat(gl) + if (colorBufferFloat === null) { + console.log('Could not find support for "color_buffer_float"') + } + const drawBuffers = getDrawBuffers(gl) + if (drawBuffers === null) { + console.log('Could not find support for "draw_buffers"') + } + const shaderTextureLod = getShaderTextureLod(gl) + if (shaderTextureLod === null) { + console.log('Could not find support for "shader_texture_lod"') + } + + return { + instancedArrays, + standardDerivatives, + blendMinMax, + textureFloat, + textureFloatLinear, + elementIndexUint, + depthTexture, + + vertexArrayObject, + fragDepth, + colorBufferFloat, + drawBuffers, + shaderTextureLod, + } +} \ No newline at end of file diff --git a/src/mol-gl/webgl/program.ts b/src/mol-gl/webgl/program.ts index 5997cc71165cb322693132650ee8412add4fe475..8d393ac7c3207c34e9082ea0084be7950f41b87c 100644 --- a/src/mol-gl/webgl/program.ts +++ b/src/mol-gl/webgl/program.ts @@ -5,7 +5,8 @@ */ import { ShaderCode, DefineValues, addShaderDefines } from '../shader-code' -import { WebGLExtensions, WebGLState } from './context'; +import { WebGLState } from './state'; +import { WebGLExtensions } from './extensions'; import { getUniformSetters, UniformsList, getUniformType } from './uniform'; import { AttributeBuffers, getAttribType } from './buffer'; import { TextureId, Textures } from './texture'; diff --git a/src/mol-gl/webgl/state.ts b/src/mol-gl/webgl/state.ts new file mode 100644 index 0000000000000000000000000000000000000000..f7a2ea4c7b518a06677170057043d1bccf4f37bf --- /dev/null +++ b/src/mol-gl/webgl/state.ts @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info. + * + * @author Alexander Rose <alexander.rose@weirdbyte.de> + */ + +import { GLRenderingContext } from './compat'; + +export type WebGLState = { + currentProgramId: number + currentMaterialId: number + currentRenderItemId: number + + /** + * specifies which WebGL capability to enable + * - `gl.BLEND`: blending of the computed fragment color values + * - `gl.CULL_FACE`: culling of polygons + * - `gl.DEPTH_TEST`: depth comparisons and updates to the depth buffer + * - `gl.DITHER`: dithering of color components before they get written to the color buffer + * - `gl.POLYGON_OFFSET_FILL`: adding an offset to depth values of polygon's fragments + * - `gl.SAMPLE_ALPHA_TO_COVERAGE`: computation of a temporary coverage value determined by the alpha value + * - `gl.SAMPLE_COVERAGE`: ANDing the fragment's coverage with the temporary coverage value + * - `gl.SCISSOR_TEST`: scissor test that discards fragments that are outside of the scissor rectangle + * - `gl.STENCIL_TEST`: stencil testing and updates to the stencil buffer + */ + enable: (cap: number) => void + /** + * specifies which WebGL capability to disable + * - `gl.BLEND`: blending of the computed fragment color values + * - `gl.CULL_FACE`: culling of polygons + * - `gl.DEPTH_TEST`: depth comparisons and updates to the depth buffer + * - `gl.DITHER`: dithering of color components before they get written to the color buffer + * - `gl.POLYGON_OFFSET_FILL`: adding an offset to depth values of polygon's fragments + * - `gl.SAMPLE_ALPHA_TO_COVERAGE`: computation of a temporary coverage value determined by the alpha value + * - `gl.SAMPLE_COVERAGE`: ANDing the fragment's coverage with the temporary coverage value + * - `gl.SCISSOR_TEST`: scissor test that discards fragments that are outside of the scissor rectangle + * - `gl.STENCIL_TEST`: stencil testing and updates to the stencil buffer + */ + disable: (cap: number) => void + + /** specifies whether polygons are front- or back-facing by setting a winding orientation */ + frontFace: (mode: number) => void + /** specifies whether or not front- and/or back-facing polygons can be culled */ + cullFace: (mode: number) => void + /** sets whether writing into the depth buffer is enabled or disabled */ + depthMask: (flag: boolean) => void + /** sets which color components to enable or to disable */ + colorMask: (red: boolean, green: boolean, blue: boolean, alpha: boolean) => void + /** specifies the color values used when clearing color buffers, used when calling `gl.clear`, clamped to [0, 1] */ + clearColor: (red: number, green: number, blue: number, alpha: number) => void + + /** defines which function is used for blending pixel arithmetic */ + blendFunc: (src: number, dst: number) => void + /** defines which function is used for blending pixel arithmetic for RGB and alpha components separately */ + blendFuncSeparate: (srcRGB: number, dstRGB: number, srcAlpha: number, dstAlpha: number) => void + + /** set both the RGB blend equation and alpha blend equation to a single equation, determines how a new pixel is combined with an existing */ + blendEquation: (mode: number) => void + /** set the RGB blend equation and alpha blend equation separately, determines how a new pixel is combined with an existing */ + blendEquationSeparate: (modeRGB: number, modeAlpha: number) => void +} + +export function createState(gl: GLRenderingContext): WebGLState { + const enabledCapabilities: { [k: number]: boolean } = {} + + let currentFrontFace = gl.getParameter(gl.FRONT_FACE) + let currentCullFace = gl.getParameter(gl.CULL_FACE_MODE) + let currentDepthMask = gl.getParameter(gl.DEPTH_WRITEMASK) + let currentColorMask = gl.getParameter(gl.COLOR_WRITEMASK) + let currentClearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE) + + let currentBlendSrcRGB = gl.getParameter(gl.BLEND_SRC_RGB) + let currentBlendDstRGB = gl.getParameter(gl.BLEND_DST_RGB) + let currentBlendSrcAlpha = gl.getParameter(gl.BLEND_SRC_ALPHA) + let currentBlendDstAlpha = gl.getParameter(gl.BLEND_DST_ALPHA) + + let currentBlendEqRGB = gl.getParameter(gl.BLEND_EQUATION_RGB) + let currentBlendEqAlpha = gl.getParameter(gl.BLEND_EQUATION_ALPHA) + + return { + currentProgramId: -1, + currentMaterialId: -1, + currentRenderItemId: -1, + + enable: (cap: number) => { + if (enabledCapabilities[cap] !== true ) { + gl.enable(cap) + enabledCapabilities[cap] = true + } + }, + disable: (cap: number) => { + if (enabledCapabilities[cap] !== false) { + gl.disable(cap) + enabledCapabilities[cap] = false + } + }, + + frontFace: (mode: number) => { + if (mode !== currentFrontFace) { + gl.frontFace(mode) + currentFrontFace = mode + } + }, + cullFace: (mode: number) => { + if (mode !== currentCullFace) { + gl.cullFace(mode) + currentCullFace = mode + } + }, + depthMask: (flag: boolean) => { + if (flag !== currentDepthMask) { + gl.depthMask(flag) + currentDepthMask = flag + } + }, + colorMask: (red: boolean, green: boolean, blue: boolean, alpha: boolean) => { + if (red !== currentColorMask[0] || green !== currentColorMask[1] || blue !== currentColorMask[2] || alpha !== currentColorMask[3]) + gl.colorMask(red, green, blue, alpha) + currentColorMask[0] = red + currentColorMask[1] = green + currentColorMask[2] = blue + currentColorMask[3] = alpha + }, + clearColor: (red: number, green: number, blue: number, alpha: number) => { + if (red !== currentClearColor[0] || green !== currentClearColor[1] || blue !== currentClearColor[2] || alpha !== currentClearColor[3]) + gl.clearColor(red, green, blue, alpha) + currentClearColor[0] = red + currentClearColor[1] = green + currentClearColor[2] = blue + currentClearColor[3] = alpha + }, + + blendFunc: (src: number, dst: number) => { + if (src !== currentBlendSrcRGB || dst !== currentBlendDstRGB || src !== currentBlendSrcAlpha || dst !== currentBlendDstAlpha) { + gl.blendFunc(src, dst) + currentBlendSrcRGB = src + currentBlendDstRGB = dst + currentBlendSrcAlpha = src + currentBlendDstAlpha = dst + } + }, + blendFuncSeparate: (srcRGB: number, dstRGB: number, srcAlpha: number, dstAlpha: number) => { + if (srcRGB !== currentBlendSrcRGB || dstRGB !== currentBlendDstRGB || srcAlpha !== currentBlendSrcAlpha || dstAlpha !== currentBlendDstAlpha) { + gl.blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha) + currentBlendSrcRGB = srcRGB + currentBlendDstRGB = dstRGB + currentBlendSrcAlpha = srcAlpha + currentBlendDstAlpha = dstAlpha + } + }, + + blendEquation: (mode: number) => { + if (mode !== currentBlendEqRGB || mode !== currentBlendEqAlpha) { + gl.blendEquation(mode) + currentBlendEqRGB = mode + currentBlendEqAlpha = mode + } + }, + blendEquationSeparate: (modeRGB: number, modeAlpha: number) => { + if (modeRGB !== currentBlendEqRGB || modeAlpha !== currentBlendEqAlpha) { + gl.blendEquationSeparate(modeRGB, modeAlpha) + currentBlendEqRGB = modeRGB + currentBlendEqAlpha = modeAlpha + } + } + } +} \ No newline at end of file