|
@@ -174,6 +174,10 @@
|
|
|
public maxVertexAttribs: number;
|
|
|
public standardDerivatives: boolean;
|
|
|
public s3tc: WEBGL_compressed_texture_s3tc;
|
|
|
+ public pvrtc: any; //WEBGL_compressed_texture_pvrtc;
|
|
|
+ public etc1: any; //WEBGL_compressed_texture_etc1;
|
|
|
+ public etc2: any; //WEBGL_compressed_texture_etc;
|
|
|
+ public astc: any; //WEBGL_compressed_texture_astc;
|
|
|
public textureFloat: boolean;
|
|
|
public textureAnisotropicFilterExtension: EXT_texture_filter_anisotropic;
|
|
|
public maxAnisotropy: number;
|
|
@@ -481,7 +485,19 @@
|
|
|
|
|
|
private _externalData: StringDictionary<Object>;
|
|
|
private _bindedRenderFunction: any;
|
|
|
-
|
|
|
+
|
|
|
+ // Hardware supported Compressed Textures
|
|
|
+ private _texturesSupported = new Array<string>();
|
|
|
+ private _textureFormatInUse : string;
|
|
|
+
|
|
|
+ public get texturesSupported(): Array<string> {
|
|
|
+ return this._texturesSupported;
|
|
|
+ }
|
|
|
+
|
|
|
+ public get textureFormatInUse(): string {
|
|
|
+ return this._textureFormatInUse;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* @constructor
|
|
|
* @param {HTMLCanvasElement} canvas - the canvas to be used for rendering
|
|
@@ -576,7 +592,13 @@
|
|
|
|
|
|
// Extensions
|
|
|
this._caps.standardDerivatives = (this._gl.getExtension('OES_standard_derivatives') !== null);
|
|
|
- this._caps.s3tc = this._gl.getExtension('WEBGL_compressed_texture_s3tc');
|
|
|
+
|
|
|
+ this._caps.astc = this._gl.getExtension('WEBGL_compressed_texture_astc');
|
|
|
+ this._caps.s3tc = this._gl.getExtension('WEBGL_compressed_texture_s3tc');
|
|
|
+ this._caps.pvrtc = this._gl.getExtension('WEBGL_compressed_texture_pvrtc') || this._gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'); // 2nd is what iOS reports
|
|
|
+ this._caps.etc1 = this._gl.getExtension('WEBGL_compressed_texture_etc1');
|
|
|
+ this._caps.etc2 = this._gl.getExtension('WEBGL_compressed_texture_etc') || this._gl.getExtension('WEBGL_compressed_texture_es3_0'); // first is the final name, found hardware using 2nd
|
|
|
+
|
|
|
this._caps.textureFloat = (this._gl.getExtension('OES_texture_float') !== null);
|
|
|
this._caps.textureAnisotropicFilterExtension = this._gl.getExtension('EXT_texture_filter_anisotropic') || this._gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic') || this._gl.getExtension('MOZ_EXT_texture_filter_anisotropic');
|
|
|
this._caps.maxAnisotropy = this._caps.textureAnisotropicFilterExtension ? this._gl.getParameter(this._caps.textureAnisotropicFilterExtension.MAX_TEXTURE_MAX_ANISOTROPY_EXT) : 0;
|
|
@@ -592,7 +614,18 @@
|
|
|
this._caps.textureHalfFloat = (this._gl.getExtension('OES_texture_half_float') !== null);
|
|
|
this._caps.textureHalfFloatLinearFiltering = this._gl.getExtension('OES_texture_half_float_linear');
|
|
|
this._caps.textureHalfFloatRender = renderToHalfFloat;
|
|
|
-
|
|
|
+
|
|
|
+ // Intelligently add supported commpressed formats in order to check for.
|
|
|
+ // Check for ASTC support first as it is most powerful and to be very cross platform.
|
|
|
+ // Next PVR & S3, which are probably superior to ETC1/2.
|
|
|
+ // Likely no hardware which supports both PVR & S3, so order matters little.
|
|
|
+ // ETC2 is newer and handles ETC1, so check for first.
|
|
|
+ if (this._caps.astc ) this.texturesSupported.push('.astc');
|
|
|
+ if (this._caps.s3tc ) this.texturesSupported.push('.dds');
|
|
|
+ if (this._caps.pvrtc) this.texturesSupported.push('.pvr');
|
|
|
+ if (this._caps.etc2 ) this.texturesSupported.push('.etc2');
|
|
|
+ if (this._caps.etc1 ) this.texturesSupported.push('.etc1');
|
|
|
+
|
|
|
if (this._gl.getShaderPrecisionFormat) {
|
|
|
var highp = this._gl.getShaderPrecisionFormat(this._gl.FRAGMENT_SHADER, this._gl.HIGH_FLOAT);
|
|
|
this._caps.highPrecisionShaderSupported = highp.precision !== 0;
|
|
@@ -1916,21 +1949,53 @@
|
|
|
|
|
|
texture.samplingMode = samplingMode;
|
|
|
}
|
|
|
+ /**
|
|
|
+ * Set the compressed texture format to use, based on the formats you have,
|
|
|
+ * the formats supported by the hardware / browser, and those currently implemented
|
|
|
+ * in BJS.
|
|
|
+ *
|
|
|
+ * Note: The result of this call is not taken into account texture is base64 or when
|
|
|
+ * using a database / manifest.
|
|
|
+ *
|
|
|
+ * @param {Array<string>} formatsAvailable - Extension names including dot. Case
|
|
|
+ * and order do not matter.
|
|
|
+ * @returns The extension selected.
|
|
|
+ */
|
|
|
+ public setTextureFormatToUse(formatsAvailable : Array<string>) : string {
|
|
|
+ for (var i = 0, len1 = this.texturesSupported.length; i < len1; i++) {
|
|
|
+ // code to allow the formats to be added as they can be developed / hw tested
|
|
|
+ if (this._texturesSupported[i] === '.astc') continue;
|
|
|
+ if (this._texturesSupported[i] === '.pvr' ) continue;
|
|
|
+ if (this._texturesSupported[i] === '.etc1') continue;
|
|
|
+ if (this._texturesSupported[i] === '.etc2') continue;
|
|
|
+
|
|
|
+ for (var j = 0, len2 = formatsAvailable.length; j < len2; j++) {
|
|
|
+ if (this._texturesSupported[i] === formatsAvailable[j].toLowerCase()) {
|
|
|
+ return this._textureFormatInUse = this._texturesSupported[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // actively set format to nothing, to allow this to be called more than once
|
|
|
+ // and possibly fail the 2nd time
|
|
|
+ return this._textureFormatInUse = null;
|
|
|
+ }
|
|
|
|
|
|
- public createTexture(urlOrList: string | Array<string>, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null): WebGLTexture {
|
|
|
+ public createTexture(url: string, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: () => void = null, onError: () => void = null, buffer: any = null): WebGLTexture {
|
|
|
var texture = this._gl.createTexture();
|
|
|
|
|
|
- var url = <string>((urlOrList.constructor === Array) ? urlOrList[0] : urlOrList);
|
|
|
-
|
|
|
var extension: string;
|
|
|
var fromData: any = false;
|
|
|
if (url.substr(0, 5) === "data:") {
|
|
|
fromData = true;
|
|
|
}
|
|
|
|
|
|
- if (!fromData)
|
|
|
- extension = url.substr(url.length - 4, 4).toLowerCase();
|
|
|
- else {
|
|
|
+ if (!fromData) {
|
|
|
+ var lastDot = url.lastIndexOf('.')
|
|
|
+ extension = url.substring(lastDot).toLowerCase();
|
|
|
+ if (this._textureFormatInUse && !fromData && !scene.database) {
|
|
|
+ url = url.substring(0, lastDot) + this._textureFormatInUse;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
var oldUrl = url;
|
|
|
fromData = oldUrl.split(':');
|
|
|
url = oldUrl;
|
|
@@ -1974,20 +2039,6 @@
|
|
|
callback(buffer);
|
|
|
|
|
|
} else if (isDDS) {
|
|
|
- if (!this.getCaps().s3tc) {
|
|
|
- if (urlOrList instanceof Array) {
|
|
|
- var newList = (<Array<string>>urlOrList).slice(1);
|
|
|
-
|
|
|
- if (newList.length > 0) {
|
|
|
- return this.createTexture(newList, noMipmap, invertY, scene, samplingMode, onLoad, onError, buffer);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- onerror();
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
callback = (data) => {
|
|
|
var info = Internals.DDSTools.GetDDSInfo(data);
|
|
|
|