import * as React from "react"; import { Constants } from "babylonjs/Engines/constants"; import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture"; import { Texture } from "babylonjs/Materials/Textures/texture"; import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTexture"; import { PostProcess } from "babylonjs/PostProcesses/postProcess"; import { PassPostProcess, PassCubePostProcess } from "babylonjs/PostProcesses/passPostProcess"; interface ITextureLineComponentProps { texture: BaseTexture; width: number; height: number; globalState?: any; hideChannelSelect?:boolean; } export class TextureLineComponent extends React.Component { constructor(props: ITextureLineComponentProps) { super(props); this.state = { displayRed: true, displayGreen: true, displayBlue: true, displayAlpha: true, face: 0 }; } shouldComponentUpdate(nextProps: ITextureLineComponentProps, nextState: { displayRed: boolean, displayGreen: boolean, displayBlue: boolean, displayAlpha: boolean, face: number }): boolean { return (nextProps.texture !== this.props.texture || nextState.displayRed !== this.state.displayRed || nextState.displayGreen !== this.state.displayGreen || nextState.displayBlue !== this.state.displayBlue || nextState.displayAlpha !== this.state.displayAlpha || nextState.face !== this.state.face); } componentDidMount() { this.updatePreview(); } componentDidUpdate() { this.updatePreview(); } updatePreview() { var texture = this.props.texture; if(!texture.isReady() && texture._texture){ texture._texture.onLoadedObservable.addOnce(()=>{ this.updatePreview(); }) } var scene = texture.getScene()!; var engine = scene.getEngine(); var size = texture.getSize(); var ratio = size.width / size.height; var width = this.props.width; var height = (width / ratio) | 1; let passPostProcess: PostProcess; if (!texture.isCube) { passPostProcess = new PassPostProcess("pass", 1, null, Texture.NEAREST_SAMPLINGMODE, engine, false, Constants.TEXTURETYPE_UNSIGNED_INT); } else { var passCubePostProcess = new PassCubePostProcess("pass", 1, null, Texture.NEAREST_SAMPLINGMODE, engine, false, Constants.TEXTURETYPE_UNSIGNED_INT); passCubePostProcess.face = this.state.face; passPostProcess = passCubePostProcess; } if (!passPostProcess.getEffect().isReady()) { // Try again later passPostProcess.dispose(); setTimeout(() => this.updatePreview(), 250); return; } const previewCanvas = this.refs.canvas as HTMLCanvasElement; if(this.props.globalState){ this.props.globalState.blockMutationUpdates = true; } let rtt = new RenderTargetTexture( "temp", { width: width, height: height }, scene, false); passPostProcess.onApply = function(effect) { effect.setTexture("textureSampler", texture); }; let internalTexture = rtt.getInternalTexture(); if (internalTexture) { scene.postProcessManager.directRender([passPostProcess], internalTexture); // Read the contents of the framebuffer var numberOfChannelsByLine = width * 4; var halfHeight = height / 2; //Reading datas from WebGL var data = engine.readPixels(0, 0, width, height); if (!texture.isCube) { if (!this.state.displayRed || !this.state.displayGreen || !this.state.displayBlue) { for (var i = 0; i < width * height * 4; i += 4) { if (!this.state.displayRed) { data[i] = 0; } if (!this.state.displayGreen) { data[i + 1] = 0; } if (!this.state.displayBlue) { data[i + 2] = 0; } if (this.state.displayAlpha) { var alpha = data[i + 2]; data[i] = alpha; data[i + 1] = alpha; data[i + 2] = alpha; data[i + 2] = 0; } } } } //To flip image on Y axis. if ((texture as Texture).invertY || texture.isCube) { for (var i = 0; i < halfHeight; i++) { for (var j = 0; j < numberOfChannelsByLine; j++) { var currentCell = j + i * numberOfChannelsByLine; var targetLine = height - i - 1; var targetCell = j + targetLine * numberOfChannelsByLine; var temp = data[currentCell]; data[currentCell] = data[targetCell]; data[targetCell] = temp; } } } previewCanvas.width = width; previewCanvas.height = height; var context = previewCanvas.getContext('2d'); if (context) { // Copy the pixels to the preview canvas var imageData = context.createImageData(width, height); var castData = imageData.data; castData.set(data); context.putImageData(imageData, 0, 0); } // Unbind engine.unBindFramebuffer(internalTexture); } rtt.dispose(); passPostProcess.dispose(); previewCanvas.style.height = height + "px"; if(this.props.globalState){ this.props.globalState.blockMutationUpdates = false; } } render() { var texture = this.props.texture; return (
{ !this.props.hideChannelSelect && texture.isCube &&
} { !this.props.hideChannelSelect && !texture.isCube &&
}
); } }