import { AbstractMethodError } from '@awayjs/core';
import { MethodEvent } from '../events/MethodEvent';
import { MaterialBase } from '../MaterialBase';
import { MethodBase, _Shader_MethodBase } from './MethodBase';
/**
* CompositeMethodBase provides a base class for diffuse methods that wrap a diffuse method to alter the
* calculated diffuse reflection strength.
*/
export class CompositeMethodBase extends MethodBase {
protected _onShaderInvalidatedDelegate: (event: MethodEvent) => void;
protected _baseMethod: MethodBase;
/**
* The base diffuse method on which this method's shading is based.
*/
public get baseMethod(): MethodBase {
return this._baseMethod;
}
public set baseMethod(value: MethodBase) {
if (this._baseMethod == value)
return;
this._baseMethod.removeEventListener(MethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
this._baseMethod = value;
this._baseMethod.addEventListener(MethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
this.invalidateShaderProgram();
}
/**
* Creates a new CompositeMethodBase object.
*
* @param modulateMethod The method which will add the code to alter the base method's strength. It needs to have the signature clampDiffuse(t:ShaderRegisterElement, regCache:ShaderRegisterCache):string, in which t.w will contain the diffuse strength.
* @param baseMethod The base diffuse method on which this method's shading is based.
*/
constructor(baseMethod: MethodBase = null) {
super();
this._onShaderInvalidatedDelegate = (event: MethodEvent) => this.onShaderInvalidated(event);
this._baseMethod = baseMethod || this.createBaseMethod();
this._baseMethod.addEventListener(MethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
}
protected createBaseMethod(): MethodBase {
throw new AbstractMethodError();
}
public iAddOwner(owner: MaterialBase): void {
super.iAddOwner(owner);
this._baseMethod.iAddOwner(owner);
}
public iRemoveOwner(owner: MaterialBase): void {
super.iRemoveOwner(owner);
this._baseMethod.iRemoveOwner(owner);
}
/**
* @inheritDoc
*/
public dispose(): void {
this._baseMethod.removeEventListener(MethodEvent.SHADER_INVALIDATED, this._onShaderInvalidatedDelegate);
}
/**
* Called when the base method's shader code is invalidated.
*/
private onShaderInvalidated(event: MethodEvent): void {
this.invalidateShaderProgram();
}
}
import { AbstractionBase } from '@awayjs/core';
import { ShaderRegisterCache, ShaderRegisterData, ShaderRegisterElement } from '@awayjs/stage';
import { _Render_RenderableBase, ChunkVO } from '@awayjs/renderer';
import { LightingShader } from '../shaders/LightingShader';
import { _IShader_LightingMethod } from './_IShader_LightingMethod';
import { _IShader_Method } from './_IShader_Method';
/**
* _Shader_CompositeMethodBase provides a base class for diffuse methods that wrap a diffuse method to alter the
* calculated diffuse reflection strength.
*/
export class _Shader_CompositeMethodBase extends AbstractionBase implements _IShader_Method {
protected _baseChunk: _IShader_Method;
public chunkVO: ChunkVO = new ChunkVO();
/**
* Creates a new _Shader_CompositeMethodBase object.
*
* @param modulateMethod The method which will add the code to alter the base method's strength. It needs to have the signature clampDiffuse(t:ShaderRegisterElement, regCache:ShaderRegisterCache):string, in which t.w will contain the diffuse strength.
* @param baseMethod The base diffuse method on which this method's shading is based.
*/
public init(method: CompositeMethodBase, shader: LightingShader): void {
super.init(method, shader);
this._baseChunk = shader.abstractions.getAbstraction<_Shader_MethodBase>(method.baseMethod);
}
public _isUsed(): boolean {
return true;
}
public _usesTangentSpace(): boolean {
return this._baseChunk._usesTangentSpace();
}
/**
* @inheritDoc
*/
public _initVO(chunkVO: ChunkVO): void {
this._baseChunk._initVO(chunkVO);
}
/**
* @inheritDoc
*/
public _initConstants(): void {
this._baseChunk._initConstants();
}
/**
* @inheritDoc
*/
public _activate(): void {
this._baseChunk._activate();
}
/**
* @inheritDoc
*/
public _setRenderState(renderState: _Render_RenderableBase): void {
this._baseChunk._setRenderState(renderState);
}
/**
* @inheritDoc
*/
public _deactivate(): void {
this._baseChunk._deactivate();
this._invalid = false;
}
/**
* @inheritDoc
*/
public _getVertexCode(registerCache: ShaderRegisterCache, sharedRegisters: ShaderRegisterData): string {
return this._baseChunk._getVertexCode(registerCache, sharedRegisters);
}
/**
* @inheritDoc
*/
public _getFragmentCode(targetReg: ShaderRegisterElement, registerCache: ShaderRegisterCache, sharedRegisters: ShaderRegisterData): string {
return this._baseChunk._getFragmentCode(targetReg, registerCache, sharedRegisters);
}
/**
* @inheritDoc
*/
public _reset(chunkVO: ChunkVO): void {
this._baseChunk._reset(chunkVO);
this._invalid = true;
this._cleanCompilationData();
}
/**
* @inheritDoc
*/
public _cleanCompilationData(): void {
this._baseChunk._cleanCompilationData();
}
}
/**
* LightingCompositeBase provides a base class for diffuse methods that wrap a diffuse method to alter the
* calculated diffuse reflection strength.
*/
export class _Shader_LightingCompositeMethod extends _Shader_CompositeMethodBase implements _IShader_LightingMethod {
public _totalLightColorReg: ShaderRegisterElement;
public _modulateFunction: (targetReg: ShaderRegisterElement, registerCache: ShaderRegisterCache, sharedRegisters: ShaderRegisterData) => string;
/**
* @inheritDoc
*/
public _getFragmentPreLightingCode(registerCache: ShaderRegisterCache, sharedRegisters: ShaderRegisterData): string {
return (<_IShader_LightingMethod> this._baseChunk)._getFragmentPreLightingCode(registerCache, sharedRegisters);
}
/**
* @inheritDoc
*/
public _getFragmentCodePerLight(lightDirReg: ShaderRegisterElement, lightColReg: ShaderRegisterElement, registerCache: ShaderRegisterCache, sharedRegisters: ShaderRegisterData): string {
const code: string = (<_IShader_LightingMethod> this._baseChunk)._getFragmentCodePerLight(lightDirReg, lightColReg, registerCache, sharedRegisters);
this._totalLightColorReg = (<_IShader_LightingMethod> this._baseChunk)._totalLightColorReg;
return code;
}
/**
* @inheritDoc
*/
public _getFragmentCodePerProbe(cubeMapReg: ShaderRegisterElement, weightRegister: string, registerCache: ShaderRegisterCache, sharedRegisters: ShaderRegisterData): string {
const code: string = (<_IShader_LightingMethod> this._baseChunk)._getFragmentCodePerProbe(cubeMapReg, weightRegister, registerCache, sharedRegisters);
this._totalLightColorReg = (<_IShader_LightingMethod> this._baseChunk)._totalLightColorReg;
return code;
}
}