UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

460 lines (457 loc) 14.7 kB
import { math } from '../../core/math/math.js'; import { isIntegerPixelFormat, TEXPROPERTY_MIN_FILTER, TEXPROPERTY_MAG_FILTER, TEXPROPERTY_ADDRESS_U, TEXPROPERTY_ADDRESS_V, TEXPROPERTY_ADDRESS_W, TEXPROPERTY_COMPARE_ON_READ, TEXPROPERTY_COMPARE_FUNC, TEXPROPERTY_ANISOTROPY, isSrgbPixelFormat, pixelFormatLinearToGamma, pixelFormatGammaToLinear, TEXTURETYPE_RGBP, TEXTURETYPE_RGBE, TEXTURETYPE_RGBM, requiresManualGamma, TEXPROPERTY_ALL, TEXTURELOCK_WRITE, getPixelFormatArrayType, TEXTURELOCK_NONE, PIXELFORMAT_RGBA8, isCompressedPixelFormat, FILTER_NEAREST, FILTER_LINEAR_MIPMAP_LINEAR, FILTER_LINEAR, ADDRESS_REPEAT, FUNC_LESS, TEXTURETYPE_DEFAULT, TEXTUREPROJECTION_NONE, TEXTUREPROJECTION_CUBE } from './constants.js'; import { TextureUtils } from './texture-utils.js'; var id = 0; class Texture { destroy() { var device = this.device; if (device) { var idx = device.textures.indexOf(this); if (idx !== -1) { device.textures.splice(idx, 1); } device.scope.removeValue(this); this.impl.destroy(device); this.adjustVramSizeTracking(device._vram, -this._gpuSize); this._levels = null; this.device = null; } } recreateImpl(upload) { if (upload === void 0) upload = true; var _this_impl; var { device } = this; (_this_impl = this.impl) == null ? void 0 : _this_impl.destroy(device); this.impl = null; this.impl = device.createTextureImpl(this); this.dirtyAll(); if (upload) { this.upload(); } } resize(width, height, depth) { if (depth === void 0) depth = 1; var device = this.device; this.adjustVramSizeTracking(device._vram, -this._gpuSize); this.impl.destroy(device); this._width = Math.floor(width); this._height = Math.floor(height); this._depth = Math.floor(depth); this._updateNumLevel(); this.impl = device.createTextureImpl(this); this.dirtyAll(); } loseContext() { this.impl.loseContext(); this.dirtyAll(); } adjustVramSizeTracking(vram, size) { vram.tex += size; } propertyChanged(flag) { this.impl.propertyChanged(flag); this.renderVersionDirty = this.device.renderVersion; } _updateNumLevel() { var maxLevels = this.mipmaps ? TextureUtils.calcMipLevelsCount(this.width, this.height) : 1; var requestedLevels = this._numLevelsRequested; this._numLevels = Math.min(requestedLevels != null ? requestedLevels : maxLevels, maxLevels); this._mipmaps = this._numLevels > 1; } get lockedMode() { return this._lockedMode; } set minFilter(v) { if (this._minFilter !== v) { if (isIntegerPixelFormat(this._format)) ; else { this._minFilter = v; this.propertyChanged(TEXPROPERTY_MIN_FILTER); } } } get minFilter() { return this._minFilter; } set magFilter(v) { if (this._magFilter !== v) { if (isIntegerPixelFormat(this._format)) ; else { this._magFilter = v; this.propertyChanged(TEXPROPERTY_MAG_FILTER); } } } get magFilter() { return this._magFilter; } set addressU(v) { if (this._addressU !== v) { this._addressU = v; this.propertyChanged(TEXPROPERTY_ADDRESS_U); } } get addressU() { return this._addressU; } set addressV(v) { if (this._addressV !== v) { this._addressV = v; this.propertyChanged(TEXPROPERTY_ADDRESS_V); } } get addressV() { return this._addressV; } set addressW(addressW) { if (!this._volume) { return; } if (addressW !== this._addressW) { this._addressW = addressW; this.propertyChanged(TEXPROPERTY_ADDRESS_W); } } get addressW() { return this._addressW; } set compareOnRead(v) { if (this._compareOnRead !== v) { this._compareOnRead = v; this.propertyChanged(TEXPROPERTY_COMPARE_ON_READ); } } get compareOnRead() { return this._compareOnRead; } set compareFunc(v) { if (this._compareFunc !== v) { this._compareFunc = v; this.propertyChanged(TEXPROPERTY_COMPARE_FUNC); } } get compareFunc() { return this._compareFunc; } set anisotropy(v) { if (this._anisotropy !== v) { this._anisotropy = v; this.propertyChanged(TEXPROPERTY_ANISOTROPY); } } get anisotropy() { return this._anisotropy; } set mipmaps(v) { if (this._mipmaps !== v) { if (this.device.isWebGPU) ; else if (isIntegerPixelFormat(this._format)) ; else { this._mipmaps = v; } if (v) this._needsMipmapsUpload = true; } } get mipmaps() { return this._mipmaps; } get numLevels() { return this._numLevels; } get storage() { return this._storage; } get width() { return this._width; } get height() { return this._height; } get depth() { return this._depth; } get format() { return this._format; } get cubemap() { return this._cubemap; } get gpuSize() { var mips = this.pot && this._mipmaps && !(this._compressed && this._levels.length === 1); return TextureUtils.calcGpuSize(this._width, this._height, this._depth, this._format, mips, this._cubemap); } get array() { return this._arrayLength > 0; } get arrayLength() { return this._arrayLength; } get volume() { return this._volume; } set srgb(value) { var currentSrgb = isSrgbPixelFormat(this.format); if (value !== currentSrgb) { if (value) { var srgbFormat = pixelFormatLinearToGamma(this.format); if (this._format !== srgbFormat) { this._format = srgbFormat; this.recreateImpl(); this.device._shadersDirty = true; } } else { var linearFormat = pixelFormatGammaToLinear(this.format); if (this._format !== linearFormat) { this._format = linearFormat; this.recreateImpl(); this.device._shadersDirty = true; } } } } get srgb() { return isSrgbPixelFormat(this.format); } set flipY(flipY) { if (this._flipY !== flipY) { this._flipY = flipY; this._needsUpload = true; } } get flipY() { return this._flipY; } set premultiplyAlpha(premultiplyAlpha) { if (this._premultiplyAlpha !== premultiplyAlpha) { this._premultiplyAlpha = premultiplyAlpha; this._needsUpload = true; } } get premultiplyAlpha() { return this._premultiplyAlpha; } get pot() { return math.powerOfTwo(this._width) && math.powerOfTwo(this._height); } get encoding() { switch(this.type){ case TEXTURETYPE_RGBM: return 'rgbm'; case TEXTURETYPE_RGBE: return 'rgbe'; case TEXTURETYPE_RGBP: return 'rgbp'; } return requiresManualGamma(this.format) ? 'srgb' : 'linear'; } dirtyAll() { this._levelsUpdated = this._cubemap ? [ [ true, true, true, true, true, true ] ] : [ true ]; this._needsUpload = true; this._needsMipmapsUpload = this._mipmaps; this._mipmapsUploaded = false; this.propertyChanged(TEXPROPERTY_ALL); } lock(options) { if (options === void 0) options = {}; var _options, _options1, _options2; var _level; (_level = (_options = options).level) != null ? _level : _options.level = 0; var _face; (_face = (_options1 = options).face) != null ? _face : _options1.face = 0; var _mode; (_mode = (_options2 = options).mode) != null ? _mode : _options2.mode = TEXTURELOCK_WRITE; this._lockedMode = options.mode; this._lockedLevel = options.level; var levels = this.cubemap ? this._levels[options.face] : this._levels; if (levels[options.level] === null) { var width = Math.max(1, this._width >> options.level); var height = Math.max(1, this._height >> options.level); var depth = Math.max(1, this._depth >> options.level); var data = new ArrayBuffer(TextureUtils.calcLevelGpuSize(width, height, depth, this._format)); levels[options.level] = new (getPixelFormatArrayType(this._format))(data); } return levels[options.level]; } setSource(source, mipLevel) { if (mipLevel === void 0) mipLevel = 0; var invalid = false; var width, height; if (this._cubemap) { if (source[0]) { width = source[0].width || 0; height = source[0].height || 0; for(var i = 0; i < 6; i++){ var face = source[i]; if (!face || face.width !== width || face.height !== height || !this.device._isBrowserInterface(face)) { invalid = true; break; } } } else { invalid = true; } if (!invalid) { for(var i1 = 0; i1 < 6; i1++){ if (this._levels[mipLevel][i1] !== source[i1]) { this._levelsUpdated[mipLevel][i1] = true; } } } } else { if (!this.device._isBrowserInterface(source)) { invalid = true; } if (!invalid) { if (source !== this._levels[mipLevel]) { this._levelsUpdated[mipLevel] = true; } if (source instanceof HTMLVideoElement) { width = source.videoWidth; height = source.videoHeight; } else { width = source.width; height = source.height; } } } if (invalid) { this._width = 4; this._height = 4; if (this._cubemap) { for(var i2 = 0; i2 < 6; i2++){ this._levels[mipLevel][i2] = null; this._levelsUpdated[mipLevel][i2] = true; } } else { this._levels[mipLevel] = null; this._levelsUpdated[mipLevel] = true; } } else { if (mipLevel === 0) { this._width = width; this._height = height; } this._levels[mipLevel] = source; } if (this._invalid !== invalid || !invalid) { this._invalid = invalid; this.upload(); } } getSource(mipLevel) { if (mipLevel === void 0) mipLevel = 0; return this._levels[mipLevel]; } unlock() { if (this._lockedMode === TEXTURELOCK_NONE) ; if (this._lockedMode === TEXTURELOCK_WRITE) { this.upload(); } this._lockedLevel = -1; this._lockedMode = TEXTURELOCK_NONE; } upload() { this._needsUpload = true; this._needsMipmapsUpload = this._mipmaps; this.impl.uploadImmediate == null ? void 0 : this.impl.uploadImmediate.call(this.impl, this.device, this); } read(x, y, width, height, options) { if (options === void 0) options = {}; return this.impl.read == null ? void 0 : this.impl.read.call(this.impl, x, y, width, height, options); } constructor(graphicsDevice, options = {}){ this._gpuSize = 0; this.id = id++; this._invalid = false; this._lockedLevel = -1; this._lockedMode = TEXTURELOCK_NONE; this.renderVersionDirty = 0; this._storage = false; this._numLevels = 0; this.device = graphicsDevice; var _options_name; this.name = (_options_name = options.name) != null ? _options_name : ''; var _options_width; this._width = Math.floor((_options_width = options.width) != null ? _options_width : 4); var _options_height; this._height = Math.floor((_options_height = options.height) != null ? _options_height : 4); var _options_format; this._format = (_options_format = options.format) != null ? _options_format : PIXELFORMAT_RGBA8; this._compressed = isCompressedPixelFormat(this._format); this._integerFormat = isIntegerPixelFormat(this._format); if (this._integerFormat) { options.minFilter = FILTER_NEAREST; options.magFilter = FILTER_NEAREST; } var _options_volume; this._volume = (_options_volume = options.volume) != null ? _options_volume : false; var _options_depth; this._depth = Math.floor((_options_depth = options.depth) != null ? _options_depth : 1); var _options_arrayLength; this._arrayLength = Math.floor((_options_arrayLength = options.arrayLength) != null ? _options_arrayLength : 0); var _options_storage; this._storage = (_options_storage = options.storage) != null ? _options_storage : false; var _options_cubemap; this._cubemap = (_options_cubemap = options.cubemap) != null ? _options_cubemap : false; var _options_flipY; this._flipY = (_options_flipY = options.flipY) != null ? _options_flipY : false; var _options_premultiplyAlpha; this._premultiplyAlpha = (_options_premultiplyAlpha = options.premultiplyAlpha) != null ? _options_premultiplyAlpha : false; var _options_mipmaps; this._mipmaps = (_options_mipmaps = options.mipmaps) != null ? _options_mipmaps : true; this._numLevelsRequested = options.numLevels; if (options.numLevels !== undefined) { this._numLevels = options.numLevels; } this._updateNumLevel(); var _options_minFilter; this._minFilter = (_options_minFilter = options.minFilter) != null ? _options_minFilter : FILTER_LINEAR_MIPMAP_LINEAR; var _options_magFilter; this._magFilter = (_options_magFilter = options.magFilter) != null ? _options_magFilter : FILTER_LINEAR; var _options_anisotropy; this._anisotropy = (_options_anisotropy = options.anisotropy) != null ? _options_anisotropy : 1; var _options_addressU; this._addressU = (_options_addressU = options.addressU) != null ? _options_addressU : ADDRESS_REPEAT; var _options_addressV; this._addressV = (_options_addressV = options.addressV) != null ? _options_addressV : ADDRESS_REPEAT; var _options_addressW; this._addressW = (_options_addressW = options.addressW) != null ? _options_addressW : ADDRESS_REPEAT; var _options_compareOnRead; this._compareOnRead = (_options_compareOnRead = options.compareOnRead) != null ? _options_compareOnRead : false; var _options_compareFunc; this._compareFunc = (_options_compareFunc = options.compareFunc) != null ? _options_compareFunc : FUNC_LESS; this.type = options.hasOwnProperty('type') ? options.type : TEXTURETYPE_DEFAULT; this.projection = TEXTUREPROJECTION_NONE; if (this._cubemap) { this.projection = TEXTUREPROJECTION_CUBE; } else if (options.projection && options.projection !== TEXTUREPROJECTION_CUBE) { this.projection = options.projection; } this._levels = options.levels; var upload = !!options.levels; if (!this._levels) { this._levels = this._cubemap ? [ [ null, null, null, null, null, null ] ] : [ null ]; } this.recreateImpl(upload); graphicsDevice.textures.push(this); } } export { Texture };