import { Utils } from '../common/Utils'
import { BaseTexture } from './BaseTexture';
import { ImageColorFormat, ImageFilterType, ImageCompressionType } from '../const';
/**
* @class BaseImageTexture
* 图像纹理,加载图像资源并由样式使用。
* @memberof THING
* @extends THING.BaseTexture
* @public
*/
class BaseImageTexture extends BaseTexture {
/**
* 图像纹理,加载图像资源并由样式使用。
* @param {object} param 初始参数。
*/
constructor(param = {}) {
super(param);
this._onUpdateUrl = param['onUpdateUrl'];
this.onLoad(param);
}
// #region Private
/**
* Called when update the url.
* @private
*/
_updateUrl() {
let onUpdateUrl = this._onUpdateUrl;
if (onUpdateUrl) {
onUpdateUrl(this, this._url);
}
}
/**
* Check whether it is a compressed texture.
* @param {string} url 要检查的 URL。
* @returns {boolean} 返回是否是压缩纹理。
* @example
* let isCompressed = this._isCompressed('image.dds');
* // @expect(isCompressed == true);
* @private
*/
_isCompressed(url) {
let image = this._image;
if (image) {
return image.format !== undefined && !!ImageCompressionType[image.format]
}
let isBasis = (_url_) => {
let extension = _url_._getExtension();
return extension == 'basis'
}
if (url) {
if (Utils.isArray(url)) {
for (let i = 0; i < url.length; i++) {
if (!isBasis(url[i])) {
return false;
}
}
return true;
}
else {
return isBasis(url);
}
}
else {
return false
}
}
/**
* Load texture.
* @param {object} param The texture param.
* @private
*/
onLoad(param) { }
/**
* Set the urls.
* @param {Array<string>} value 要设置的 URL 数组。
* @private
*/
_setUrl(value) {
if (!value) {
return;
}
this.unloadResource();
this._url = value;
this._updateUrl();
// Break the previous loading
if (this.pendingPromise) {
this.pendingPromise.reject();
this.pendingPromise = null;
}
// Load resource
this.onLoad({
url: value,
onLoad: () => {
if (this.textureResource) {
if (Utils.isArray(value)) {
this.textureResource.setImages(this._image);
}
else {
this.textureResource.setImage(this._image);
}
}
}
});
}
_fixColorFomat(image) {
if (image.format) {
this.colorFormat = image.format;
}
}
_fixMinFilterType(image) {
// It's compressed texture
if (image.format === ImageColorFormat.BC7_M6_OPAQUE_ONLY) {
let mipmaps = image.mipmaps;
if (mipmaps && mipmaps.length !== 1) {
return;
}
this.minFilterType = ImageFilterType.LinearFilter;
}
else {
if (this.generateMipmaps) {
return;
}
// If we do not have any mipmaps then we can not use mipmaps filter
let mipmaps = image.mipmaps;
if (mipmaps && mipmaps.length !== 1) {
return;
}
if (this.minFilterType != ImageFilterType.NearestFilter || this.minFilterType != ImageFilterType.LinearFilter) {
this.minFilterType = ImageFilterType.LinearFilter;
}
}
}
// #endregion
// #region Override
onTriggerErrorEvent(ev) {
if (!ev) {
return;
}
let err;
let target = ev.target;
if (target) {
let src = ev.target.src;
err = {
desc: `Load '${src}' image texture failed`
}
}
else {
err = ev;
}
this.onNotifyError(err);
}
onFixupFromImage(image) {
this._fixColorFomat(image);
this._fixMinFilterType(image);
}
// #endregion
/**
* Copy from image.
* @param {THING.ImageTexture} source The image.
* @returns {THING.ImageTexture} 返回当前图像纹理。
* @private
*/
copy(source) {
super.copy(source);
this._setUrl(source.url);
return this;
}
/**
* Clone image.
* @returns {THING.ImageTexture} 返回克隆的图像纹理。
* @private
*/
clone() {
let resource = new ImageTexture();
resource.copy(this);
return resource;
}
/**
* Convert to uniform data.
* @returns {object} 返回 uniform 数据。
* @private
*/
toUniform() {
return {
key: this._url,
value: this.getTextureResource()
};
}
// #region Accessors
/**
* Get/Set the update url callback function.
* @type {Function}
* @private
*/
get onUpdateUrl() {
return this._onUpdateUrl;
}
set onUpdateUrl(value) {
if (!value) return
this._onUpdateUrl = value;
}
/**
* 获取/设置 url。
* @type {string}
* @public
*/
get url() {
return this._url;
}
set url(value) {
this._setUrl(value);
}
// #endregion
}
export { BaseImageTexture }