|
@@ -58,7 +58,7 @@
|
|
|
var potWidth = Tools.GetExponentOfTwo(width, engine.getCaps().maxTextureSize);
|
|
|
var potHeight = Tools.GetExponentOfTwo(height, engine.getCaps().maxTextureSize);
|
|
|
|
|
|
- gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
|
+ engine._bindTextureDirectly(gl.TEXTURE_2D, texture);
|
|
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, invertY === undefined ? 1 : (invertY ? 1 : 0));
|
|
|
|
|
|
texture._baseWidth = width;
|
|
@@ -78,7 +78,7 @@
|
|
|
gl.generateMipmap(gl.TEXTURE_2D);
|
|
|
}
|
|
|
|
|
|
- gl.bindTexture(gl.TEXTURE_2D, null);
|
|
|
+ engine._bindTextureDirectly(gl.TEXTURE_2D, null);
|
|
|
|
|
|
engine.resetTextureCache();
|
|
|
scene._removePendingData(texture);
|
|
@@ -337,7 +337,8 @@
|
|
|
// Cache
|
|
|
private _loadedTexturesCache = new Array<WebGLTexture>();
|
|
|
private _maxTextureChannels = 16;
|
|
|
- private _activeTexturesCache = new Array<BaseTexture>(this._maxTextureChannels);
|
|
|
+ private _activeTexture: number;
|
|
|
+ private _activeTexturesCache = new Array<WebGLTexture>(this._maxTextureChannels);
|
|
|
private _currentEffect: Effect;
|
|
|
private _currentProgram: WebGLProgram;
|
|
|
private _compiledEffects = {};
|
|
@@ -862,9 +863,9 @@
|
|
|
this._currentRenderTarget = null;
|
|
|
if (texture.generateMipMaps && !disableGenerateMipMaps) {
|
|
|
var gl = this._gl;
|
|
|
- gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_2D, texture);
|
|
|
gl.generateMipmap(gl.TEXTURE_2D);
|
|
|
- gl.bindTexture(gl.TEXTURE_2D, null);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_2D, null);
|
|
|
}
|
|
|
|
|
|
this.bindUnboundFramebuffer(null);
|
|
@@ -873,9 +874,9 @@
|
|
|
public generateMipMapsForCubemap(texture: WebGLTexture) {
|
|
|
if (texture.generateMipMaps) {
|
|
|
var gl = this._gl;
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1560,7 +1561,7 @@
|
|
|
public setSamplingMode(texture: WebGLTexture, samplingMode: number): void {
|
|
|
var gl = this._gl;
|
|
|
|
|
|
- gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_2D, texture);
|
|
|
|
|
|
var magFilter = gl.NEAREST;
|
|
|
var minFilter = gl.NEAREST;
|
|
@@ -1576,7 +1577,7 @@
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
|
|
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
|
|
|
|
|
|
- gl.bindTexture(gl.TEXTURE_2D, null);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_2D, null);
|
|
|
|
|
|
texture.samplingMode = samplingMode;
|
|
|
}
|
|
@@ -1719,7 +1720,7 @@
|
|
|
|
|
|
public updateRawTexture(texture: WebGLTexture, data: ArrayBufferView, format: number, invertY: boolean, compression: string = null): void {
|
|
|
var internalFormat = this._getInternalFormat(format);
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
|
|
|
this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, invertY === undefined ? 1 : (invertY ? 1 : 0));
|
|
|
|
|
|
if (texture._width % 4 !== 0) {
|
|
@@ -1735,7 +1736,7 @@
|
|
|
if (texture.generateMipMaps) {
|
|
|
this._gl.generateMipmap(this._gl.TEXTURE_2D);
|
|
|
}
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
|
|
|
this.resetTextureCache();
|
|
|
texture.isReady = true;
|
|
|
}
|
|
@@ -1749,14 +1750,14 @@
|
|
|
texture.references = 1;
|
|
|
|
|
|
this.updateRawTexture(texture, data, format, invertY, compression);
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
|
|
|
|
|
|
// Filters
|
|
|
var filters = getSamplingParameters(samplingMode, generateMipMaps, this._gl);
|
|
|
|
|
|
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);
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
|
|
|
|
|
|
texture.samplingMode = samplingMode;
|
|
|
|
|
@@ -1794,22 +1795,22 @@
|
|
|
var filters = getSamplingParameters(samplingMode, texture.generateMipMaps, this._gl);
|
|
|
|
|
|
if (texture.isCube) {
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_CUBE_MAP, texture);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, texture);
|
|
|
|
|
|
this._gl.texParameteri(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_MAG_FILTER, filters.mag);
|
|
|
this._gl.texParameteri(this._gl.TEXTURE_CUBE_MAP, this._gl.TEXTURE_MIN_FILTER, filters.min);
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_CUBE_MAP, null);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
|
|
|
} else {
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
|
|
|
|
|
|
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);
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public updateDynamicTexture(texture: WebGLTexture, canvas: HTMLCanvasElement, invertY: boolean, premulAlpha: boolean = false): void {
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
|
|
|
this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, invertY ? 1 : 0);
|
|
|
if (premulAlpha) {
|
|
|
this._gl.pixelStorei(this._gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
|
|
@@ -1818,7 +1819,7 @@
|
|
|
if (texture.generateMipMaps) {
|
|
|
this._gl.generateMipmap(this._gl.TEXTURE_2D);
|
|
|
}
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
|
|
|
this.resetTextureCache();
|
|
|
texture.isReady = true;
|
|
|
}
|
|
@@ -1828,7 +1829,7 @@
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
|
|
|
this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, invertY ? 0 : 1); // Video are upside down by default
|
|
|
|
|
|
try {
|
|
@@ -1863,7 +1864,7 @@
|
|
|
this._gl.generateMipmap(this._gl.TEXTURE_2D);
|
|
|
}
|
|
|
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
|
|
|
this.resetTextureCache();
|
|
|
texture.isReady = true;
|
|
|
|
|
@@ -1897,7 +1898,7 @@
|
|
|
var gl = this._gl;
|
|
|
|
|
|
var texture = gl.createTexture();
|
|
|
- gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_2D, texture);
|
|
|
|
|
|
var width = size.width || size;
|
|
|
var height = size.height || size;
|
|
@@ -1935,7 +1936,7 @@
|
|
|
}
|
|
|
|
|
|
// Unbind
|
|
|
- gl.bindTexture(gl.TEXTURE_2D, null);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_2D, null);
|
|
|
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
|
|
|
this.bindUnboundFramebuffer(null);
|
|
|
|
|
@@ -1980,7 +1981,7 @@
|
|
|
|
|
|
var filters = getSamplingParameters(samplingMode, generateMipMaps, gl);
|
|
|
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
|
|
|
for (var face = 0; face < 6; face++) {
|
|
|
gl.texImage2D((gl.TEXTURE_CUBE_MAP_POSITIVE_X + face), 0, gl.RGBA, size, size, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
@@ -2003,12 +2004,12 @@
|
|
|
|
|
|
// Mipmaps
|
|
|
if (texture.generateMipMaps) {
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
|
|
|
}
|
|
|
|
|
|
// Unbind
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
|
|
|
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
|
|
|
this.bindUnboundFramebuffer(null);
|
|
|
|
|
@@ -2041,7 +2042,7 @@
|
|
|
|
|
|
var loadMipmap = (info.isRGB || info.isLuminance || info.mipmapCount > 1) && !noMipmap;
|
|
|
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
|
|
|
|
|
|
Internals.DDSTools.UploadDDSLevels(this._gl, this.getCaps().s3tc, data, info, loadMipmap, 6);
|
|
@@ -2055,7 +2056,7 @@
|
|
|
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);
|
|
|
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
|
|
|
|
|
|
this.resetTextureCache();
|
|
|
|
|
@@ -2077,7 +2078,7 @@
|
|
|
gl.TEXTURE_CUBE_MAP_NEGATIVE_X, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
|
|
|
];
|
|
|
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
|
|
|
|
|
|
for (var index = 0; index < faces.length; index++) {
|
|
@@ -2094,7 +2095,7 @@
|
|
|
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);
|
|
|
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
|
|
|
|
|
|
this.resetTextureCache();
|
|
|
|
|
@@ -2155,7 +2156,7 @@
|
|
|
height = texture._height;
|
|
|
isPot = (Tools.IsExponentOfTwo(width) && Tools.IsExponentOfTwo(height));
|
|
|
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture);
|
|
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
|
|
|
|
|
|
if (!noMipmap && isPot) {
|
|
@@ -2244,7 +2245,7 @@
|
|
|
|
|
|
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);
|
|
|
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
|
|
|
+ this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
|
|
|
|
|
|
texture.isReady = true;
|
|
|
|
|
@@ -2295,16 +2296,28 @@
|
|
|
this._currentEffect = null;
|
|
|
}
|
|
|
|
|
|
+ private activateTexture(texture: number): void {
|
|
|
+ if (this._activeTexture !== texture) {
|
|
|
+ this._gl.activeTexture(texture);
|
|
|
+ this._activeTexture = texture;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public _bindTextureDirectly(target: number, texture: WebGLTexture): void
|
|
|
+ {
|
|
|
+ if (this._activeTexturesCache[this._activeTexture] !== texture) {
|
|
|
+ this._gl.bindTexture(target, texture);
|
|
|
+ this._activeTexturesCache[this._activeTexture] = texture;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
public _bindTexture(channel: number, texture: WebGLTexture): void {
|
|
|
if (channel < 0) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- this._gl.activeTexture(this._gl["TEXTURE" + channel]);
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
|
|
|
-
|
|
|
- this._activeTexturesCache[channel] = null;
|
|
|
+ this.activateTexture(this._gl["TEXTURE" + channel]);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, texture);
|
|
|
}
|
|
|
|
|
|
public setTextureFromPostProcess(channel: number, postProcess: PostProcess): void {
|
|
@@ -2313,10 +2326,9 @@
|
|
|
|
|
|
public unbindAllTextures(): void {
|
|
|
for (var channel = 0; channel < this._caps.maxTexturesImageUnits; channel++) {
|
|
|
- this._gl.activeTexture(this._gl["TEXTURE" + channel]);
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_CUBE_MAP, null);
|
|
|
- this._activeTexturesCache[channel] = null;
|
|
|
+ this.activateTexture(this._gl["TEXTURE" + channel]);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2327,10 +2339,9 @@
|
|
|
// Not ready?
|
|
|
if (!texture || !texture.isReady()) {
|
|
|
if (this._activeTexturesCache[channel] != null) {
|
|
|
- this._gl.activeTexture(this._gl["TEXTURE" + channel]);
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, null);
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_CUBE_MAP, null);
|
|
|
- this._activeTexturesCache[channel] = null;
|
|
|
+ this.activateTexture(this._gl["TEXTURE" + channel]);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
@@ -2338,7 +2349,7 @@
|
|
|
// Video
|
|
|
var alreadyActivated = false;
|
|
|
if (texture instanceof VideoTexture) {
|
|
|
- this._gl.activeTexture(this._gl["TEXTURE" + channel]);
|
|
|
+ this.activateTexture(this._gl["TEXTURE" + channel]);
|
|
|
alreadyActivated = true;
|
|
|
texture.update();
|
|
|
} else if (texture.delayLoadState === Engine.DELAYLOADSTATE_NOTLOADED) { // Delay loading
|
|
@@ -2346,19 +2357,18 @@
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (this._activeTexturesCache[channel] === texture) {
|
|
|
+ var internalTexture = texture.getInternalTexture();
|
|
|
+
|
|
|
+ if (this._activeTexturesCache[channel] === internalTexture) {
|
|
|
return;
|
|
|
}
|
|
|
- this._activeTexturesCache[channel] = texture;
|
|
|
-
|
|
|
- var internalTexture = texture.getInternalTexture();
|
|
|
|
|
|
if (!alreadyActivated) {
|
|
|
- this._gl.activeTexture(this._gl["TEXTURE" + channel]);
|
|
|
+ this.activateTexture(this._gl["TEXTURE" + channel]);
|
|
|
}
|
|
|
|
|
|
if (internalTexture.isCube) {
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_CUBE_MAP, internalTexture);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, internalTexture);
|
|
|
|
|
|
if (internalTexture._cachedCoordinatesMode !== texture.coordinatesMode) {
|
|
|
internalTexture._cachedCoordinatesMode = texture.coordinatesMode;
|
|
@@ -2370,7 +2380,7 @@
|
|
|
|
|
|
this._setAnisotropicLevel(this._gl.TEXTURE_CUBE_MAP, texture);
|
|
|
} else {
|
|
|
- this._gl.bindTexture(this._gl.TEXTURE_2D, internalTexture);
|
|
|
+ this._bindTextureDirectly(this._gl.TEXTURE_2D, internalTexture);
|
|
|
|
|
|
if (internalTexture._cachedWrapU !== texture.wrapU) {
|
|
|
internalTexture._cachedWrapU = texture.wrapU;
|