@lightningjs/renderer
Advanced tools
Comparing version 2.13.0 to 3.0.0-beta1
@@ -20,2 +20,8 @@ /** | ||
export { CanvasTextRenderer } from '../src/core/text-rendering/renderers/CanvasTextRenderer.js'; | ||
export { CanvasCoreRenderer } from '../src/core/renderers/canvas/CanvasCoreRenderer.js'; | ||
export { CanvasRenderer } from '../src/core/renderers/canvas/CanvasRenderer.js'; | ||
export { CanvasTexture } from '../src/core/renderers/canvas/CanvasTexture.js'; | ||
export * from '../src/core/renderers/canvas/CanvasShaderNode.js'; | ||
/** | ||
* @deprecated Use CanvasRenderer. | ||
*/ | ||
export { CanvasRenderer as CanvasCoreRenderer } from '../src/core/renderers/canvas/CanvasRenderer.js'; |
@@ -38,3 +38,9 @@ /* | ||
export { CanvasTextRenderer } from '../src/core/text-rendering/renderers/CanvasTextRenderer.js'; | ||
export { CanvasCoreRenderer } from '../src/core/renderers/canvas/CanvasCoreRenderer.js'; | ||
export { CanvasRenderer } from '../src/core/renderers/canvas/CanvasRenderer.js'; | ||
export { CanvasTexture } from '../src/core/renderers/canvas/CanvasTexture.js'; | ||
export * from '../src/core/renderers/canvas/CanvasShaderNode.js'; | ||
/** | ||
* @deprecated Use CanvasRenderer. | ||
*/ | ||
export { CanvasRenderer as CanvasCoreRenderer } from '../src/core/renderers/canvas/CanvasRenderer.js'; | ||
//# sourceMappingURL=canvas.js.map |
@@ -22,4 +22,2 @@ /** | ||
export * from '../src/main-api/Renderer.js'; | ||
export * from '../src/main-api/ShaderController.js'; | ||
export * from '../src/main-api/DynamicShaderController.js'; | ||
export * from '../src/common/IAnimationController.js'; | ||
@@ -29,13 +27,14 @@ export * from '../src/common/CommonTypes.js'; | ||
export type { MemoryInfo } from '../src/core/TextureMemoryManager.js'; | ||
export type { ShaderMap, EffectMap } from '../src/core/CoreShaderManager.js'; | ||
export type { TextRendererMap } from '../src/core/text-rendering/renderers/TextRenderer.js'; | ||
export type { TrFontFaceMap } from '../src/core/text-rendering/font-face-types/TrFontFace.js'; | ||
export type { AnimationSettings } from '../src/core/animations/CoreAnimation.js'; | ||
export type { EffectProps, FadeOutEffectProps, LinearGradientEffectProps, RadialGradientEffectProps, GrayscaleEffectProps, GlitchEffectProps, RadialProgressEffectProps, HolePunchEffectProps, } from '../src/core/CoreShaderManager.js'; | ||
export type { WebGlCoreRenderer } from '../src/core/renderers/webgl/WebGlCoreRenderer.js'; | ||
export type { WebGlCoreCtxTexture } from '../src/core/renderers/webgl/WebGlCoreCtxTexture.js'; | ||
export type { Inspector } from '../src/main-api/Inspector.js'; | ||
export type { CoreNodeRenderState } from '../src/core/CoreNode.js'; | ||
export * from '../src/core/renderers/webgl/WebGlCoreShader.js'; | ||
export * from '../src/core/renderers/webgl/shaders/effects/ShaderEffect.js'; | ||
export * from '../src/core/renderers/CoreShaderNode.js'; | ||
export * from '../src/core/shaders/templates/BorderTemplate.js'; | ||
export * from '../src/core/shaders/templates/HolePunchTemplate.js'; | ||
export * from '../src/core/shaders/templates/RoundedTemplate.js'; | ||
export * from '../src/core/shaders/templates/LinearGradientTemplate.js'; | ||
export * from '../src/core/shaders/templates/RadialGradientTemplate.js'; | ||
export * from '../src/core/renderers/webgl/WebGlShaderProgram.js'; | ||
export type { ShaderProgramSources } from '../src/core/renderers/webgl/internal/ShaderUtils.js'; | ||
@@ -48,1 +47,9 @@ export * from '../src/core/textures/Texture.js'; | ||
export type * from '../src/core/Stage.js'; | ||
/** | ||
* @deprecated Use `import { WebGlRenderer } @lightningjs/renderer/webgl` instead | ||
*/ | ||
export type { WebGlRenderer as WebGlCoreRenderer } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
/** | ||
* @deprecated Use `import { WebGlCtxTexture } @lightningjs/renderer/webgl` instead | ||
*/ | ||
export type { WebGlCtxTexture as WebGlCoreCtxTexture } from '../src/core/renderers/webgl/WebGlCtxTexture.js'; |
@@ -40,4 +40,2 @@ /* | ||
export * from '../src/main-api/Renderer.js'; | ||
export * from '../src/main-api/ShaderController.js'; | ||
export * from '../src/main-api/DynamicShaderController.js'; | ||
export * from '../src/common/IAnimationController.js'; | ||
@@ -48,5 +46,10 @@ export * from '../src/common/CommonTypes.js'; | ||
export { CoreTextureManager, } from '../src/core/CoreTextureManager.js'; | ||
export * from '../src/core/renderers/CoreShaderNode.js'; | ||
export * from '../src/core/shaders/templates/BorderTemplate.js'; | ||
export * from '../src/core/shaders/templates/HolePunchTemplate.js'; | ||
export * from '../src/core/shaders/templates/RoundedTemplate.js'; | ||
export * from '../src/core/shaders/templates/LinearGradientTemplate.js'; | ||
export * from '../src/core/shaders/templates/RadialGradientTemplate.js'; | ||
// Shaders | ||
export * from '../src/core/renderers/webgl/WebGlCoreShader.js'; | ||
export * from '../src/core/renderers/webgl/shaders/effects/ShaderEffect.js'; | ||
export * from '../src/core/renderers/webgl/WebGlShaderProgram.js'; | ||
// Textures | ||
@@ -53,0 +56,0 @@ export * from '../src/core/textures/Texture.js'; |
@@ -19,2 +19,10 @@ /** | ||
export { SdfTextRenderer } from '../src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js'; | ||
export { WebGlCoreRenderer } from '../src/core/renderers/webgl/WebGlCoreRenderer.js'; | ||
export { WebGlRenderer } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
export { WebGlCtxTexture } from '../src/core/renderers/webgl/WebGlCtxTexture.js'; | ||
export * from '../src/core/renderers/webgl/WebGlShaderNode.js'; | ||
/** | ||
* @deprecated Use WebGlRenderer. | ||
*/ | ||
export { WebGlRenderer as WebGlCoreRenderer } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
export { WebGlRenderer as WebGlCoreCtxTexture } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
export * as shaders from './webgl-shaders.js'; |
@@ -37,3 +37,11 @@ /* | ||
export { SdfTextRenderer } from '../src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js'; | ||
export { WebGlCoreRenderer } from '../src/core/renderers/webgl/WebGlCoreRenderer.js'; | ||
export { WebGlRenderer } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
export { WebGlCtxTexture } from '../src/core/renderers/webgl/WebGlCtxTexture.js'; | ||
export * from '../src/core/renderers/webgl/WebGlShaderNode.js'; | ||
/** | ||
* @deprecated Use WebGlRenderer. | ||
*/ | ||
export { WebGlRenderer as WebGlCoreRenderer } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
export { WebGlRenderer as WebGlCoreCtxTexture } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
export * as shaders from './webgl-shaders.js'; | ||
//# sourceMappingURL=webgl.js.map |
@@ -26,3 +26,2 @@ import { type CoreNode, type CoreNodeAnimateProps } from '../CoreNode.js'; | ||
propValuesMap: PropValuesMap; | ||
dynPropValuesMap: PropValuesMap | undefined; | ||
constructor(node: CoreNode, props: Partial<CoreNodeAnimateProps>, settings: Partial<AnimationSettings>); | ||
@@ -29,0 +28,0 @@ reset(): void; |
@@ -32,3 +32,2 @@ /* | ||
propValuesMap = {}; | ||
dynPropValuesMap = undefined; | ||
constructor(node, props, settings) { | ||
@@ -48,7 +47,11 @@ super(); | ||
} | ||
else if (node.shader.type !== 'DynamicShader') { | ||
else if (key === 'shaderProps' && node.shader !== null) { | ||
this.propValuesMap['shaderProps'] = {}; | ||
for (const key in props.shaderProps) { | ||
let start = node.shader.props[key]; | ||
if (Array.isArray(start) === true) { | ||
start = start[0]; | ||
} | ||
this.propValuesMap['shaderProps'][key] = { | ||
start: node.shader.props[key], | ||
start, | ||
target: props.shaderProps[key], | ||
@@ -58,21 +61,2 @@ }; | ||
} | ||
else { | ||
const shaderPropKeys = Object.keys(props.shaderProps); | ||
const spLength = shaderPropKeys.length; | ||
this.dynPropValuesMap = {}; | ||
for (let j = 0; j < spLength; j++) { | ||
const effectName = shaderPropKeys[j]; | ||
const effect = props.shaderProps[effectName]; | ||
this.dynPropValuesMap[effectName] = {}; | ||
const effectProps = Object.entries(effect); | ||
const eLength = effectProps.length; | ||
for (let k = 0; k < eLength; k++) { | ||
const [key, value] = effectProps[k]; | ||
this.dynPropValuesMap[effectName][key] = { | ||
start: node.shader.props[effectName][key], | ||
target: value, | ||
}; | ||
} | ||
} | ||
} | ||
} | ||
@@ -115,12 +99,2 @@ const easing = settings.easing || 'linear'; | ||
} | ||
if (this.dynPropValuesMap !== undefined) { | ||
const dynEntries = Object.keys(this.dynPropValuesMap); | ||
const dynEntriesL = dynEntries.length; | ||
if (dynEntriesL > 0) { | ||
for (let i = 0; i < dynEntriesL; i++) { | ||
const key = dynEntries[i]; | ||
this.restoreValues(this.node.shader.props[key], this.dynPropValuesMap[key]); | ||
} | ||
} | ||
} | ||
} | ||
@@ -146,12 +120,2 @@ reverseValues(valueMap) { | ||
} | ||
if (this.dynPropValuesMap !== undefined) { | ||
const dynEntries = Object.keys(this.dynPropValuesMap); | ||
const dynEntriesL = dynEntries.length; | ||
if (dynEntriesL > 0) { | ||
for (let i = 0; i < dynEntriesL; i++) { | ||
const key = dynEntries[i]; | ||
this.reverseValues(this.dynPropValuesMap[key]); | ||
} | ||
} | ||
} | ||
// restore stop method if we are not looping | ||
@@ -243,12 +207,2 @@ if (!this.settings.loop) { | ||
} | ||
if (this.dynPropValuesMap !== undefined) { | ||
const dynEntries = Object.keys(this.dynPropValuesMap); | ||
const dynEntriesL = dynEntries.length; | ||
if (dynEntriesL > 0) { | ||
for (let i = 0; i < dynEntriesL; i++) { | ||
const key = dynEntries[i]; | ||
this.updateValues(this.node.shader.props[key], this.dynPropValuesMap[key], easing); | ||
} | ||
} | ||
} | ||
if (this.progress < 1) { | ||
@@ -255,0 +209,0 @@ this.emit('tick', { progress: this.progress }); |
@@ -12,3 +12,3 @@ import type { TextureOptions } from './CoreTextureManager.js'; | ||
import type { IAnimationController } from '../common/IAnimationController.js'; | ||
import type { BaseShaderController } from '../main-api/ShaderController.js'; | ||
import type { CoreShaderNode } from './renderers/CoreShaderNode.js'; | ||
export declare enum CoreNodeRenderState { | ||
@@ -129,3 +129,7 @@ Init = 0, | ||
*/ | ||
All = 14335 | ||
All = 14335, | ||
/** | ||
* RecalcUniforms | ||
*/ | ||
RecalcUniforms = 16384 | ||
} | ||
@@ -379,3 +383,3 @@ /** | ||
*/ | ||
shader: BaseShaderController; | ||
shader: CoreShaderNode<any> | null; | ||
/** | ||
@@ -825,4 +829,4 @@ * Image URL | ||
private clearRTTInheritance; | ||
get shader(): BaseShaderController; | ||
set shader(value: BaseShaderController); | ||
get shader(): CoreShaderNode<any> | null; | ||
set shader(shader: CoreShaderNode<any> | null); | ||
get src(): string | null; | ||
@@ -829,0 +833,0 @@ set src(imageUrl: string | null); |
@@ -150,2 +150,6 @@ /* | ||
UpdateType[UpdateType["All"] = 14335] = "All"; | ||
/** | ||
* RecalcUniforms | ||
*/ | ||
UpdateType[UpdateType["RecalcUniforms"] = 16384] = "RecalcUniforms"; | ||
})(UpdateType || (UpdateType = {})); | ||
@@ -197,12 +201,13 @@ /** | ||
this.stage = stage; | ||
this.props = { | ||
...props, | ||
this.props = Object.assign({}, props, { | ||
parent: null, | ||
texture: null, | ||
shader: null, | ||
src: null, | ||
rtt: false, | ||
}; | ||
}); | ||
// Assign props to instance | ||
this.parent = props.parent; | ||
this.texture = props.texture; | ||
this.shader = props.shader; | ||
this.src = props.src; | ||
@@ -458,3 +463,5 @@ this.rtt = props.rtt; | ||
this.updateBoundingRect(); | ||
this.setUpdateType(UpdateType.RenderState | UpdateType.Children); | ||
this.setUpdateType(UpdateType.RenderState | | ||
UpdateType.Children | | ||
UpdateType.RecalcUniforms); | ||
this.childUpdateType |= UpdateType.Global; | ||
@@ -531,2 +538,7 @@ if (this.clipping === true) { | ||
} | ||
if (this.shader?.update !== undefined && | ||
(this.updateType & UpdateType.Local || | ||
this.updateType & UpdateType.RecalcUniforms)) { | ||
this.shader.update(); | ||
} | ||
if (this.updateType & UpdateType.Children && this.children.length > 0) { | ||
@@ -904,3 +916,3 @@ for (let i = 0, length = this.children.length; i < length; i++) { | ||
this.props.texture = null; | ||
this.props.shader = this.stage.defShaderCtr; | ||
this.props.shader = this.stage.defShaderNode; | ||
while (this.children.length > 0) { | ||
@@ -943,4 +955,3 @@ this.children[0]?.destroy(); | ||
zIndex: this.zIndex, | ||
shader: this.shader.shader, | ||
shaderProps: this.shader.getResolvedProps(), | ||
shader: this.props.shader, | ||
alpha: this.worldAlpha, | ||
@@ -1383,7 +1394,13 @@ clippingRect: this.clippingRect, | ||
} | ||
set shader(value) { | ||
if (this.props.shader === value) { | ||
set shader(shader) { | ||
if (this.props.shader === shader) { | ||
return; | ||
} | ||
this.props.shader = value; | ||
if (shader === null) { | ||
this.props.shader = this.stage.defShaderNode; | ||
this.setUpdateType(UpdateType.IsRenderable); | ||
return; | ||
} | ||
shader.attachNode(this); | ||
this.props.shader = shader; | ||
this.setUpdateType(UpdateType.IsRenderable); | ||
@@ -1390,0 +1407,0 @@ } |
@@ -1,68 +0,28 @@ | ||
import type { ExtractProps } from './CoreTextureManager.js'; | ||
import type { CoreRenderer } from './renderers/CoreRenderer.js'; | ||
import type { CoreShader } from './renderers/CoreShader.js'; | ||
import { DefaultShader } from './renderers/webgl/shaders/DefaultShader.js'; | ||
import { DefaultShaderBatched } from './renderers/webgl/shaders/DefaultShaderBatched.js'; | ||
import { DynamicShader, type DynamicShaderProps } from './renderers/webgl/shaders/DynamicShader.js'; | ||
import { RoundedRectangle } from './renderers/webgl/shaders/RoundedRectangle.js'; | ||
import { SdfShader } from './renderers/webgl/shaders/SdfShader.js'; | ||
import { RadiusEffect } from './renderers/webgl/shaders/effects/RadiusEffect.js'; | ||
import { BorderEffect } from './renderers/webgl/shaders/effects/BorderEffect.js'; | ||
import { LinearGradientEffect, type LinearGradientEffectProps } from './renderers/webgl/shaders/effects/LinearGradientEffect.js'; | ||
import { GrayscaleEffect, type GrayscaleEffectProps } from './renderers/webgl/shaders/effects/GrayscaleEffect.js'; | ||
import { BorderRightEffect } from './renderers/webgl/shaders/effects/BorderRightEffect.js'; | ||
import { BorderTopEffect } from './renderers/webgl/shaders/effects/BorderTopEffect.js'; | ||
import { BorderBottomEffect } from './renderers/webgl/shaders/effects/BorderBottomEffect.js'; | ||
import { BorderLeftEffect } from './renderers/webgl/shaders/effects/BorderLeftEffect.js'; | ||
import { GlitchEffect, type GlitchEffectProps } from './renderers/webgl/shaders/effects/GlitchEffect.js'; | ||
import { FadeOutEffect, type FadeOutEffectProps } from './renderers/webgl/shaders/effects/FadeOutEffect.js'; | ||
import { RadialGradientEffect, type RadialGradientEffectProps } from './renderers/webgl/shaders/effects/RadialGradientEffect.js'; | ||
import { RadialProgressEffect, type RadialProgressEffectProps } from './renderers/webgl/shaders/effects/RadialProgressEffect.js'; | ||
import { HolePunchEffect, type HolePunchEffectProps } from './renderers/webgl/shaders/effects/HolePunchEffect.js'; | ||
import { UnsupportedShader } from './renderers/canvas/shaders/UnsupportedShader.js'; | ||
import { ShaderController } from '../main-api/ShaderController.js'; | ||
import { DynamicShaderController, type DynamicEffects } from '../main-api/DynamicShaderController.js'; | ||
export type { FadeOutEffectProps }; | ||
export type { LinearGradientEffectProps }; | ||
export type { RadialGradientEffectProps }; | ||
export type { GrayscaleEffectProps }; | ||
export type { GlitchEffectProps }; | ||
export type { RadialProgressEffectProps }; | ||
export type { HolePunchEffectProps }; | ||
import { CoreShaderNode, type CoreShaderType } from './renderers/CoreShaderNode.js'; | ||
import type { CoreShaderProgram } from './renderers/CoreShaderProgram.js'; | ||
import type { Stage } from './Stage.js'; | ||
export interface ShaderMap { | ||
DefaultShader: typeof DefaultShader; | ||
DefaultShaderBatched: typeof DefaultShaderBatched; | ||
RoundedRectangle: typeof RoundedRectangle; | ||
DynamicShader: typeof DynamicShader; | ||
SdfShader: typeof SdfShader; | ||
UnsupportedShader: typeof UnsupportedShader; | ||
[key: string]: CoreShaderType<any>; | ||
} | ||
export interface EffectMap { | ||
radius: typeof RadiusEffect; | ||
border: typeof BorderEffect; | ||
borderBottom: typeof BorderBottomEffect; | ||
borderLeft: typeof BorderLeftEffect; | ||
borderRight: typeof BorderRightEffect; | ||
borderTop: typeof BorderTopEffect; | ||
fadeOut: typeof FadeOutEffect; | ||
linearGradient: typeof LinearGradientEffect; | ||
radialGradient: typeof RadialGradientEffect; | ||
grayscale: typeof GrayscaleEffect; | ||
glitch: typeof GlitchEffect; | ||
radialProgress: typeof RadialProgressEffect; | ||
holePunch: typeof HolePunchEffect; | ||
} | ||
export type EffectProps = FadeOutEffectProps | LinearGradientEffectProps | RadialGradientEffectProps | GrayscaleEffectProps | GlitchEffectProps | RadialProgressEffectProps | HolePunchEffectProps; | ||
export type ExtractProps<Props> = { | ||
[K in keyof Props]: Props[K] extends { | ||
default: infer D; | ||
} ? D : Props[K]; | ||
}; | ||
export type PartialShaderProps<Props> = Partial<ExtractProps<Props>>; | ||
export type ExtractShaderProps<T extends keyof ShaderMap> = ExtractProps<ShaderMap[T]['props']>; | ||
export type OptionalShaderProps<T extends keyof ShaderMap> = PartialShaderProps<ShaderMap[T]['props']>; | ||
export declare class CoreShaderManager { | ||
protected shCache: Map<string, InstanceType<ShaderMap[keyof ShaderMap]>>; | ||
protected shConstructors: Partial<ShaderMap>; | ||
protected attachedShader: CoreShader | null; | ||
protected effectConstructors: Partial<EffectMap>; | ||
renderer: CoreRenderer; | ||
constructor(); | ||
registerShaderType<Type extends keyof ShaderMap>(shType: Type, shClass: ShaderMap[Type]): void; | ||
registerEffectType<Type extends keyof EffectMap>(effectType: Type, effectClass: EffectMap[Type]): void; | ||
getRegisteredEffects(): Partial<EffectMap>; | ||
getRegisteredShaders(): Partial<ShaderMap>; | ||
readonly stage: Stage; | ||
protected shTypes: Record<string, CoreShaderType>; | ||
protected shCache: Map<string, CoreShaderProgram>; | ||
/** | ||
* valuesCache is used to store calculations that can be shared between shader nodes. | ||
*/ | ||
protected valuesCache: Map<string, Record<string, unknown>>; | ||
protected valuesCacheUsage: Map<string, number>; | ||
protected attachedShader: CoreShaderProgram | null; | ||
constructor(stage: Stage); | ||
registerShaderType<Name extends keyof ShaderMap>(name: Name, shType: ShaderMap[Name]): void; | ||
/** | ||
* Loads a shader (if not already loaded) and returns a controller for it. | ||
@@ -74,10 +34,8 @@ * | ||
*/ | ||
loadShader<Type extends keyof ShaderMap>(shType: Type, props?: ExtractProps<ShaderMap[Type]>): ShaderController<Type>; | ||
loadDynamicShader<T extends DynamicEffects<[...{ | ||
name?: string; | ||
type: keyof EffectMap; | ||
}[]]>>(props: DynamicShaderProps): DynamicShaderController<T>; | ||
private _createShaderCtr; | ||
private _createDynShaderCtr; | ||
useShader(shader: CoreShader): void; | ||
createShader<Name extends keyof ShaderMap>(name: Name, props?: Record<string, unknown>): CoreShaderNode | null; | ||
mutateShaderValueUsage(key: string, mutation: number): void; | ||
getShaderValues(key: string): Record<string, unknown> | undefined; | ||
setShaderValues(key: string, values: Record<string, unknown>): void; | ||
cleanup(): void; | ||
useShader(shader: CoreShaderProgram): void; | ||
} |
@@ -1,61 +0,51 @@ | ||
import { DefaultShader } from './renderers/webgl/shaders/DefaultShader.js'; | ||
import { DefaultShaderBatched } from './renderers/webgl/shaders/DefaultShaderBatched.js'; | ||
import { DynamicShader, } from './renderers/webgl/shaders/DynamicShader.js'; | ||
import { RoundedRectangle } from './renderers/webgl/shaders/RoundedRectangle.js'; | ||
import { SdfShader } from './renderers/webgl/shaders/SdfShader.js'; | ||
import { RadiusEffect } from './renderers/webgl/shaders/effects/RadiusEffect.js'; | ||
import { BorderEffect } from './renderers/webgl/shaders/effects/BorderEffect.js'; | ||
import { LinearGradientEffect, } from './renderers/webgl/shaders/effects/LinearGradientEffect.js'; | ||
import { GrayscaleEffect, } from './renderers/webgl/shaders/effects/GrayscaleEffect.js'; | ||
import { BorderRightEffect } from './renderers/webgl/shaders/effects/BorderRightEffect.js'; | ||
import { BorderTopEffect } from './renderers/webgl/shaders/effects/BorderTopEffect.js'; | ||
import { BorderBottomEffect } from './renderers/webgl/shaders/effects/BorderBottomEffect.js'; | ||
import { BorderLeftEffect } from './renderers/webgl/shaders/effects/BorderLeftEffect.js'; | ||
import { GlitchEffect, } from './renderers/webgl/shaders/effects/GlitchEffect.js'; | ||
import { FadeOutEffect, } from './renderers/webgl/shaders/effects/FadeOutEffect.js'; | ||
import { RadialGradientEffect, } from './renderers/webgl/shaders/effects/RadialGradientEffect.js'; | ||
import { RadialProgressEffect, } from './renderers/webgl/shaders/effects/RadialProgressEffect.js'; | ||
import { HolePunchEffect, } from './renderers/webgl/shaders/effects/HolePunchEffect.js'; | ||
import { WebGlCoreShader } from './renderers/webgl/WebGlCoreShader.js'; | ||
import { UnsupportedShader } from './renderers/canvas/shaders/UnsupportedShader.js'; | ||
import { ShaderController } from '../main-api/ShaderController.js'; | ||
import { DynamicShaderController, } from '../main-api/DynamicShaderController.js'; | ||
/* | ||
* If not stated otherwise in this file or this component's LICENSE file the | ||
* following copyright and licenses apply: | ||
* | ||
* Copyright 2023 Comcast Cable Communications Management, LLC. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the License); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
import { deepClone } from '../utils.js'; | ||
import { CoreShaderNode, resolveShaderProps, } from './renderers/CoreShaderNode.js'; | ||
export class CoreShaderManager { | ||
stage; | ||
shTypes = {}; | ||
shCache = new Map(); | ||
shConstructors = {}; | ||
/** | ||
* valuesCache is used to store calculations that can be shared between shader nodes. | ||
*/ | ||
valuesCache = new Map(); | ||
valuesCacheUsage = new Map(); | ||
attachedShader = null; | ||
effectConstructors = {}; | ||
renderer; | ||
constructor() { | ||
this.registerShaderType('DefaultShader', DefaultShader); | ||
this.registerShaderType('DefaultShaderBatched', DefaultShaderBatched); | ||
this.registerShaderType('RoundedRectangle', RoundedRectangle); | ||
this.registerShaderType('DynamicShader', DynamicShader); | ||
this.registerShaderType('SdfShader', SdfShader); | ||
this.registerEffectType('border', BorderEffect); | ||
this.registerEffectType('borderBottom', BorderBottomEffect); | ||
this.registerEffectType('borderLeft', BorderLeftEffect); | ||
this.registerEffectType('borderRight', BorderRightEffect); | ||
this.registerEffectType('borderTop', BorderTopEffect); | ||
this.registerEffectType('fadeOut', FadeOutEffect); | ||
this.registerEffectType('linearGradient', LinearGradientEffect); | ||
this.registerEffectType('radialGradient', RadialGradientEffect); | ||
this.registerEffectType('grayscale', GrayscaleEffect); | ||
this.registerEffectType('glitch', GlitchEffect); | ||
this.registerEffectType('radius', RadiusEffect); | ||
this.registerEffectType('radialProgress', RadialProgressEffect); | ||
this.registerEffectType('holePunch', HolePunchEffect); | ||
constructor(stage) { | ||
this.stage = stage; | ||
} | ||
registerShaderType(shType, shClass) { | ||
this.shConstructors[shType] = shClass; | ||
registerShaderType(name, shType) { | ||
/** | ||
* block name duplicates | ||
*/ | ||
if (this.shTypes[name] !== undefined) { | ||
console.warn(`ShaderType already exists with the name: ${name}. Breaking off registration.`); | ||
return; | ||
} | ||
/** | ||
* Check renderer if shader type is supported. | ||
*/ | ||
if (this.stage.renderer.supportsShaderType(shType) === false) { | ||
console.warn(`The renderer being used does not support this shader type. Breaking off registration.`); | ||
return; | ||
} | ||
this.shTypes[name] = deepClone(shType); | ||
} | ||
registerEffectType(effectType, effectClass) { | ||
this.effectConstructors[effectType] = effectClass; | ||
} | ||
getRegisteredEffects() { | ||
return this.effectConstructors; | ||
} | ||
getRegisteredShaders() { | ||
return this.shConstructors; | ||
} | ||
/** | ||
@@ -68,50 +58,71 @@ * Loads a shader (if not already loaded) and returns a controller for it. | ||
*/ | ||
loadShader(shType, props) { | ||
if (!this.renderer) { | ||
throw new Error(`Renderer is not been defined`); | ||
createShader(name, props) { | ||
const shType = this.shTypes[name]; | ||
if (shType === undefined) { | ||
console.warn(`ShaderType not found falling back on renderer default shader`); | ||
return this.stage.defShaderNode; | ||
} | ||
const ShaderClass = this.shConstructors[shType]; | ||
if (!ShaderClass) { | ||
throw new Error(`Shader type "${shType}" is not registered`); | ||
let shaderKey = name; | ||
if (shType.props !== undefined) { | ||
/** | ||
* if props is undefined create empty obj to fill | ||
*/ | ||
props = props || {}; | ||
/** | ||
* resolve shader values | ||
*/ | ||
resolveShaderProps(props, shType.props); | ||
if (shType.getCacheMarkers !== undefined) { | ||
shaderKey += `-${shType.getCacheMarkers(props)}`; | ||
} | ||
} | ||
if (this.renderer.mode === 'canvas' && | ||
ShaderClass.prototype instanceof WebGlCoreShader) { | ||
return this._createShaderCtr(shType, new UnsupportedShader(shType), props); | ||
if (this.stage.renderer.mode === 'canvas') { | ||
return this.stage.renderer.createShaderNode(shaderKey, shType, props); | ||
} | ||
if (shType === 'DynamicShader') { | ||
return this.loadDynamicShader(props); | ||
/** | ||
* get shaderProgram by cacheKey | ||
*/ | ||
let shProgram = this.shCache.get(shaderKey); | ||
/** | ||
* if shaderProgram was not found create a new one | ||
*/ | ||
if (shProgram === undefined) { | ||
shProgram = this.stage.renderer.createShaderProgram(shType, props); | ||
this.shCache.set(shaderKey, shProgram); | ||
} | ||
const resolvedProps = ShaderClass.resolveDefaults(props); | ||
const cacheKey = ShaderClass.makeCacheKey(resolvedProps) || ShaderClass.name; | ||
if (cacheKey && this.shCache.has(cacheKey)) { | ||
return this._createShaderCtr(shType, this.shCache.get(cacheKey), resolvedProps); | ||
} | ||
// @ts-expect-error ShaderClass WILL accept a Renderer | ||
const shader = new ShaderClass(this.renderer, props); | ||
if (cacheKey) { | ||
this.shCache.set(cacheKey, shader); | ||
} | ||
return this._createShaderCtr(shType, shader, resolvedProps); | ||
return this.stage.renderer.createShaderNode(shaderKey, shType, props, shProgram); | ||
} | ||
loadDynamicShader(props) { | ||
if (!this.renderer) { | ||
throw new Error(`Renderer is not been defined`); | ||
mutateShaderValueUsage(key, mutation) { | ||
let usage = this.valuesCacheUsage.get(key) || 0; | ||
this.valuesCacheUsage.set(key, usage + mutation); | ||
} | ||
getShaderValues(key) { | ||
const values = this.valuesCache.get(key); | ||
if (values === undefined) { | ||
return undefined; | ||
} | ||
const resolvedProps = DynamicShader.resolveDefaults(props, this.effectConstructors); | ||
const cacheKey = DynamicShader.makeCacheKey(resolvedProps, this.effectConstructors); | ||
if (cacheKey && this.shCache.has(cacheKey)) { | ||
return this._createDynShaderCtr(this.shCache.get(cacheKey), resolvedProps); | ||
} | ||
const shader = new DynamicShader(this.renderer, props, this.effectConstructors); | ||
if (cacheKey) { | ||
this.shCache.set(cacheKey, shader); | ||
} | ||
return this._createDynShaderCtr(shader, resolvedProps); | ||
this.mutateShaderValueUsage(key, 1); | ||
return values; | ||
} | ||
_createShaderCtr(type, shader, props) { | ||
return new ShaderController(type, shader, props, this.renderer.stage); | ||
setShaderValues(key, values) { | ||
this.valuesCache.set(key, values); | ||
this.mutateShaderValueUsage(key, 1); | ||
} | ||
_createDynShaderCtr(shader, props) { | ||
shader.bindUniformMethods(props); | ||
return new DynamicShaderController(shader, props, this); | ||
cleanup() { | ||
const values = [...this.valuesCacheUsage.entries()].sort((entryA, entryB) => { | ||
if (entryA[1] < entryB[1]) { | ||
return -1; | ||
} | ||
else if (entryA[1] > entryB[1]) { | ||
return 1; | ||
} | ||
return 0; | ||
}); | ||
for (let i = 0; i < values.length; i++) { | ||
if (values[i][1] > 0) { | ||
break; | ||
} | ||
this.valuesCacheUsage.delete(values[i][0]); | ||
this.valuesCache.delete(values[i][0]); | ||
} | ||
} | ||
@@ -122,6 +133,8 @@ useShader(shader) { | ||
} | ||
if (this.attachedShader) { | ||
if (this.attachedShader && this.attachedShader.detach) { | ||
this.attachedShader.detach(); | ||
} | ||
shader.attach(); | ||
if (shader.attach) { | ||
shader.attach(); | ||
} | ||
this.attachedShader = shader; | ||
@@ -128,0 +141,0 @@ } |
@@ -309,3 +309,3 @@ /* | ||
assertTruthy(this.globalTransform); | ||
this.textRenderer.renderQuads(this.trState, this.globalTransform, this.clippingRect, this.worldAlpha, this.parentHasRenderTexture, this.framebufferDimensions); | ||
this.textRenderer.renderQuads(this); | ||
} | ||
@@ -312,0 +312,0 @@ /** |
@@ -98,3 +98,2 @@ /* | ||
// @ts-expect-error Object possibly undefined | ||
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands | ||
const dataOffset = header[pvrMetadata] + 52; | ||
@@ -101,0 +100,0 @@ const pvrtcData = new Uint8Array(arrayBuffer, dataOffset); |
@@ -0,1 +1,2 @@ | ||
import type { Vec4 } from '../renderers/webgl/internal/ShaderUtils.js'; | ||
export declare const PROTOCOL_REGEX: RegExp; | ||
@@ -56,1 +57,4 @@ export type RGBA = [r: number, g: number, b: number, a: number]; | ||
export declare function isBase64Image(src: string): boolean; | ||
export declare function calcFactoredRadius(radius: number, width: number, height: number): number; | ||
export declare function valuesAreEqual(values: number[]): boolean; | ||
export declare function calcFactoredRadiusArray(radius: Vec4, width: number, height: number): [number, number, number, number]; |
@@ -218,2 +218,28 @@ /* | ||
} | ||
export function calcFactoredRadius(radius, width, height) { | ||
return radius * Math.min(Math.min(width, height) / (2.0 * radius), 1); | ||
} | ||
export function valuesAreEqual(values) { | ||
let prevValue = values[0]; | ||
for (let i = 1; i < values.length; i++) { | ||
if (prevValue !== values[i]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
export function calcFactoredRadiusArray(radius, width, height) { | ||
const result = [ | ||
radius[0], | ||
radius[1], | ||
radius[2], | ||
radius[3], | ||
]; | ||
const factor = Math.min(Math.min(Math.min(width / Math.max(width, radius[0] + radius[1]), width / Math.max(width, radius[2] + radius[3])), Math.min(height / Math.max(height, radius[0] + radius[3]), height / Math.max(height, radius[1] + radius[2]))), 1); | ||
result[0] *= factor; | ||
result[1] *= factor; | ||
result[2] *= factor; | ||
result[3] *= factor; | ||
return result; | ||
} | ||
//# sourceMappingURL=utils.js.map |
@@ -38,36 +38,36 @@ /** | ||
private curProgram; | ||
readonly canvas: HTMLCanvasElement | OffscreenCanvas; | ||
readonly MAX_RENDERBUFFER_SIZE: 34024; | ||
readonly MAX_TEXTURE_SIZE: 3379; | ||
readonly MAX_VIEWPORT_DIMS: 3386; | ||
readonly MAX_VERTEX_TEXTURE_IMAGE_UNITS: 35660; | ||
readonly MAX_TEXTURE_IMAGE_UNITS: 34930; | ||
readonly MAX_COMBINED_TEXTURE_IMAGE_UNITS: 35661; | ||
readonly MAX_VERTEX_ATTRIBS: 34921; | ||
readonly MAX_VARYING_VECTORS: 36348; | ||
readonly MAX_VERTEX_UNIFORM_VECTORS: 36347; | ||
readonly MAX_FRAGMENT_UNIFORM_VECTORS: 36349; | ||
readonly TEXTURE_MAG_FILTER: 10240; | ||
readonly TEXTURE_MIN_FILTER: 10241; | ||
readonly TEXTURE_WRAP_S: 10242; | ||
readonly TEXTURE_WRAP_T: 10243; | ||
readonly LINEAR: 9729; | ||
readonly CLAMP_TO_EDGE: 33071; | ||
readonly RGB: 6407; | ||
readonly RGBA: 6408; | ||
readonly UNSIGNED_BYTE: 5121; | ||
readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL: 37441; | ||
readonly UNPACK_FLIP_Y_WEBGL: 37440; | ||
readonly FLOAT: 5126; | ||
readonly TRIANGLES: 4; | ||
readonly UNSIGNED_SHORT: 5123; | ||
readonly ONE: 1; | ||
readonly ONE_MINUS_SRC_ALPHA: 771; | ||
readonly VERTEX_SHADER: 35633; | ||
readonly FRAGMENT_SHADER: 35632; | ||
readonly STATIC_DRAW: 35044; | ||
readonly COMPILE_STATUS: 35713; | ||
readonly LINK_STATUS: 35714; | ||
readonly DYNAMIC_DRAW: 35048; | ||
readonly COLOR_ATTACHMENT0: 36064; | ||
readonly canvas: any; | ||
readonly MAX_RENDERBUFFER_SIZE: any; | ||
readonly MAX_TEXTURE_SIZE: any; | ||
readonly MAX_VIEWPORT_DIMS: any; | ||
readonly MAX_VERTEX_TEXTURE_IMAGE_UNITS: any; | ||
readonly MAX_TEXTURE_IMAGE_UNITS: any; | ||
readonly MAX_COMBINED_TEXTURE_IMAGE_UNITS: any; | ||
readonly MAX_VERTEX_ATTRIBS: any; | ||
readonly MAX_VARYING_VECTORS: any; | ||
readonly MAX_VERTEX_UNIFORM_VECTORS: any; | ||
readonly MAX_FRAGMENT_UNIFORM_VECTORS: any; | ||
readonly TEXTURE_MAG_FILTER: any; | ||
readonly TEXTURE_MIN_FILTER: any; | ||
readonly TEXTURE_WRAP_S: any; | ||
readonly TEXTURE_WRAP_T: any; | ||
readonly LINEAR: any; | ||
readonly CLAMP_TO_EDGE: any; | ||
readonly RGB: any; | ||
readonly RGBA: any; | ||
readonly UNSIGNED_BYTE: any; | ||
readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL: any; | ||
readonly UNPACK_FLIP_Y_WEBGL: any; | ||
readonly FLOAT: any; | ||
readonly TRIANGLES: any; | ||
readonly UNSIGNED_SHORT: any; | ||
readonly ONE: any; | ||
readonly ONE_MINUS_SRC_ALPHA: any; | ||
readonly VERTEX_SHADER: any; | ||
readonly FRAGMENT_SHADER: any; | ||
readonly STATIC_DRAW: any; | ||
readonly COMPILE_STATUS: any; | ||
readonly LINK_STATUS: any; | ||
readonly DYNAMIC_DRAW: any; | ||
readonly COLOR_ATTACHMENT0: any; | ||
readonly INVALID_ENUM: number; | ||
@@ -333,2 +333,15 @@ readonly INVALID_OPERATION: number; | ||
/** | ||
* Returns object with Attribute names as key and numbers as location values | ||
* | ||
* @param program | ||
* @returns object with numbers | ||
*/ | ||
getUniformLocations(program: WebGLProgram): Record<string, number>; | ||
/** | ||
* Returns object with Attribute names as key and numbers as location values | ||
* @param program | ||
* @returns object with numbers | ||
*/ | ||
getAttributeLocations(program: WebGLProgram): Record<string, number>; | ||
/** | ||
* ``` | ||
@@ -348,3 +361,3 @@ * gl.useProgram(program); | ||
*/ | ||
uniform1f(location: WebGLUniformLocation | null, v0: number): void; | ||
uniform1f(location: string, v0: number): void; | ||
/** | ||
@@ -356,3 +369,3 @@ * Sets the value of a float array uniform variable. | ||
*/ | ||
uniform1fv(location: WebGLUniformLocation | null, value: Float32Array | number[]): void; | ||
uniform1fv(location: string, value: Float32Array): void; | ||
/** | ||
@@ -364,3 +377,3 @@ * Sets the value of a single integer uniform variable. | ||
*/ | ||
uniform1i(location: WebGLUniformLocation | null, v0: number): void; | ||
uniform1i(location: string, v0: number): void; | ||
/** | ||
@@ -372,3 +385,3 @@ * Sets the value of an integer array uniform variable. | ||
*/ | ||
uniform1iv(location: WebGLUniformLocation | null, value: Int32Array | number[]): void; | ||
uniform1iv(location: string, value: Int32Array): void; | ||
/** | ||
@@ -381,3 +394,3 @@ * Sets the value of a vec2 uniform variable. | ||
*/ | ||
uniform2f(location: WebGLUniformLocation | null, v0: number, v1: number): void; | ||
uniform2f(location: string, v0: number, v1: number): void; | ||
/** | ||
@@ -389,3 +402,3 @@ * Sets the value of a vec2 array uniform variable. | ||
*/ | ||
uniform2fv(location: WebGLUniformLocation | null, value: Float32Array | number[]): void; | ||
uniform2fv(location: string, value: Float32Array): void; | ||
/** | ||
@@ -398,3 +411,3 @@ * Sets the value of a ivec2 uniform variable. | ||
*/ | ||
uniform2i(location: WebGLUniformLocation | null, v0: number, v1: number): void; | ||
uniform2i(location: string, v0: number, v1: number): void; | ||
/** | ||
@@ -406,3 +419,3 @@ * Sets the value of an ivec2 array uniform variable. | ||
*/ | ||
uniform2iv(location: WebGLUniformLocation | null, value: Int32Array | number[]): void; | ||
uniform2iv(location: string, value: Int32Array): void; | ||
/** | ||
@@ -416,3 +429,3 @@ * Sets the value of a vec3 uniform variable. | ||
*/ | ||
uniform3f(location: WebGLUniformLocation | null, v0: number, v1: number, v2: number): void; | ||
uniform3f(location: string, v0: number, v1: number, v2: number): void; | ||
/** | ||
@@ -424,3 +437,3 @@ * Sets the value of a vec3 array uniform variable. | ||
*/ | ||
uniform3fv(location: WebGLUniformLocation | null, value: Float32Array | number[]): void; | ||
uniform3fv(location: string, value: Float32Array): void; | ||
/** | ||
@@ -434,3 +447,3 @@ * Sets the value of a ivec3 uniform variable. | ||
*/ | ||
uniform3i(location: WebGLUniformLocation | null, v0: number, v1: number, v2: number): void; | ||
uniform3i(location: string, v0: number, v1: number, v2: number): void; | ||
/** | ||
@@ -442,3 +455,3 @@ * Sets the value of an ivec3 array uniform variable. | ||
*/ | ||
uniform3iv(location: WebGLUniformLocation | null, value: Int32Array | number[]): void; | ||
uniform3iv(location: string, value: Int32Array): void; | ||
/** | ||
@@ -453,3 +466,3 @@ * Sets the value of a vec4 uniform variable. | ||
*/ | ||
uniform4f(location: WebGLUniformLocation | null, v0: number, v1: number, v2: number, v3: number): void; | ||
uniform4f(location: string, v0: number, v1: number, v2: number, v3: number): void; | ||
/** | ||
@@ -461,3 +474,3 @@ * Sets the value of a vec4 array uniform variable. | ||
*/ | ||
uniform4fv(location: WebGLUniformLocation | null, value: Float32Array | number[]): void; | ||
uniform4fv(location: string, value: Float32Array): void; | ||
/** | ||
@@ -472,3 +485,3 @@ * Sets the value of a ivec4 uniform variable. | ||
*/ | ||
uniform4i(location: WebGLUniformLocation | null, v0: number, v1: number, v2: number, v3: number): void; | ||
uniform4i(location: string, v0: number, v1: number, v2: number, v3: number): void; | ||
/** | ||
@@ -480,3 +493,3 @@ * Sets the value of an ivec4 array uniform variable. | ||
*/ | ||
uniform4iv(location: WebGLUniformLocation | null, value: Int32Array | number[]): void; | ||
uniform4iv(location: string, value: Int32Array): void; | ||
/** | ||
@@ -489,3 +502,3 @@ * Sets the value of a mat2 uniform variable. | ||
*/ | ||
uniformMatrix2fv(location: WebGLUniformLocation | null, value: Float32Array | number[]): void; | ||
uniformMatrix2fv(location: string, value: Float32Array): void; | ||
/** | ||
@@ -496,3 +509,3 @@ * Sets the value of a mat2 uniform variable. | ||
*/ | ||
uniformMatrix3fv(location: WebGLUniformLocation | null, value: Float32Array | number[]): void; | ||
uniformMatrix3fv(location: string, value: Float32Array): void; | ||
/** | ||
@@ -503,3 +516,3 @@ * Sets the value of a mat4 uniform variable. | ||
*/ | ||
uniformMatrix4fv(location: WebGLUniformLocation | null, value: Float32Array | number[]): void; | ||
uniformMatrix4fv(location: string, value: Float32Array): void; | ||
/** | ||
@@ -549,3 +562,3 @@ * ``` | ||
*/ | ||
createVertexArray(): WebGLVertexArrayObject | null; | ||
createVertexArray(): WebGLVertexArrayObject | null | undefined; | ||
/** | ||
@@ -552,0 +565,0 @@ * ``` |
@@ -179,5 +179,4 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ | ||
activeTexture(textureUnit) { | ||
const { gl } = this; | ||
if (this.activeTextureUnit !== textureUnit) { | ||
gl.activeTexture(textureUnit + gl.TEXTURE0); | ||
this.gl.activeTexture(textureUnit + this.gl.TEXTURE0); | ||
this.activeTextureUnit = textureUnit; | ||
@@ -196,12 +195,10 @@ } | ||
bindTexture(texture) { | ||
const { gl, activeTextureUnit, texture2dUnits } = this; | ||
if (texture2dUnits[activeTextureUnit] === texture) { | ||
if (this.texture2dUnits[this.activeTextureUnit] === texture) { | ||
return; | ||
} | ||
texture2dUnits[activeTextureUnit] = texture; | ||
gl.bindTexture(this.gl.TEXTURE_2D, texture); | ||
this.texture2dUnits[this.activeTextureUnit] = texture; | ||
this.gl.bindTexture(this.gl.TEXTURE_2D, texture); | ||
} | ||
_getActiveTexture() { | ||
const { activeTextureUnit, texture2dUnits } = this; | ||
return texture2dUnits[activeTextureUnit]; | ||
return this.texture2dUnits[this.activeTextureUnit]; | ||
} | ||
@@ -220,3 +217,2 @@ /** | ||
texParameteri(pname, param) { | ||
const { gl, texture2dParams } = this; | ||
const activeTexture = this._getActiveTexture(); | ||
@@ -226,6 +222,6 @@ if (!activeTexture) { | ||
} | ||
let textureParams = texture2dParams.get(activeTexture); | ||
let textureParams = this.texture2dParams.get(activeTexture); | ||
if (!textureParams) { | ||
textureParams = {}; | ||
texture2dParams.set(activeTexture, textureParams); | ||
this.texture2dParams.set(activeTexture, textureParams); | ||
} | ||
@@ -236,11 +232,10 @@ if (textureParams[pname] === param) { | ||
textureParams[pname] = param; | ||
gl.texParameteri(gl.TEXTURE_2D, pname, param); | ||
this.gl.texParameteri(this.gl.TEXTURE_2D, pname, param); | ||
} | ||
texImage2D(level, internalFormat, widthOrFormat, heightOrType, borderOrSource, format, type, pixels) { | ||
const { gl } = this; | ||
if (format) { | ||
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, widthOrFormat, heightOrType, borderOrSource, format, type, pixels); | ||
this.gl.texImage2D(this.gl.TEXTURE_2D, level, internalFormat, widthOrFormat, heightOrType, borderOrSource, format, type, pixels); | ||
} | ||
else { | ||
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, widthOrFormat, heightOrType, borderOrSource); | ||
this.gl.texImage2D(this.gl.TEXTURE_2D, level, internalFormat, widthOrFormat, heightOrType, borderOrSource); | ||
} | ||
@@ -257,4 +252,3 @@ } | ||
compressedTexImage2D(level, internalformat, width, height, border, data) { | ||
const { gl } = this; | ||
gl.compressedTexImage2D(gl.TEXTURE_2D, level, internalformat, width, height, border, data); | ||
this.gl.compressedTexImage2D(this.gl.TEXTURE_2D, level, internalformat, width, height, border, data); | ||
} | ||
@@ -270,4 +264,3 @@ /** | ||
pixelStorei(pname, param) { | ||
const { gl } = this; | ||
gl.pixelStorei(pname, param); | ||
this.gl.pixelStorei(pname, param); | ||
} | ||
@@ -283,4 +276,3 @@ /** | ||
generateMipmap() { | ||
const { gl } = this; | ||
gl.generateMipmap(gl.TEXTURE_2D); | ||
this.gl.generateMipmap(this.gl.TEXTURE_2D); | ||
} | ||
@@ -295,4 +287,3 @@ /** | ||
createTexture() { | ||
const { gl } = this; | ||
return gl.createTexture(); | ||
return this.gl.createTexture(); | ||
} | ||
@@ -307,7 +298,6 @@ /** | ||
deleteTexture(texture) { | ||
const { gl } = this; | ||
if (texture) { | ||
this.texture2dParams.delete(texture); | ||
} | ||
gl.deleteTexture(texture); | ||
this.gl.deleteTexture(texture); | ||
} | ||
@@ -329,4 +319,3 @@ /** | ||
viewport(x, y, width, height) { | ||
const { gl } = this; | ||
gl.viewport(x, y, width, height); | ||
this.gl.viewport(x, y, width, height); | ||
} | ||
@@ -344,4 +333,3 @@ /** | ||
clearColor(red, green, blue, alpha) { | ||
const { gl } = this; | ||
gl.clearColor(red, green, blue, alpha); | ||
this.gl.clearColor(red, green, blue, alpha); | ||
} | ||
@@ -355,11 +343,10 @@ /** | ||
setScissorTest(enable) { | ||
const { gl, scissorEnabled } = this; | ||
if (enable === scissorEnabled) { | ||
if (enable === this.scissorEnabled) { | ||
return; | ||
} | ||
if (enable) { | ||
gl.enable(gl.SCISSOR_TEST); | ||
this.gl.enable(this.gl.SCISSOR_TEST); | ||
} | ||
else { | ||
gl.disable(gl.SCISSOR_TEST); | ||
this.gl.disable(this.gl.SCISSOR_TEST); | ||
} | ||
@@ -379,8 +366,7 @@ this.scissorEnabled = enable; | ||
scissor(x, y, width, height) { | ||
const { gl, scissorX, scissorY, scissorWidth, scissorHeight } = this; | ||
if (x !== scissorX || | ||
y !== scissorY || | ||
width !== scissorWidth || | ||
height !== scissorHeight) { | ||
gl.scissor(x, y, width, height); | ||
if (x !== this.scissorX || | ||
y !== this.scissorY || | ||
width !== this.scissorWidth || | ||
height !== this.scissorHeight) { | ||
this.gl.scissor(x, y, width, height); | ||
this.scissorX = x; | ||
@@ -401,11 +387,10 @@ this.scissorY = y; | ||
setBlend(blend) { | ||
const { gl, blendEnabled } = this; | ||
if (blend === blendEnabled) { | ||
if (blend === this.blendEnabled) { | ||
return; | ||
} | ||
if (blend) { | ||
gl.enable(gl.BLEND); | ||
this.gl.enable(this.gl.BLEND); | ||
} | ||
else { | ||
gl.disable(gl.BLEND); | ||
this.gl.disable(this.gl.BLEND); | ||
} | ||
@@ -423,8 +408,7 @@ this.blendEnabled = blend; | ||
blendFunc(src, dst) { | ||
const { gl, blendSrcRgb, blendDstRgb, blendSrcAlpha, blendDstAlpha } = this; | ||
if (src !== blendSrcRgb || | ||
dst !== blendDstRgb || | ||
src !== blendSrcAlpha || | ||
dst !== blendDstAlpha) { | ||
gl.blendFunc(src, dst); | ||
if (src !== this.blendSrcRgb || | ||
dst !== this.blendDstRgb || | ||
src !== this.blendSrcAlpha || | ||
dst !== this.blendDstAlpha) { | ||
this.gl.blendFunc(src, dst); | ||
this.blendSrcRgb = src; | ||
@@ -444,4 +428,3 @@ this.blendDstRgb = dst; | ||
createBuffer() { | ||
const { gl } = this; | ||
return gl.createBuffer(); | ||
return this.gl.createBuffer(); | ||
} | ||
@@ -455,4 +438,3 @@ /** | ||
createFramebuffer() { | ||
const { gl } = this; | ||
return gl.createFramebuffer(); | ||
return this.gl.createFramebuffer(); | ||
} | ||
@@ -467,4 +449,3 @@ /** | ||
bindFramebuffer(framebuffer) { | ||
const { gl } = this; | ||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); | ||
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer); | ||
} | ||
@@ -479,3 +460,3 @@ /** | ||
framebufferTexture2D(attachment, texture, level) { | ||
const { gl } = this; | ||
const gl = this.gl; | ||
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, texture, level); | ||
@@ -492,4 +473,3 @@ } | ||
clear() { | ||
const { gl } = this; | ||
gl.clear(gl.COLOR_BUFFER_BIT); | ||
this.gl.clear(this.gl.COLOR_BUFFER_BIT); | ||
} | ||
@@ -510,8 +490,7 @@ /** | ||
arrayBufferData(buffer, data, usage) { | ||
const { gl, boundArrayBuffer } = this; | ||
if (boundArrayBuffer !== buffer) { | ||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | ||
if (this.boundArrayBuffer !== buffer) { | ||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer); | ||
this.boundArrayBuffer = buffer; | ||
} | ||
gl.bufferData(gl.ARRAY_BUFFER, data, usage); | ||
this.gl.bufferData(this.gl.ARRAY_BUFFER, data, usage); | ||
} | ||
@@ -531,8 +510,7 @@ /** | ||
elementArrayBufferData(buffer, data, usage) { | ||
const { gl, boundElementArrayBuffer } = this; | ||
if (boundElementArrayBuffer !== buffer) { | ||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer); | ||
if (this.boundElementArrayBuffer !== buffer) { | ||
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, buffer); | ||
this.boundElementArrayBuffer = buffer; | ||
} | ||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data, usage); | ||
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, data, usage); | ||
} | ||
@@ -557,10 +535,40 @@ /** | ||
vertexAttribPointer(buffer, index, size, type, normalized, stride, offset) { | ||
const { gl, boundArrayBuffer } = this; | ||
if (boundArrayBuffer !== buffer) { | ||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | ||
if (this.boundArrayBuffer !== buffer) { | ||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer); | ||
this.boundArrayBuffer = buffer; | ||
} | ||
gl.vertexAttribPointer(index, size, type, normalized, stride, offset); | ||
this.gl.vertexAttribPointer(index, size, type, normalized, stride, offset); | ||
} | ||
/** | ||
* Returns object with Attribute names as key and numbers as location values | ||
* | ||
* @param program | ||
* @returns object with numbers | ||
*/ | ||
getUniformLocations(program) { | ||
const gl = this.gl; | ||
const length = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); | ||
const result = {}; | ||
for (let i = 0; i < length; i++) { | ||
const { name } = gl.getActiveUniform(program, i); | ||
result[name] = i; | ||
} | ||
return result; | ||
} | ||
/** | ||
* Returns object with Attribute names as key and numbers as location values | ||
* @param program | ||
* @returns object with numbers | ||
*/ | ||
getAttributeLocations(program) { | ||
const gl = this.gl; | ||
const length = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); | ||
const result = {}; | ||
for (let i = 0; i < length; i++) { | ||
const { name } = gl.getActiveAttrib(program, i); | ||
result[name] = i; | ||
} | ||
return result; | ||
} | ||
/** | ||
* ``` | ||
@@ -574,7 +582,6 @@ * gl.useProgram(program); | ||
useProgram(program) { | ||
const { gl, curProgram } = this; | ||
if (curProgram === program) { | ||
if (this.curProgram === program) { | ||
return; | ||
} | ||
gl.useProgram(program); | ||
this.gl.useProgram(program); | ||
this.curProgram = program; | ||
@@ -589,4 +596,3 @@ } | ||
uniform1f(location, v0) { | ||
const { gl } = this; | ||
gl.uniform1f(location, v0); | ||
this.gl.uniform1f(this.gl.getUniformLocation(this.curProgram, location), v0); | ||
} | ||
@@ -600,4 +606,3 @@ /** | ||
uniform1fv(location, value) { | ||
const { gl } = this; | ||
gl.uniform1fv(location, value); | ||
this.gl.uniform1fv(this.gl.getUniformLocation(this.curProgram, location), value); | ||
} | ||
@@ -611,4 +616,3 @@ /** | ||
uniform1i(location, v0) { | ||
const { gl } = this; | ||
gl.uniform1i(location, v0); | ||
this.gl.uniform1i(this.gl.getUniformLocation(this.curProgram, location), v0); | ||
} | ||
@@ -622,4 +626,3 @@ /** | ||
uniform1iv(location, value) { | ||
const { gl } = this; | ||
gl.uniform1iv(location, value); | ||
this.gl.uniform1iv(this.gl.getUniformLocation(this.curProgram, location), value); | ||
} | ||
@@ -634,4 +637,3 @@ /** | ||
uniform2f(location, v0, v1) { | ||
const { gl } = this; | ||
gl.uniform2f(location, v0, v1); | ||
this.gl.uniform2f(this.gl.getUniformLocation(this.curProgram, location), v0, v1); | ||
} | ||
@@ -645,4 +647,3 @@ /** | ||
uniform2fv(location, value) { | ||
const { gl } = this; | ||
gl.uniform2fv(location, value); | ||
this.gl.uniform2fv(this.gl.getUniformLocation(this.curProgram, location), value); | ||
} | ||
@@ -657,4 +658,3 @@ /** | ||
uniform2i(location, v0, v1) { | ||
const { gl } = this; | ||
gl.uniform2i(location, v0, v1); | ||
this.gl.uniform2i(this.gl.getUniformLocation(this.curProgram, location), v0, v1); | ||
} | ||
@@ -668,4 +668,3 @@ /** | ||
uniform2iv(location, value) { | ||
const { gl } = this; | ||
gl.uniform2iv(location, value); | ||
this.gl.uniform2iv(this.gl.getUniformLocation(this.curProgram, location), value); | ||
} | ||
@@ -681,4 +680,3 @@ /** | ||
uniform3f(location, v0, v1, v2) { | ||
const { gl } = this; | ||
gl.uniform3f(location, v0, v1, v2); | ||
this.gl.uniform3f(this.gl.getUniformLocation(this.curProgram, location), v0, v1, v2); | ||
} | ||
@@ -692,4 +690,3 @@ /** | ||
uniform3fv(location, value) { | ||
const { gl } = this; | ||
gl.uniform3fv(location, value); | ||
this.gl.uniform3fv(this.gl.getUniformLocation(this.curProgram, location), value); | ||
} | ||
@@ -705,4 +702,3 @@ /** | ||
uniform3i(location, v0, v1, v2) { | ||
const { gl } = this; | ||
gl.uniform3i(location, v0, v1, v2); | ||
this.gl.uniform3i(this.gl.getUniformLocation(this.curProgram, location), v0, v1, v2); | ||
} | ||
@@ -716,4 +712,3 @@ /** | ||
uniform3iv(location, value) { | ||
const { gl } = this; | ||
gl.uniform3iv(location, value); | ||
this.gl.uniform3iv(this.gl.getUniformLocation(this.curProgram, location), value); | ||
} | ||
@@ -730,4 +725,3 @@ /** | ||
uniform4f(location, v0, v1, v2, v3) { | ||
const { gl } = this; | ||
gl.uniform4f(location, v0, v1, v2, v3); | ||
this.gl.uniform4f(this.gl.getUniformLocation(this.curProgram, location), v0, v1, v2, v3); | ||
} | ||
@@ -741,4 +735,3 @@ /** | ||
uniform4fv(location, value) { | ||
const { gl } = this; | ||
gl.uniform4fv(location, value); | ||
this.gl.uniform4fv(this.gl.getUniformLocation(this.curProgram, location), value); | ||
} | ||
@@ -755,4 +748,3 @@ /** | ||
uniform4i(location, v0, v1, v2, v3) { | ||
const { gl } = this; | ||
gl.uniform4i(location, v0, v1, v2, v3); | ||
this.gl.uniform4i(this.gl.getUniformLocation(this.curProgram, location), v0, v1, v2, v3); | ||
} | ||
@@ -766,4 +758,3 @@ /** | ||
uniform4iv(location, value) { | ||
const { gl } = this; | ||
gl.uniform4iv(location, value); | ||
this.gl.uniform4iv(this.gl.getUniformLocation(this.curProgram, location), value); | ||
} | ||
@@ -778,4 +769,3 @@ /** | ||
uniformMatrix2fv(location, value) { | ||
const { gl } = this; | ||
gl.uniformMatrix2fv(location, false, value); | ||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.curProgram, location), false, value); | ||
} | ||
@@ -788,4 +778,3 @@ /** | ||
uniformMatrix3fv(location, value) { | ||
const { gl } = this; | ||
gl.uniformMatrix3fv(location, false, value); | ||
this.gl.uniformMatrix3fv(this.gl.getUniformLocation(this.curProgram, location), false, value); | ||
} | ||
@@ -798,4 +787,3 @@ /** | ||
uniformMatrix4fv(location, value) { | ||
const { gl } = this; | ||
gl.uniformMatrix4fv(location, false, value); | ||
this.gl.uniformMatrix4fv(this.gl.getUniformLocation(this.curProgram, location), false, value); | ||
} | ||
@@ -811,4 +799,3 @@ /** | ||
getParameter(pname) { | ||
const { gl } = this; | ||
return gl.getParameter(pname); | ||
return this.gl.getParameter(pname); | ||
} | ||
@@ -826,4 +813,3 @@ /** | ||
drawElements(mode, count, type, offset) { | ||
const { gl } = this; | ||
gl.drawElements(mode, count, type, offset); | ||
this.gl.drawElements(mode, count, type, offset); | ||
} | ||
@@ -839,4 +825,3 @@ /** | ||
getExtension(name) { | ||
const { gl } = this; | ||
return gl.getExtension(name); | ||
return this.gl.getExtension(name); | ||
} | ||
@@ -851,4 +836,3 @@ /** | ||
getError() { | ||
const { gl } = this; | ||
return gl.getError(); | ||
return this.gl.getError(); | ||
} | ||
@@ -863,5 +847,6 @@ /** | ||
createVertexArray() { | ||
const { gl } = this; | ||
assertTruthy(gl instanceof WebGL2RenderingContext); | ||
return gl.createVertexArray(); | ||
if (this.gl instanceof WebGL2RenderingContext) { | ||
return this.gl.createVertexArray(); | ||
} | ||
return undefined; | ||
} | ||
@@ -876,5 +861,5 @@ /** | ||
bindVertexArray(vertexArray) { | ||
const { gl } = this; | ||
assertTruthy(gl instanceof WebGL2RenderingContext); | ||
gl.bindVertexArray(vertexArray); | ||
if (this.gl instanceof WebGL2RenderingContext) { | ||
this.gl.bindVertexArray(vertexArray); | ||
} | ||
} | ||
@@ -891,4 +876,3 @@ /** | ||
getAttribLocation(program, name) { | ||
const { gl } = this; | ||
return gl.getAttribLocation(program, name); | ||
return this.gl.getAttribLocation(program, name); | ||
} | ||
@@ -905,4 +889,3 @@ /** | ||
getUniformLocation(program, name) { | ||
const { gl } = this; | ||
return gl.getUniformLocation(program, name); | ||
return this.gl.getUniformLocation(program, name); | ||
} | ||
@@ -917,4 +900,3 @@ /** | ||
enableVertexAttribArray(index) { | ||
const { gl } = this; | ||
gl.enableVertexAttribArray(index); | ||
this.gl.enableVertexAttribArray(index); | ||
} | ||
@@ -929,4 +911,3 @@ /** | ||
disableVertexAttribArray(index) { | ||
const { gl } = this; | ||
gl.disableVertexAttribArray(index); | ||
this.gl.disableVertexAttribArray(index); | ||
} | ||
@@ -942,4 +923,3 @@ /** | ||
createShader(type) { | ||
const { gl } = this; | ||
return gl.createShader(type); | ||
return this.gl.createShader(type); | ||
} | ||
@@ -955,4 +935,3 @@ /** | ||
compileShader(shader) { | ||
const { gl } = this; | ||
gl.compileShader(shader); | ||
this.gl.compileShader(shader); | ||
} | ||
@@ -968,4 +947,3 @@ /** | ||
attachShader(program, shader) { | ||
const { gl } = this; | ||
gl.attachShader(program, shader); | ||
this.gl.attachShader(program, shader); | ||
} | ||
@@ -980,4 +958,3 @@ /** | ||
linkProgram(program) { | ||
const { gl } = this; | ||
gl.linkProgram(program); | ||
this.gl.linkProgram(program); | ||
} | ||
@@ -992,4 +969,3 @@ /** | ||
deleteProgram(shader) { | ||
const { gl } = this; | ||
gl.deleteProgram(shader); | ||
this.gl.deleteProgram(shader); | ||
} | ||
@@ -1005,4 +981,3 @@ /** | ||
getShaderParameter(shader, pname) { | ||
const { gl } = this; | ||
return gl.getShaderParameter(shader, pname); | ||
return this.gl.getShaderParameter(shader, pname); | ||
} | ||
@@ -1017,4 +992,3 @@ /** | ||
getShaderInfoLog(shader) { | ||
const { gl } = this; | ||
return gl.getShaderInfoLog(shader); | ||
return this.gl.getShaderInfoLog(shader); | ||
} | ||
@@ -1029,4 +1003,3 @@ /** | ||
createProgram() { | ||
const { gl } = this; | ||
return gl.createProgram(); | ||
return this.gl.createProgram(); | ||
} | ||
@@ -1043,4 +1016,3 @@ /** | ||
getProgramParameter(program, pname) { | ||
const { gl } = this; | ||
return gl.getProgramParameter(program, pname); | ||
return this.gl.getProgramParameter(program, pname); | ||
} | ||
@@ -1056,4 +1028,3 @@ /** | ||
getProgramInfoLog(program) { | ||
const { gl } = this; | ||
return gl.getProgramInfoLog(program); | ||
return this.gl.getProgramInfoLog(program); | ||
} | ||
@@ -1069,4 +1040,3 @@ /** | ||
shaderSource(shader, source) { | ||
const { gl } = this; | ||
gl.shaderSource(shader, source); | ||
this.gl.shaderSource(shader, source); | ||
} | ||
@@ -1081,4 +1051,3 @@ /** | ||
deleteShader(shader) { | ||
const { gl } = this; | ||
gl.deleteShader(shader); | ||
this.gl.deleteShader(shader); | ||
} | ||
@@ -1085,0 +1054,0 @@ } |
@@ -32,2 +32,3 @@ /* | ||
if (!isIdle) { | ||
stage.shManager.cleanup(); | ||
stage.eventBus.emit('idle'); | ||
@@ -34,0 +35,0 @@ isIdle = true; |
@@ -1,14 +0,1 @@ | ||
import type { QuadOptions } from '../../CoreRenderer.js'; | ||
import type { BorderEffectProps } from '../../webgl/shaders/effects/BorderEffect.js'; | ||
import type { RadiusEffectProps } from '../../webgl/shaders/effects/RadiusEffect.js'; | ||
type Direction = 'Top' | 'Right' | 'Bottom' | 'Left'; | ||
/** | ||
* Extract `RoundedRectangle` shader radius to apply as a clipping | ||
*/ | ||
export declare function getRadius(quad: QuadOptions): RadiusEffectProps['radius']; | ||
/** | ||
* Extract `RoundedRectangle` shader radius to apply as a clipping */ | ||
export declare function getBorder(quad: QuadOptions, direction?: '' | Direction): BorderEffectProps | undefined; | ||
export declare function roundRect(this: CanvasRenderingContext2D | Path2D, x: number, y: number, width: number, height: number, radius: number | DOMPointInit | (number | DOMPointInit)[]): void; | ||
export declare function strokeLine(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, lineWidth: number | undefined, color: number | undefined, direction: Direction): void; | ||
export {}; |
@@ -19,121 +19,200 @@ /* | ||
*/ | ||
import { ROUNDED_RECTANGLE_SHADER_TYPE, UnsupportedShader, } from '../shaders/UnsupportedShader.js'; | ||
import { formatRgba, parseColorRgba } from './ColorUtils.js'; | ||
/** | ||
* Extract `RoundedRectangle` shader radius to apply as a clipping | ||
*/ | ||
export function getRadius(quad) { | ||
if (quad.shader instanceof UnsupportedShader) { | ||
const shType = quad.shader.shType; | ||
if (shType === ROUNDED_RECTANGLE_SHADER_TYPE) { | ||
return quad.shaderProps?.radius ?? 0; | ||
} | ||
else if (shType === 'DynamicShader') { | ||
const effects = quad.shaderProps?.effects; | ||
if (effects) { | ||
const effect = effects.find((effect) => { | ||
return effect.type === 'radius' && effect?.props?.radius; | ||
}); | ||
return (effect && effect.type === 'radius' && effect.props.radius) || 0; | ||
} | ||
} | ||
export {}; | ||
/* | ||
export function getRadius(quad: QuadOptions): RadiusEffectProps['radius'] { | ||
if (quad.shader instanceof UnsupportedShader) { | ||
const shType = quad.shader.shType; | ||
if (shType === ROUNDED_RECTANGLE_SHADER_TYPE) { | ||
return (quad.shaderProps?.radius as number) ?? 0; | ||
} else if (shType === 'DynamicShader') { | ||
const effects = quad.shaderProps?.effects as | ||
| EffectDescUnion[] | ||
| undefined; | ||
if (effects) { | ||
const effect = effects.find((effect: EffectDescUnion) => { | ||
return effect.type === 'radius' && effect?.props?.radius; | ||
}); | ||
return (effect && effect.type === 'radius' && effect.props.radius) || 0; | ||
} | ||
} | ||
return 0; | ||
} | ||
return 0; | ||
} | ||
/** | ||
* Extract `RoundedRectangle` shader radius to apply as a clipping */ | ||
export function getBorder(quad, direction = '') { | ||
if (quad.shader instanceof UnsupportedShader) { | ||
const shType = quad.shader.shType; | ||
if (shType === 'DynamicShader') { | ||
const effects = quad.shaderProps?.effects; | ||
if (effects && effects.length) { | ||
const effect = effects.find((effect) => { | ||
return (effect.type === `border${direction}` && | ||
effect.props && | ||
effect.props.width); | ||
}); | ||
return effect && effect.props; | ||
} | ||
} | ||
export function getBorder( | ||
quad: QuadOptions, | ||
direction: '' | Direction = '', | ||
): BorderEffectProps | undefined { | ||
if (quad.shader instanceof UnsupportedShader) { | ||
const shType = quad.shader.shType; | ||
if (shType === 'DynamicShader') { | ||
const effects = quad.shaderProps?.effects as | ||
| EffectDescUnion[] | ||
| undefined; | ||
if (effects && effects.length) { | ||
const effect = effects.find((effect: EffectDescUnion) => { | ||
return ( | ||
effect.type === `border${direction}` && | ||
effect.props && | ||
effect.props.width | ||
); | ||
}); | ||
return effect && effect.props; | ||
} | ||
} | ||
return undefined; | ||
} | ||
return undefined; | ||
} | ||
export function roundRect(x, y, width, height, radius) { | ||
const context = Object.getPrototypeOf(this); | ||
if (!context.roundRect) { | ||
const fixOverlappingCorners = (radii) => { | ||
const maxRadius = Math.min(width / 2, height / 2); | ||
const totalHorizontal = radii.topLeft + radii.topRight + radii.bottomRight + radii.bottomLeft; | ||
if (totalHorizontal > width || totalHorizontal > height) { | ||
const scale = maxRadius / | ||
Math.max(radii.topLeft, radii.topRight, radii.bottomRight, radii.bottomLeft); | ||
radii.topLeft *= scale; | ||
radii.topRight *= scale; | ||
radii.bottomRight *= scale; | ||
radii.bottomLeft *= scale; | ||
} | ||
}; | ||
const radii = typeof radius === 'number' | ||
? { | ||
topLeft: radius, | ||
topRight: radius, | ||
bottomRight: radius, | ||
bottomLeft: radius, | ||
} | ||
: { topLeft: 0, topRight: 0, bottomRight: 0, bottomLeft: 0, ...radius }; | ||
fixOverlappingCorners(radii); | ||
this.moveTo(x + radii.topLeft, y); | ||
this.lineTo(x + width - radii.topRight, y); | ||
this.ellipse(x + width - radii.topRight, y + radii.topRight, radii.topRight, radii.topRight, 0, 1.5 * Math.PI, 2 * Math.PI); | ||
this.lineTo(x + width, y + height - radii.bottomRight); | ||
this.ellipse(x + width - radii.bottomRight, y + height - radii.bottomRight, radii.bottomRight, radii.bottomRight, 0, 0, 0.5 * Math.PI); | ||
this.lineTo(x + radii.bottomLeft, y + height); | ||
this.ellipse(x + radii.bottomLeft, y + height - radii.bottomLeft, radii.bottomLeft, radii.bottomLeft, 0, 0.5 * Math.PI, Math.PI); | ||
this.lineTo(x, y + radii.topLeft); | ||
this.ellipse(x + radii.topLeft, y + radii.topLeft, radii.topLeft, radii.topLeft, 0, Math.PI, 1.5 * Math.PI); | ||
} | ||
else { | ||
this.roundRect(x, y, width, height, radius); | ||
} | ||
export function roundRect( | ||
this: CanvasRenderingContext2D | Path2D, | ||
x: number, | ||
y: number, | ||
width: number, | ||
height: number, | ||
radius: number | DOMPointInit | (number | DOMPointInit)[], | ||
) { | ||
const context = Object.getPrototypeOf(this) as Path2D; | ||
if (!context.roundRect) { | ||
const fixOverlappingCorners = (radii: { | ||
topLeft: number; | ||
topRight: number; | ||
bottomRight: number; | ||
bottomLeft: number; | ||
}) => { | ||
const maxRadius = Math.min(width / 2, height / 2); | ||
const totalHorizontal = | ||
radii.topLeft + radii.topRight + radii.bottomRight + radii.bottomLeft; | ||
if (totalHorizontal > width || totalHorizontal > height) { | ||
const scale = | ||
maxRadius / | ||
Math.max( | ||
radii.topLeft, | ||
radii.topRight, | ||
radii.bottomRight, | ||
radii.bottomLeft, | ||
); | ||
radii.topLeft *= scale; | ||
radii.topRight *= scale; | ||
radii.bottomRight *= scale; | ||
radii.bottomLeft *= scale; | ||
} | ||
}; | ||
const radii = | ||
typeof radius === 'number' | ||
? { | ||
topLeft: radius, | ||
topRight: radius, | ||
bottomRight: radius, | ||
bottomLeft: radius, | ||
} | ||
: { topLeft: 0, topRight: 0, bottomRight: 0, bottomLeft: 0, ...radius }; | ||
fixOverlappingCorners(radii); | ||
this.moveTo(x + radii.topLeft, y); | ||
this.lineTo(x + width - radii.topRight, y); | ||
this.ellipse( | ||
x + width - radii.topRight, | ||
y + radii.topRight, | ||
radii.topRight, | ||
radii.topRight, | ||
0, | ||
1.5 * Math.PI, | ||
2 * Math.PI, | ||
); | ||
this.lineTo(x + width, y + height - radii.bottomRight); | ||
this.ellipse( | ||
x + width - radii.bottomRight, | ||
y + height - radii.bottomRight, | ||
radii.bottomRight, | ||
radii.bottomRight, | ||
0, | ||
0, | ||
0.5 * Math.PI, | ||
); | ||
this.lineTo(x + radii.bottomLeft, y + height); | ||
this.ellipse( | ||
x + radii.bottomLeft, | ||
y + height - radii.bottomLeft, | ||
radii.bottomLeft, | ||
radii.bottomLeft, | ||
0, | ||
0.5 * Math.PI, | ||
Math.PI, | ||
); | ||
this.lineTo(x, y + radii.topLeft); | ||
this.ellipse( | ||
x + radii.topLeft, | ||
y + radii.topLeft, | ||
radii.topLeft, | ||
radii.topLeft, | ||
0, | ||
Math.PI, | ||
1.5 * Math.PI, | ||
); | ||
} else { | ||
this.roundRect(x, y, width, height, radius); | ||
} | ||
} | ||
export function strokeLine(ctx, x, y, width, height, lineWidth = 0, color, direction) { | ||
if (!lineWidth) { | ||
return; | ||
} | ||
let sx, sy = 0; | ||
let ex, ey = 0; | ||
switch (direction) { | ||
case 'Top': | ||
sx = x; | ||
sy = y; | ||
ex = width + x; | ||
ey = y; | ||
break; | ||
case 'Right': | ||
sx = x + width; | ||
sy = y; | ||
ex = x + width; | ||
ey = y + height; | ||
break; | ||
case 'Bottom': | ||
sx = x; | ||
sy = y + height; | ||
ex = x + width; | ||
ey = y + height; | ||
break; | ||
case 'Left': | ||
sx = x; | ||
sy = y; | ||
ex = x; | ||
ey = y + height; | ||
break; | ||
} | ||
ctx.beginPath(); | ||
ctx.lineWidth = lineWidth; | ||
ctx.strokeStyle = formatRgba(parseColorRgba(color ?? 0)); | ||
ctx.moveTo(sx, sy); | ||
ctx.lineTo(ex, ey); | ||
ctx.stroke(); | ||
export function strokeLine( | ||
ctx: CanvasRenderingContext2D, | ||
x: number, | ||
y: number, | ||
width: number, | ||
height: number, | ||
lineWidth = 0, | ||
color: number | undefined, | ||
direction: Direction, | ||
) { | ||
if (!lineWidth) { | ||
return; | ||
} | ||
let sx, | ||
sy = 0; | ||
let ex, | ||
ey = 0; | ||
switch (direction) { | ||
case 'Top': | ||
sx = x; | ||
sy = y; | ||
ex = width + x; | ||
ey = y; | ||
break; | ||
case 'Right': | ||
sx = x + width; | ||
sy = y; | ||
ex = x + width; | ||
ey = y + height; | ||
break; | ||
case 'Bottom': | ||
sx = x; | ||
sy = y + height; | ||
ex = x + width; | ||
ey = y + height; | ||
break; | ||
case 'Left': | ||
sx = x; | ||
sy = y; | ||
ex = x; | ||
ey = y + height; | ||
break; | ||
} | ||
ctx.beginPath(); | ||
ctx.lineWidth = lineWidth; | ||
ctx.strokeStyle = formatRgba(parseColorRgba(color ?? 0)); | ||
ctx.moveTo(sx, sy); | ||
ctx.lineTo(ex, ey); | ||
ctx.stroke(); | ||
} | ||
*/ | ||
//# sourceMappingURL=C2DShaderUtils.js.map |
@@ -12,2 +12,4 @@ export interface IParsedColor { | ||
export declare function parseColor(abgr: number): IParsedColor; | ||
export declare function parseToAbgrString(abgr: number): string; | ||
export declare function parseToRgbaString(rgba: number): string; | ||
/** | ||
@@ -14,0 +16,0 @@ * Extract color components |
@@ -39,2 +39,16 @@ /* | ||
} | ||
export function parseToAbgrString(abgr) { | ||
const a = ((abgr >>> 24) & 0xff) / 255; | ||
const b = (abgr >>> 16) & 0xff & 0xff; | ||
const g = (abgr >>> 8) & 0xff & 0xff; | ||
const r = abgr & 0xff & 0xff; | ||
return `rgba(${r},${g},${b},${a})`; | ||
} | ||
export function parseToRgbaString(rgba) { | ||
const r = (rgba >>> 24) & 0xff; | ||
const g = (rgba >>> 16) & 0xff & 0xff; | ||
const b = (rgba >>> 8) & 0xff & 0xff; | ||
const a = (rgba & 0xff & 0xff) / 255; | ||
return `rgba(${r},${g},${b},${a})`; | ||
} | ||
/** | ||
@@ -41,0 +55,0 @@ * Extract color components |
import type { Dimensions } from '../../common/CommonTypes.js'; | ||
import type { BaseShaderController } from '../../main-api/ShaderController.js'; | ||
import type { CoreNode } from '../CoreNode.js'; | ||
import type { CoreShaderManager } from '../CoreShaderManager.js'; | ||
import type { CoreTextureManager, TextureOptions } from '../CoreTextureManager.js'; | ||
import type { TextureOptions } from '../CoreTextureManager.js'; | ||
import type { Stage } from '../Stage.js'; | ||
import type { TextureMemoryManager } from '../TextureMemoryManager.js'; | ||
import type { ContextSpy } from '../lib/ContextSpy.js'; | ||
import type { RenderCoords } from '../lib/RenderCoords.js'; | ||
import type { RectWithValid } from '../lib/utils.js'; | ||
import type { CoreShaderProgram } from './CoreShaderProgram.js'; | ||
import type { Texture } from '../textures/Texture.js'; | ||
import { CoreContextTexture } from './CoreContextTexture.js'; | ||
import type { CoreShader } from './CoreShader.js'; | ||
import type { CoreShaderType, CoreShaderNode } from './CoreShaderNode.js'; | ||
export interface QuadOptions { | ||
@@ -24,4 +22,3 @@ width: number; | ||
zIndex: number; | ||
shader: CoreShader | null; | ||
shaderProps: Record<string, unknown> | null; | ||
shader: CoreShaderNode | null; | ||
alpha: number; | ||
@@ -36,5 +33,5 @@ clippingRect: RectWithValid; | ||
renderCoords?: RenderCoords; | ||
rtt?: boolean; | ||
parentHasRenderTexture?: boolean; | ||
framebufferDimensions?: Dimensions; | ||
rtt: boolean; | ||
parentHasRenderTexture: boolean; | ||
framebufferDimensions: Dimensions; | ||
} | ||
@@ -44,8 +41,2 @@ export interface CoreRendererOptions { | ||
canvas: HTMLCanvasElement | OffscreenCanvas; | ||
pixelRatio: number; | ||
txManager: CoreTextureManager; | ||
txMemManager: TextureMemoryManager; | ||
shManager: CoreShaderManager; | ||
clearColor: number; | ||
bufferMemory: number; | ||
contextSpy: ContextSpy | null; | ||
@@ -62,5 +53,2 @@ forceWebGL2: boolean; | ||
readonly stage: Stage; | ||
txManager: CoreTextureManager; | ||
txMemManager: TextureMemoryManager; | ||
shManager: CoreShaderManager; | ||
rttNodes: CoreNode[]; | ||
@@ -72,3 +60,6 @@ constructor(options: CoreRendererOptions); | ||
abstract createCtxTexture(textureSource: Texture): CoreContextTexture; | ||
abstract getShaderManager(): CoreShaderManager; | ||
abstract createShaderProgram(shaderConfig: Readonly<CoreShaderType>, props?: Record<string, unknown>): CoreShaderProgram | null; | ||
abstract createShaderNode(shaderKey: string, shaderType: Readonly<CoreShaderType>, props?: Record<string, unknown>, program?: CoreShaderProgram): CoreShaderNode; | ||
abstract supportsShaderType(shaderType: Readonly<CoreShaderType>): boolean; | ||
abstract getDefaultShaderNode(): CoreShaderNode | null; | ||
abstract get renderToTextureActive(): boolean; | ||
@@ -81,4 +72,3 @@ abstract get activeRttNode(): CoreNode | null; | ||
abstract getQuadCount(): number | null; | ||
abstract getDefShaderCtr(): BaseShaderController; | ||
abstract updateClearColor(color: number): void; | ||
} |
@@ -25,5 +25,2 @@ /* | ||
//// Core Managers | ||
txManager; | ||
txMemManager; | ||
shManager; | ||
rttNodes = []; | ||
@@ -33,7 +30,4 @@ constructor(options) { | ||
this.stage = options.stage; | ||
this.txManager = options.txManager; | ||
this.txMemManager = options.txMemManager; | ||
this.shManager = options.shManager; | ||
} | ||
} | ||
//# sourceMappingURL=CoreRenderer.js.map |
import type { WebGlContextWrapper } from '../../../lib/WebGlContextWrapper.js'; | ||
import type { WebGlCoreRenderer } from '../WebGlCoreRenderer.js'; | ||
export interface AttributeInfo { | ||
@@ -15,6 +14,23 @@ name: string; | ||
} | ||
export type SingleValue = number | Float32Array | Int32Array; | ||
export type Vec2 = [number, number]; | ||
export type Vec3 = [number, number, number]; | ||
export type Vec4 = [number, number, number, number]; | ||
export type UniformValue = SingleValue | Vec2 | Vec3 | Vec4; | ||
export interface UniformCollection { | ||
single: Record<string, Uniform<SingleValue>>; | ||
vec2: Record<string, Uniform<Vec2>>; | ||
vec3: Record<string, Uniform<Vec3>>; | ||
vec4: Record<string, Uniform<Vec4>>; | ||
} | ||
export interface Uniform<T = UniformValue> { | ||
method: string; | ||
value: T; | ||
} | ||
export interface SupportedSetUniforms { | ||
uniform2fv: Float32Array; | ||
uniform2iv: Int32Array; | ||
uniform3fv: 'uniform2iv' | 'uniform3fv' | 'uniform3iv' | 'uniform4fv' | 'uniform4iv' | 'uniformMatrix2fv' | 'uniformMatrix3fv' | 'uniformMatrix4fv' | 'uniform1f' | 'uniform1fv' | 'uniform1i' | 'uniform1iv' | 'uniform3fv' | 'uniform2f' | 'uniform2i' | 'uniform3f' | 'uniform3i' | 'uniform4f' | 'uniform4i'; | ||
} | ||
export interface ShaderOptions { | ||
renderer: WebGlCoreRenderer; | ||
attributes: string[]; | ||
uniforms: UniformInfo[]; | ||
shaderSources?: ShaderProgramSources; | ||
@@ -29,2 +45,6 @@ supportsIndexedTextures?: boolean; | ||
}; | ||
export type UniformSet1Param = Omit<UniformMethodMap, 'uniform2f' | 'uniform2i' | 'uniform3f' | 'uniform3i' | 'uniform4f' | 'uniform4i'>; | ||
export type UniformSet2Params = Pick<UniformMethodMap, 'uniform2f' | 'uniform2i'>; | ||
export type UniformSet3Params = Pick<UniformMethodMap, 'uniform3f' | 'uniform3i'>; | ||
export type UniformSet4Params = Pick<UniformMethodMap, 'uniform4f' | 'uniform4i'>; | ||
type TupleToObject<T extends any[]> = Omit<T, keyof any[]>; | ||
@@ -38,3 +58,3 @@ export type UniformTupleToMap<Uniforms extends [...UniformInfo[]]> = { | ||
}; | ||
type ShaderSource = string | ((textureUnits: number) => string); | ||
export type ShaderSource = string | ((textureUnits: number) => string); | ||
export interface ShaderProgramSources { | ||
@@ -50,2 +70,9 @@ vertex: ShaderSource; | ||
export declare function createProgram(glw: WebGlContextWrapper, vertexShader: WebGLShader, fragmentShader: WebGLShader): WebGLProgram | undefined; | ||
export declare const DefaultVertexSource = "\n # ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n # else\n precision mediump float;\n # endif\n\n attribute vec2 a_position;\n attribute vec2 a_textureCoords;\n attribute vec4 a_color;\n attribute vec2 a_nodeCoords;\n\n uniform vec2 u_resolution;\n uniform float u_pixelRatio;\n uniform vec2 u_dimensions;\n uniform vec4 u_shadow;\n\n varying vec4 v_color;\n varying vec2 v_textureCoords;\n\n void main() {\n vec2 normalized = a_position * u_pixelRatio;\n vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y);\n\n vec2 outerEdge = clamp(a_textureCoords * 2.0 - vec2(1.0), -1.0, 1.0);\n vec2 shadowEdge = outerEdge;\n vec2 vertexPos = normalized + outerEdge + shadowEdge;\n v_color = a_color;\n v_textureCoords = a_textureCoords;\n\n gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);\n }\n"; | ||
/** | ||
* generate fragment source for | ||
* @param stops | ||
* @returns | ||
*/ | ||
export declare function genGradientColors(stops: number): string; | ||
export {}; |
@@ -51,2 +51,52 @@ /* | ||
} | ||
export const DefaultVertexSource = ` | ||
# ifdef GL_FRAGMENT_PRECISION_HIGH | ||
precision highp float; | ||
# else | ||
precision mediump float; | ||
# endif | ||
attribute vec2 a_position; | ||
attribute vec2 a_textureCoords; | ||
attribute vec4 a_color; | ||
attribute vec2 a_nodeCoords; | ||
uniform vec2 u_resolution; | ||
uniform float u_pixelRatio; | ||
uniform vec2 u_dimensions; | ||
uniform vec4 u_shadow; | ||
varying vec4 v_color; | ||
varying vec2 v_textureCoords; | ||
void main() { | ||
vec2 normalized = a_position * u_pixelRatio; | ||
vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y); | ||
vec2 outerEdge = clamp(a_textureCoords * 2.0 - vec2(1.0), -1.0, 1.0); | ||
vec2 shadowEdge = outerEdge; | ||
vec2 vertexPos = normalized + outerEdge + shadowEdge; | ||
v_color = a_color; | ||
v_textureCoords = a_textureCoords; | ||
gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0); | ||
} | ||
`; | ||
/** | ||
* generate fragment source for | ||
* @param stops | ||
* @returns | ||
*/ | ||
export function genGradientColors(stops) { | ||
let result = ` | ||
float stopCalc = (dist - u_stops[0]) / (u_stops[1] - u_stops[0]); | ||
vec4 colorOut = mix(u_colors[0], u_colors[1], stopCalc); | ||
`; | ||
if (stops > 2) { | ||
for (let i = 2; i < stops; i++) { | ||
result += `colorOut = mix(colorOut, u_colors[${i}], clamp((dist - u_stops[${i - 1}]) / (u_stops[${i}] - u_stops[${i - 1}]), 0.0, 1.0));`; | ||
} | ||
} | ||
return result; | ||
} | ||
//# sourceMappingURL=ShaderUtils.js.map |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ import { WebGlCoreShader, } from '../WebGlCoreShader.js'; |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ import { ShaderEffect, } from './ShaderEffect.js'; |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ import { updateWebSafeRadius, validateArrayLength4 } from './EffectUtils.js'; |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -5,3 +5,3 @@ import { AnimationManager } from './animations/AnimationManager.js'; | ||
import { TrFontManager } from './text-rendering/TrFontManager.js'; | ||
import { CoreShaderManager, type ShaderMap } from './CoreShaderManager.js'; | ||
import { CoreShaderManager } from './CoreShaderManager.js'; | ||
import { TextRenderer, type TextRendererMap, type TrProps } from './text-rendering/renderers/TextRenderer.js'; | ||
@@ -13,8 +13,8 @@ import { EventEmitter } from '../common/EventEmitter.js'; | ||
import { CoreRenderer } from './renderers/CoreRenderer.js'; | ||
import type { WebGlCoreRenderer } from './renderers/webgl/WebGlCoreRenderer.js'; | ||
import type { CanvasCoreRenderer } from './renderers/canvas/CanvasCoreRenderer.js'; | ||
import type { BaseShaderController } from '../main-api/ShaderController.js'; | ||
import type { WebGlRenderer } from './renderers/webgl/WebGlRenderer.js'; | ||
import type { CanvasRenderer } from './renderers/canvas/CanvasRenderer.js'; | ||
import { CoreTextNode, type CoreTextNodeProps } from './CoreTextNode.js'; | ||
import type { SdfTextRenderer } from './text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js'; | ||
import type { CanvasTextRenderer } from './text-rendering/renderers/CanvasTextRenderer.js'; | ||
import type { CoreShaderNode } from './renderers/CoreShaderNode.js'; | ||
import { type Bound } from './lib/utils.js'; | ||
@@ -35,3 +35,3 @@ import type { Texture } from './textures/Texture.js'; | ||
numImageWorkers: number; | ||
renderEngine: typeof WebGlCoreRenderer | typeof CanvasCoreRenderer; | ||
renderEngine: typeof WebGlRenderer | typeof CanvasRenderer; | ||
eventBus: EventEmitter; | ||
@@ -58,3 +58,3 @@ quadBufferSize: number; | ||
boundsMargin: [number, number, number, number]; | ||
readonly defShaderCtr: BaseShaderController; | ||
readonly defShaderNode: CoreShaderNode | null; | ||
readonly strictBound: Bound; | ||
@@ -64,2 +64,4 @@ readonly preloadBound: Bound; | ||
readonly defaultTexture: Texture | null; | ||
readonly pixelRatio: number; | ||
readonly bufferMemory: number; | ||
/** | ||
@@ -77,2 +79,3 @@ * Renderer Event Bus for the Stage to emit events onto | ||
currentFrameTime: number; | ||
private clrColor; | ||
private fpsNumFrames; | ||
@@ -150,10 +153,2 @@ private fpsElapsedTime; | ||
resolveTextRenderer(trProps: TrProps, textRendererOverride?: keyof TextRendererMap | null): TextRenderer | null; | ||
/** | ||
* Create a shader controller instance | ||
* | ||
* @param type | ||
* @param props | ||
* @returns | ||
*/ | ||
createShaderCtr(type: keyof ShaderMap, props: Record<string, unknown>): BaseShaderController; | ||
createNode(props: Partial<CoreNodeProps>): CoreNode; | ||
@@ -181,2 +176,4 @@ createTextNode(props: Partial<CoreTextNodeProps>): CoreTextNode; | ||
cleanup(aggressive: boolean): void; | ||
set clearColor(value: number); | ||
get clearColor(): number; | ||
} |
@@ -35,3 +35,2 @@ /* | ||
import { ColorTexture } from './textures/ColorTexture.js'; | ||
const bufferMemory = 2e6; | ||
const autoStart = true; | ||
@@ -50,3 +49,3 @@ export class Stage { | ||
boundsMargin; | ||
defShaderCtr; | ||
defShaderNode = null; | ||
strictBound; | ||
@@ -56,2 +55,4 @@ preloadBound; | ||
defaultTexture = null; | ||
pixelRatio; | ||
bufferMemory = 2e6; | ||
/** | ||
@@ -70,2 +71,3 @@ * Renderer Event Bus for the Stage to emit events onto | ||
currentFrameTime = 0; | ||
clrColor = 0x00000000; | ||
fpsNumFrames = 0; | ||
@@ -96,3 +98,2 @@ fpsElapsedTime = 0; | ||
this.txMemManager = new TextureMemoryManager(this, textureMemory); | ||
this.shManager = new CoreShaderManager(); | ||
this.animationManager = new AnimationManager(); | ||
@@ -111,18 +112,15 @@ this.contextSpy = enableContextSpy ? new ContextSpy() : null; | ||
this.preloadBound = createPreloadBounds(this.strictBound, bm); | ||
const rendererOptions = { | ||
this.clrColor = clearColor; | ||
this.pixelRatio = | ||
options.devicePhysicalPixelRatio * options.deviceLogicalPixelRatio; | ||
this.renderer = new renderEngine({ | ||
stage: this, | ||
canvas, | ||
pixelRatio: options.devicePhysicalPixelRatio * options.deviceLogicalPixelRatio, | ||
clearColor: clearColor ?? 0xff000000, | ||
bufferMemory, | ||
txManager: this.txManager, | ||
txMemManager: this.txMemManager, | ||
shManager: this.shManager, | ||
contextSpy: this.contextSpy, | ||
forceWebGL2, | ||
}; | ||
this.renderer = new renderEngine(rendererOptions); | ||
}); | ||
this.shManager = new CoreShaderManager(this); | ||
this.defShaderNode = this.renderer.getDefaultShaderNode(); | ||
const renderMode = this.renderer.mode || 'webgl'; | ||
this.createDefaultTexture(); | ||
this.defShaderCtr = this.renderer.getDefShaderCtr(); | ||
setPremultiplyMode(renderMode); | ||
@@ -187,3 +185,3 @@ // Must do this after renderer is created | ||
textureOptions: {}, | ||
shader: this.defShaderCtr, | ||
shader: this.defShaderNode, | ||
rtt: false, | ||
@@ -202,2 +200,3 @@ src: null, | ||
setClearColor(color) { | ||
this.clearColor = color; | ||
this.renderer.updateClearColor(color); | ||
@@ -447,12 +446,2 @@ this.renderRequested = true; | ||
} | ||
/** | ||
* Create a shader controller instance | ||
* | ||
* @param type | ||
* @param props | ||
* @returns | ||
*/ | ||
createShaderCtr(type, props) { | ||
return this.shManager.loadShader(type, props); | ||
} | ||
createNode(props) { | ||
@@ -543,3 +532,3 @@ const resolvedProps = this.resolveNodeDefaults(props); | ||
textureOptions: props.textureOptions ?? {}, | ||
shader: props.shader ?? this.defShaderCtr, | ||
shader: props.shader ?? this.defShaderNode, | ||
// Since setting the `src` will trigger a texture load, we need to set it after | ||
@@ -578,3 +567,11 @@ // we set the texture. Otherwise, problems happen. | ||
} | ||
set clearColor(value) { | ||
this.renderer.updateClearColor(value); | ||
this.renderRequested = true; | ||
this.clrColor = value; | ||
} | ||
get clearColor() { | ||
return this.clrColor; | ||
} | ||
} | ||
//# sourceMappingURL=Stage.js.map |
@@ -21,3 +21,3 @@ /* | ||
import { assertTruthy } from '../../../../utils.js'; | ||
import { WebGlCoreRenderer } from '../../../renderers/webgl/WebGlCoreRenderer.js'; | ||
import { WebGlRenderer } from '../../../renderers/webgl/WebGlRenderer.js'; | ||
import { ImageTexture } from '../../../textures/ImageTexture.js'; | ||
@@ -43,3 +43,3 @@ import { TrFontFace, } from '../TrFontFace.js'; | ||
const renderer = stage.renderer; | ||
assertTruthy(renderer instanceof WebGlCoreRenderer, 'SDF Font Faces can only be used with the WebGL Renderer'); | ||
assertTruthy(renderer instanceof WebGlRenderer, 'SDF Font Faces can only be used with the WebGL Renderer'); | ||
// Load image | ||
@@ -46,0 +46,0 @@ this.texture = stage.txManager.createTexture('ImageTexture', { |
@@ -93,2 +93,8 @@ import { type RGBA } from '../../lib/utils.js'; | ||
} | ||
export interface LineType { | ||
text: string; | ||
x: number; | ||
y: number; | ||
w: number; | ||
} | ||
export declare class LightningTextTextureRenderer { | ||
@@ -95,0 +101,0 @@ private _canvas; |
@@ -8,4 +8,3 @@ import { type BoundWithValid, type RectWithValid } from '../../../lib/utils.js'; | ||
import { BufferCollection } from '../../../renderers/webgl/internal/BufferCollection.js'; | ||
import type { Matrix3d } from '../../../lib/Matrix3d.js'; | ||
import type { Dimensions } from '../../../../common/CommonTypes.js'; | ||
import type { CoreTextNode } from '../../../CoreTextNode.js'; | ||
declare module '../TextRenderer.js' { | ||
@@ -71,3 +70,3 @@ interface TextRendererMap { | ||
updateState(state: SdfTextRendererState): void; | ||
renderQuads(state: SdfTextRendererState, transform: Matrix3d, clippingRect: Readonly<RectWithValid>, alpha: number, parentHasRenderTexture: boolean, framebufferDimensions: Dimensions): void; | ||
renderQuads(node: CoreTextNode): void; | ||
setIsRenderable(state: SdfTextRendererState, renderable: boolean): void; | ||
@@ -74,0 +73,0 @@ destroyState(state: SdfTextRendererState): void; |
@@ -26,8 +26,9 @@ /* | ||
import { setRenderWindow, } from './internal/setRenderWindow.js'; | ||
import { TrFontManager } from '../../TrFontManager.js'; | ||
import {} from '../../TrFontManager.js'; | ||
import { assertTruthy, mergeColorAlpha } from '../../../../utils.js'; | ||
import { WebGlCoreRenderOp } from '../../../renderers/webgl/WebGlCoreRenderOp.js'; | ||
import { WebGlRenderOp } from '../../../renderers/webgl/WebGlRenderOp.js'; | ||
import { BufferCollection } from '../../../renderers/webgl/internal/BufferCollection.js'; | ||
import { Sdf } from '../../../shaders/webgl/SdfShader.js'; | ||
import { EventEmitter } from '../../../../common/EventEmitter.js'; | ||
import { WebGlCoreRenderer } from '../../../renderers/webgl/WebGlCoreRenderer.js'; | ||
import { WebGlRenderer } from '../../../renderers/webgl/WebGlRenderer.js'; | ||
import { calcDefaultLineHeight } from '../../TextRenderingUtils.js'; | ||
@@ -64,10 +65,4 @@ /** | ||
super(stage); | ||
this.sdfShader = this.stage.shManager.loadShader('SdfShader', { | ||
transform: new Float32Array(), | ||
color: 0, | ||
size: 0, | ||
scrollY: 0, | ||
distanceRange: 0, | ||
debug: false, | ||
}).shader; | ||
this.stage.shManager.registerShaderType('Sdf', Sdf); | ||
this.sdfShader = this.stage.shManager.createShader('Sdf'); | ||
this.rendererBounds = { | ||
@@ -425,3 +420,4 @@ x1: 0, | ||
} | ||
renderQuads(state, transform, clippingRect, alpha, parentHasRenderTexture, framebufferDimensions) { | ||
renderQuads(node) { | ||
const state = node.trState; | ||
if (!state.vertexBuffer) { | ||
@@ -432,3 +428,3 @@ // Nothing to draw | ||
const renderer = this.stage.renderer; | ||
assertTruthy(renderer instanceof WebGlCoreRenderer); | ||
assertTruthy(renderer instanceof WebGlRenderer); | ||
const { fontSize, color, contain, scrollable, zIndex, debug } = state.props; | ||
@@ -456,4 +452,4 @@ // scrollY only has an effect when contain === 'both' and scrollable === true | ||
}, | ||
a_textureCoordinate: { | ||
name: 'a_textureCoordinate', | ||
a_textureCoords: { | ||
name: 'a_textureCoords', | ||
size: 2, | ||
@@ -474,3 +470,3 @@ type: glw.FLOAT, | ||
const glw = renderer.glw; | ||
const buffer = webGlBuffers?.getBuffer('a_textureCoordinate') ?? null; | ||
const buffer = webGlBuffers?.getBuffer('a_textureCoords') ?? null; | ||
glw.arrayBufferData(buffer, vertexBuffer, glw.STATIC_DRAW); | ||
@@ -483,22 +479,30 @@ state.bufferUploaded = true; | ||
const elementRect = convertBoundToRect(elementBounds, tmpRect); | ||
if (clippingRect.valid) { | ||
if (node.clippingRect.valid) { | ||
state.clippingRect.valid = true; | ||
clippingRect = intersectRect(clippingRect, elementRect, state.clippingRect); | ||
node.clippingRect = intersectRect(node.clippingRect, elementRect, state.clippingRect); | ||
} | ||
else { | ||
state.clippingRect.valid = true; | ||
clippingRect = copyRect(elementRect, state.clippingRect); | ||
node.clippingRect = copyRect(elementRect, state.clippingRect); | ||
} | ||
} | ||
const renderOp = new WebGlCoreRenderOp(renderer.glw, renderer.options, webGlBuffers, this.sdfShader, { | ||
transform: transform.getFloatArr(), | ||
// IMPORTANT: The SDF Shader expects the color NOT to be premultiplied | ||
// for the best blending results. Which is why we use `mergeColorAlpha` | ||
// instead of `mergeColorAlphaPremultiplied` here. | ||
color: mergeColorAlpha(color, alpha), | ||
size: fontSize / (trFontFace.data?.info.size || 0), | ||
scrollY, | ||
distanceRange, | ||
debug: debug.sdfShaderDebug, | ||
}, alpha, clippingRect, { height: textH, width: textW }, 0, zIndex, false, parentHasRenderTexture, framebufferDimensions); | ||
const renderOp = new WebGlRenderOp(renderer, { | ||
sdfShaderProps: { | ||
transform: node.globalTransform.getFloatArr(), | ||
color: mergeColorAlpha(color, node.worldAlpha), | ||
size: fontSize / (trFontFace.data?.info.size || 0), | ||
scrollY, | ||
distanceRange, | ||
debug: debug.sdfShaderDebug, | ||
}, | ||
sdfBuffers: state.webGlBuffers, | ||
shader: this.sdfShader, | ||
alpha: node.worldAlpha, | ||
clippingRect: node.clippingRect, | ||
height: textH, | ||
width: textW, | ||
rtt: false, | ||
parentHasRenderTexture: node.parentHasRenderTexture, | ||
framebufferDimensions: node.framebufferDimensions, | ||
}, 0); | ||
const texture = state.trFontFace?.texture; | ||
@@ -505,0 +509,0 @@ assertTruthy(texture); |
@@ -1,7 +0,4 @@ | ||
import type { Dimensions } from '../../../common/CommonTypes.js'; | ||
import type { EventEmitter } from '../../../common/EventEmitter.js'; | ||
import type { CoreTextNode } from '../../CoreTextNode.js'; | ||
import type { Stage } from '../../Stage.js'; | ||
import type { Matrix3d } from '../../lib/Matrix3d.js'; | ||
import type { RectWithValid } from '../../lib/utils.js'; | ||
import type { TrFontFace, TrFontFaceDescriptors } from '../font-face-types/TrFontFace.js'; | ||
@@ -372,3 +369,3 @@ import type { TextBaseline, TextVerticalAlign } from './LightningTextTextureRenderer.js'; | ||
abstract updateState(state: StateT): void; | ||
renderQuads?(state: StateT, transform: Matrix3d, clippingRect: RectWithValid, alpha: number, parentHasRenderTexture: boolean, framebufferDimensions: Dimensions | undefined): void; | ||
renderQuads?(node: CoreTextNode): void; | ||
} |
@@ -195,4 +195,4 @@ import type { CoreTextureManager } from '../CoreTextureManager.js'; | ||
*/ | ||
static resolveDefaults(props: unknown): Record<string, unknown>; | ||
static resolveDefaults(props: unknown): Record<string, any>; | ||
} | ||
export {}; |
@@ -5,3 +5,3 @@ import type { IAnimationController } from '../common/IAnimationController.js'; | ||
import type { AnimationSettings } from '../core/animations/CoreAnimation.js'; | ||
import type { BaseShaderController } from './ShaderController.js'; | ||
import type { CoreShaderNode } from '../core/renderers/CoreShaderNode.js'; | ||
/** | ||
@@ -25,5 +25,5 @@ * A visual Node in the Renderer scene graph. | ||
*/ | ||
export interface INode<SC extends BaseShaderController = BaseShaderController> extends Omit<CoreNode, 'shader' | 'animate' | 'parent'> { | ||
shader: SC; | ||
animate(props: Partial<INodeAnimateProps<SC>>, settings: Partial<AnimationSettings>): IAnimationController; | ||
export interface INode<ShaderNode extends CoreShaderNode = CoreShaderNode> extends Omit<CoreNode, 'shader' | 'animate' | 'parent'> { | ||
shader: ShaderNode; | ||
animate(props: Partial<INodeAnimateProps<ShaderNode>>, settings: Partial<AnimationSettings>): IAnimationController; | ||
parent: INode | null; | ||
@@ -34,4 +34,4 @@ } | ||
*/ | ||
export interface INodeAnimateProps<SC extends BaseShaderController = BaseShaderController> extends Omit<CoreNodeAnimateProps, 'shaderProps'> { | ||
shaderProps: Partial<SC['props']>; | ||
export interface INodeAnimateProps<ShNode extends CoreShaderNode> extends Omit<CoreNodeAnimateProps, 'shaderProps'> { | ||
shaderProps: Partial<ShNode['props']>; | ||
} | ||
@@ -41,4 +41,4 @@ /** | ||
*/ | ||
export interface INodeProps<SC extends BaseShaderController = BaseShaderController> extends Omit<CoreNodeProps, 'shader' | 'parent'> { | ||
shader: SC; | ||
export interface INodeProps<ShNode extends CoreShaderNode> extends Omit<CoreNodeProps, 'shader' | 'parent'> { | ||
shader: ShNode; | ||
parent: INode | null; | ||
@@ -59,3 +59,3 @@ } | ||
export interface ITextNode extends Omit<CoreTextNode, 'animate' | 'parent'> { | ||
animate(props: Partial<INodeAnimateProps<BaseShaderController>>, settings: Partial<AnimationSettings>): IAnimationController; | ||
animate(props: Partial<INodeAnimateProps<CoreShaderNode>>, settings: Partial<AnimationSettings>): IAnimationController; | ||
parent: INode | null; | ||
@@ -62,0 +62,0 @@ } |
@@ -1,2 +0,1 @@ | ||
import type { EffectMap, ShaderMap } from '../core/CoreShaderManager.js'; | ||
import type { ExtractProps, TextureMap } from '../core/CoreTextureManager.js'; | ||
@@ -6,42 +5,12 @@ import { EventEmitter } from '../common/EventEmitter.js'; | ||
import { CoreNode } from '../core/CoreNode.js'; | ||
import type { BaseShaderController, ShaderController } from './ShaderController.js'; | ||
import type { INode, INodeProps, ITextNode, ITextNodeProps } from './INode.js'; | ||
import type { DynamicEffects, DynamicShaderController } from './DynamicShaderController.js'; | ||
import type { EffectDesc } from '../core/renderers/webgl/shaders/effects/ShaderEffect.js'; | ||
import type { TextureMemoryManagerSettings } from '../core/TextureMemoryManager.js'; | ||
import type { CanvasTextRenderer } from '../core/text-rendering/renderers/CanvasTextRenderer.js'; | ||
import type { SdfTextRenderer } from '../core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js'; | ||
import type { WebGlCoreRenderer } from '../core/renderers/webgl/WebGlCoreRenderer.js'; | ||
import type { CanvasCoreRenderer } from '../core/renderers/canvas/CanvasCoreRenderer.js'; | ||
import type { WebGlRenderer } from '../core/renderers/webgl/WebGlRenderer.js'; | ||
import type { CanvasRenderer } from '../core/renderers/canvas/CanvasRenderer.js'; | ||
import type { Inspector } from './Inspector.js'; | ||
import type { CoreShaderNode } from '../core/renderers/CoreShaderNode.js'; | ||
import type { ExtractShaderProps, OptionalShaderProps, ShaderMap } from '../core/CoreShaderManager.js'; | ||
/** | ||
* An immutable reference to a specific Shader type | ||
* | ||
* @remarks | ||
* See {@link ShaderRef} for more details. | ||
*/ | ||
export interface SpecificShaderRef<ShType extends keyof ShaderMap> { | ||
readonly descType: 'shader'; | ||
readonly shType: ShType; | ||
readonly props: ExtractProps<ShaderMap[ShType]>; | ||
} | ||
type MapShaderRefs<ShType extends keyof ShaderMap> = ShType extends keyof ShaderMap ? SpecificShaderRef<ShType> : never; | ||
/** | ||
* An immutable reference to a Shader | ||
* | ||
* @remarks | ||
* This structure should only be created by the RendererMain's `createShader` | ||
* method. The structure is immutable and should not be modified once created. | ||
* | ||
* A `ShaderRef` exists in the Main API Space and is used to point to an actual | ||
* `Shader` instance in the Core API Space. The `ShaderRef` is used to | ||
* communicate with the Core API Space to create, load, and destroy the | ||
* `Shader` instance. | ||
* | ||
* This type is technically a discriminated union of all possible shader types. | ||
* If you'd like to represent a specific shader type, you can use the | ||
* `SpecificShaderRef` generic type. | ||
*/ | ||
export type ShaderRef = MapShaderRefs<keyof ShaderMap>; | ||
/** | ||
* Configuration settings for {@link RendererMain} | ||
@@ -164,3 +133,3 @@ */ | ||
*/ | ||
renderEngine: typeof CanvasCoreRenderer | typeof WebGlCoreRenderer; | ||
renderEngine: typeof CanvasRenderer | typeof WebGlRenderer; | ||
/** | ||
@@ -316,3 +285,3 @@ * Quad buffer size in bytes | ||
export declare class RendererMain extends EventEmitter { | ||
readonly root: INode<ShaderController<'DefaultShader'>>; | ||
readonly root: INode; | ||
readonly canvas: HTMLCanvasElement; | ||
@@ -345,3 +314,3 @@ readonly settings: Readonly<Required<RendererMainSettings>>; | ||
*/ | ||
createNode<ShCtr extends BaseShaderController = ShaderController<'DefaultShader'>>(props: Partial<INodeProps<ShCtr>>): INode<ShCtr>; | ||
createNode<ShNode extends CoreShaderNode<any>>(props: Partial<INodeProps<ShNode>>): INode<ShNode>; | ||
/** | ||
@@ -403,55 +372,4 @@ * Create a new scene graph text node | ||
*/ | ||
createShader<ShType extends keyof ShaderMap>(shaderType: ShType, props?: ExtractProps<ShaderMap[ShType]>): ShaderController<ShType>; | ||
createShader<ShType extends keyof ShaderMap>(shType: ShType, props?: OptionalShaderProps<ShType>): CoreShaderNode<ExtractShaderProps<ShType>>; | ||
/** | ||
* Create a new Dynamic Shader controller | ||
* | ||
* @remarks | ||
* A Dynamic Shader is a shader that can be composed of an array of mulitple | ||
* effects. Each effect can be animated or changed after creation (provided | ||
* the effect is given a name). | ||
* | ||
* Example: | ||
* ```ts | ||
* renderer.createNode({ | ||
* shader: renderer.createDynamicShader([ | ||
* renderer.createEffect('radius', { | ||
* radius: 0 | ||
* }, 'effect1'), | ||
* renderer.createEffect('border', { | ||
* color: 0xff00ffff, | ||
* width: 10, | ||
* }, 'effect2'), | ||
* ]), | ||
* }); | ||
* ``` | ||
* | ||
* @param effects | ||
* @returns | ||
*/ | ||
createDynamicShader<T extends DynamicEffects<[...{ | ||
name?: string; | ||
type: keyof EffectMap; | ||
}[]]>>(effects: [...T]): DynamicShaderController<T>; | ||
/** | ||
* Create an effect to be used in a Dynamic Shader | ||
* | ||
* @remark | ||
* The {name} parameter is optional but required if you want to animate the effect | ||
* or change the effect's properties after creation. | ||
* | ||
* See {@link createDynamicShader} for an example. | ||
* | ||
* @param type | ||
* @param props | ||
* @param name | ||
* @returns | ||
*/ | ||
createEffect<Type extends keyof EffectMap, Name extends string | undefined = undefined>(type: Type, props: EffectDesc<{ | ||
name: Name; | ||
type: Type; | ||
}>['props'], name?: Name): EffectDesc<{ | ||
name: Name; | ||
type: Type; | ||
}>; | ||
/** | ||
* Get a Node by its ID | ||
@@ -502,2 +420,1 @@ * | ||
} | ||
export {}; |
@@ -185,2 +185,3 @@ /* | ||
createNode(props) { | ||
assertTruthy(this.stage, 'Stage is not initialized'); | ||
const node = this.stage.createNode(props); | ||
@@ -263,58 +264,6 @@ if (this.inspector) { | ||
*/ | ||
createShader(shaderType, props) { | ||
return this.stage.shManager.loadShader(shaderType, props); | ||
createShader(shType, props) { | ||
return this.stage.shManager.createShader(shType, props); | ||
} | ||
/** | ||
* Create a new Dynamic Shader controller | ||
* | ||
* @remarks | ||
* A Dynamic Shader is a shader that can be composed of an array of mulitple | ||
* effects. Each effect can be animated or changed after creation (provided | ||
* the effect is given a name). | ||
* | ||
* Example: | ||
* ```ts | ||
* renderer.createNode({ | ||
* shader: renderer.createDynamicShader([ | ||
* renderer.createEffect('radius', { | ||
* radius: 0 | ||
* }, 'effect1'), | ||
* renderer.createEffect('border', { | ||
* color: 0xff00ffff, | ||
* width: 10, | ||
* }, 'effect2'), | ||
* ]), | ||
* }); | ||
* ``` | ||
* | ||
* @param effects | ||
* @returns | ||
*/ | ||
createDynamicShader(effects) { | ||
return this.stage.shManager.loadDynamicShader({ | ||
effects: effects, | ||
}); | ||
} | ||
/** | ||
* Create an effect to be used in a Dynamic Shader | ||
* | ||
* @remark | ||
* The {name} parameter is optional but required if you want to animate the effect | ||
* or change the effect's properties after creation. | ||
* | ||
* See {@link createDynamicShader} for an example. | ||
* | ||
* @param type | ||
* @param props | ||
* @param name | ||
* @returns | ||
*/ | ||
createEffect(type, props, name) { | ||
return { | ||
name, | ||
type, | ||
props, | ||
}; | ||
} | ||
/** | ||
* Get a Node by its ID | ||
@@ -321,0 +270,0 @@ * |
@@ -105,1 +105,7 @@ import type { ContextSpy } from './core/lib/ContextSpy.js'; | ||
export declare function getNewId(): number; | ||
/** | ||
* Makes a deep clone of an object | ||
* @param object | ||
* @returns | ||
*/ | ||
export declare function deepClone<T>(obj: T): T; |
@@ -211,2 +211,20 @@ /* | ||
} | ||
/** | ||
* Makes a deep clone of an object | ||
* @param object | ||
* @returns | ||
*/ | ||
export function deepClone(obj) { | ||
if (typeof obj !== 'object') { | ||
return obj; | ||
} | ||
if (Array.isArray(obj)) { | ||
return obj.map((item) => deepClone(item)); | ||
} | ||
const copy = {}; | ||
for (const key in obj) { | ||
copy[key] = deepClone(obj[key]); | ||
} | ||
return copy; | ||
} | ||
//# sourceMappingURL=utils.js.map |
@@ -39,2 +39,8 @@ /* | ||
export { CanvasTextRenderer } from '../src/core/text-rendering/renderers/CanvasTextRenderer.js'; | ||
export { CanvasCoreRenderer } from '../src/core/renderers/canvas/CanvasCoreRenderer.js'; | ||
export { CanvasRenderer } from '../src/core/renderers/canvas/CanvasRenderer.js'; | ||
export { CanvasTexture } from '../src/core/renderers/canvas/CanvasTexture.js'; | ||
export * from '../src/core/renderers/canvas/CanvasShaderNode.js'; | ||
/** | ||
* @deprecated Use CanvasRenderer. | ||
*/ | ||
export { CanvasRenderer as CanvasCoreRenderer } from '../src/core/renderers/canvas/CanvasRenderer.js'; |
@@ -42,4 +42,2 @@ /* | ||
export * from '../src/main-api/Renderer.js'; | ||
export * from '../src/main-api/ShaderController.js'; | ||
export * from '../src/main-api/DynamicShaderController.js'; | ||
export * from '../src/common/IAnimationController.js'; | ||
@@ -55,24 +53,17 @@ export * from '../src/common/CommonTypes.js'; | ||
export type { MemoryInfo } from '../src/core/TextureMemoryManager.js'; | ||
export type { ShaderMap, EffectMap } from '../src/core/CoreShaderManager.js'; | ||
export type { TextRendererMap } from '../src/core/text-rendering/renderers/TextRenderer.js'; | ||
export type { TrFontFaceMap } from '../src/core/text-rendering/font-face-types/TrFontFace.js'; | ||
export type { AnimationSettings } from '../src/core/animations/CoreAnimation.js'; | ||
export type { | ||
EffectProps, | ||
FadeOutEffectProps, | ||
LinearGradientEffectProps, | ||
RadialGradientEffectProps, | ||
GrayscaleEffectProps, | ||
GlitchEffectProps, | ||
RadialProgressEffectProps, | ||
HolePunchEffectProps, | ||
} from '../src/core/CoreShaderManager.js'; | ||
export type { WebGlCoreRenderer } from '../src/core/renderers/webgl/WebGlCoreRenderer.js'; | ||
export type { WebGlCoreCtxTexture } from '../src/core/renderers/webgl/WebGlCoreCtxTexture.js'; | ||
export type { Inspector } from '../src/main-api/Inspector.js'; | ||
export type { CoreNodeRenderState } from '../src/core/CoreNode.js'; | ||
export * from '../src/core/renderers/CoreShaderNode.js'; | ||
export * from '../src/core/shaders/templates/BorderTemplate.js'; | ||
export * from '../src/core/shaders/templates/HolePunchTemplate.js'; | ||
export * from '../src/core/shaders/templates/RoundedTemplate.js'; | ||
export * from '../src/core/shaders/templates/LinearGradientTemplate.js'; | ||
export * from '../src/core/shaders/templates/RadialGradientTemplate.js'; | ||
// Shaders | ||
export * from '../src/core/renderers/webgl/WebGlCoreShader.js'; | ||
export * from '../src/core/renderers/webgl/shaders/effects/ShaderEffect.js'; | ||
export * from '../src/core/renderers/webgl/WebGlShaderProgram.js'; | ||
export type { ShaderProgramSources } from '../src/core/renderers/webgl/internal/ShaderUtils.js'; | ||
@@ -92,1 +83,10 @@ | ||
export type * from '../src/core/Stage.js'; | ||
/** | ||
* @deprecated Use `import { WebGlRenderer } @lightningjs/renderer/webgl` instead | ||
*/ | ||
export type { WebGlRenderer as WebGlCoreRenderer } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
/** | ||
* @deprecated Use `import { WebGlCtxTexture } @lightningjs/renderer/webgl` instead | ||
*/ | ||
export type { WebGlCtxTexture as WebGlCoreCtxTexture } from '../src/core/renderers/webgl/WebGlCtxTexture.js'; |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -19,2 +19,3 @@ /* | ||
*/ | ||
/** | ||
@@ -39,2 +40,13 @@ * SDF Font renderer | ||
export { SdfTextRenderer } from '../src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js'; | ||
export { WebGlCoreRenderer } from '../src/core/renderers/webgl/WebGlCoreRenderer.js'; | ||
export { WebGlRenderer } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
export { WebGlCtxTexture } from '../src/core/renderers/webgl/WebGlCtxTexture.js'; | ||
export * from '../src/core/renderers/webgl/WebGlShaderNode.js'; | ||
/** | ||
* @deprecated Use WebGlRenderer. | ||
*/ | ||
export { WebGlRenderer as WebGlCoreRenderer } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
export { WebGlRenderer as WebGlCoreCtxTexture } from '../src/core/renderers/webgl/WebGlRenderer.js'; | ||
export * as shaders from './webgl-shaders.js'; |
{ | ||
"name": "@lightningjs/renderer", | ||
"version": "2.13.0", | ||
"version": "3.0.0-beta1", | ||
"description": "Lightning 3 Renderer", | ||
@@ -11,3 +11,5 @@ "type": "module", | ||
"./canvas": "./dist/exports/canvas.js", | ||
"./canvas/shaders": "./dist/exports/canvas-shaders.js", | ||
"./webgl": "./dist/exports/webgl.js", | ||
"./webgl/shaders": "./dist/exports/webgl-shaders.js", | ||
"./inspector": "./dist/exports/inspector.js" | ||
@@ -65,2 +67,3 @@ }, | ||
], | ||
"packageManager": "pnpm@8.9.2", | ||
"engines": { | ||
@@ -67,0 +70,0 @@ "npm": ">= 10.0.0", |
@@ -0,0 +0,0 @@ # Lightning 3 Renderer |
@@ -0,0 +0,0 @@ if ( |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -49,3 +49,2 @@ /* | ||
propValuesMap: PropValuesMap = {}; | ||
dynPropValuesMap: PropValuesMap | undefined = undefined; | ||
@@ -71,29 +70,14 @@ constructor( | ||
}; | ||
} else if (node.shader.type !== 'DynamicShader') { | ||
} else if (key === 'shaderProps' && node.shader !== null) { | ||
this.propValuesMap['shaderProps'] = {}; | ||
for (const key in props.shaderProps) { | ||
let start = node.shader.props![key]; | ||
if (Array.isArray(start) === true) { | ||
start = start[0]; | ||
} | ||
this.propValuesMap['shaderProps'][key] = { | ||
start: node.shader.props[key] as number, | ||
start, | ||
target: props.shaderProps[key] as number, | ||
}; | ||
} | ||
} else { | ||
const shaderPropKeys = Object.keys(props.shaderProps!); | ||
const spLength = shaderPropKeys.length; | ||
this.dynPropValuesMap = {}; | ||
for (let j = 0; j < spLength; j++) { | ||
const effectName = shaderPropKeys[j]!; | ||
const effect = props.shaderProps![effectName]!; | ||
this.dynPropValuesMap[effectName] = {}; | ||
const effectProps = Object.entries(effect); | ||
const eLength = effectProps.length; | ||
for (let k = 0; k < eLength; k++) { | ||
const [key, value] = effectProps[k]!; | ||
this.dynPropValuesMap[effectName]![key] = { | ||
start: node.shader.props[effectName][key], | ||
target: value, | ||
}; | ||
} | ||
} | ||
} | ||
@@ -147,20 +131,6 @@ } | ||
this.restoreValues( | ||
this.node.shader.props as Record<string, number>, | ||
this.node.shader!.props as Record<string, number>, | ||
this.propValuesMap['shaderProps'], | ||
); | ||
} | ||
if (this.dynPropValuesMap !== undefined) { | ||
const dynEntries = Object.keys(this.dynPropValuesMap); | ||
const dynEntriesL = dynEntries.length; | ||
if (dynEntriesL > 0) { | ||
for (let i = 0; i < dynEntriesL; i++) { | ||
const key = dynEntries[i]!; | ||
this.restoreValues( | ||
this.node.shader.props[key], | ||
this.dynPropValuesMap[key]!, | ||
); | ||
} | ||
} | ||
} | ||
} | ||
@@ -191,13 +161,2 @@ | ||
if (this.dynPropValuesMap !== undefined) { | ||
const dynEntries = Object.keys(this.dynPropValuesMap); | ||
const dynEntriesL = dynEntries.length; | ||
if (dynEntriesL > 0) { | ||
for (let i = 0; i < dynEntriesL; i++) { | ||
const key = dynEntries[i]!; | ||
this.reverseValues(this.dynPropValuesMap[key]!); | ||
} | ||
} | ||
} | ||
// restore stop method if we are not looping | ||
@@ -315,3 +274,3 @@ if (!this.settings.loop) { | ||
this.updateValues( | ||
this.node.shader.props as Record<string, number>, | ||
this.node.shader!.props as Record<string, number>, | ||
this.propValuesMap['shaderProps'], | ||
@@ -322,17 +281,2 @@ easing, | ||
if (this.dynPropValuesMap !== undefined) { | ||
const dynEntries = Object.keys(this.dynPropValuesMap); | ||
const dynEntriesL = dynEntries.length; | ||
if (dynEntriesL > 0) { | ||
for (let i = 0; i < dynEntriesL; i++) { | ||
const key = dynEntries[i]!; | ||
this.updateValues( | ||
this.node.shader.props[key], | ||
this.dynPropValuesMap[key]!, | ||
easing, | ||
); | ||
} | ||
} | ||
} | ||
if (this.progress < 1) { | ||
@@ -339,0 +283,0 @@ this.emit('tick', { progress: this.progress }); |
@@ -0,0 +0,0 @@ /* eslint-disable @typescript-eslint/unbound-method */ |
@@ -25,3 +25,2 @@ /* | ||
import { type TextureOptions } from './CoreTextureManager.js'; | ||
import { type BaseShaderController } from '../main-api/ShaderController'; | ||
import { createBound } from './lib/utils.js'; | ||
@@ -58,3 +57,3 @@ import { ImageTexture } from './textures/ImageTexture.js'; | ||
scaleY: 0, | ||
shader: mock<BaseShaderController>(), | ||
shader: null, | ||
src: '', | ||
@@ -97,2 +96,3 @@ texture: null, | ||
node.color = 0xffffffff; | ||
node.color = 0xffffffff; | ||
@@ -115,2 +115,3 @@ expect(node.color).toBe(0xffffffff); | ||
node.color = 0xffffffff; | ||
node.color = 0xffffffff; | ||
@@ -117,0 +118,0 @@ expect(node.updateType).toBe(UpdateType.PremultipliedColors); |
@@ -19,152 +19,66 @@ /* | ||
*/ | ||
import type { ExtractProps } from './CoreTextureManager.js'; | ||
import type { CoreRenderer } from './renderers/CoreRenderer.js'; | ||
import type { CoreShader } from './renderers/CoreShader.js'; | ||
import { DefaultShader } from './renderers/webgl/shaders/DefaultShader.js'; | ||
import { DefaultShaderBatched } from './renderers/webgl/shaders/DefaultShaderBatched.js'; | ||
import { deepClone } from '../utils.js'; | ||
import { | ||
DynamicShader, | ||
type DynamicShaderProps, | ||
} from './renderers/webgl/shaders/DynamicShader.js'; | ||
import { RoundedRectangle } from './renderers/webgl/shaders/RoundedRectangle.js'; | ||
import { SdfShader } from './renderers/webgl/shaders/SdfShader.js'; | ||
CoreShaderNode, | ||
resolveShaderProps, | ||
type CoreShaderType, | ||
} from './renderers/CoreShaderNode.js'; | ||
import type { CoreShaderProgram } from './renderers/CoreShaderProgram.js'; | ||
import type { Stage } from './Stage.js'; | ||
import { RadiusEffect } from './renderers/webgl/shaders/effects/RadiusEffect.js'; | ||
import { BorderEffect } from './renderers/webgl/shaders/effects/BorderEffect.js'; | ||
import { | ||
LinearGradientEffect, | ||
type LinearGradientEffectProps, | ||
} from './renderers/webgl/shaders/effects/LinearGradientEffect.js'; | ||
import { | ||
GrayscaleEffect, | ||
type GrayscaleEffectProps, | ||
} from './renderers/webgl/shaders/effects/GrayscaleEffect.js'; | ||
import { BorderRightEffect } from './renderers/webgl/shaders/effects/BorderRightEffect.js'; | ||
import { BorderTopEffect } from './renderers/webgl/shaders/effects/BorderTopEffect.js'; | ||
import { BorderBottomEffect } from './renderers/webgl/shaders/effects/BorderBottomEffect.js'; | ||
import { BorderLeftEffect } from './renderers/webgl/shaders/effects/BorderLeftEffect.js'; | ||
import { | ||
GlitchEffect, | ||
type GlitchEffectProps, | ||
} from './renderers/webgl/shaders/effects/GlitchEffect.js'; | ||
import { | ||
FadeOutEffect, | ||
type FadeOutEffectProps, | ||
} from './renderers/webgl/shaders/effects/FadeOutEffect.js'; | ||
import { | ||
RadialGradientEffect, | ||
type RadialGradientEffectProps, | ||
} from './renderers/webgl/shaders/effects/RadialGradientEffect.js'; | ||
import type { WebGlCoreRenderer } from './renderers/webgl/WebGlCoreRenderer.js'; | ||
import { | ||
RadialProgressEffect, | ||
type RadialProgressEffectProps, | ||
} from './renderers/webgl/shaders/effects/RadialProgressEffect.js'; | ||
import { | ||
HolePunchEffect, | ||
type HolePunchEffectProps, | ||
} from './renderers/webgl/shaders/effects/HolePunchEffect.js'; | ||
import { WebGlCoreShader } from './renderers/webgl/WebGlCoreShader.js'; | ||
import { UnsupportedShader } from './renderers/canvas/shaders/UnsupportedShader.js'; | ||
import { ShaderController } from '../main-api/ShaderController.js'; | ||
import { | ||
DynamicShaderController, | ||
type DynamicEffects, | ||
} from '../main-api/DynamicShaderController.js'; | ||
export type { FadeOutEffectProps }; | ||
export type { LinearGradientEffectProps }; | ||
export type { RadialGradientEffectProps }; | ||
export type { GrayscaleEffectProps }; | ||
export type { GlitchEffectProps }; | ||
export type { RadialProgressEffectProps }; | ||
export type { HolePunchEffectProps }; | ||
export interface ShaderMap { | ||
DefaultShader: typeof DefaultShader; | ||
DefaultShaderBatched: typeof DefaultShaderBatched; | ||
RoundedRectangle: typeof RoundedRectangle; | ||
DynamicShader: typeof DynamicShader; | ||
SdfShader: typeof SdfShader; | ||
UnsupportedShader: typeof UnsupportedShader; | ||
[key: string]: CoreShaderType<any>; | ||
} | ||
export interface EffectMap { | ||
radius: typeof RadiusEffect; | ||
border: typeof BorderEffect; | ||
borderBottom: typeof BorderBottomEffect; | ||
borderLeft: typeof BorderLeftEffect; | ||
borderRight: typeof BorderRightEffect; | ||
borderTop: typeof BorderTopEffect; | ||
fadeOut: typeof FadeOutEffect; | ||
linearGradient: typeof LinearGradientEffect; | ||
radialGradient: typeof RadialGradientEffect; | ||
grayscale: typeof GrayscaleEffect; | ||
glitch: typeof GlitchEffect; | ||
radialProgress: typeof RadialProgressEffect; | ||
holePunch: typeof HolePunchEffect; | ||
} | ||
export type ExtractProps<Props> = { | ||
[K in keyof Props]: Props[K] extends { default: infer D } ? D : Props[K]; | ||
}; | ||
export type EffectProps = | ||
| FadeOutEffectProps | ||
| LinearGradientEffectProps | ||
| RadialGradientEffectProps | ||
| GrayscaleEffectProps | ||
| GlitchEffectProps | ||
| RadialProgressEffectProps | ||
| HolePunchEffectProps; | ||
export type PartialShaderProps<Props> = Partial<ExtractProps<Props>>; | ||
export type ExtractShaderProps<T extends keyof ShaderMap> = ExtractProps< | ||
ShaderMap[T]['props'] | ||
>; | ||
export type OptionalShaderProps<T extends keyof ShaderMap> = PartialShaderProps< | ||
ShaderMap[T]['props'] | ||
>; | ||
export class CoreShaderManager { | ||
protected shCache: Map<string, InstanceType<ShaderMap[keyof ShaderMap]>> = | ||
new Map(); | ||
protected shConstructors: Partial<ShaderMap> = {}; | ||
protected attachedShader: CoreShader | null = null; | ||
protected effectConstructors: Partial<EffectMap> = {}; | ||
renderer!: CoreRenderer; | ||
protected shTypes: Record<string, CoreShaderType> = {}; | ||
protected shCache: Map<string, CoreShaderProgram> = new Map(); | ||
constructor() { | ||
this.registerShaderType('DefaultShader', DefaultShader); | ||
this.registerShaderType('DefaultShaderBatched', DefaultShaderBatched); | ||
this.registerShaderType('RoundedRectangle', RoundedRectangle); | ||
this.registerShaderType('DynamicShader', DynamicShader); | ||
this.registerShaderType('SdfShader', SdfShader); | ||
/** | ||
* valuesCache is used to store calculations that can be shared between shader nodes. | ||
*/ | ||
protected valuesCache: Map<string, Record<string, unknown>> = new Map(); | ||
protected valuesCacheUsage: Map<string, number> = new Map(); | ||
this.registerEffectType('border', BorderEffect); | ||
this.registerEffectType('borderBottom', BorderBottomEffect); | ||
this.registerEffectType('borderLeft', BorderLeftEffect); | ||
this.registerEffectType('borderRight', BorderRightEffect); | ||
this.registerEffectType('borderTop', BorderTopEffect); | ||
this.registerEffectType('fadeOut', FadeOutEffect); | ||
this.registerEffectType('linearGradient', LinearGradientEffect); | ||
this.registerEffectType('radialGradient', RadialGradientEffect); | ||
this.registerEffectType('grayscale', GrayscaleEffect); | ||
this.registerEffectType('glitch', GlitchEffect); | ||
this.registerEffectType('radius', RadiusEffect); | ||
this.registerEffectType('radialProgress', RadialProgressEffect); | ||
this.registerEffectType('holePunch', HolePunchEffect); | ||
} | ||
protected attachedShader: CoreShaderProgram | null = null; | ||
registerShaderType<Type extends keyof ShaderMap>( | ||
shType: Type, | ||
shClass: ShaderMap[Type], | ||
): void { | ||
this.shConstructors[shType] = shClass; | ||
} | ||
constructor(readonly stage: Stage) {} | ||
registerEffectType<Type extends keyof EffectMap>( | ||
effectType: Type, | ||
effectClass: EffectMap[Type], | ||
registerShaderType<Name extends keyof ShaderMap>( | ||
name: Name, | ||
shType: ShaderMap[Name], | ||
): void { | ||
this.effectConstructors[effectType] = effectClass; | ||
/** | ||
* block name duplicates | ||
*/ | ||
if (this.shTypes[name as string] !== undefined) { | ||
console.warn( | ||
`ShaderType already exists with the name: ${name}. Breaking off registration.`, | ||
); | ||
return; | ||
} | ||
/** | ||
* Check renderer if shader type is supported. | ||
*/ | ||
if (this.stage.renderer.supportsShaderType(shType) === false) { | ||
console.warn( | ||
`The renderer being used does not support this shader type. Breaking off registration.`, | ||
); | ||
return; | ||
} | ||
this.shTypes[name as string] = deepClone(shType); | ||
} | ||
getRegisteredEffects(): Partial<EffectMap> { | ||
return this.effectConstructors; | ||
} | ||
getRegisteredShaders(): Partial<ShaderMap> { | ||
return this.shConstructors; | ||
} | ||
/** | ||
@@ -177,118 +91,105 @@ * Loads a shader (if not already loaded) and returns a controller for it. | ||
*/ | ||
loadShader<Type extends keyof ShaderMap>( | ||
shType: Type, | ||
props?: ExtractProps<ShaderMap[Type]>, | ||
): ShaderController<Type> { | ||
if (!this.renderer) { | ||
throw new Error(`Renderer is not been defined`); | ||
createShader<Name extends keyof ShaderMap>( | ||
name: Name, | ||
props?: Record<string, unknown>, | ||
): CoreShaderNode | null { | ||
const shType = this.shTypes[name as string] as ShaderMap[Name]; | ||
if (shType === undefined) { | ||
console.warn( | ||
`ShaderType not found falling back on renderer default shader`, | ||
); | ||
return this.stage.defShaderNode; | ||
} | ||
const ShaderClass = this.shConstructors[shType]; | ||
if (!ShaderClass) { | ||
throw new Error(`Shader type "${shType as string}" is not registered`); | ||
let shaderKey = name as string; | ||
if (shType.props !== undefined) { | ||
/** | ||
* if props is undefined create empty obj to fill | ||
*/ | ||
props = props || {}; | ||
/** | ||
* resolve shader values | ||
*/ | ||
resolveShaderProps(props, shType.props); | ||
if (shType.getCacheMarkers !== undefined) { | ||
shaderKey += `-${shType.getCacheMarkers(props)}`; | ||
} | ||
} | ||
if ( | ||
this.renderer.mode === 'canvas' && | ||
ShaderClass.prototype instanceof WebGlCoreShader | ||
) { | ||
return this._createShaderCtr( | ||
shType, | ||
new UnsupportedShader(shType) as InstanceType<ShaderMap[Type]>, | ||
props as ExtractProps<ShaderMap[Type]>, | ||
); | ||
if (this.stage.renderer.mode === 'canvas') { | ||
return this.stage.renderer.createShaderNode(shaderKey, shType, props); | ||
} | ||
if (shType === 'DynamicShader') { | ||
return this.loadDynamicShader( | ||
props as DynamicShaderProps, | ||
) as unknown as ShaderController<Type>; | ||
} | ||
/** | ||
* get shaderProgram by cacheKey | ||
*/ | ||
let shProgram = this.shCache.get(shaderKey); | ||
const resolvedProps = ShaderClass.resolveDefaults( | ||
props as Record<string, unknown>, | ||
); | ||
const cacheKey = | ||
ShaderClass.makeCacheKey(resolvedProps) || ShaderClass.name; | ||
if (cacheKey && this.shCache.has(cacheKey)) { | ||
return this._createShaderCtr( | ||
shType, | ||
this.shCache.get(cacheKey) as InstanceType<ShaderMap[Type]>, | ||
resolvedProps as ExtractProps<ShaderMap[Type]>, | ||
); | ||
/** | ||
* if shaderProgram was not found create a new one | ||
*/ | ||
if (shProgram === undefined) { | ||
shProgram = this.stage.renderer.createShaderProgram(shType, props)!; | ||
this.shCache.set(shaderKey, shProgram); | ||
} | ||
// @ts-expect-error ShaderClass WILL accept a Renderer | ||
const shader = new ShaderClass(this.renderer, props) as InstanceType< | ||
ShaderMap[Type] | ||
>; | ||
if (cacheKey) { | ||
this.shCache.set(cacheKey, shader); | ||
} | ||
return this._createShaderCtr( | ||
return this.stage.renderer.createShaderNode( | ||
shaderKey, | ||
shType, | ||
shader, | ||
resolvedProps as ExtractProps<ShaderMap[Type]>, | ||
props, | ||
shProgram, | ||
); | ||
} | ||
loadDynamicShader< | ||
T extends DynamicEffects<[...{ name?: string; type: keyof EffectMap }[]]>, | ||
>(props: DynamicShaderProps): DynamicShaderController<T> { | ||
if (!this.renderer) { | ||
throw new Error(`Renderer is not been defined`); | ||
mutateShaderValueUsage(key: string, mutation: number) { | ||
let usage = this.valuesCacheUsage.get(key) || 0; | ||
this.valuesCacheUsage.set(key, usage + mutation); | ||
} | ||
getShaderValues(key: string) { | ||
const values = this.valuesCache.get(key); | ||
if (values === undefined) { | ||
return undefined; | ||
} | ||
const resolvedProps = DynamicShader.resolveDefaults( | ||
props as Record<string, unknown>, | ||
this.effectConstructors, | ||
); | ||
const cacheKey = DynamicShader.makeCacheKey( | ||
resolvedProps, | ||
this.effectConstructors, | ||
); | ||
if (cacheKey && this.shCache.has(cacheKey)) { | ||
return this._createDynShaderCtr( | ||
this.shCache.get(cacheKey) as InstanceType<ShaderMap['DynamicShader']>, | ||
resolvedProps, | ||
); | ||
} | ||
const shader = new DynamicShader( | ||
this.renderer as WebGlCoreRenderer, | ||
props, | ||
this.effectConstructors, | ||
); | ||
if (cacheKey) { | ||
this.shCache.set(cacheKey, shader); | ||
} | ||
return this._createDynShaderCtr(shader, resolvedProps); | ||
this.mutateShaderValueUsage(key, 1); | ||
return values; | ||
} | ||
private _createShaderCtr<Type extends keyof ShaderMap>( | ||
type: Type, | ||
shader: InstanceType<ShaderMap[Type]>, | ||
props: ExtractProps<ShaderMap[Type]>, | ||
): ShaderController<Type> { | ||
return new ShaderController(type, shader, props, this.renderer.stage); | ||
setShaderValues(key: string, values: Record<string, unknown>) { | ||
this.valuesCache.set(key, values); | ||
this.mutateShaderValueUsage(key, 1); | ||
} | ||
private _createDynShaderCtr< | ||
T extends DynamicEffects<[...{ name?: string; type: keyof EffectMap }[]]>, | ||
>( | ||
shader: InstanceType<ShaderMap['DynamicShader']>, | ||
props: ExtractProps<ShaderMap['DynamicShader']>, | ||
): DynamicShaderController<T> { | ||
shader.bindUniformMethods(props); | ||
return new DynamicShaderController(shader, props, this); | ||
cleanup() { | ||
const values = [...this.valuesCacheUsage.entries()].sort( | ||
(entryA, entryB) => { | ||
if (entryA[1] < entryB[1]) { | ||
return -1; | ||
} else if (entryA[1] > entryB[1]) { | ||
return 1; | ||
} | ||
return 0; | ||
}, | ||
); | ||
for (let i = 0; i < values.length; i++) { | ||
if (values[i]![1] > 0) { | ||
break; | ||
} | ||
this.valuesCacheUsage.delete(values[i]![0]); | ||
this.valuesCache.delete(values[i]![0]); | ||
} | ||
} | ||
useShader(shader: CoreShader): void { | ||
useShader(shader: CoreShaderProgram): void { | ||
if (this.attachedShader === shader) { | ||
return; | ||
} | ||
if (this.attachedShader) { | ||
if (this.attachedShader && this.attachedShader.detach) { | ||
this.attachedShader.detach(); | ||
} | ||
shader.attach(); | ||
if (shader.attach) { | ||
shader.attach(); | ||
} | ||
this.attachedShader = shader; | ||
} | ||
} |
@@ -421,10 +421,3 @@ /* | ||
this.textRenderer.renderQuads( | ||
this.trState, | ||
this.globalTransform, | ||
this.clippingRect, | ||
this.worldAlpha, | ||
this.parentHasRenderTexture, | ||
this.framebufferDimensions, | ||
); | ||
this.textRenderer.renderQuads(this); | ||
} | ||
@@ -431,0 +424,0 @@ |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ const rx1 = 0; |
@@ -60,3 +60,3 @@ /* | ||
const littleEndian = view.getUint32(12) === 16909060 ? true : false; | ||
const mipmaps = []; | ||
const mipmaps: ArrayBuffer[] = []; | ||
@@ -115,6 +115,6 @@ const data = { | ||
// @ts-expect-error Object possibly undefined | ||
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands | ||
const dataOffset = header[pvrMetadata] + 52; | ||
const pvrtcData = new Uint8Array(arrayBuffer, dataOffset); | ||
const mipmaps = []; | ||
const mipmaps: Uint8Array[] = []; | ||
const data = { | ||
@@ -121,0 +121,0 @@ pixelWidth: header[pvrWidth], |
@@ -0,0 +0,0 @@ /* |
@@ -20,2 +20,4 @@ /* | ||
import type { Vec4 } from '../renderers/webgl/internal/ShaderUtils.js'; | ||
export const PROTOCOL_REGEX = /^(data|ftps?|https?):/; | ||
@@ -312,1 +314,50 @@ | ||
} | ||
export function calcFactoredRadius( | ||
radius: number, | ||
width: number, | ||
height: number, | ||
): number { | ||
return radius * Math.min(Math.min(width, height) / (2.0 * radius), 1); | ||
} | ||
export function valuesAreEqual(values: number[]) { | ||
let prevValue = values[0]; | ||
for (let i = 1; i < values.length; i++) { | ||
if (prevValue !== values[i]) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
export function calcFactoredRadiusArray( | ||
radius: Vec4, | ||
width: number, | ||
height: number, | ||
): [number, number, number, number] { | ||
const result: [number, number, number, number] = [ | ||
radius[0], | ||
radius[1], | ||
radius[2], | ||
radius[3], | ||
]; | ||
const factor = Math.min( | ||
Math.min( | ||
Math.min( | ||
width / Math.max(width, radius[0] + radius[1]), | ||
width / Math.max(width, radius[2] + radius[3]), | ||
), | ||
Math.min( | ||
height / Math.max(height, radius[0] + radius[3]), | ||
height / Math.max(height, radius[1] + radius[2]), | ||
), | ||
), | ||
1, | ||
); | ||
result[0] *= factor; | ||
result[1] *= factor; | ||
result[2] *= factor; | ||
result[3] *= factor; | ||
return result; | ||
} |
@@ -0,0 +0,0 @@ export interface CreateImageBitmapSupport { |
@@ -205,5 +205,4 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ | ||
activeTexture(textureUnit: number) { | ||
const { gl } = this; | ||
if (this.activeTextureUnit !== textureUnit) { | ||
gl.activeTexture(textureUnit + gl.TEXTURE0); | ||
this.gl.activeTexture(textureUnit + this.gl.TEXTURE0); | ||
this.activeTextureUnit = textureUnit; | ||
@@ -223,15 +222,12 @@ } | ||
bindTexture(texture: WebGLTexture | null) { | ||
const { gl, activeTextureUnit, texture2dUnits } = this; | ||
if (texture2dUnits[activeTextureUnit] === texture) { | ||
if (this.texture2dUnits[this.activeTextureUnit] === texture) { | ||
return; | ||
} | ||
texture2dUnits[activeTextureUnit] = texture; | ||
this.texture2dUnits[this.activeTextureUnit] = texture; | ||
gl.bindTexture(this.gl.TEXTURE_2D, texture); | ||
this.gl.bindTexture(this.gl.TEXTURE_2D, texture); | ||
} | ||
private _getActiveTexture(): WebGLTexture | null { | ||
const { activeTextureUnit, texture2dUnits } = this; | ||
return texture2dUnits[activeTextureUnit]!; | ||
return this.texture2dUnits[this.activeTextureUnit]!; | ||
} | ||
@@ -251,4 +247,2 @@ | ||
texParameteri(pname: number, param: number) { | ||
const { gl, texture2dParams } = this; | ||
const activeTexture = this._getActiveTexture(); | ||
@@ -258,6 +252,6 @@ if (!activeTexture) { | ||
} | ||
let textureParams = texture2dParams.get(activeTexture); | ||
let textureParams = this.texture2dParams.get(activeTexture); | ||
if (!textureParams) { | ||
textureParams = {}; | ||
texture2dParams.set(activeTexture, textureParams); | ||
this.texture2dParams.set(activeTexture, textureParams); | ||
} | ||
@@ -268,3 +262,3 @@ if (textureParams[pname] === param) { | ||
textureParams[pname] = param; | ||
gl.texParameteri(gl.TEXTURE_2D, pname, param); | ||
this.gl.texParameteri(this.gl.TEXTURE_2D, pname, param); | ||
} | ||
@@ -325,6 +319,5 @@ | ||
) { | ||
const { gl } = this; | ||
if (format) { | ||
gl.texImage2D( | ||
gl.TEXTURE_2D, | ||
this.gl.texImage2D( | ||
this.gl.TEXTURE_2D, | ||
level, | ||
@@ -340,4 +333,4 @@ internalFormat, | ||
} else { | ||
gl.texImage2D( | ||
gl.TEXTURE_2D, | ||
this.gl.texImage2D( | ||
this.gl.TEXTURE_2D, | ||
level, | ||
@@ -368,5 +361,4 @@ internalFormat, | ||
): void { | ||
const { gl } = this; | ||
gl.compressedTexImage2D( | ||
gl.TEXTURE_2D, | ||
this.gl.compressedTexImage2D( | ||
this.gl.TEXTURE_2D, | ||
level, | ||
@@ -389,4 +381,3 @@ internalformat, | ||
pixelStorei(pname: GLenum, param: GLint | GLboolean) { | ||
const { gl } = this; | ||
gl.pixelStorei(pname, param); | ||
this.gl.pixelStorei(pname, param); | ||
} | ||
@@ -403,4 +394,3 @@ | ||
generateMipmap() { | ||
const { gl } = this; | ||
gl.generateMipmap(gl.TEXTURE_2D); | ||
this.gl.generateMipmap(this.gl.TEXTURE_2D); | ||
} | ||
@@ -416,4 +406,3 @@ | ||
createTexture() { | ||
const { gl } = this; | ||
return gl.createTexture(); | ||
return this.gl.createTexture(); | ||
} | ||
@@ -429,7 +418,6 @@ | ||
deleteTexture(texture: WebGLTexture | null) { | ||
const { gl } = this; | ||
if (texture) { | ||
this.texture2dParams.delete(texture); | ||
} | ||
gl.deleteTexture(texture); | ||
this.gl.deleteTexture(texture); | ||
} | ||
@@ -453,4 +441,3 @@ | ||
viewport(x: GLint, y: GLint, width: GLsizei, height: GLsizei) { | ||
const { gl } = this; | ||
gl.viewport(x, y, width, height); | ||
this.gl.viewport(x, y, width, height); | ||
} | ||
@@ -469,4 +456,3 @@ | ||
clearColor(red: GLclampf, green: GLclampf, blue: GLclampf, alpha: GLclampf) { | ||
const { gl } = this; | ||
gl.clearColor(red, green, blue, alpha); | ||
this.gl.clearColor(red, green, blue, alpha); | ||
} | ||
@@ -481,10 +467,9 @@ | ||
setScissorTest(enable: boolean) { | ||
const { gl, scissorEnabled } = this; | ||
if (enable === scissorEnabled) { | ||
if (enable === this.scissorEnabled) { | ||
return; | ||
} | ||
if (enable) { | ||
gl.enable(gl.SCISSOR_TEST); | ||
this.gl.enable(this.gl.SCISSOR_TEST); | ||
} else { | ||
gl.disable(gl.SCISSOR_TEST); | ||
this.gl.disable(this.gl.SCISSOR_TEST); | ||
} | ||
@@ -505,10 +490,9 @@ this.scissorEnabled = enable; | ||
scissor(x: GLint, y: GLint, width: GLsizei, height: GLsizei) { | ||
const { gl, scissorX, scissorY, scissorWidth, scissorHeight } = this; | ||
if ( | ||
x !== scissorX || | ||
y !== scissorY || | ||
width !== scissorWidth || | ||
height !== scissorHeight | ||
x !== this.scissorX || | ||
y !== this.scissorY || | ||
width !== this.scissorWidth || | ||
height !== this.scissorHeight | ||
) { | ||
gl.scissor(x, y, width, height); | ||
this.gl.scissor(x, y, width, height); | ||
this.scissorX = x; | ||
@@ -530,10 +514,9 @@ this.scissorY = y; | ||
setBlend(blend: boolean) { | ||
const { gl, blendEnabled } = this; | ||
if (blend === blendEnabled) { | ||
if (blend === this.blendEnabled) { | ||
return; | ||
} | ||
if (blend) { | ||
gl.enable(gl.BLEND); | ||
this.gl.enable(this.gl.BLEND); | ||
} else { | ||
gl.disable(gl.BLEND); | ||
this.gl.disable(this.gl.BLEND); | ||
} | ||
@@ -552,10 +535,9 @@ this.blendEnabled = blend; | ||
blendFunc(src: GLenum, dst: GLenum) { | ||
const { gl, blendSrcRgb, blendDstRgb, blendSrcAlpha, blendDstAlpha } = this; | ||
if ( | ||
src !== blendSrcRgb || | ||
dst !== blendDstRgb || | ||
src !== blendSrcAlpha || | ||
dst !== blendDstAlpha | ||
src !== this.blendSrcRgb || | ||
dst !== this.blendDstRgb || | ||
src !== this.blendSrcAlpha || | ||
dst !== this.blendDstAlpha | ||
) { | ||
gl.blendFunc(src, dst); | ||
this.gl.blendFunc(src, dst); | ||
this.blendSrcRgb = src; | ||
@@ -576,4 +558,3 @@ this.blendDstRgb = dst; | ||
createBuffer() { | ||
const { gl } = this; | ||
return gl.createBuffer(); | ||
return this.gl.createBuffer(); | ||
} | ||
@@ -588,4 +569,3 @@ | ||
createFramebuffer() { | ||
const { gl } = this; | ||
return gl.createFramebuffer(); | ||
return this.gl.createFramebuffer(); | ||
} | ||
@@ -601,4 +581,3 @@ | ||
bindFramebuffer(framebuffer: WebGLFramebuffer | null) { | ||
const { gl } = this; | ||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); | ||
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, framebuffer); | ||
} | ||
@@ -619,3 +598,3 @@ | ||
) { | ||
const { gl } = this; | ||
const gl = this.gl; | ||
gl.framebufferTexture2D( | ||
@@ -639,4 +618,3 @@ gl.FRAMEBUFFER, | ||
clear() { | ||
const { gl } = this; | ||
gl.clear(gl.COLOR_BUFFER_BIT); | ||
this.gl.clear(this.gl.COLOR_BUFFER_BIT); | ||
} | ||
@@ -662,8 +640,7 @@ | ||
) { | ||
const { gl, boundArrayBuffer } = this; | ||
if (boundArrayBuffer !== buffer) { | ||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | ||
if (this.boundArrayBuffer !== buffer) { | ||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer); | ||
this.boundArrayBuffer = buffer; | ||
} | ||
gl.bufferData(gl.ARRAY_BUFFER, data, usage); | ||
this.gl.bufferData(this.gl.ARRAY_BUFFER, data, usage); | ||
} | ||
@@ -688,8 +665,7 @@ | ||
) { | ||
const { gl, boundElementArrayBuffer } = this; | ||
if (boundElementArrayBuffer !== buffer) { | ||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer); | ||
if (this.boundElementArrayBuffer !== buffer) { | ||
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, buffer); | ||
this.boundElementArrayBuffer = buffer; | ||
} | ||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data, usage); | ||
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, data, usage); | ||
} | ||
@@ -723,11 +699,49 @@ | ||
) { | ||
const { gl, boundArrayBuffer } = this; | ||
if (boundArrayBuffer !== buffer) { | ||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | ||
if (this.boundArrayBuffer !== buffer) { | ||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer); | ||
this.boundArrayBuffer = buffer; | ||
} | ||
gl.vertexAttribPointer(index, size, type, normalized, stride, offset); | ||
this.gl.vertexAttribPointer(index, size, type, normalized, stride, offset); | ||
} | ||
/** | ||
* Returns object with Attribute names as key and numbers as location values | ||
* | ||
* @param program | ||
* @returns object with numbers | ||
*/ | ||
getUniformLocations(program: WebGLProgram): Record<string, number> { | ||
const gl = this.gl; | ||
const length = gl.getProgramParameter( | ||
program, | ||
gl.ACTIVE_UNIFORMS, | ||
) as number; | ||
const result = {} as Record<string, number>; | ||
for (let i = 0; i < length; i++) { | ||
const { name } = gl.getActiveUniform(program, i) as WebGLActiveInfo; | ||
result[name] = i; | ||
} | ||
return result; | ||
} | ||
/** | ||
* Returns object with Attribute names as key and numbers as location values | ||
* @param program | ||
* @returns object with numbers | ||
*/ | ||
getAttributeLocations(program: WebGLProgram): Record<string, number> { | ||
const gl = this.gl; | ||
const length = gl.getProgramParameter( | ||
program, | ||
gl.ACTIVE_ATTRIBUTES, | ||
) as number; | ||
const result = {} as Record<string, number>; | ||
for (let i = 0; i < length; i++) { | ||
const { name } = gl.getActiveAttrib(program, i) as WebGLActiveInfo; | ||
result[name] = i; | ||
} | ||
return result; | ||
} | ||
/** | ||
* ``` | ||
@@ -741,7 +755,6 @@ * gl.useProgram(program); | ||
useProgram(program: WebGLProgram | null) { | ||
const { gl, curProgram } = this; | ||
if (curProgram === program) { | ||
if (this.curProgram === program) { | ||
return; | ||
} | ||
gl.useProgram(program); | ||
this.gl.useProgram(program); | ||
this.curProgram = program; | ||
@@ -756,5 +769,7 @@ } | ||
*/ | ||
uniform1f(location: WebGLUniformLocation | null, v0: number) { | ||
const { gl } = this; | ||
gl.uniform1f(location, v0); | ||
uniform1f(location: string, v0: number) { | ||
this.gl.uniform1f( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
v0, | ||
); | ||
} | ||
@@ -768,8 +783,7 @@ | ||
*/ | ||
uniform1fv( | ||
location: WebGLUniformLocation | null, | ||
value: Float32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniform1fv(location, value); | ||
uniform1fv(location: string, value: Float32Array) { | ||
this.gl.uniform1fv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
value, | ||
); | ||
} | ||
@@ -783,5 +797,7 @@ | ||
*/ | ||
uniform1i(location: WebGLUniformLocation | null, v0: number) { | ||
const { gl } = this; | ||
gl.uniform1i(location, v0); | ||
uniform1i(location: string, v0: number) { | ||
this.gl.uniform1i( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
v0, | ||
); | ||
} | ||
@@ -795,8 +811,7 @@ | ||
*/ | ||
uniform1iv( | ||
location: WebGLUniformLocation | null, | ||
value: Int32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniform1iv(location, value); | ||
uniform1iv(location: string, value: Int32Array) { | ||
this.gl.uniform1iv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
value, | ||
); | ||
} | ||
@@ -811,5 +826,8 @@ | ||
*/ | ||
uniform2f(location: WebGLUniformLocation | null, v0: number, v1: number) { | ||
const { gl } = this; | ||
gl.uniform2f(location, v0, v1); | ||
uniform2f(location: string, v0: number, v1: number) { | ||
this.gl.uniform2f( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
v0, | ||
v1, | ||
); | ||
} | ||
@@ -823,8 +841,7 @@ | ||
*/ | ||
uniform2fv( | ||
location: WebGLUniformLocation | null, | ||
value: Float32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniform2fv(location, value); | ||
uniform2fv(location: string, value: Float32Array) { | ||
this.gl.uniform2fv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
value, | ||
); | ||
} | ||
@@ -839,5 +856,8 @@ | ||
*/ | ||
uniform2i(location: WebGLUniformLocation | null, v0: number, v1: number) { | ||
const { gl } = this; | ||
gl.uniform2i(location, v0, v1); | ||
uniform2i(location: string, v0: number, v1: number) { | ||
this.gl.uniform2i( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
v0, | ||
v1, | ||
); | ||
} | ||
@@ -851,8 +871,7 @@ | ||
*/ | ||
uniform2iv( | ||
location: WebGLUniformLocation | null, | ||
value: Int32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniform2iv(location, value); | ||
uniform2iv(location: string, value: Int32Array) { | ||
this.gl.uniform2iv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
value, | ||
); | ||
} | ||
@@ -868,10 +887,9 @@ | ||
*/ | ||
uniform3f( | ||
location: WebGLUniformLocation | null, | ||
v0: number, | ||
v1: number, | ||
v2: number, | ||
) { | ||
const { gl } = this; | ||
gl.uniform3f(location, v0, v1, v2); | ||
uniform3f(location: string, v0: number, v1: number, v2: number) { | ||
this.gl.uniform3f( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
v0, | ||
v1, | ||
v2, | ||
); | ||
} | ||
@@ -885,8 +903,7 @@ | ||
*/ | ||
uniform3fv( | ||
location: WebGLUniformLocation | null, | ||
value: Float32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniform3fv(location, value); | ||
uniform3fv(location: string, value: Float32Array) { | ||
this.gl.uniform3fv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
value, | ||
); | ||
} | ||
@@ -902,10 +919,9 @@ | ||
*/ | ||
uniform3i( | ||
location: WebGLUniformLocation | null, | ||
v0: number, | ||
v1: number, | ||
v2: number, | ||
) { | ||
const { gl } = this; | ||
gl.uniform3i(location, v0, v1, v2); | ||
uniform3i(location: string, v0: number, v1: number, v2: number) { | ||
this.gl.uniform3i( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
v0, | ||
v1, | ||
v2, | ||
); | ||
} | ||
@@ -919,8 +935,7 @@ | ||
*/ | ||
uniform3iv( | ||
location: WebGLUniformLocation | null, | ||
value: Int32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniform3iv(location, value); | ||
uniform3iv(location: string, value: Int32Array) { | ||
this.gl.uniform3iv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
value, | ||
); | ||
} | ||
@@ -937,11 +952,10 @@ | ||
*/ | ||
uniform4f( | ||
location: WebGLUniformLocation | null, | ||
v0: number, | ||
v1: number, | ||
v2: number, | ||
v3: number, | ||
) { | ||
const { gl } = this; | ||
gl.uniform4f(location, v0, v1, v2, v3); | ||
uniform4f(location: string, v0: number, v1: number, v2: number, v3: number) { | ||
this.gl.uniform4f( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
v0, | ||
v1, | ||
v2, | ||
v3, | ||
); | ||
} | ||
@@ -955,8 +969,7 @@ | ||
*/ | ||
uniform4fv( | ||
location: WebGLUniformLocation | null, | ||
value: Float32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniform4fv(location, value); | ||
uniform4fv(location: string, value: Float32Array) { | ||
this.gl.uniform4fv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
value, | ||
); | ||
} | ||
@@ -973,11 +986,10 @@ | ||
*/ | ||
uniform4i( | ||
location: WebGLUniformLocation | null, | ||
v0: number, | ||
v1: number, | ||
v2: number, | ||
v3: number, | ||
) { | ||
const { gl } = this; | ||
gl.uniform4i(location, v0, v1, v2, v3); | ||
uniform4i(location: string, v0: number, v1: number, v2: number, v3: number) { | ||
this.gl.uniform4i( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
v0, | ||
v1, | ||
v2, | ||
v3, | ||
); | ||
} | ||
@@ -991,8 +1003,7 @@ | ||
*/ | ||
uniform4iv( | ||
location: WebGLUniformLocation | null, | ||
value: Int32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniform4iv(location, value); | ||
uniform4iv(location: string, value: Int32Array) { | ||
this.gl.uniform4iv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
value, | ||
); | ||
} | ||
@@ -1007,8 +1018,8 @@ | ||
*/ | ||
uniformMatrix2fv( | ||
location: WebGLUniformLocation | null, | ||
value: Float32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniformMatrix2fv(location, false, value); | ||
uniformMatrix2fv(location: string, value: Float32Array) { | ||
this.gl.uniformMatrix2fv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
false, | ||
value, | ||
); | ||
} | ||
@@ -1021,8 +1032,8 @@ | ||
*/ | ||
uniformMatrix3fv( | ||
location: WebGLUniformLocation | null, | ||
value: Float32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniformMatrix3fv(location, false, value); | ||
uniformMatrix3fv(location: string, value: Float32Array) { | ||
this.gl.uniformMatrix3fv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
false, | ||
value, | ||
); | ||
} | ||
@@ -1035,8 +1046,8 @@ | ||
*/ | ||
uniformMatrix4fv( | ||
location: WebGLUniformLocation | null, | ||
value: Float32Array | number[], | ||
) { | ||
const { gl } = this; | ||
gl.uniformMatrix4fv(location, false, value); | ||
uniformMatrix4fv(location: string, value: Float32Array) { | ||
this.gl.uniformMatrix4fv( | ||
this.gl.getUniformLocation(this.curProgram!, location), | ||
false, | ||
value, | ||
); | ||
} | ||
@@ -1053,4 +1064,3 @@ | ||
getParameter(pname: GLenum): any { | ||
const { gl } = this; | ||
return gl.getParameter(pname); | ||
return this.gl.getParameter(pname); | ||
} | ||
@@ -1069,4 +1079,3 @@ | ||
drawElements(mode: GLenum, count: GLsizei, type: GLenum, offset: GLintptr) { | ||
const { gl } = this; | ||
gl.drawElements(mode, count, type, offset); | ||
this.gl.drawElements(mode, count, type, offset); | ||
} | ||
@@ -1083,4 +1092,3 @@ | ||
getExtension(name: string) { | ||
const { gl } = this; | ||
return gl.getExtension(name); | ||
return this.gl.getExtension(name); | ||
} | ||
@@ -1096,4 +1104,3 @@ | ||
getError() { | ||
const { gl } = this; | ||
return gl.getError(); | ||
return this.gl.getError(); | ||
} | ||
@@ -1109,5 +1116,6 @@ | ||
createVertexArray() { | ||
const { gl } = this; | ||
assertTruthy(gl instanceof WebGL2RenderingContext); | ||
return gl.createVertexArray(); | ||
if (this.gl instanceof WebGL2RenderingContext) { | ||
return this.gl.createVertexArray(); | ||
} | ||
return undefined; | ||
} | ||
@@ -1123,5 +1131,5 @@ | ||
bindVertexArray(vertexArray: WebGLVertexArrayObject | null) { | ||
const { gl } = this; | ||
assertTruthy(gl instanceof WebGL2RenderingContext); | ||
gl.bindVertexArray(vertexArray); | ||
if (this.gl instanceof WebGL2RenderingContext) { | ||
this.gl.bindVertexArray(vertexArray); | ||
} | ||
} | ||
@@ -1139,4 +1147,3 @@ | ||
getAttribLocation(program: WebGLProgram, name: string) { | ||
const { gl } = this; | ||
return gl.getAttribLocation(program, name); | ||
return this.gl.getAttribLocation(program, name); | ||
} | ||
@@ -1154,4 +1161,3 @@ | ||
getUniformLocation(program: WebGLProgram, name: string) { | ||
const { gl } = this; | ||
return gl.getUniformLocation(program, name); | ||
return this.gl.getUniformLocation(program, name); | ||
} | ||
@@ -1167,4 +1173,3 @@ | ||
enableVertexAttribArray(index: number) { | ||
const { gl } = this; | ||
gl.enableVertexAttribArray(index); | ||
this.gl.enableVertexAttribArray(index); | ||
} | ||
@@ -1180,4 +1185,3 @@ | ||
disableVertexAttribArray(index: number) { | ||
const { gl } = this; | ||
gl.disableVertexAttribArray(index); | ||
this.gl.disableVertexAttribArray(index); | ||
} | ||
@@ -1194,4 +1198,3 @@ | ||
createShader(type: number) { | ||
const { gl } = this; | ||
return gl.createShader(type); | ||
return this.gl.createShader(type); | ||
} | ||
@@ -1208,4 +1211,3 @@ | ||
compileShader(shader: WebGLShader) { | ||
const { gl } = this; | ||
gl.compileShader(shader); | ||
this.gl.compileShader(shader); | ||
} | ||
@@ -1222,4 +1224,3 @@ | ||
attachShader(program: WebGLProgram, shader: WebGLShader) { | ||
const { gl } = this; | ||
gl.attachShader(program, shader); | ||
this.gl.attachShader(program, shader); | ||
} | ||
@@ -1235,4 +1236,3 @@ | ||
linkProgram(program: WebGLProgram) { | ||
const { gl } = this; | ||
gl.linkProgram(program); | ||
this.gl.linkProgram(program); | ||
} | ||
@@ -1248,4 +1248,3 @@ | ||
deleteProgram(shader: WebGLProgram) { | ||
const { gl } = this; | ||
gl.deleteProgram(shader); | ||
this.gl.deleteProgram(shader); | ||
} | ||
@@ -1262,4 +1261,3 @@ | ||
getShaderParameter(shader: WebGLShader, pname: GLenum) { | ||
const { gl } = this; | ||
return gl.getShaderParameter(shader, pname); | ||
return this.gl.getShaderParameter(shader, pname); | ||
} | ||
@@ -1275,4 +1273,3 @@ | ||
getShaderInfoLog(shader: WebGLShader) { | ||
const { gl } = this; | ||
return gl.getShaderInfoLog(shader); | ||
return this.gl.getShaderInfoLog(shader); | ||
} | ||
@@ -1288,4 +1285,3 @@ | ||
createProgram() { | ||
const { gl } = this; | ||
return gl.createProgram(); | ||
return this.gl.createProgram(); | ||
} | ||
@@ -1303,4 +1299,3 @@ | ||
getProgramParameter(program: WebGLProgram, pname: GLenum) { | ||
const { gl } = this; | ||
return gl.getProgramParameter(program, pname); | ||
return this.gl.getProgramParameter(program, pname); | ||
} | ||
@@ -1317,4 +1312,3 @@ | ||
getProgramInfoLog(program: WebGLProgram) { | ||
const { gl } = this; | ||
return gl.getProgramInfoLog(program); | ||
return this.gl.getProgramInfoLog(program); | ||
} | ||
@@ -1331,4 +1325,3 @@ | ||
shaderSource(shader: WebGLShader, source: string) { | ||
const { gl } = this; | ||
gl.shaderSource(shader, source); | ||
this.gl.shaderSource(shader, source); | ||
} | ||
@@ -1344,4 +1337,3 @@ | ||
deleteShader(shader: WebGLShader) { | ||
const { gl } = this; | ||
gl.deleteShader(shader); | ||
this.gl.deleteShader(shader); | ||
} | ||
@@ -1348,0 +1340,0 @@ } |
@@ -37,2 +37,3 @@ /* | ||
if (!isIdle) { | ||
stage.shManager.cleanup(); | ||
stage.eventBus.emit('idle'); | ||
@@ -39,0 +40,0 @@ isIdle = true; |
@@ -21,16 +21,6 @@ /* | ||
import type { QuadOptions } from '../../CoreRenderer.js'; | ||
import type { BorderEffectProps } from '../../webgl/shaders/effects/BorderEffect.js'; | ||
import type { RadiusEffectProps } from '../../webgl/shaders/effects/RadiusEffect.js'; | ||
import type { EffectDescUnion } from '../../webgl/shaders/effects/ShaderEffect.js'; | ||
import { | ||
ROUNDED_RECTANGLE_SHADER_TYPE, | ||
UnsupportedShader, | ||
} from '../shaders/UnsupportedShader.js'; | ||
import { formatRgba, parseColorRgba } from './ColorUtils.js'; | ||
type Direction = 'Top' | 'Right' | 'Bottom' | 'Left'; | ||
/** | ||
* Extract `RoundedRectangle` shader radius to apply as a clipping | ||
*/ | ||
/* | ||
export function getRadius(quad: QuadOptions): RadiusEffectProps['radius'] { | ||
@@ -58,4 +48,2 @@ if (quad.shader instanceof UnsupportedShader) { | ||
/** | ||
* Extract `RoundedRectangle` shader radius to apply as a clipping */ | ||
export function getBorder( | ||
@@ -234,1 +222,2 @@ quad: QuadOptions, | ||
} | ||
*/ |
@@ -50,2 +50,18 @@ /* | ||
export function parseToAbgrString(abgr: number) { | ||
const a = ((abgr >>> 24) & 0xff) / 255; | ||
const b = (abgr >>> 16) & 0xff & 0xff; | ||
const g = (abgr >>> 8) & 0xff & 0xff; | ||
const r = abgr & 0xff & 0xff; | ||
return `rgba(${r},${g},${b},${a})`; | ||
} | ||
export function parseToRgbaString(rgba: number) { | ||
const r = (rgba >>> 24) & 0xff; | ||
const g = (rgba >>> 16) & 0xff & 0xff; | ||
const b = (rgba >>> 8) & 0xff & 0xff; | ||
const a = (rgba & 0xff & 0xff) / 255; | ||
return `rgba(${r},${g},${b},${a})`; | ||
} | ||
/** | ||
@@ -52,0 +68,0 @@ * Extract color components |
@@ -0,0 +0,0 @@ /* |
@@ -21,17 +21,12 @@ /* | ||
import type { Dimensions } from '../../common/CommonTypes.js'; | ||
import type { BaseShaderController } from '../../main-api/ShaderController.js'; | ||
import type { CoreNode } from '../CoreNode.js'; | ||
import type { CoreShaderManager } from '../CoreShaderManager.js'; | ||
import type { | ||
CoreTextureManager, | ||
TextureOptions, | ||
} from '../CoreTextureManager.js'; | ||
import type { TextureOptions } from '../CoreTextureManager.js'; | ||
import type { Stage } from '../Stage.js'; | ||
import type { TextureMemoryManager } from '../TextureMemoryManager.js'; | ||
import type { ContextSpy } from '../lib/ContextSpy.js'; | ||
import type { RenderCoords } from '../lib/RenderCoords.js'; | ||
import type { RectWithValid } from '../lib/utils.js'; | ||
import type { CoreShaderProgram } from './CoreShaderProgram.js'; | ||
import type { Texture } from '../textures/Texture.js'; | ||
import { CoreContextTexture } from './CoreContextTexture.js'; | ||
import type { CoreShader } from './CoreShader.js'; | ||
import type { CoreShaderType, CoreShaderNode } from './CoreShaderNode.js'; | ||
@@ -48,4 +43,3 @@ export interface QuadOptions { | ||
zIndex: number; | ||
shader: CoreShader | null; | ||
shaderProps: Record<string, unknown> | null; | ||
shader: CoreShaderNode | null; | ||
alpha: number; | ||
@@ -60,5 +54,5 @@ clippingRect: RectWithValid; | ||
renderCoords?: RenderCoords; | ||
rtt?: boolean; | ||
parentHasRenderTexture?: boolean; | ||
framebufferDimensions?: Dimensions; | ||
rtt: boolean; | ||
parentHasRenderTexture: boolean; | ||
framebufferDimensions: Dimensions; | ||
} | ||
@@ -69,8 +63,2 @@ | ||
canvas: HTMLCanvasElement | OffscreenCanvas; | ||
pixelRatio: number; | ||
txManager: CoreTextureManager; | ||
txMemManager: TextureMemoryManager; | ||
shManager: CoreShaderManager; | ||
clearColor: number; | ||
bufferMemory: number; | ||
contextSpy: ContextSpy | null; | ||
@@ -92,5 +80,2 @@ forceWebGL2: boolean; | ||
//// Core Managers | ||
txManager: CoreTextureManager; | ||
txMemManager: TextureMemoryManager; | ||
shManager: CoreShaderManager; | ||
rttNodes: CoreNode[] = []; | ||
@@ -101,5 +86,2 @@ | ||
this.stage = options.stage; | ||
this.txManager = options.txManager; | ||
this.txMemManager = options.txMemManager; | ||
this.shManager = options.shManager; | ||
} | ||
@@ -111,3 +93,14 @@ | ||
abstract createCtxTexture(textureSource: Texture): CoreContextTexture; | ||
abstract getShaderManager(): CoreShaderManager; | ||
abstract createShaderProgram( | ||
shaderConfig: Readonly<CoreShaderType>, | ||
props?: Record<string, unknown>, | ||
): CoreShaderProgram | null; | ||
abstract createShaderNode( | ||
shaderKey: string, | ||
shaderType: Readonly<CoreShaderType>, | ||
props?: Record<string, unknown>, | ||
program?: CoreShaderProgram, | ||
): CoreShaderNode; | ||
abstract supportsShaderType(shaderType: Readonly<CoreShaderType>): boolean; | ||
abstract getDefaultShaderNode(): CoreShaderNode | null; | ||
abstract get renderToTextureActive(): boolean; | ||
@@ -120,4 +113,3 @@ abstract get activeRttNode(): CoreNode | null; | ||
abstract getQuadCount(): number | null; | ||
abstract getDefShaderCtr(): BaseShaderController; | ||
abstract updateClearColor(color: number): void; | ||
} |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -21,3 +21,2 @@ /* | ||
import type { WebGlContextWrapper } from '../../../lib/WebGlContextWrapper.js'; | ||
import type { WebGlCoreRenderer } from '../WebGlCoreRenderer.js'; | ||
@@ -39,6 +38,69 @@ //#region Types | ||
export type SingleValue = number | Float32Array | Int32Array; | ||
export type Vec2 = [number, number]; | ||
export type Vec3 = [number, number, number]; | ||
export type Vec4 = [number, number, number, number]; | ||
export type UniformValue = SingleValue | Vec2 | Vec3 | Vec4; | ||
export interface UniformCollection { | ||
single: Record<string, Uniform<SingleValue>>; | ||
vec2: Record<string, Uniform<Vec2>>; | ||
vec3: Record<string, Uniform<Vec3>>; | ||
vec4: Record<string, Uniform<Vec4>>; | ||
} | ||
export interface Uniform<T = UniformValue> { | ||
method: string; | ||
value: T; | ||
} | ||
export interface SupportedSetUniforms { | ||
uniform2fv: Float32Array; | ||
uniform2iv: Int32Array; | ||
uniform3fv: | ||
| 'uniform2iv' | ||
| 'uniform3fv' | ||
| 'uniform3iv' | ||
| 'uniform4fv' | ||
| 'uniform4iv' | ||
| 'uniformMatrix2fv' | ||
| 'uniformMatrix3fv' | ||
| 'uniformMatrix4fv' | ||
| 'uniform1f' | ||
| 'uniform1fv' | ||
| 'uniform1i' | ||
| 'uniform1iv' | ||
| 'uniform3fv' | ||
| 'uniform2f' | ||
| 'uniform2i' | ||
| 'uniform3f' | ||
| 'uniform3i' | ||
| 'uniform4f' | ||
| 'uniform4i'; | ||
} | ||
type SupportSetUniforms = | ||
| 'uniform2fv' | ||
| 'uniform2iv' | ||
| 'uniform3fv' | ||
| 'uniform3iv' | ||
| 'uniform4fv' | ||
| 'uniform4iv' | ||
| 'uniformMatrix2fv' | ||
| 'uniformMatrix3fv' | ||
| 'uniformMatrix4fv' | ||
| 'uniform1f' | ||
| 'uniform1fv' | ||
| 'uniform1i' | ||
| 'uniform1iv' | ||
| 'uniform3fv' | ||
| 'uniform2f' | ||
| 'uniform2i' | ||
| 'uniform3f' | ||
| 'uniform3i' | ||
| 'uniform4f' | ||
| 'uniform4i'; | ||
export interface ShaderOptions { | ||
renderer: WebGlCoreRenderer; | ||
attributes: string[]; | ||
uniforms: UniformInfo[]; | ||
shaderSources?: ShaderProgramSources; | ||
@@ -68,2 +130,24 @@ supportsIndexedTextures?: boolean; | ||
export type UniformSet1Param = Omit< | ||
UniformMethodMap, | ||
| 'uniform2f' | ||
| 'uniform2i' | ||
| 'uniform3f' | ||
| 'uniform3i' | ||
| 'uniform4f' | ||
| 'uniform4i' | ||
>; | ||
export type UniformSet2Params = Pick< | ||
UniformMethodMap, | ||
'uniform2f' | 'uniform2i' | ||
>; | ||
export type UniformSet3Params = Pick< | ||
UniformMethodMap, | ||
'uniform3f' | 'uniform3i' | ||
>; | ||
export type UniformSet4Params = Pick< | ||
UniformMethodMap, | ||
'uniform4f' | 'uniform4i' | ||
>; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
@@ -86,3 +170,3 @@ type TupleToObject<T extends any[]> = Omit<T, keyof any[]>; | ||
type ShaderSource = string | ((textureUnits: number) => string); | ||
export type ShaderSource = string | ((textureUnits: number) => string); | ||
@@ -148,1 +232,55 @@ export interface ShaderProgramSources { | ||
} | ||
export const DefaultVertexSource = ` | ||
# ifdef GL_FRAGMENT_PRECISION_HIGH | ||
precision highp float; | ||
# else | ||
precision mediump float; | ||
# endif | ||
attribute vec2 a_position; | ||
attribute vec2 a_textureCoords; | ||
attribute vec4 a_color; | ||
attribute vec2 a_nodeCoords; | ||
uniform vec2 u_resolution; | ||
uniform float u_pixelRatio; | ||
uniform vec2 u_dimensions; | ||
uniform vec4 u_shadow; | ||
varying vec4 v_color; | ||
varying vec2 v_textureCoords; | ||
void main() { | ||
vec2 normalized = a_position * u_pixelRatio; | ||
vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y); | ||
vec2 outerEdge = clamp(a_textureCoords * 2.0 - vec2(1.0), -1.0, 1.0); | ||
vec2 shadowEdge = outerEdge; | ||
vec2 vertexPos = normalized + outerEdge + shadowEdge; | ||
v_color = a_color; | ||
v_textureCoords = a_textureCoords; | ||
gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0); | ||
} | ||
`; | ||
/** | ||
* generate fragment source for | ||
* @param stops | ||
* @returns | ||
*/ | ||
export function genGradientColors(stops: number): string { | ||
let result = ` | ||
float stopCalc = (dist - u_stops[0]) / (u_stops[1] - u_stops[0]); | ||
vec4 colorOut = mix(u_colors[0], u_colors[1], stopCalc); | ||
`; | ||
if (stops > 2) { | ||
for (let i = 2; i < stops; i++) { | ||
result += `colorOut = mix(colorOut, u_colors[${i}], clamp((dist - u_stops[${ | ||
i - 1 | ||
}]) / (u_stops[${i}] - u_stops[${i - 1}]), 0.0, 1.0));`; | ||
} | ||
} | ||
return result; | ||
} |
@@ -0,0 +0,0 @@ /* |
@@ -30,3 +30,3 @@ /* | ||
import { TrFontManager } from './text-rendering/TrFontManager.js'; | ||
import { CoreShaderManager, type ShaderMap } from './CoreShaderManager.js'; | ||
import { CoreShaderManager } from './CoreShaderManager.js'; | ||
import { | ||
@@ -49,7 +49,5 @@ TextRenderer, | ||
} from './TextureMemoryManager.js'; | ||
import type { CoreRendererOptions } from './renderers/CoreRenderer.js'; | ||
import { CoreRenderer } from './renderers/CoreRenderer.js'; | ||
import type { WebGlCoreRenderer } from './renderers/webgl/WebGlCoreRenderer.js'; | ||
import type { CanvasCoreRenderer } from './renderers/canvas/CanvasCoreRenderer.js'; | ||
import type { BaseShaderController } from '../main-api/ShaderController.js'; | ||
import type { WebGlRenderer } from './renderers/webgl/WebGlRenderer.js'; | ||
import type { CanvasRenderer } from './renderers/canvas/CanvasRenderer.js'; | ||
import { CoreTextNode, type CoreTextNodeProps } from './CoreTextNode.js'; | ||
@@ -59,2 +57,3 @@ import { santizeCustomDataMap } from '../main-api/utils.js'; | ||
import type { CanvasTextRenderer } from './text-rendering/renderers/CanvasTextRenderer.js'; | ||
import type { CoreShaderNode } from './renderers/CoreShaderNode.js'; | ||
import { createBound, createPreloadBounds, type Bound } from './lib/utils.js'; | ||
@@ -77,3 +76,3 @@ import type { Texture } from './textures/Texture.js'; | ||
numImageWorkers: number; | ||
renderEngine: typeof WebGlCoreRenderer | typeof CanvasCoreRenderer; | ||
renderEngine: typeof WebGlRenderer | typeof CanvasRenderer; | ||
eventBus: EventEmitter; | ||
@@ -98,3 +97,2 @@ quadBufferSize: number; | ||
const bufferMemory = 2e6; | ||
const autoStart = true; | ||
@@ -113,3 +111,3 @@ | ||
public boundsMargin: [number, number, number, number]; | ||
public readonly defShaderCtr: BaseShaderController; | ||
public readonly defShaderNode: CoreShaderNode | null = null; | ||
public readonly strictBound: Bound; | ||
@@ -119,3 +117,4 @@ public readonly preloadBound: Bound; | ||
public readonly defaultTexture: Texture | null = null; | ||
public readonly pixelRatio: number; | ||
public readonly bufferMemory: number = 2e6; | ||
/** | ||
@@ -135,2 +134,3 @@ * Renderer Event Bus for the Stage to emit events onto | ||
currentFrameTime = 0; | ||
private clrColor = 0x00000000; | ||
private fpsNumFrames = 0; | ||
@@ -179,3 +179,3 @@ private fpsElapsedTime = 0; | ||
this.txMemManager = new TextureMemoryManager(this, textureMemory); | ||
this.shManager = new CoreShaderManager(); | ||
this.animationManager = new AnimationManager(); | ||
@@ -197,21 +197,21 @@ this.contextSpy = enableContextSpy ? new ContextSpy() : null; | ||
const rendererOptions: CoreRendererOptions = { | ||
this.clrColor = clearColor; | ||
this.pixelRatio = | ||
options.devicePhysicalPixelRatio * options.deviceLogicalPixelRatio; | ||
this.renderer = new renderEngine({ | ||
stage: this, | ||
canvas, | ||
pixelRatio: | ||
options.devicePhysicalPixelRatio * options.deviceLogicalPixelRatio, | ||
clearColor: clearColor ?? 0xff000000, | ||
bufferMemory, | ||
txManager: this.txManager, | ||
txMemManager: this.txMemManager, | ||
shManager: this.shManager, | ||
contextSpy: this.contextSpy, | ||
forceWebGL2, | ||
}; | ||
}); | ||
this.renderer = new renderEngine(rendererOptions); | ||
this.shManager = new CoreShaderManager(this); | ||
this.defShaderNode = this.renderer.getDefaultShaderNode(); | ||
const renderMode = this.renderer.mode || 'webgl'; | ||
this.createDefaultTexture(); | ||
this.defShaderCtr = this.renderer.getDefShaderCtr(); | ||
setPremultiplyMode(renderMode); | ||
@@ -284,3 +284,3 @@ | ||
textureOptions: {}, | ||
shader: this.defShaderCtr, | ||
shader: this.defShaderNode, | ||
rtt: false, | ||
@@ -302,2 +302,3 @@ src: null, | ||
setClearColor(color: number) { | ||
this.clearColor = color; | ||
this.renderer.updateClearColor(color); | ||
@@ -604,16 +605,2 @@ this.renderRequested = true; | ||
/** | ||
* Create a shader controller instance | ||
* | ||
* @param type | ||
* @param props | ||
* @returns | ||
*/ | ||
createShaderCtr( | ||
type: keyof ShaderMap, | ||
props: Record<string, unknown>, | ||
): BaseShaderController { | ||
return this.shManager.loadShader(type, props); | ||
} | ||
createNode(props: Partial<CoreNodeProps>) { | ||
@@ -721,3 +708,3 @@ const resolvedProps = this.resolveNodeDefaults(props); | ||
textureOptions: props.textureOptions ?? {}, | ||
shader: props.shader ?? this.defShaderCtr, | ||
shader: props.shader ?? this.defShaderNode, | ||
// Since setting the `src` will trigger a texture load, we need to set it after | ||
@@ -757,2 +744,12 @@ // we set the texture. Otherwise, problems happen. | ||
} | ||
set clearColor(value: number) { | ||
this.renderer.updateClearColor(value); | ||
this.renderRequested = true; | ||
this.clrColor = value; | ||
} | ||
get clearColor() { | ||
return this.clrColor; | ||
} | ||
} |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -23,3 +23,3 @@ /* | ||
import type { Stage } from '../../../Stage.js'; | ||
import { WebGlCoreRenderer } from '../../../renderers/webgl/WebGlCoreRenderer.js'; | ||
import { WebGlRenderer } from '../../../renderers/webgl/WebGlRenderer.js'; | ||
import { ImageTexture } from '../../../textures/ImageTexture.js'; | ||
@@ -77,3 +77,3 @@ import { | ||
assertTruthy( | ||
renderer instanceof WebGlCoreRenderer, | ||
renderer instanceof WebGlRenderer, | ||
'SDF Font Faces can only be used with the WebGL Renderer', | ||
@@ -80,0 +80,0 @@ ); |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -140,2 +140,9 @@ /* | ||
export interface LineType { | ||
text: string; | ||
x: number; | ||
y: number; | ||
w: number; | ||
} | ||
/** | ||
@@ -203,6 +210,6 @@ * Calculate height for the canvas | ||
const ffs = []; | ||
const ffs: string[] = []; | ||
for (let i = 0, n = ff.length; i < n; i++) { | ||
if (ff[i] === 'serif' || ff[i] === 'sans-serif') { | ||
ffs.push(ff[i]); | ||
ffs.push(ff[i]!); | ||
} else { | ||
@@ -344,3 +351,3 @@ ffs.push(`"${ff[i]!}"`); | ||
let otherLines = null; | ||
let otherLines: string[] | null = null; | ||
if (this._settings.overflowSuffix) { | ||
@@ -360,3 +367,3 @@ // Wrap again with max lines suffix enabled. | ||
}`; | ||
otherLines = [al.l.length > 1 ? al.l[1] : '']; | ||
otherLines = [al.l.length > 1 ? al.l[1]! : '']; | ||
} else { | ||
@@ -522,3 +529,3 @@ otherLines = ['']; | ||
const drawLines = []; | ||
const drawLines: LineType[] = []; | ||
@@ -525,0 +532,0 @@ const { metrics } = renderInfo; |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -47,17 +47,17 @@ /* | ||
import type { TrFontFace } from '../../font-face-types/TrFontFace.js'; | ||
import { TrFontManager, type FontFamilyMap } from '../../TrFontManager.js'; | ||
import { type FontFamilyMap } from '../../TrFontManager.js'; | ||
import { assertTruthy, mergeColorAlpha } from '../../../../utils.js'; | ||
import type { Stage } from '../../../Stage.js'; | ||
import { WebGlCoreRenderOp } from '../../../renderers/webgl/WebGlCoreRenderOp.js'; | ||
import { WebGlRenderOp } from '../../../renderers/webgl/WebGlRenderOp.js'; | ||
import { BufferCollection } from '../../../renderers/webgl/internal/BufferCollection.js'; | ||
import type { | ||
SdfShader, | ||
SdfShaderProps, | ||
} from '../../../renderers/webgl/shaders/SdfShader.js'; | ||
import type { WebGlCoreCtxTexture } from '../../../renderers/webgl/WebGlCoreCtxTexture.js'; | ||
import { Sdf, type SdfShaderProps } from '../../../shaders/webgl/SdfShader.js'; | ||
import type { WebGlCtxTexture } from '../../../renderers/webgl/WebGlCtxTexture.js'; | ||
import { EventEmitter } from '../../../../common/EventEmitter.js'; | ||
import type { Matrix3d } from '../../../lib/Matrix3d.js'; | ||
import type { Dimensions } from '../../../../common/CommonTypes.js'; | ||
import { WebGlCoreRenderer } from '../../../renderers/webgl/WebGlCoreRenderer.js'; | ||
import { WebGlRenderer } from '../../../renderers/webgl/WebGlRenderer.js'; | ||
import { calcDefaultLineHeight } from '../../TextRenderingUtils.js'; | ||
import type { WebGlShaderProgram } from '../../../renderers/webgl/WebGlShaderProgram.js'; | ||
import type { WebGlShaderNode } from '../../../renderers/webgl/WebGlShaderNode.js'; | ||
import type { CoreTextNode } from '../../../CoreTextNode.js'; | ||
@@ -143,3 +143,3 @@ declare module '../TextRenderer.js' { | ||
]; | ||
private sdfShader: SdfShader; | ||
private sdfShader: WebGlShaderNode; | ||
private rendererBounds: Bound; | ||
@@ -151,10 +151,6 @@ | ||
super(stage); | ||
this.sdfShader = this.stage.shManager.loadShader('SdfShader', { | ||
transform: new Float32Array(), | ||
color: 0, | ||
size: 0, | ||
scrollY: 0, | ||
distanceRange: 0, | ||
debug: false, | ||
}).shader; | ||
this.stage.shManager.registerShaderType('Sdf', Sdf); | ||
this.sdfShader = this.stage.shManager.createShader( | ||
'Sdf', | ||
) as WebGlShaderNode; | ||
this.rendererBounds = { | ||
@@ -607,10 +603,4 @@ x1: 0, | ||
override renderQuads( | ||
state: SdfTextRendererState, | ||
transform: Matrix3d, | ||
clippingRect: Readonly<RectWithValid>, | ||
alpha: number, | ||
parentHasRenderTexture: boolean, | ||
framebufferDimensions: Dimensions, | ||
): void { | ||
override renderQuads(node: CoreTextNode): void { | ||
const state = node.trState as SdfTextRendererState; | ||
if (!state.vertexBuffer) { | ||
@@ -622,3 +612,3 @@ // Nothing to draw | ||
const renderer = this.stage.renderer; | ||
assertTruthy(renderer instanceof WebGlCoreRenderer); | ||
assertTruthy(renderer instanceof WebGlRenderer); | ||
@@ -659,4 +649,4 @@ const { fontSize, color, contain, scrollable, zIndex, debug } = state.props; | ||
}, | ||
a_textureCoordinate: { | ||
name: 'a_textureCoordinate', | ||
a_textureCoords: { | ||
name: 'a_textureCoords', | ||
size: 2, | ||
@@ -679,3 +669,3 @@ type: glw.FLOAT, | ||
const buffer = webGlBuffers?.getBuffer('a_textureCoordinate') ?? null; | ||
const buffer = webGlBuffers?.getBuffer('a_textureCoords') ?? null; | ||
glw.arrayBufferData(buffer, vertexBuffer, glw.STATIC_DRAW); | ||
@@ -690,6 +680,6 @@ state.bufferUploaded = true; | ||
if (clippingRect.valid) { | ||
if (node.clippingRect.valid) { | ||
state.clippingRect.valid = true; | ||
clippingRect = intersectRect( | ||
clippingRect, | ||
node.clippingRect = intersectRect( | ||
node.clippingRect, | ||
elementRect, | ||
@@ -700,30 +690,28 @@ state.clippingRect, | ||
state.clippingRect.valid = true; | ||
clippingRect = copyRect(elementRect, state.clippingRect); | ||
node.clippingRect = copyRect(elementRect, state.clippingRect); | ||
} | ||
} | ||
const renderOp = new WebGlCoreRenderOp( | ||
renderer.glw, | ||
renderer.options, | ||
webGlBuffers, | ||
this.sdfShader, | ||
const renderOp = new WebGlRenderOp( | ||
renderer, | ||
{ | ||
transform: transform.getFloatArr(), | ||
// IMPORTANT: The SDF Shader expects the color NOT to be premultiplied | ||
// for the best blending results. Which is why we use `mergeColorAlpha` | ||
// instead of `mergeColorAlphaPremultiplied` here. | ||
color: mergeColorAlpha(color, alpha), | ||
size: fontSize / (trFontFace.data?.info.size || 0), | ||
scrollY, | ||
distanceRange, | ||
debug: debug.sdfShaderDebug, | ||
} satisfies SdfShaderProps, | ||
alpha, | ||
clippingRect, | ||
{ height: textH, width: textW }, | ||
sdfShaderProps: { | ||
transform: node.globalTransform!.getFloatArr(), | ||
color: mergeColorAlpha(color, node.worldAlpha), | ||
size: fontSize / (trFontFace.data?.info.size || 0), | ||
scrollY, | ||
distanceRange, | ||
debug: debug.sdfShaderDebug, | ||
}, | ||
sdfBuffers: state.webGlBuffers as BufferCollection, | ||
shader: this.sdfShader, | ||
alpha: node.worldAlpha, | ||
clippingRect: node.clippingRect, | ||
height: textH, | ||
width: textW, | ||
rtt: false, | ||
parentHasRenderTexture: node.parentHasRenderTexture, | ||
framebufferDimensions: node.framebufferDimensions, | ||
}, | ||
0, | ||
zIndex, | ||
false, | ||
parentHasRenderTexture, | ||
framebufferDimensions, | ||
); | ||
@@ -735,3 +723,3 @@ | ||
renderOp.addTexture(ctxTexture as WebGlCoreCtxTexture); | ||
renderOp.addTexture(ctxTexture as WebGlCtxTexture); | ||
renderOp.length = state.bufferNumFloats; | ||
@@ -738,0 +726,0 @@ renderOp.numQuads = state.bufferNumQuads; |
@@ -47,3 +47,3 @@ /* | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-empty-interface | ||
export interface TextRendererMap {} | ||
@@ -550,10 +550,3 @@ | ||
renderQuads?( | ||
state: StateT, | ||
transform: Matrix3d, | ||
clippingRect: RectWithValid, | ||
alpha: number, | ||
parentHasRenderTexture: boolean, | ||
framebufferDimensions: Dimensions | undefined, | ||
): void; | ||
renderQuads?(node: CoreTextNode): void; | ||
} |
@@ -0,0 +0,0 @@ /* |
@@ -46,3 +46,3 @@ /* | ||
const ffs = []; | ||
const ffs: string[] = []; | ||
for (let i = 0, n = ff.length; i < n; i++) { | ||
@@ -49,0 +49,0 @@ let curFf = ff[i]; |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ /* |
@@ -334,5 +334,5 @@ /* | ||
props: unknown, | ||
): Record<string, unknown> { | ||
): Record<string, any> { | ||
return {}; | ||
} | ||
} |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ interface ImportMetaEnv { |
@@ -27,3 +27,3 @@ /* | ||
import type { AnimationSettings } from '../core/animations/CoreAnimation.js'; | ||
import type { BaseShaderController } from './ShaderController.js'; | ||
import type { CoreShaderNode } from '../core/renderers/CoreShaderNode.js'; | ||
@@ -48,7 +48,7 @@ /** | ||
*/ | ||
export interface INode<SC extends BaseShaderController = BaseShaderController> | ||
export interface INode<ShaderNode extends CoreShaderNode = CoreShaderNode> | ||
extends Omit<CoreNode, 'shader' | 'animate' | 'parent'> { | ||
shader: SC; | ||
shader: ShaderNode; | ||
animate( | ||
props: Partial<INodeAnimateProps<SC>>, | ||
props: Partial<INodeAnimateProps<ShaderNode>>, | ||
settings: Partial<AnimationSettings>, | ||
@@ -62,6 +62,5 @@ ): IAnimationController; | ||
*/ | ||
export interface INodeAnimateProps< | ||
SC extends BaseShaderController = BaseShaderController, | ||
> extends Omit<CoreNodeAnimateProps, 'shaderProps'> { | ||
shaderProps: Partial<SC['props']>; | ||
export interface INodeAnimateProps<ShNode extends CoreShaderNode> | ||
extends Omit<CoreNodeAnimateProps, 'shaderProps'> { | ||
shaderProps: Partial<ShNode['props']>; | ||
} | ||
@@ -72,6 +71,5 @@ | ||
*/ | ||
export interface INodeProps< | ||
SC extends BaseShaderController = BaseShaderController, | ||
> extends Omit<CoreNodeProps, 'shader' | 'parent'> { | ||
shader: SC; | ||
export interface INodeProps<ShNode extends CoreShaderNode> | ||
extends Omit<CoreNodeProps, 'shader' | 'parent'> { | ||
shader: ShNode; | ||
parent: INode | null; | ||
@@ -94,3 +92,3 @@ } | ||
animate( | ||
props: Partial<INodeAnimateProps<BaseShaderController>>, | ||
props: Partial<INodeAnimateProps<CoreShaderNode>>, | ||
settings: Partial<AnimationSettings>, | ||
@@ -97,0 +95,0 @@ ): IAnimationController; |
@@ -0,0 +0,0 @@ import { |
@@ -20,4 +20,2 @@ /* | ||
/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
import type { EffectMap, ShaderMap } from '../core/CoreShaderManager.js'; | ||
import type { ExtractProps, TextureMap } from '../core/CoreTextureManager.js'; | ||
@@ -29,56 +27,17 @@ import { EventEmitter } from '../common/EventEmitter.js'; | ||
import { type CoreTextNodeProps } from '../core/CoreTextNode.js'; | ||
import type { | ||
BaseShaderController, | ||
ShaderController, | ||
} from './ShaderController.js'; | ||
import type { INode, INodeProps, ITextNode, ITextNodeProps } from './INode.js'; | ||
import type { | ||
DynamicEffects, | ||
DynamicShaderController, | ||
} from './DynamicShaderController.js'; | ||
import type { | ||
EffectDesc, | ||
EffectDescUnion, | ||
} from '../core/renderers/webgl/shaders/effects/ShaderEffect.js'; | ||
import type { TextureMemoryManagerSettings } from '../core/TextureMemoryManager.js'; | ||
import type { CanvasTextRenderer } from '../core/text-rendering/renderers/CanvasTextRenderer.js'; | ||
import type { SdfTextRenderer } from '../core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js'; | ||
import type { WebGlCoreRenderer } from '../core/renderers/webgl/WebGlCoreRenderer.js'; | ||
import type { CanvasCoreRenderer } from '../core/renderers/canvas/CanvasCoreRenderer.js'; | ||
import type { WebGlRenderer } from '../core/renderers/webgl/WebGlRenderer.js'; | ||
import type { CanvasRenderer } from '../core/renderers/canvas/CanvasRenderer.js'; | ||
import type { Inspector } from './Inspector.js'; | ||
import type { CoreShaderNode } from '../core/renderers/CoreShaderNode.js'; | ||
import type { | ||
ExtractShaderProps, | ||
OptionalShaderProps, | ||
ShaderMap, | ||
} from '../core/CoreShaderManager.js'; | ||
/** | ||
* An immutable reference to a specific Shader type | ||
* | ||
* @remarks | ||
* See {@link ShaderRef} for more details. | ||
*/ | ||
export interface SpecificShaderRef<ShType extends keyof ShaderMap> { | ||
readonly descType: 'shader'; | ||
readonly shType: ShType; | ||
readonly props: ExtractProps<ShaderMap[ShType]>; | ||
} | ||
type MapShaderRefs<ShType extends keyof ShaderMap> = | ||
ShType extends keyof ShaderMap ? SpecificShaderRef<ShType> : never; | ||
/** | ||
* An immutable reference to a Shader | ||
* | ||
* @remarks | ||
* This structure should only be created by the RendererMain's `createShader` | ||
* method. The structure is immutable and should not be modified once created. | ||
* | ||
* A `ShaderRef` exists in the Main API Space and is used to point to an actual | ||
* `Shader` instance in the Core API Space. The `ShaderRef` is used to | ||
* communicate with the Core API Space to create, load, and destroy the | ||
* `Shader` instance. | ||
* | ||
* This type is technically a discriminated union of all possible shader types. | ||
* If you'd like to represent a specific shader type, you can use the | ||
* `SpecificShaderRef` generic type. | ||
*/ | ||
export type ShaderRef = MapShaderRefs<keyof ShaderMap>; | ||
/** | ||
* Configuration settings for {@link RendererMain} | ||
@@ -212,3 +171,3 @@ */ | ||
*/ | ||
renderEngine: typeof CanvasCoreRenderer | typeof WebGlCoreRenderer; | ||
renderEngine: typeof CanvasRenderer | typeof WebGlRenderer; | ||
@@ -372,3 +331,3 @@ /** | ||
export class RendererMain extends EventEmitter { | ||
readonly root: INode<ShaderController<'DefaultShader'>>; | ||
readonly root: INode; | ||
readonly canvas: HTMLCanvasElement; | ||
@@ -469,5 +428,3 @@ readonly settings: Readonly<Required<RendererMainSettings>>; | ||
// Extract the root node | ||
this.root = this.stage.root as unknown as INode< | ||
ShaderController<'DefaultShader'> | ||
>; | ||
this.root = this.stage.root as unknown as INode; | ||
@@ -509,9 +466,11 @@ // Get the target element and attach the canvas to it | ||
*/ | ||
createNode< | ||
ShCtr extends BaseShaderController = ShaderController<'DefaultShader'>, | ||
>(props: Partial<INodeProps<ShCtr>>): INode<ShCtr> { | ||
createNode<ShNode extends CoreShaderNode<any>>( | ||
props: Partial<INodeProps<ShNode>>, | ||
): INode<ShNode> { | ||
assertTruthy(this.stage, 'Stage is not initialized'); | ||
const node = this.stage.createNode(props as Partial<CoreNodeProps>); | ||
if (this.inspector) { | ||
return this.inspector.createNode(node) as unknown as INode<ShCtr>; | ||
return this.inspector.createNode(node) as unknown as INode<ShNode>; | ||
} | ||
@@ -521,3 +480,3 @@ | ||
// FIXME onCreate event? | ||
return node as unknown as INode<ShCtr>; | ||
return node as unknown as INode<ShNode>; | ||
} | ||
@@ -543,3 +502,3 @@ | ||
if (this.inspector) { | ||
return this.inspector.createTextNode(textNode); | ||
return this.inspector.createTextNode(textNode) as unknown as ITextNode; | ||
} | ||
@@ -605,72 +564,11 @@ | ||
createShader<ShType extends keyof ShaderMap>( | ||
shaderType: ShType, | ||
props?: ExtractProps<ShaderMap[ShType]>, | ||
): ShaderController<ShType> { | ||
return this.stage.shManager.loadShader(shaderType, props); | ||
shType: ShType, | ||
props?: OptionalShaderProps<ShType>, | ||
) { | ||
return this.stage.shManager.createShader(shType, props) as CoreShaderNode< | ||
ExtractShaderProps<ShType> | ||
>; | ||
} | ||
/** | ||
* Create a new Dynamic Shader controller | ||
* | ||
* @remarks | ||
* A Dynamic Shader is a shader that can be composed of an array of mulitple | ||
* effects. Each effect can be animated or changed after creation (provided | ||
* the effect is given a name). | ||
* | ||
* Example: | ||
* ```ts | ||
* renderer.createNode({ | ||
* shader: renderer.createDynamicShader([ | ||
* renderer.createEffect('radius', { | ||
* radius: 0 | ||
* }, 'effect1'), | ||
* renderer.createEffect('border', { | ||
* color: 0xff00ffff, | ||
* width: 10, | ||
* }, 'effect2'), | ||
* ]), | ||
* }); | ||
* ``` | ||
* | ||
* @param effects | ||
* @returns | ||
*/ | ||
createDynamicShader< | ||
T extends DynamicEffects<[...{ name?: string; type: keyof EffectMap }[]]>, | ||
>(effects: [...T]): DynamicShaderController<T> { | ||
return this.stage.shManager.loadDynamicShader({ | ||
effects: effects as EffectDescUnion[], | ||
}); | ||
} | ||
/** | ||
* Create an effect to be used in a Dynamic Shader | ||
* | ||
* @remark | ||
* The {name} parameter is optional but required if you want to animate the effect | ||
* or change the effect's properties after creation. | ||
* | ||
* See {@link createDynamicShader} for an example. | ||
* | ||
* @param type | ||
* @param props | ||
* @param name | ||
* @returns | ||
*/ | ||
createEffect< | ||
Type extends keyof EffectMap, | ||
Name extends string | undefined = undefined, | ||
>( | ||
type: Type, | ||
props: EffectDesc<{ name: Name; type: Type }>['props'], | ||
name?: Name, | ||
): EffectDesc<{ name: Name; type: Type }> { | ||
return { | ||
name, | ||
type, | ||
props, | ||
}; | ||
} | ||
/** | ||
* Get a Node by its ID | ||
@@ -677,0 +575,0 @@ * |
@@ -0,0 +0,0 @@ import type { CustomDataMap } from '../core/CoreNode.js'; |
@@ -249,1 +249,20 @@ /* | ||
} | ||
/** | ||
* Makes a deep clone of an object | ||
* @param object | ||
* @returns | ||
*/ | ||
export function deepClone<T>(obj: T): T { | ||
if (typeof obj !== 'object') { | ||
return obj; | ||
} | ||
if (Array.isArray(obj)) { | ||
return obj.map((item) => deepClone(item)) as T; | ||
} | ||
const copy = {} as Record<string, unknown>; | ||
for (const key in obj) { | ||
copy[key] = deepClone(obj[key]); | ||
} | ||
return copy as T; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
3216386
743
1
66908
1