123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- import { InternalTexture, InternalTextureSource } from "../../Materials/Textures/internalTexture.js";
- import { Logger } from "../../Misc/logger.js";
- import { ThinEngine } from "../thinEngine.js";
- import { IsExponentOfTwo } from "../../Misc/tools.functions.js";
- ThinEngine.prototype.updateRawTexture = function (texture, data, format, invertY, compression = null, type = 0, useSRGBBuffer = false) {
- if (!texture) {
- return;
- }
- // Babylon's internalSizedFomat but gl's texImage2D internalFormat
- const internalSizedFomat = this._getRGBABufferInternalSizedFormat(type, format, useSRGBBuffer);
- // Babylon's internalFormat but gl's texImage2D format
- const internalFormat = this._getInternalFormat(format);
- const textureType = this._getWebGLTextureType(type);
- this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);
- this._unpackFlipY(invertY === undefined ? true : invertY ? true : false);
- if (!this._doNotHandleContextLost) {
- texture._bufferView = data;
- texture.format = format;
- texture.type = type;
- texture.invertY = invertY;
- texture._compression = compression;
- }
- if (texture.width % 4 !== 0) {
- this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);
- }
- if (compression && data) {
- this._gl.compressedTexImage2D(this._gl.TEXTURE_2D, 0, this.getCaps().s3tc[compression], texture.width, texture.height, 0, data);
- }
- else {
- this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, data);
- }
- if (texture.generateMipMaps) {
- this._gl.generateMipmap(this._gl.TEXTURE_2D);
- }
- this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
- // this.resetTextureCache();
- texture.isReady = true;
- };
- ThinEngine.prototype.createRawTexture = function (data, width, height, format, generateMipMaps, invertY, samplingMode, compression = null, type = 0,
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- creationFlags = 0, useSRGBBuffer = false) {
- const texture = new InternalTexture(this, InternalTextureSource.Raw);
- texture.baseWidth = width;
- texture.baseHeight = height;
- texture.width = width;
- texture.height = height;
- texture.format = format;
- texture.generateMipMaps = generateMipMaps;
- texture.samplingMode = samplingMode;
- texture.invertY = invertY;
- texture._compression = compression;
- texture.type = type;
- texture._useSRGBBuffer = this._getUseSRGBBuffer(useSRGBBuffer, !generateMipMaps);
- if (!this._doNotHandleContextLost) {
- texture._bufferView = data;
- }
- this.updateRawTexture(texture, data, format, invertY, compression, type, texture._useSRGBBuffer);
- this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);
- // Filters
- const filters = this._getSamplingParameters(samplingMode, generateMipMaps);
- this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, filters.mag);
- this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, filters.min);
- if (generateMipMaps) {
- this._gl.generateMipmap(this._gl.TEXTURE_2D);
- }
- this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
- this._internalTexturesCache.push(texture);
- return texture;
- };
- ThinEngine.prototype.createRawCubeTexture = function (data, size, format, type, generateMipMaps, invertY, samplingMode, compression = null) {
- const gl = this._gl;
- const texture = new InternalTexture(this, InternalTextureSource.CubeRaw);
- texture.isCube = true;
- texture.format = format;
- texture.type = type;
- if (!this._doNotHandleContextLost) {
- texture._bufferViewArray = data;
- }
- const textureType = this._getWebGLTextureType(type);
- let internalFormat = this._getInternalFormat(format);
- if (internalFormat === gl.RGB) {
- internalFormat = gl.RGBA;
- }
- // Mipmap generation needs a sized internal format that is both color-renderable and texture-filterable
- if (textureType === gl.FLOAT && !this._caps.textureFloatLinearFiltering) {
- generateMipMaps = false;
- samplingMode = 1;
- Logger.Warn("Float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
- }
- else if (textureType === this._gl.HALF_FLOAT_OES && !this._caps.textureHalfFloatLinearFiltering) {
- generateMipMaps = false;
- samplingMode = 1;
- Logger.Warn("Half float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
- }
- else if (textureType === gl.FLOAT && !this._caps.textureFloatRender) {
- generateMipMaps = false;
- Logger.Warn("Render to float textures is not supported. Mipmap generation forced to false.");
- }
- else if (textureType === gl.HALF_FLOAT && !this._caps.colorBufferFloat) {
- generateMipMaps = false;
- Logger.Warn("Render to half float textures is not supported. Mipmap generation forced to false.");
- }
- const width = size;
- const height = width;
- texture.width = width;
- texture.height = height;
- texture.invertY = invertY;
- texture._compression = compression;
- // Double check on POT to generate Mips.
- const isPot = !this.needPOTTextures || (IsExponentOfTwo(texture.width) && IsExponentOfTwo(texture.height));
- if (!isPot) {
- generateMipMaps = false;
- }
- // Upload data if needed. The texture won't be ready until then.
- if (data) {
- this.updateRawCubeTexture(texture, data, format, type, invertY, compression);
- }
- else {
- const internalSizedFomat = this._getRGBABufferInternalSizedFormat(type);
- const level = 0;
- this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
- for (let faceIndex = 0; faceIndex < 6; faceIndex++) {
- if (compression) {
- gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, this.getCaps().s3tc[compression], texture.width, texture.height, 0, undefined);
- }
- else {
- gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, null);
- }
- }
- this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
- }
- this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, texture, true);
- // Filters
- if (data && generateMipMaps) {
- this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
- }
- const filters = this._getSamplingParameters(samplingMode, generateMipMaps);
- gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);
- gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);
- gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
- texture.generateMipMaps = generateMipMaps;
- texture.samplingMode = samplingMode;
- texture.isReady = true;
- return texture;
- };
- ThinEngine.prototype.updateRawCubeTexture = function (texture, data, format, type, invertY, compression = null, level = 0) {
- texture._bufferViewArray = data;
- texture.format = format;
- texture.type = type;
- texture.invertY = invertY;
- texture._compression = compression;
- const gl = this._gl;
- const textureType = this._getWebGLTextureType(type);
- let internalFormat = this._getInternalFormat(format);
- const internalSizedFomat = this._getRGBABufferInternalSizedFormat(type);
- let needConversion = false;
- if (internalFormat === gl.RGB) {
- internalFormat = gl.RGBA;
- needConversion = true;
- }
- this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
- this._unpackFlipY(invertY === undefined ? true : invertY ? true : false);
- if (texture.width % 4 !== 0) {
- gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
- }
- // Data are known to be in +X +Y +Z -X -Y -Z
- for (let faceIndex = 0; faceIndex < 6; faceIndex++) {
- let faceData = data[faceIndex];
- if (compression) {
- gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, this.getCaps().s3tc[compression], texture.width, texture.height, 0, faceData);
- }
- else {
- if (needConversion) {
- faceData = _convertRGBtoRGBATextureData(faceData, texture.width, texture.height, type);
- }
- gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, faceData);
- }
- }
- const isPot = !this.needPOTTextures || (IsExponentOfTwo(texture.width) && IsExponentOfTwo(texture.height));
- if (isPot && texture.generateMipMaps && level === 0) {
- this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
- }
- this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
- // this.resetTextureCache();
- texture.isReady = true;
- };
- ThinEngine.prototype.createRawCubeTextureFromUrl = function (url, scene, size, format, type, noMipmap, callback, mipmapGenerator, onLoad = null, onError = null, samplingMode = 3, invertY = false) {
- const gl = this._gl;
- const texture = this.createRawCubeTexture(null, size, format, type, !noMipmap, invertY, samplingMode, null);
- scene?.addPendingData(texture);
- texture.url = url;
- texture.isReady = false;
- this._internalTexturesCache.push(texture);
- const onerror = (request, exception) => {
- scene?.removePendingData(texture);
- if (onError && request) {
- onError(request.status + " " + request.statusText, exception);
- }
- };
- const internalCallback = (data) => {
- const width = texture.width;
- const faceDataArrays = callback(data);
- if (!faceDataArrays) {
- return;
- }
- if (mipmapGenerator) {
- const textureType = this._getWebGLTextureType(type);
- let internalFormat = this._getInternalFormat(format);
- const internalSizedFomat = this._getRGBABufferInternalSizedFormat(type);
- let needConversion = false;
- if (internalFormat === gl.RGB) {
- internalFormat = gl.RGBA;
- needConversion = true;
- }
- this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
- this._unpackFlipY(false);
- const mipData = mipmapGenerator(faceDataArrays);
- for (let level = 0; level < mipData.length; level++) {
- const mipSize = width >> level;
- for (let faceIndex = 0; faceIndex < 6; faceIndex++) {
- let mipFaceData = mipData[level][faceIndex];
- if (needConversion) {
- mipFaceData = _convertRGBtoRGBATextureData(mipFaceData, mipSize, mipSize, type);
- }
- gl.texImage2D(faceIndex, level, internalSizedFomat, mipSize, mipSize, 0, internalFormat, textureType, mipFaceData);
- }
- }
- this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
- }
- else {
- this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);
- }
- texture.isReady = true;
- // this.resetTextureCache();
- scene?.removePendingData(texture);
- texture.onLoadedObservable.notifyObservers(texture);
- texture.onLoadedObservable.clear();
- if (onLoad) {
- onLoad();
- }
- };
- this._loadFile(url, (data) => {
- internalCallback(data);
- }, undefined, scene?.offlineProvider, true, onerror);
- return texture;
- };
- /**
- * @internal
- */
- // eslint-disable-next-line @typescript-eslint/naming-convention
- function _convertRGBtoRGBATextureData(rgbData, width, height, textureType) {
- // Create new RGBA data container.
- let rgbaData;
- let val1 = 1;
- if (textureType === 1) {
- rgbaData = new Float32Array(width * height * 4);
- }
- else if (textureType === 2) {
- rgbaData = new Uint16Array(width * height * 4);
- val1 = 15360; // 15360 is the encoding of 1 in half float
- }
- else if (textureType === 7) {
- rgbaData = new Uint32Array(width * height * 4);
- }
- else {
- rgbaData = new Uint8Array(width * height * 4);
- }
- // Convert each pixel.
- for (let x = 0; x < width; x++) {
- for (let y = 0; y < height; y++) {
- const index = (y * width + x) * 3;
- const newIndex = (y * width + x) * 4;
- // Map Old Value to new value.
- rgbaData[newIndex + 0] = rgbData[index + 0];
- rgbaData[newIndex + 1] = rgbData[index + 1];
- rgbaData[newIndex + 2] = rgbData[index + 2];
- // Add fully opaque alpha channel.
- rgbaData[newIndex + 3] = val1;
- }
- }
- return rgbaData;
- }
- /**
- * Create a function for createRawTexture3D/createRawTexture2DArray
- * @param is3D true for TEXTURE_3D and false for TEXTURE_2D_ARRAY
- * @internal
- */
- // eslint-disable-next-line @typescript-eslint/naming-convention
- function _makeCreateRawTextureFunction(is3D) {
- return function (data, width, height, depth, format, generateMipMaps, invertY, samplingMode, compression = null, textureType = 0) {
- const target = is3D ? this._gl.TEXTURE_3D : this._gl.TEXTURE_2D_ARRAY;
- const source = is3D ? InternalTextureSource.Raw3D : InternalTextureSource.Raw2DArray;
- const texture = new InternalTexture(this, source);
- texture.baseWidth = width;
- texture.baseHeight = height;
- texture.baseDepth = depth;
- texture.width = width;
- texture.height = height;
- texture.depth = depth;
- texture.format = format;
- texture.type = textureType;
- texture.generateMipMaps = generateMipMaps;
- texture.samplingMode = samplingMode;
- if (is3D) {
- texture.is3D = true;
- }
- else {
- texture.is2DArray = true;
- }
- if (!this._doNotHandleContextLost) {
- texture._bufferView = data;
- }
- if (is3D) {
- this.updateRawTexture3D(texture, data, format, invertY, compression, textureType);
- }
- else {
- this.updateRawTexture2DArray(texture, data, format, invertY, compression, textureType);
- }
- this._bindTextureDirectly(target, texture, true);
- // Filters
- const filters = this._getSamplingParameters(samplingMode, generateMipMaps);
- this._gl.texParameteri(target, this._gl.TEXTURE_MAG_FILTER, filters.mag);
- this._gl.texParameteri(target, this._gl.TEXTURE_MIN_FILTER, filters.min);
- if (generateMipMaps) {
- this._gl.generateMipmap(target);
- }
- this._bindTextureDirectly(target, null);
- this._internalTexturesCache.push(texture);
- return texture;
- };
- }
- ThinEngine.prototype.createRawTexture2DArray = _makeCreateRawTextureFunction(false);
- ThinEngine.prototype.createRawTexture3D = _makeCreateRawTextureFunction(true);
- /**
- * Create a function for updateRawTexture3D/updateRawTexture2DArray
- * @param is3D true for TEXTURE_3D and false for TEXTURE_2D_ARRAY
- * @internal
- */
- // eslint-disable-next-line @typescript-eslint/naming-convention
- function _makeUpdateRawTextureFunction(is3D) {
- return function (texture, data, format, invertY, compression = null, textureType = 0) {
- const target = is3D ? this._gl.TEXTURE_3D : this._gl.TEXTURE_2D_ARRAY;
- const internalType = this._getWebGLTextureType(textureType);
- const internalFormat = this._getInternalFormat(format);
- const internalSizedFomat = this._getRGBABufferInternalSizedFormat(textureType, format);
- this._bindTextureDirectly(target, texture, true);
- this._unpackFlipY(invertY === undefined ? true : invertY ? true : false);
- if (!this._doNotHandleContextLost) {
- texture._bufferView = data;
- texture.format = format;
- texture.invertY = invertY;
- texture._compression = compression;
- }
- if (texture.width % 4 !== 0) {
- this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);
- }
- if (compression && data) {
- this._gl.compressedTexImage3D(target, 0, this.getCaps().s3tc[compression], texture.width, texture.height, texture.depth, 0, data);
- }
- else {
- this._gl.texImage3D(target, 0, internalSizedFomat, texture.width, texture.height, texture.depth, 0, internalFormat, internalType, data);
- }
- if (texture.generateMipMaps) {
- this._gl.generateMipmap(target);
- }
- this._bindTextureDirectly(target, null);
- // this.resetTextureCache();
- texture.isReady = true;
- };
- }
- ThinEngine.prototype.updateRawTexture2DArray = _makeUpdateRawTextureFunction(false);
- ThinEngine.prototype.updateRawTexture3D = _makeUpdateRawTextureFunction(true);
- //# sourceMappingURL=engine.rawTexture.js.map
|