UNPKG

@awayjs/renderer

Version:
173 lines (139 loc) 4.78 kB
import { ErrorBase } from '@awayjs/core'; import { ImageSampler, Image2D, ImageUtils } from '@awayjs/stage'; import { Texture2D } from './Texture2D'; export class ImageTexture2D extends Texture2D { public static assetType: string = '[texture ImageTexture2D]'; /** * * @returns {string} */ public get assetType(): string { return ImageTexture2D.assetType; } /** * * @returns {ImageBase} */ public get sampler(): ImageSampler { return <ImageSampler> this._samplers[0]; } public set sampler(value: ImageSampler) { if (this._samplers[0] == value) return; this.setSamplerAt(value, 0); } /** * * @returns {ImageBase} */ public get image(): Image2D { return <Image2D> this._images[0]; } public set image(value: Image2D) { if (this._images[0] == value) return; if (!ImageUtils.isImage2DValid(value)) throw new ErrorBase('Invalid imageData: Width and height must be power of 2 and cannot exceed 2048'); this.setImageAt(value, 0); } constructor(image: Image2D = null, mappingMode: MappingMode = null) { super(mappingMode); this.setNumImages(1); this.image = image; } } import { ShaderRegisterCache, ShaderRegisterData, ShaderRegisterElement } from '@awayjs/stage'; import { _Shader_ImageTexture } from './ImageTextureCube'; import { MappingMode } from '../base/MappingMode'; import { _Render_RenderableBase } from '../base/_Render_RenderableBase'; import { ShaderBase } from '../base/ShaderBase'; /** * * @class away.pool.GL_SingleImageTexture */ export class _Shader_ImageTexture2D extends _Shader_ImageTexture { /** * * @param shader * @param regCache * @param targetReg The register in which to store the sampled colour. * @param uvReg The uv coordinate vector with which to sample the texture map. * @returns {string} * @private */ public _getFragmentCode( targetReg: ShaderRegisterElement, regCache: ShaderRegisterCache, sharedReg: ShaderRegisterData, inputReg: ShaderRegisterElement ): string { let code: string = ''; let temp: ShaderRegisterElement; //modify depending on mapping mode if ((<Texture2D> this._texture).mappingMode == MappingMode.RADIAL) { temp = regCache.getFreeFragmentVectorTemp(); code += 'mul ' + temp + '.xy, ' + inputReg + ', ' + inputReg + '\n'; code += 'add ' + temp + '.x, ' + temp + '.x, ' + temp + '.y\n'; code += 'sub ' + temp + '.y, ' + temp + '.y, ' + temp + '.y\n'; code += 'sqt ' + temp + '.x, ' + temp + '.x, ' + temp + '.x\n'; inputReg = temp; } //handles texture atlasing if (this._shader.useImageRect) { const samplerReg: ShaderRegisterElement = regCache.getFreeFragmentConstant(); this._samplerIndex = samplerReg.index * 4; temp = regCache.getFreeFragmentVectorTemp(); code += 'mul ' + temp + ', ' + inputReg + ', ' + samplerReg + '.xy\n'; code += 'add ' + temp + ', ' + temp + ', ' + samplerReg + '.zw\n'; inputReg = temp; } code += super._getFragmentCode(targetReg, regCache, sharedReg, inputReg); //un-premultiply alpha if is is required if (this._shader.usesPremultipliedAlpha) { const tmp = regCache.getFreeFragmentSingleTemp(); code += 'sge ' + tmp + ' #native vec4(0.0) native#, ' + targetReg + '.w \n'; code += 'add ' + tmp + ', ' + tmp + ',' + targetReg + '.w \n'; code += 'div ' + targetReg + '.xyz, ' + targetReg + ', ' + tmp + '\n'; } return code; } public activate(): void { super.activate(); const sampler: ImageSampler = <ImageSampler> this._shader.renderMaterial.samplers[this._imageIndex]; if (this._shader.useImageRect) { const index: number = this._samplerIndex; const data: Float32Array = this._shader.fragmentConstantData; if (!sampler.imageRect) { data[index] = 1; data[index + 1] = 1; data[index + 2] = 0; data[index + 3] = 0; } else { data[index] = sampler.imageRect.width; data[index + 1] = sampler.imageRect.height; data[index + 2] = sampler.imageRect.x; data[index + 3] = sampler.imageRect.y; } } } public _setRenderState(renderState: _Render_RenderableBase): void { super._setRenderState(renderState); const sampler: ImageSampler = renderState.samplers[this._imageIndex]; if (this._shader.useImageRect && sampler) { const index: number = this._samplerIndex; const data: Float32Array = this._shader.fragmentConstantData; if (!sampler.imageRect) { data[index] = 1; data[index + 1] = 1; data[index + 2] = 0; data[index + 3] = 0; } else { data[index] = sampler.imageRect.width; data[index + 1] = sampler.imageRect.height; data[index + 2] = sampler.imageRect.x; data[index + 3] = sampler.imageRect.y; } } } } ShaderBase.registerAbstraction(_Shader_ImageTexture2D, ImageTexture2D);