diff --git a/src/core/const.js b/src/core/const.js index 3de0efe..9cc0879 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -179,9 +179,9 @@ * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring */ export const WRAP_MODES = { - CLAMP: 0, - REPEAT: 1, - MIRRORED_REPEAT: 2, + CLAMP: 33071, + REPEAT: 10497, + MIRRORED_REPEAT: 33648, }; /** diff --git a/src/core/const.js b/src/core/const.js index 3de0efe..9cc0879 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -179,9 +179,9 @@ * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring */ export const WRAP_MODES = { - CLAMP: 0, - REPEAT: 1, - MIRRORED_REPEAT: 2, + CLAMP: 33071, + REPEAT: 10497, + MIRRORED_REPEAT: 33648, }; /** diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 308e959..d839dc6 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -48,7 +48,16 @@ this.updateFramebuffer(framebuffer); } - this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].glTextures[this.CONTEXT_UID]._bound) + if(framebuffer.colorTextures[0].texturePart) + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].texture) + } + else + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0]) + } } else { @@ -96,15 +105,30 @@ for (var i = 0; i < count; i++) { - const texture = framebuffer.colorTextures[i]; + let texture = framebuffer.colorTextures[i]; - this.renderer.newTextureManager.bindTexture(texture, 0); + if(texture.texturePart) + { + this.renderer.newTextureManager.bindTexture(texture.texture, 0); - const glTexture = texture.glTextures[this.CONTEXT_UID]; + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, + texture.texture.glTextures[this.CONTEXT_UID].texture, + 0); + } + else + { + this.renderer.newTextureManager.bindTexture(texture, 0); + + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_2D, + texture.glTextures[this.CONTEXT_UID].texture, + 0); + } activeTextures.push(gl.COLOR_ATTACHMENT0 + i); - - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, glTexture.texture, 0); } if(this.drawBufferExtension && activeTextures.length > 1) diff --git a/src/core/const.js b/src/core/const.js index 3de0efe..9cc0879 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -179,9 +179,9 @@ * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring */ export const WRAP_MODES = { - CLAMP: 0, - REPEAT: 1, - MIRRORED_REPEAT: 2, + CLAMP: 33071, + REPEAT: 10497, + MIRRORED_REPEAT: 33648, }; /** diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 308e959..d839dc6 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -48,7 +48,16 @@ this.updateFramebuffer(framebuffer); } - this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].glTextures[this.CONTEXT_UID]._bound) + if(framebuffer.colorTextures[0].texturePart) + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].texture) + } + else + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0]) + } } else { @@ -96,15 +105,30 @@ for (var i = 0; i < count; i++) { - const texture = framebuffer.colorTextures[i]; + let texture = framebuffer.colorTextures[i]; - this.renderer.newTextureManager.bindTexture(texture, 0); + if(texture.texturePart) + { + this.renderer.newTextureManager.bindTexture(texture.texture, 0); - const glTexture = texture.glTextures[this.CONTEXT_UID]; + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, + texture.texture.glTextures[this.CONTEXT_UID].texture, + 0); + } + else + { + this.renderer.newTextureManager.bindTexture(texture, 0); + + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_2D, + texture.glTextures[this.CONTEXT_UID].texture, + 0); + } activeTextures.push(gl.COLOR_ATTACHMENT0 + i); - - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, glTexture.texture, 0); } if(this.drawBufferExtension && activeTextures.length > 1) diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index 0b9e282..542a460 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -35,8 +35,24 @@ */ onContextChange() { - this.gl = this.renderer.gl; + const gl = this.gl = this.renderer.gl; this.CONTEXT_UID = this.renderer.CONTEXT_UID; + + // TODO move this.. to a nice make empty textures class.. + this.emptyTextures = {} + + this.emptyTextures[gl.TEXTURE_2D] = new GLTexture.fromData(this.gl, null, 1, 1); + this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(this.gl); + + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture); + + for (var i = 0; i < 6; i++) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); } bindTexture(texture, location) @@ -47,36 +63,37 @@ gl.activeTexture(gl.TEXTURE0 + location); - if(texture) + if(texture && texture.valid) { const glTexture = texture.glTextures[this.CONTEXT_UID] || this.initTexture(texture); - if(texture.isCube) + gl.bindTexture(texture.type, glTexture.texture); + + if(glTexture.dirtyId !== texture.dirtyId) { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, glTexture.texture); + glTexture.dirtyId = texture.dirtyId; + this.updateTexture(texture); } this.boundTextures[location] = texture; } else { - gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindTexture(texture.type, this.emptyTextures[texture.type].texture); this.boundTextures[location] = null; } } unbindTexture(texture) { + const gl = this.gl; + for (var i = 0; i < this.boundTextures.length; i++) { if(this.boundTextures[i] === texture) { - gl.activeTexture(gl.TEXTURE0 + location); - gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE0 + i); + gl.bindTexture(gl.TEXTURE_2D, this.emptyGLTexture.texture); this.boundTextures[i] = null; } } @@ -88,45 +105,73 @@ var glTexture = new GLTexture(this.gl); - if(texture.isCube) - { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - - glTexture.width = texture.width; - glTexture.height = texture.height; - - // upload the 6 faces.. - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex1); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex2); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex3); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex4); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex5); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex6); - - - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - } - else - { - glTexture.uploadData(null, texture.width, texture.height); - - // settings.. - glTexture.enableNearestScaling(); - glTexture.enableWrapClamp(); - } - - + // guarentee an update.. + glTexture.dirtyId = -1; texture.glTextures[this.CONTEXT_UID] = glTexture; return glTexture; } + + updateTexture(texture) + { + const glTexture = texture.glTextures[this.CONTEXT_UID]; + const gl = this.gl; + + // TODO there are only 3 textures as far as im aware? + // Cube / 2D and later 3d. (the latter is WebGL2, we will get to that soon!) + if(texture.type === gl.TEXTURE_CUBE_MAP) + { + + for (var i = 0; i < texture.sides.length; i++) + { + // TODO - we should only upload what changed.. + // but im sure this is not going to be a problem just yet! + var texturePart = texture.sides[i]; + + if(texturePart.resource) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, glTexture.format, glTexture.format, glTexture.type, texturePart.resource.source); + } + else + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, gl.RGBA, texture.width, texture.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + } + } + else + { + if(texture.resource) + { + glTexture.upload(texture.resource.source); + } + else + { + glTexture.uploadData(null, texture.width, texture.height); + } + } + + // lets only update what changes.. + this.setStyle(texture); + } + + setStyle(texture) + { + const gl = this.gl; + const style = texture.style; + + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_S, style.wrapMode); + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_T, style.wrapMode); + + if(texture.mipmap) + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); + } + else + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } + + gl.texParameteri(texture.type, gl.TEXTURE_MAG_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } } \ No newline at end of file diff --git a/src/core/const.js b/src/core/const.js index 3de0efe..9cc0879 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -179,9 +179,9 @@ * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring */ export const WRAP_MODES = { - CLAMP: 0, - REPEAT: 1, - MIRRORED_REPEAT: 2, + CLAMP: 33071, + REPEAT: 10497, + MIRRORED_REPEAT: 33648, }; /** diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 308e959..d839dc6 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -48,7 +48,16 @@ this.updateFramebuffer(framebuffer); } - this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].glTextures[this.CONTEXT_UID]._bound) + if(framebuffer.colorTextures[0].texturePart) + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].texture) + } + else + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0]) + } } else { @@ -96,15 +105,30 @@ for (var i = 0; i < count; i++) { - const texture = framebuffer.colorTextures[i]; + let texture = framebuffer.colorTextures[i]; - this.renderer.newTextureManager.bindTexture(texture, 0); + if(texture.texturePart) + { + this.renderer.newTextureManager.bindTexture(texture.texture, 0); - const glTexture = texture.glTextures[this.CONTEXT_UID]; + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, + texture.texture.glTextures[this.CONTEXT_UID].texture, + 0); + } + else + { + this.renderer.newTextureManager.bindTexture(texture, 0); + + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_2D, + texture.glTextures[this.CONTEXT_UID].texture, + 0); + } activeTextures.push(gl.COLOR_ATTACHMENT0 + i); - - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, glTexture.texture, 0); } if(this.drawBufferExtension && activeTextures.length > 1) diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index 0b9e282..542a460 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -35,8 +35,24 @@ */ onContextChange() { - this.gl = this.renderer.gl; + const gl = this.gl = this.renderer.gl; this.CONTEXT_UID = this.renderer.CONTEXT_UID; + + // TODO move this.. to a nice make empty textures class.. + this.emptyTextures = {} + + this.emptyTextures[gl.TEXTURE_2D] = new GLTexture.fromData(this.gl, null, 1, 1); + this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(this.gl); + + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture); + + for (var i = 0; i < 6; i++) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); } bindTexture(texture, location) @@ -47,36 +63,37 @@ gl.activeTexture(gl.TEXTURE0 + location); - if(texture) + if(texture && texture.valid) { const glTexture = texture.glTextures[this.CONTEXT_UID] || this.initTexture(texture); - if(texture.isCube) + gl.bindTexture(texture.type, glTexture.texture); + + if(glTexture.dirtyId !== texture.dirtyId) { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, glTexture.texture); + glTexture.dirtyId = texture.dirtyId; + this.updateTexture(texture); } this.boundTextures[location] = texture; } else { - gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindTexture(texture.type, this.emptyTextures[texture.type].texture); this.boundTextures[location] = null; } } unbindTexture(texture) { + const gl = this.gl; + for (var i = 0; i < this.boundTextures.length; i++) { if(this.boundTextures[i] === texture) { - gl.activeTexture(gl.TEXTURE0 + location); - gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE0 + i); + gl.bindTexture(gl.TEXTURE_2D, this.emptyGLTexture.texture); this.boundTextures[i] = null; } } @@ -88,45 +105,73 @@ var glTexture = new GLTexture(this.gl); - if(texture.isCube) - { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - - glTexture.width = texture.width; - glTexture.height = texture.height; - - // upload the 6 faces.. - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex1); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex2); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex3); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex4); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex5); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex6); - - - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - } - else - { - glTexture.uploadData(null, texture.width, texture.height); - - // settings.. - glTexture.enableNearestScaling(); - glTexture.enableWrapClamp(); - } - - + // guarentee an update.. + glTexture.dirtyId = -1; texture.glTextures[this.CONTEXT_UID] = glTexture; return glTexture; } + + updateTexture(texture) + { + const glTexture = texture.glTextures[this.CONTEXT_UID]; + const gl = this.gl; + + // TODO there are only 3 textures as far as im aware? + // Cube / 2D and later 3d. (the latter is WebGL2, we will get to that soon!) + if(texture.type === gl.TEXTURE_CUBE_MAP) + { + + for (var i = 0; i < texture.sides.length; i++) + { + // TODO - we should only upload what changed.. + // but im sure this is not going to be a problem just yet! + var texturePart = texture.sides[i]; + + if(texturePart.resource) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, glTexture.format, glTexture.format, glTexture.type, texturePart.resource.source); + } + else + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, gl.RGBA, texture.width, texture.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + } + } + else + { + if(texture.resource) + { + glTexture.upload(texture.resource.source); + } + else + { + glTexture.uploadData(null, texture.width, texture.height); + } + } + + // lets only update what changes.. + this.setStyle(texture); + } + + setStyle(texture) + { + const gl = this.gl; + const style = texture.style; + + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_S, style.wrapMode); + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_T, style.wrapMode); + + if(texture.mipmap) + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); + } + else + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } + + gl.texParameteri(texture.type, gl.TEXTURE_MAG_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } } \ No newline at end of file diff --git a/src/core/settings.js b/src/core/settings.js index f4dd087..7de1975 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -162,7 +162,7 @@ * @type {PIXI.WRAP_MODES} * @default PIXI.WRAP_MODES.CLAMP */ - WRAP_MODE: 0, + WRAP_MODE: 33071, /** * The scale modes that are supported by pixi. diff --git a/src/core/const.js b/src/core/const.js index 3de0efe..9cc0879 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -179,9 +179,9 @@ * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring */ export const WRAP_MODES = { - CLAMP: 0, - REPEAT: 1, - MIRRORED_REPEAT: 2, + CLAMP: 33071, + REPEAT: 10497, + MIRRORED_REPEAT: 33648, }; /** diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 308e959..d839dc6 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -48,7 +48,16 @@ this.updateFramebuffer(framebuffer); } - this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].glTextures[this.CONTEXT_UID]._bound) + if(framebuffer.colorTextures[0].texturePart) + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].texture) + } + else + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0]) + } } else { @@ -96,15 +105,30 @@ for (var i = 0; i < count; i++) { - const texture = framebuffer.colorTextures[i]; + let texture = framebuffer.colorTextures[i]; - this.renderer.newTextureManager.bindTexture(texture, 0); + if(texture.texturePart) + { + this.renderer.newTextureManager.bindTexture(texture.texture, 0); - const glTexture = texture.glTextures[this.CONTEXT_UID]; + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, + texture.texture.glTextures[this.CONTEXT_UID].texture, + 0); + } + else + { + this.renderer.newTextureManager.bindTexture(texture, 0); + + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_2D, + texture.glTextures[this.CONTEXT_UID].texture, + 0); + } activeTextures.push(gl.COLOR_ATTACHMENT0 + i); - - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, glTexture.texture, 0); } if(this.drawBufferExtension && activeTextures.length > 1) diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index 0b9e282..542a460 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -35,8 +35,24 @@ */ onContextChange() { - this.gl = this.renderer.gl; + const gl = this.gl = this.renderer.gl; this.CONTEXT_UID = this.renderer.CONTEXT_UID; + + // TODO move this.. to a nice make empty textures class.. + this.emptyTextures = {} + + this.emptyTextures[gl.TEXTURE_2D] = new GLTexture.fromData(this.gl, null, 1, 1); + this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(this.gl); + + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture); + + for (var i = 0; i < 6; i++) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); } bindTexture(texture, location) @@ -47,36 +63,37 @@ gl.activeTexture(gl.TEXTURE0 + location); - if(texture) + if(texture && texture.valid) { const glTexture = texture.glTextures[this.CONTEXT_UID] || this.initTexture(texture); - if(texture.isCube) + gl.bindTexture(texture.type, glTexture.texture); + + if(glTexture.dirtyId !== texture.dirtyId) { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, glTexture.texture); + glTexture.dirtyId = texture.dirtyId; + this.updateTexture(texture); } this.boundTextures[location] = texture; } else { - gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindTexture(texture.type, this.emptyTextures[texture.type].texture); this.boundTextures[location] = null; } } unbindTexture(texture) { + const gl = this.gl; + for (var i = 0; i < this.boundTextures.length; i++) { if(this.boundTextures[i] === texture) { - gl.activeTexture(gl.TEXTURE0 + location); - gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE0 + i); + gl.bindTexture(gl.TEXTURE_2D, this.emptyGLTexture.texture); this.boundTextures[i] = null; } } @@ -88,45 +105,73 @@ var glTexture = new GLTexture(this.gl); - if(texture.isCube) - { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - - glTexture.width = texture.width; - glTexture.height = texture.height; - - // upload the 6 faces.. - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex1); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex2); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex3); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex4); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex5); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex6); - - - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - } - else - { - glTexture.uploadData(null, texture.width, texture.height); - - // settings.. - glTexture.enableNearestScaling(); - glTexture.enableWrapClamp(); - } - - + // guarentee an update.. + glTexture.dirtyId = -1; texture.glTextures[this.CONTEXT_UID] = glTexture; return glTexture; } + + updateTexture(texture) + { + const glTexture = texture.glTextures[this.CONTEXT_UID]; + const gl = this.gl; + + // TODO there are only 3 textures as far as im aware? + // Cube / 2D and later 3d. (the latter is WebGL2, we will get to that soon!) + if(texture.type === gl.TEXTURE_CUBE_MAP) + { + + for (var i = 0; i < texture.sides.length; i++) + { + // TODO - we should only upload what changed.. + // but im sure this is not going to be a problem just yet! + var texturePart = texture.sides[i]; + + if(texturePart.resource) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, glTexture.format, glTexture.format, glTexture.type, texturePart.resource.source); + } + else + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, gl.RGBA, texture.width, texture.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + } + } + else + { + if(texture.resource) + { + glTexture.upload(texture.resource.source); + } + else + { + glTexture.uploadData(null, texture.width, texture.height); + } + } + + // lets only update what changes.. + this.setStyle(texture); + } + + setStyle(texture) + { + const gl = this.gl; + const style = texture.style; + + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_S, style.wrapMode); + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_T, style.wrapMode); + + if(texture.mipmap) + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); + } + else + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } + + gl.texParameteri(texture.type, gl.TEXTURE_MAG_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } } \ No newline at end of file diff --git a/src/core/settings.js b/src/core/settings.js index f4dd087..7de1975 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -162,7 +162,7 @@ * @type {PIXI.WRAP_MODES} * @default PIXI.WRAP_MODES.CLAMP */ - WRAP_MODE: 0, + WRAP_MODE: 33071, /** * The scale modes that are supported by pixi. diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index f3e46c5..e9ab29c 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -110,11 +110,12 @@ } else if(uniformValues.${i}._new) { - uniformData.${i}.value = ${textureCount}; renderer.newTextureManager.bindTexture(uniformValues.${i}, ${textureCount}) - - gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len - + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } } else { diff --git a/src/core/const.js b/src/core/const.js index 3de0efe..9cc0879 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -179,9 +179,9 @@ * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring */ export const WRAP_MODES = { - CLAMP: 0, - REPEAT: 1, - MIRRORED_REPEAT: 2, + CLAMP: 33071, + REPEAT: 10497, + MIRRORED_REPEAT: 33648, }; /** diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 308e959..d839dc6 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -48,7 +48,16 @@ this.updateFramebuffer(framebuffer); } - this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].glTextures[this.CONTEXT_UID]._bound) + if(framebuffer.colorTextures[0].texturePart) + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].texture) + } + else + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0]) + } } else { @@ -96,15 +105,30 @@ for (var i = 0; i < count; i++) { - const texture = framebuffer.colorTextures[i]; + let texture = framebuffer.colorTextures[i]; - this.renderer.newTextureManager.bindTexture(texture, 0); + if(texture.texturePart) + { + this.renderer.newTextureManager.bindTexture(texture.texture, 0); - const glTexture = texture.glTextures[this.CONTEXT_UID]; + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, + texture.texture.glTextures[this.CONTEXT_UID].texture, + 0); + } + else + { + this.renderer.newTextureManager.bindTexture(texture, 0); + + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_2D, + texture.glTextures[this.CONTEXT_UID].texture, + 0); + } activeTextures.push(gl.COLOR_ATTACHMENT0 + i); - - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, glTexture.texture, 0); } if(this.drawBufferExtension && activeTextures.length > 1) diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index 0b9e282..542a460 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -35,8 +35,24 @@ */ onContextChange() { - this.gl = this.renderer.gl; + const gl = this.gl = this.renderer.gl; this.CONTEXT_UID = this.renderer.CONTEXT_UID; + + // TODO move this.. to a nice make empty textures class.. + this.emptyTextures = {} + + this.emptyTextures[gl.TEXTURE_2D] = new GLTexture.fromData(this.gl, null, 1, 1); + this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(this.gl); + + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture); + + for (var i = 0; i < 6; i++) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); } bindTexture(texture, location) @@ -47,36 +63,37 @@ gl.activeTexture(gl.TEXTURE0 + location); - if(texture) + if(texture && texture.valid) { const glTexture = texture.glTextures[this.CONTEXT_UID] || this.initTexture(texture); - if(texture.isCube) + gl.bindTexture(texture.type, glTexture.texture); + + if(glTexture.dirtyId !== texture.dirtyId) { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, glTexture.texture); + glTexture.dirtyId = texture.dirtyId; + this.updateTexture(texture); } this.boundTextures[location] = texture; } else { - gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindTexture(texture.type, this.emptyTextures[texture.type].texture); this.boundTextures[location] = null; } } unbindTexture(texture) { + const gl = this.gl; + for (var i = 0; i < this.boundTextures.length; i++) { if(this.boundTextures[i] === texture) { - gl.activeTexture(gl.TEXTURE0 + location); - gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE0 + i); + gl.bindTexture(gl.TEXTURE_2D, this.emptyGLTexture.texture); this.boundTextures[i] = null; } } @@ -88,45 +105,73 @@ var glTexture = new GLTexture(this.gl); - if(texture.isCube) - { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - - glTexture.width = texture.width; - glTexture.height = texture.height; - - // upload the 6 faces.. - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex1); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex2); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex3); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex4); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex5); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex6); - - - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - } - else - { - glTexture.uploadData(null, texture.width, texture.height); - - // settings.. - glTexture.enableNearestScaling(); - glTexture.enableWrapClamp(); - } - - + // guarentee an update.. + glTexture.dirtyId = -1; texture.glTextures[this.CONTEXT_UID] = glTexture; return glTexture; } + + updateTexture(texture) + { + const glTexture = texture.glTextures[this.CONTEXT_UID]; + const gl = this.gl; + + // TODO there are only 3 textures as far as im aware? + // Cube / 2D and later 3d. (the latter is WebGL2, we will get to that soon!) + if(texture.type === gl.TEXTURE_CUBE_MAP) + { + + for (var i = 0; i < texture.sides.length; i++) + { + // TODO - we should only upload what changed.. + // but im sure this is not going to be a problem just yet! + var texturePart = texture.sides[i]; + + if(texturePart.resource) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, glTexture.format, glTexture.format, glTexture.type, texturePart.resource.source); + } + else + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, gl.RGBA, texture.width, texture.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + } + } + else + { + if(texture.resource) + { + glTexture.upload(texture.resource.source); + } + else + { + glTexture.uploadData(null, texture.width, texture.height); + } + } + + // lets only update what changes.. + this.setStyle(texture); + } + + setStyle(texture) + { + const gl = this.gl; + const style = texture.style; + + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_S, style.wrapMode); + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_T, style.wrapMode); + + if(texture.mipmap) + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); + } + else + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } + + gl.texParameteri(texture.type, gl.TEXTURE_MAG_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } } \ No newline at end of file diff --git a/src/core/settings.js b/src/core/settings.js index f4dd087..7de1975 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -162,7 +162,7 @@ * @type {PIXI.WRAP_MODES} * @default PIXI.WRAP_MODES.CLAMP */ - WRAP_MODE: 0, + WRAP_MODE: 33071, /** * The scale modes that are supported by pixi. diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index f3e46c5..e9ab29c 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -110,11 +110,12 @@ } else if(uniformValues.${i}._new) { - uniformData.${i}.value = ${textureCount}; renderer.newTextureManager.bindTexture(uniformValues.${i}, ${textureCount}) - - gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len - + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } } else { diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js index eea3526..97b4f37 100644 --- a/src/core/textures/new/CubeTexture.js +++ b/src/core/textures/new/CubeTexture.js @@ -1,4 +1,5 @@ import Texture from './Texture'; +import ImageResource from './resources/ImageResource'; export default class CubeTexture extends Texture { @@ -7,12 +8,82 @@ super(width, height, format); this.isCube = true; + this.type = 34067; // gl.TEXTURE_CUBE_MAP - //this.side1 = {_glTextures:this.glTextures, id:1}; - //this.side2 = {_glTextures:this.glTextures, id:2}; - //this.side3 = {_glTextures:this.glTextures, id:3}; - //this.side4 = {_glTextures:this.glTextures, id:4}; - //this.side5 = {_glTextures:this.glTextures, id:5}; - //this.side6 = {_glTextures:this.glTextures, id:6}; + this.resources = []; + + this.positiveX = {side:0, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeX = {side:1, texture:this, resource:null, texturePart:true, dirtyId:0}; + + this.positiveY = {side:2, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeY = {side:3, texture:this, resource:null, texturePart:true, dirtyId:0}; + + this.positiveZ = {side:4, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeZ = {side:5, texture:this, resource:null, texturePart:true, dirtyId:0}; + + + this.sides = [this.positiveX, this.negativeX, + this.positiveY, this.negativeY, + this.positiveZ, this.negativeZ]; + } + + setResource(resource, index) + { + var side = this.sides[index]; + side.resource = resource; + + resource.load.then((resource) => { + + if(side.resource === resource) + { + this.width = resource.width; + this.height = resource.height; + // we have not swapped half way! + //side.dirtyId++; + this.validate(); + + this.dirtyId++; + } + + }) + } + + validate() + { + let valid = true; + + if(this.width === -1 || this.height === -1) + { + valid = false; + } + + if(this.sides) + { + for (var i = 0; i < this.sides.length; i++) { + + const side = this.sides[i]; + + if(side.resource && !side.resource.loaded) + { + valid = false; + break; + } + } + } + + + this.valid = valid; + } + + static from(...urls) + { + var cubeTexture = new CubeTexture(); + + for (var i = 0; i < 6; i++) + { + cubeTexture.setResource(ImageResource.from(urls[i % urls.length]), i); + } + + return cubeTexture; } } \ No newline at end of file diff --git a/src/core/const.js b/src/core/const.js index 3de0efe..9cc0879 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -179,9 +179,9 @@ * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring */ export const WRAP_MODES = { - CLAMP: 0, - REPEAT: 1, - MIRRORED_REPEAT: 2, + CLAMP: 33071, + REPEAT: 10497, + MIRRORED_REPEAT: 33648, }; /** diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 308e959..d839dc6 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -48,7 +48,16 @@ this.updateFramebuffer(framebuffer); } - this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].glTextures[this.CONTEXT_UID]._bound) + if(framebuffer.colorTextures[0].texturePart) + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].texture) + } + else + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0]) + } } else { @@ -96,15 +105,30 @@ for (var i = 0; i < count; i++) { - const texture = framebuffer.colorTextures[i]; + let texture = framebuffer.colorTextures[i]; - this.renderer.newTextureManager.bindTexture(texture, 0); + if(texture.texturePart) + { + this.renderer.newTextureManager.bindTexture(texture.texture, 0); - const glTexture = texture.glTextures[this.CONTEXT_UID]; + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, + texture.texture.glTextures[this.CONTEXT_UID].texture, + 0); + } + else + { + this.renderer.newTextureManager.bindTexture(texture, 0); + + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_2D, + texture.glTextures[this.CONTEXT_UID].texture, + 0); + } activeTextures.push(gl.COLOR_ATTACHMENT0 + i); - - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, glTexture.texture, 0); } if(this.drawBufferExtension && activeTextures.length > 1) diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index 0b9e282..542a460 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -35,8 +35,24 @@ */ onContextChange() { - this.gl = this.renderer.gl; + const gl = this.gl = this.renderer.gl; this.CONTEXT_UID = this.renderer.CONTEXT_UID; + + // TODO move this.. to a nice make empty textures class.. + this.emptyTextures = {} + + this.emptyTextures[gl.TEXTURE_2D] = new GLTexture.fromData(this.gl, null, 1, 1); + this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(this.gl); + + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture); + + for (var i = 0; i < 6; i++) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); } bindTexture(texture, location) @@ -47,36 +63,37 @@ gl.activeTexture(gl.TEXTURE0 + location); - if(texture) + if(texture && texture.valid) { const glTexture = texture.glTextures[this.CONTEXT_UID] || this.initTexture(texture); - if(texture.isCube) + gl.bindTexture(texture.type, glTexture.texture); + + if(glTexture.dirtyId !== texture.dirtyId) { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, glTexture.texture); + glTexture.dirtyId = texture.dirtyId; + this.updateTexture(texture); } this.boundTextures[location] = texture; } else { - gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindTexture(texture.type, this.emptyTextures[texture.type].texture); this.boundTextures[location] = null; } } unbindTexture(texture) { + const gl = this.gl; + for (var i = 0; i < this.boundTextures.length; i++) { if(this.boundTextures[i] === texture) { - gl.activeTexture(gl.TEXTURE0 + location); - gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE0 + i); + gl.bindTexture(gl.TEXTURE_2D, this.emptyGLTexture.texture); this.boundTextures[i] = null; } } @@ -88,45 +105,73 @@ var glTexture = new GLTexture(this.gl); - if(texture.isCube) - { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - - glTexture.width = texture.width; - glTexture.height = texture.height; - - // upload the 6 faces.. - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex1); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex2); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex3); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex4); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex5); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex6); - - - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - } - else - { - glTexture.uploadData(null, texture.width, texture.height); - - // settings.. - glTexture.enableNearestScaling(); - glTexture.enableWrapClamp(); - } - - + // guarentee an update.. + glTexture.dirtyId = -1; texture.glTextures[this.CONTEXT_UID] = glTexture; return glTexture; } + + updateTexture(texture) + { + const glTexture = texture.glTextures[this.CONTEXT_UID]; + const gl = this.gl; + + // TODO there are only 3 textures as far as im aware? + // Cube / 2D and later 3d. (the latter is WebGL2, we will get to that soon!) + if(texture.type === gl.TEXTURE_CUBE_MAP) + { + + for (var i = 0; i < texture.sides.length; i++) + { + // TODO - we should only upload what changed.. + // but im sure this is not going to be a problem just yet! + var texturePart = texture.sides[i]; + + if(texturePart.resource) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, glTexture.format, glTexture.format, glTexture.type, texturePart.resource.source); + } + else + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, gl.RGBA, texture.width, texture.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + } + } + else + { + if(texture.resource) + { + glTexture.upload(texture.resource.source); + } + else + { + glTexture.uploadData(null, texture.width, texture.height); + } + } + + // lets only update what changes.. + this.setStyle(texture); + } + + setStyle(texture) + { + const gl = this.gl; + const style = texture.style; + + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_S, style.wrapMode); + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_T, style.wrapMode); + + if(texture.mipmap) + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); + } + else + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } + + gl.texParameteri(texture.type, gl.TEXTURE_MAG_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } } \ No newline at end of file diff --git a/src/core/settings.js b/src/core/settings.js index f4dd087..7de1975 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -162,7 +162,7 @@ * @type {PIXI.WRAP_MODES} * @default PIXI.WRAP_MODES.CLAMP */ - WRAP_MODE: 0, + WRAP_MODE: 33071, /** * The scale modes that are supported by pixi. diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index f3e46c5..e9ab29c 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -110,11 +110,12 @@ } else if(uniformValues.${i}._new) { - uniformData.${i}.value = ${textureCount}; renderer.newTextureManager.bindTexture(uniformValues.${i}, ${textureCount}) - - gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len - + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } } else { diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js index eea3526..97b4f37 100644 --- a/src/core/textures/new/CubeTexture.js +++ b/src/core/textures/new/CubeTexture.js @@ -1,4 +1,5 @@ import Texture from './Texture'; +import ImageResource from './resources/ImageResource'; export default class CubeTexture extends Texture { @@ -7,12 +8,82 @@ super(width, height, format); this.isCube = true; + this.type = 34067; // gl.TEXTURE_CUBE_MAP - //this.side1 = {_glTextures:this.glTextures, id:1}; - //this.side2 = {_glTextures:this.glTextures, id:2}; - //this.side3 = {_glTextures:this.glTextures, id:3}; - //this.side4 = {_glTextures:this.glTextures, id:4}; - //this.side5 = {_glTextures:this.glTextures, id:5}; - //this.side6 = {_glTextures:this.glTextures, id:6}; + this.resources = []; + + this.positiveX = {side:0, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeX = {side:1, texture:this, resource:null, texturePart:true, dirtyId:0}; + + this.positiveY = {side:2, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeY = {side:3, texture:this, resource:null, texturePart:true, dirtyId:0}; + + this.positiveZ = {side:4, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeZ = {side:5, texture:this, resource:null, texturePart:true, dirtyId:0}; + + + this.sides = [this.positiveX, this.negativeX, + this.positiveY, this.negativeY, + this.positiveZ, this.negativeZ]; + } + + setResource(resource, index) + { + var side = this.sides[index]; + side.resource = resource; + + resource.load.then((resource) => { + + if(side.resource === resource) + { + this.width = resource.width; + this.height = resource.height; + // we have not swapped half way! + //side.dirtyId++; + this.validate(); + + this.dirtyId++; + } + + }) + } + + validate() + { + let valid = true; + + if(this.width === -1 || this.height === -1) + { + valid = false; + } + + if(this.sides) + { + for (var i = 0; i < this.sides.length; i++) { + + const side = this.sides[i]; + + if(side.resource && !side.resource.loaded) + { + valid = false; + break; + } + } + } + + + this.valid = valid; + } + + static from(...urls) + { + var cubeTexture = new CubeTexture(); + + for (var i = 0; i < 6; i++) + { + cubeTexture.setResource(ImageResource.from(urls[i % urls.length]), i); + } + + return cubeTexture; } } \ No newline at end of file diff --git a/src/core/textures/new/FrameBuffer.js b/src/core/textures/new/FrameBuffer.js index 004c84f..f67f458 100644 --- a/src/core/textures/new/FrameBuffer.js +++ b/src/core/textures/new/FrameBuffer.js @@ -34,6 +34,7 @@ return this; } + addDepthTexture() { this.depthTexture[0] = new Texture(this.width, this.height, 'depth');// || new Texture(); diff --git a/src/core/const.js b/src/core/const.js index 3de0efe..9cc0879 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -179,9 +179,9 @@ * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring */ export const WRAP_MODES = { - CLAMP: 0, - REPEAT: 1, - MIRRORED_REPEAT: 2, + CLAMP: 33071, + REPEAT: 10497, + MIRRORED_REPEAT: 33648, }; /** diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 308e959..d839dc6 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -48,7 +48,16 @@ this.updateFramebuffer(framebuffer); } - this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].glTextures[this.CONTEXT_UID]._bound) + if(framebuffer.colorTextures[0].texturePart) + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].texture) + } + else + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0]) + } } else { @@ -96,15 +105,30 @@ for (var i = 0; i < count; i++) { - const texture = framebuffer.colorTextures[i]; + let texture = framebuffer.colorTextures[i]; - this.renderer.newTextureManager.bindTexture(texture, 0); + if(texture.texturePart) + { + this.renderer.newTextureManager.bindTexture(texture.texture, 0); - const glTexture = texture.glTextures[this.CONTEXT_UID]; + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, + texture.texture.glTextures[this.CONTEXT_UID].texture, + 0); + } + else + { + this.renderer.newTextureManager.bindTexture(texture, 0); + + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_2D, + texture.glTextures[this.CONTEXT_UID].texture, + 0); + } activeTextures.push(gl.COLOR_ATTACHMENT0 + i); - - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, glTexture.texture, 0); } if(this.drawBufferExtension && activeTextures.length > 1) diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index 0b9e282..542a460 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -35,8 +35,24 @@ */ onContextChange() { - this.gl = this.renderer.gl; + const gl = this.gl = this.renderer.gl; this.CONTEXT_UID = this.renderer.CONTEXT_UID; + + // TODO move this.. to a nice make empty textures class.. + this.emptyTextures = {} + + this.emptyTextures[gl.TEXTURE_2D] = new GLTexture.fromData(this.gl, null, 1, 1); + this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(this.gl); + + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture); + + for (var i = 0; i < 6; i++) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); } bindTexture(texture, location) @@ -47,36 +63,37 @@ gl.activeTexture(gl.TEXTURE0 + location); - if(texture) + if(texture && texture.valid) { const glTexture = texture.glTextures[this.CONTEXT_UID] || this.initTexture(texture); - if(texture.isCube) + gl.bindTexture(texture.type, glTexture.texture); + + if(glTexture.dirtyId !== texture.dirtyId) { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, glTexture.texture); + glTexture.dirtyId = texture.dirtyId; + this.updateTexture(texture); } this.boundTextures[location] = texture; } else { - gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindTexture(texture.type, this.emptyTextures[texture.type].texture); this.boundTextures[location] = null; } } unbindTexture(texture) { + const gl = this.gl; + for (var i = 0; i < this.boundTextures.length; i++) { if(this.boundTextures[i] === texture) { - gl.activeTexture(gl.TEXTURE0 + location); - gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE0 + i); + gl.bindTexture(gl.TEXTURE_2D, this.emptyGLTexture.texture); this.boundTextures[i] = null; } } @@ -88,45 +105,73 @@ var glTexture = new GLTexture(this.gl); - if(texture.isCube) - { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - - glTexture.width = texture.width; - glTexture.height = texture.height; - - // upload the 6 faces.. - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex1); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex2); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex3); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex4); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex5); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex6); - - - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - } - else - { - glTexture.uploadData(null, texture.width, texture.height); - - // settings.. - glTexture.enableNearestScaling(); - glTexture.enableWrapClamp(); - } - - + // guarentee an update.. + glTexture.dirtyId = -1; texture.glTextures[this.CONTEXT_UID] = glTexture; return glTexture; } + + updateTexture(texture) + { + const glTexture = texture.glTextures[this.CONTEXT_UID]; + const gl = this.gl; + + // TODO there are only 3 textures as far as im aware? + // Cube / 2D and later 3d. (the latter is WebGL2, we will get to that soon!) + if(texture.type === gl.TEXTURE_CUBE_MAP) + { + + for (var i = 0; i < texture.sides.length; i++) + { + // TODO - we should only upload what changed.. + // but im sure this is not going to be a problem just yet! + var texturePart = texture.sides[i]; + + if(texturePart.resource) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, glTexture.format, glTexture.format, glTexture.type, texturePart.resource.source); + } + else + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, gl.RGBA, texture.width, texture.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + } + } + else + { + if(texture.resource) + { + glTexture.upload(texture.resource.source); + } + else + { + glTexture.uploadData(null, texture.width, texture.height); + } + } + + // lets only update what changes.. + this.setStyle(texture); + } + + setStyle(texture) + { + const gl = this.gl; + const style = texture.style; + + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_S, style.wrapMode); + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_T, style.wrapMode); + + if(texture.mipmap) + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); + } + else + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } + + gl.texParameteri(texture.type, gl.TEXTURE_MAG_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } } \ No newline at end of file diff --git a/src/core/settings.js b/src/core/settings.js index f4dd087..7de1975 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -162,7 +162,7 @@ * @type {PIXI.WRAP_MODES} * @default PIXI.WRAP_MODES.CLAMP */ - WRAP_MODE: 0, + WRAP_MODE: 33071, /** * The scale modes that are supported by pixi. diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index f3e46c5..e9ab29c 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -110,11 +110,12 @@ } else if(uniformValues.${i}._new) { - uniformData.${i}.value = ${textureCount}; renderer.newTextureManager.bindTexture(uniformValues.${i}, ${textureCount}) - - gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len - + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } } else { diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js index eea3526..97b4f37 100644 --- a/src/core/textures/new/CubeTexture.js +++ b/src/core/textures/new/CubeTexture.js @@ -1,4 +1,5 @@ import Texture from './Texture'; +import ImageResource from './resources/ImageResource'; export default class CubeTexture extends Texture { @@ -7,12 +8,82 @@ super(width, height, format); this.isCube = true; + this.type = 34067; // gl.TEXTURE_CUBE_MAP - //this.side1 = {_glTextures:this.glTextures, id:1}; - //this.side2 = {_glTextures:this.glTextures, id:2}; - //this.side3 = {_glTextures:this.glTextures, id:3}; - //this.side4 = {_glTextures:this.glTextures, id:4}; - //this.side5 = {_glTextures:this.glTextures, id:5}; - //this.side6 = {_glTextures:this.glTextures, id:6}; + this.resources = []; + + this.positiveX = {side:0, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeX = {side:1, texture:this, resource:null, texturePart:true, dirtyId:0}; + + this.positiveY = {side:2, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeY = {side:3, texture:this, resource:null, texturePart:true, dirtyId:0}; + + this.positiveZ = {side:4, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeZ = {side:5, texture:this, resource:null, texturePart:true, dirtyId:0}; + + + this.sides = [this.positiveX, this.negativeX, + this.positiveY, this.negativeY, + this.positiveZ, this.negativeZ]; + } + + setResource(resource, index) + { + var side = this.sides[index]; + side.resource = resource; + + resource.load.then((resource) => { + + if(side.resource === resource) + { + this.width = resource.width; + this.height = resource.height; + // we have not swapped half way! + //side.dirtyId++; + this.validate(); + + this.dirtyId++; + } + + }) + } + + validate() + { + let valid = true; + + if(this.width === -1 || this.height === -1) + { + valid = false; + } + + if(this.sides) + { + for (var i = 0; i < this.sides.length; i++) { + + const side = this.sides[i]; + + if(side.resource && !side.resource.loaded) + { + valid = false; + break; + } + } + } + + + this.valid = valid; + } + + static from(...urls) + { + var cubeTexture = new CubeTexture(); + + for (var i = 0; i < 6; i++) + { + cubeTexture.setResource(ImageResource.from(urls[i % urls.length]), i); + } + + return cubeTexture; } } \ No newline at end of file diff --git a/src/core/textures/new/FrameBuffer.js b/src/core/textures/new/FrameBuffer.js index 004c84f..f67f458 100644 --- a/src/core/textures/new/FrameBuffer.js +++ b/src/core/textures/new/FrameBuffer.js @@ -34,6 +34,7 @@ return this; } + addDepthTexture() { this.depthTexture[0] = new Texture(this.width, this.height, 'depth');// || new Texture(); diff --git a/src/core/textures/new/Texture.js b/src/core/textures/new/Texture.js index ae8db17..a120a09 100644 --- a/src/core/textures/new/Texture.js +++ b/src/core/textures/new/Texture.js @@ -1,4 +1,5 @@ import TextureStyle from './TextureStyle'; +import ImageResource from './resources/ImageResource'; export default class Texture { @@ -7,6 +8,7 @@ this.style = new TextureStyle(); + /** * The width of texture * @@ -30,7 +32,63 @@ this.data = null; this.glTextures = {}; - this.isCube = false; + this._new = true; + + this.resource = null; + + this.type = 3553;// gl.TEXTURE_2D + + this.dirtyId = 0; + + this.valid = false; + + this.validate(); + } + + setResource(resource) + { + this.resource = resource; + + this.resource.load.then((resource) => { + + if(this.resource === resource) + { + this.width = resource.width; + this.height = resource.height; + + this.validate(); + + if(this.valid) + { + // we have not swapped half way! + this.dirtyId++; + } + } + + }) + } + + validate() + { + let valid = true; + + if(this.width === -1 || this.height === -1) + { + valid = false; + } + + this.valid = valid; + } + + static from(url) + { + var texture = new Texture(); + + var image = new Image(); + image.src = url; + texture.setResource(new ImageResource(image)); + + return texture; } } \ No newline at end of file diff --git a/src/core/const.js b/src/core/const.js index 3de0efe..9cc0879 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -179,9 +179,9 @@ * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring */ export const WRAP_MODES = { - CLAMP: 0, - REPEAT: 1, - MIRRORED_REPEAT: 2, + CLAMP: 33071, + REPEAT: 10497, + MIRRORED_REPEAT: 33648, }; /** diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 308e959..d839dc6 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -48,7 +48,16 @@ this.updateFramebuffer(framebuffer); } - this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].glTextures[this.CONTEXT_UID]._bound) + if(framebuffer.colorTextures[0].texturePart) + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].texture) + } + else + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0]) + } } else { @@ -96,15 +105,30 @@ for (var i = 0; i < count; i++) { - const texture = framebuffer.colorTextures[i]; + let texture = framebuffer.colorTextures[i]; - this.renderer.newTextureManager.bindTexture(texture, 0); + if(texture.texturePart) + { + this.renderer.newTextureManager.bindTexture(texture.texture, 0); - const glTexture = texture.glTextures[this.CONTEXT_UID]; + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, + texture.texture.glTextures[this.CONTEXT_UID].texture, + 0); + } + else + { + this.renderer.newTextureManager.bindTexture(texture, 0); + + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_2D, + texture.glTextures[this.CONTEXT_UID].texture, + 0); + } activeTextures.push(gl.COLOR_ATTACHMENT0 + i); - - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, glTexture.texture, 0); } if(this.drawBufferExtension && activeTextures.length > 1) diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index 0b9e282..542a460 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -35,8 +35,24 @@ */ onContextChange() { - this.gl = this.renderer.gl; + const gl = this.gl = this.renderer.gl; this.CONTEXT_UID = this.renderer.CONTEXT_UID; + + // TODO move this.. to a nice make empty textures class.. + this.emptyTextures = {} + + this.emptyTextures[gl.TEXTURE_2D] = new GLTexture.fromData(this.gl, null, 1, 1); + this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(this.gl); + + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture); + + for (var i = 0; i < 6; i++) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); } bindTexture(texture, location) @@ -47,36 +63,37 @@ gl.activeTexture(gl.TEXTURE0 + location); - if(texture) + if(texture && texture.valid) { const glTexture = texture.glTextures[this.CONTEXT_UID] || this.initTexture(texture); - if(texture.isCube) + gl.bindTexture(texture.type, glTexture.texture); + + if(glTexture.dirtyId !== texture.dirtyId) { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, glTexture.texture); + glTexture.dirtyId = texture.dirtyId; + this.updateTexture(texture); } this.boundTextures[location] = texture; } else { - gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindTexture(texture.type, this.emptyTextures[texture.type].texture); this.boundTextures[location] = null; } } unbindTexture(texture) { + const gl = this.gl; + for (var i = 0; i < this.boundTextures.length; i++) { if(this.boundTextures[i] === texture) { - gl.activeTexture(gl.TEXTURE0 + location); - gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE0 + i); + gl.bindTexture(gl.TEXTURE_2D, this.emptyGLTexture.texture); this.boundTextures[i] = null; } } @@ -88,45 +105,73 @@ var glTexture = new GLTexture(this.gl); - if(texture.isCube) - { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - - glTexture.width = texture.width; - glTexture.height = texture.height; - - // upload the 6 faces.. - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex1); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex2); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex3); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex4); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex5); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex6); - - - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - } - else - { - glTexture.uploadData(null, texture.width, texture.height); - - // settings.. - glTexture.enableNearestScaling(); - glTexture.enableWrapClamp(); - } - - + // guarentee an update.. + glTexture.dirtyId = -1; texture.glTextures[this.CONTEXT_UID] = glTexture; return glTexture; } + + updateTexture(texture) + { + const glTexture = texture.glTextures[this.CONTEXT_UID]; + const gl = this.gl; + + // TODO there are only 3 textures as far as im aware? + // Cube / 2D and later 3d. (the latter is WebGL2, we will get to that soon!) + if(texture.type === gl.TEXTURE_CUBE_MAP) + { + + for (var i = 0; i < texture.sides.length; i++) + { + // TODO - we should only upload what changed.. + // but im sure this is not going to be a problem just yet! + var texturePart = texture.sides[i]; + + if(texturePart.resource) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, glTexture.format, glTexture.format, glTexture.type, texturePart.resource.source); + } + else + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, gl.RGBA, texture.width, texture.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + } + } + else + { + if(texture.resource) + { + glTexture.upload(texture.resource.source); + } + else + { + glTexture.uploadData(null, texture.width, texture.height); + } + } + + // lets only update what changes.. + this.setStyle(texture); + } + + setStyle(texture) + { + const gl = this.gl; + const style = texture.style; + + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_S, style.wrapMode); + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_T, style.wrapMode); + + if(texture.mipmap) + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); + } + else + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } + + gl.texParameteri(texture.type, gl.TEXTURE_MAG_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } } \ No newline at end of file diff --git a/src/core/settings.js b/src/core/settings.js index f4dd087..7de1975 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -162,7 +162,7 @@ * @type {PIXI.WRAP_MODES} * @default PIXI.WRAP_MODES.CLAMP */ - WRAP_MODE: 0, + WRAP_MODE: 33071, /** * The scale modes that are supported by pixi. diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index f3e46c5..e9ab29c 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -110,11 +110,12 @@ } else if(uniformValues.${i}._new) { - uniformData.${i}.value = ${textureCount}; renderer.newTextureManager.bindTexture(uniformValues.${i}, ${textureCount}) - - gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len - + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } } else { diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js index eea3526..97b4f37 100644 --- a/src/core/textures/new/CubeTexture.js +++ b/src/core/textures/new/CubeTexture.js @@ -1,4 +1,5 @@ import Texture from './Texture'; +import ImageResource from './resources/ImageResource'; export default class CubeTexture extends Texture { @@ -7,12 +8,82 @@ super(width, height, format); this.isCube = true; + this.type = 34067; // gl.TEXTURE_CUBE_MAP - //this.side1 = {_glTextures:this.glTextures, id:1}; - //this.side2 = {_glTextures:this.glTextures, id:2}; - //this.side3 = {_glTextures:this.glTextures, id:3}; - //this.side4 = {_glTextures:this.glTextures, id:4}; - //this.side5 = {_glTextures:this.glTextures, id:5}; - //this.side6 = {_glTextures:this.glTextures, id:6}; + this.resources = []; + + this.positiveX = {side:0, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeX = {side:1, texture:this, resource:null, texturePart:true, dirtyId:0}; + + this.positiveY = {side:2, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeY = {side:3, texture:this, resource:null, texturePart:true, dirtyId:0}; + + this.positiveZ = {side:4, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeZ = {side:5, texture:this, resource:null, texturePart:true, dirtyId:0}; + + + this.sides = [this.positiveX, this.negativeX, + this.positiveY, this.negativeY, + this.positiveZ, this.negativeZ]; + } + + setResource(resource, index) + { + var side = this.sides[index]; + side.resource = resource; + + resource.load.then((resource) => { + + if(side.resource === resource) + { + this.width = resource.width; + this.height = resource.height; + // we have not swapped half way! + //side.dirtyId++; + this.validate(); + + this.dirtyId++; + } + + }) + } + + validate() + { + let valid = true; + + if(this.width === -1 || this.height === -1) + { + valid = false; + } + + if(this.sides) + { + for (var i = 0; i < this.sides.length; i++) { + + const side = this.sides[i]; + + if(side.resource && !side.resource.loaded) + { + valid = false; + break; + } + } + } + + + this.valid = valid; + } + + static from(...urls) + { + var cubeTexture = new CubeTexture(); + + for (var i = 0; i < 6; i++) + { + cubeTexture.setResource(ImageResource.from(urls[i % urls.length]), i); + } + + return cubeTexture; } } \ No newline at end of file diff --git a/src/core/textures/new/FrameBuffer.js b/src/core/textures/new/FrameBuffer.js index 004c84f..f67f458 100644 --- a/src/core/textures/new/FrameBuffer.js +++ b/src/core/textures/new/FrameBuffer.js @@ -34,6 +34,7 @@ return this; } + addDepthTexture() { this.depthTexture[0] = new Texture(this.width, this.height, 'depth');// || new Texture(); diff --git a/src/core/textures/new/Texture.js b/src/core/textures/new/Texture.js index ae8db17..a120a09 100644 --- a/src/core/textures/new/Texture.js +++ b/src/core/textures/new/Texture.js @@ -1,4 +1,5 @@ import TextureStyle from './TextureStyle'; +import ImageResource from './resources/ImageResource'; export default class Texture { @@ -7,6 +8,7 @@ this.style = new TextureStyle(); + /** * The width of texture * @@ -30,7 +32,63 @@ this.data = null; this.glTextures = {}; - this.isCube = false; + this._new = true; + + this.resource = null; + + this.type = 3553;// gl.TEXTURE_2D + + this.dirtyId = 0; + + this.valid = false; + + this.validate(); + } + + setResource(resource) + { + this.resource = resource; + + this.resource.load.then((resource) => { + + if(this.resource === resource) + { + this.width = resource.width; + this.height = resource.height; + + this.validate(); + + if(this.valid) + { + // we have not swapped half way! + this.dirtyId++; + } + } + + }) + } + + validate() + { + let valid = true; + + if(this.width === -1 || this.height === -1) + { + valid = false; + } + + this.valid = valid; + } + + static from(url) + { + var texture = new Texture(); + + var image = new Image(); + image.src = url; + texture.setResource(new ImageResource(image)); + + return texture; } } \ No newline at end of file diff --git a/src/core/textures/new/resources/BufferResource.js b/src/core/textures/new/resources/BufferResource.js new file mode 100644 index 0000000..4955d45 --- /dev/null +++ b/src/core/textures/new/resources/BufferResource.js @@ -0,0 +1,24 @@ + +export default class BufferResource +{ + constructor(source) + { + this.source = source; + this.loaded = false; // TODO rename to ready? + this.width = 1; + this.height = 1; + + this.load = new Promise((resolve, reject) => { + + resolve(this); + + }) + } + + static from(array) + { + return new BufferResource(array); + } + + +} \ No newline at end of file diff --git a/src/core/const.js b/src/core/const.js index 3de0efe..9cc0879 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -179,9 +179,9 @@ * @property {number} MIRRORED_REPEAT - The texture uvs tile and repeat with mirroring */ export const WRAP_MODES = { - CLAMP: 0, - REPEAT: 1, - MIRRORED_REPEAT: 2, + CLAMP: 33071, + REPEAT: 10497, + MIRRORED_REPEAT: 33648, }; /** diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 308e959..d839dc6 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -48,7 +48,16 @@ this.updateFramebuffer(framebuffer); } - this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].glTextures[this.CONTEXT_UID]._bound) + if(framebuffer.colorTextures[0].texturePart) + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0].texture) + } + else + { + + this.renderer.newTextureManager.unbindTexture(framebuffer.colorTextures[0]) + } } else { @@ -96,15 +105,30 @@ for (var i = 0; i < count; i++) { - const texture = framebuffer.colorTextures[i]; + let texture = framebuffer.colorTextures[i]; - this.renderer.newTextureManager.bindTexture(texture, 0); + if(texture.texturePart) + { + this.renderer.newTextureManager.bindTexture(texture.texture, 0); - const glTexture = texture.glTextures[this.CONTEXT_UID]; + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, + texture.texture.glTextures[this.CONTEXT_UID].texture, + 0); + } + else + { + this.renderer.newTextureManager.bindTexture(texture, 0); + + gl.framebufferTexture2D(gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.TEXTURE_2D, + texture.glTextures[this.CONTEXT_UID].texture, + 0); + } activeTextures.push(gl.COLOR_ATTACHMENT0 + i); - - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, glTexture.texture, 0); } if(this.drawBufferExtension && activeTextures.length > 1) diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index 0b9e282..542a460 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -35,8 +35,24 @@ */ onContextChange() { - this.gl = this.renderer.gl; + const gl = this.gl = this.renderer.gl; this.CONTEXT_UID = this.renderer.CONTEXT_UID; + + // TODO move this.. to a nice make empty textures class.. + this.emptyTextures = {} + + this.emptyTextures[gl.TEXTURE_2D] = new GLTexture.fromData(this.gl, null, 1, 1); + this.emptyTextures[gl.TEXTURE_CUBE_MAP] = new GLTexture(this.gl); + + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.emptyTextures[gl.TEXTURE_CUBE_MAP].texture); + + for (var i = 0; i < 6; i++) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); } bindTexture(texture, location) @@ -47,36 +63,37 @@ gl.activeTexture(gl.TEXTURE0 + location); - if(texture) + if(texture && texture.valid) { const glTexture = texture.glTextures[this.CONTEXT_UID] || this.initTexture(texture); - if(texture.isCube) + gl.bindTexture(texture.type, glTexture.texture); + + if(glTexture.dirtyId !== texture.dirtyId) { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - } - else - { - gl.bindTexture(gl.TEXTURE_2D, glTexture.texture); + glTexture.dirtyId = texture.dirtyId; + this.updateTexture(texture); } this.boundTextures[location] = texture; } else { - gl.bindTexture(gl.TEXTURE_2D, null); + gl.bindTexture(texture.type, this.emptyTextures[texture.type].texture); this.boundTextures[location] = null; } } unbindTexture(texture) { + const gl = this.gl; + for (var i = 0; i < this.boundTextures.length; i++) { if(this.boundTextures[i] === texture) { - gl.activeTexture(gl.TEXTURE0 + location); - gl.bindTexture(gl.TEXTURE_2D, null); + gl.activeTexture(gl.TEXTURE0 + i); + gl.bindTexture(gl.TEXTURE_2D, this.emptyGLTexture.texture); this.boundTextures[i] = null; } } @@ -88,45 +105,73 @@ var glTexture = new GLTexture(this.gl); - if(texture.isCube) - { - gl.bindTexture(gl.TEXTURE_CUBE_MAP, glTexture.texture); - - glTexture.width = texture.width; - glTexture.height = texture.height; - - // upload the 6 faces.. - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.width, glTexture.height, 0, glTexture.format, glTexture.type, null); - - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex1); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, glTexture.format, glTexture.format, glTexture.type, window.tex2); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex3); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, glTexture.format, glTexture.format, glTexture.type, window.tex4); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex5); - gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, glTexture.format, glTexture.format, glTexture.type, window.tex6); - - - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - } - else - { - glTexture.uploadData(null, texture.width, texture.height); - - // settings.. - glTexture.enableNearestScaling(); - glTexture.enableWrapClamp(); - } - - + // guarentee an update.. + glTexture.dirtyId = -1; texture.glTextures[this.CONTEXT_UID] = glTexture; return glTexture; } + + updateTexture(texture) + { + const glTexture = texture.glTextures[this.CONTEXT_UID]; + const gl = this.gl; + + // TODO there are only 3 textures as far as im aware? + // Cube / 2D and later 3d. (the latter is WebGL2, we will get to that soon!) + if(texture.type === gl.TEXTURE_CUBE_MAP) + { + + for (var i = 0; i < texture.sides.length; i++) + { + // TODO - we should only upload what changed.. + // but im sure this is not going to be a problem just yet! + var texturePart = texture.sides[i]; + + if(texturePart.resource) + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, glTexture.format, glTexture.format, glTexture.type, texturePart.resource.source); + } + else + { + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + texturePart.side, 0, gl.RGBA, texture.width, texture.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + } + } + else + { + if(texture.resource) + { + glTexture.upload(texture.resource.source); + } + else + { + glTexture.uploadData(null, texture.width, texture.height); + } + } + + // lets only update what changes.. + this.setStyle(texture); + } + + setStyle(texture) + { + const gl = this.gl; + const style = texture.style; + + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_S, style.wrapMode); + gl.texParameteri(texture.type, gl.TEXTURE_WRAP_T, style.wrapMode); + + if(texture.mipmap) + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST); + } + else + { + gl.texParameteri(texture.type, gl.TEXTURE_MIN_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } + + gl.texParameteri(texture.type, gl.TEXTURE_MAG_FILTER, style.scaleMode ? gl.LINEAR : gl.NEAREST); + } } \ No newline at end of file diff --git a/src/core/settings.js b/src/core/settings.js index f4dd087..7de1975 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -162,7 +162,7 @@ * @type {PIXI.WRAP_MODES} * @default PIXI.WRAP_MODES.CLAMP */ - WRAP_MODE: 0, + WRAP_MODE: 33071, /** * The scale modes that are supported by pixi. diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index f3e46c5..e9ab29c 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -110,11 +110,12 @@ } else if(uniformValues.${i}._new) { - uniformData.${i}.value = ${textureCount}; renderer.newTextureManager.bindTexture(uniformValues.${i}, ${textureCount}) - - gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len - + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } } else { diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js index eea3526..97b4f37 100644 --- a/src/core/textures/new/CubeTexture.js +++ b/src/core/textures/new/CubeTexture.js @@ -1,4 +1,5 @@ import Texture from './Texture'; +import ImageResource from './resources/ImageResource'; export default class CubeTexture extends Texture { @@ -7,12 +8,82 @@ super(width, height, format); this.isCube = true; + this.type = 34067; // gl.TEXTURE_CUBE_MAP - //this.side1 = {_glTextures:this.glTextures, id:1}; - //this.side2 = {_glTextures:this.glTextures, id:2}; - //this.side3 = {_glTextures:this.glTextures, id:3}; - //this.side4 = {_glTextures:this.glTextures, id:4}; - //this.side5 = {_glTextures:this.glTextures, id:5}; - //this.side6 = {_glTextures:this.glTextures, id:6}; + this.resources = []; + + this.positiveX = {side:0, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeX = {side:1, texture:this, resource:null, texturePart:true, dirtyId:0}; + + this.positiveY = {side:2, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeY = {side:3, texture:this, resource:null, texturePart:true, dirtyId:0}; + + this.positiveZ = {side:4, texture:this, resource:null, texturePart:true, dirtyId:0}; + this.negativeZ = {side:5, texture:this, resource:null, texturePart:true, dirtyId:0}; + + + this.sides = [this.positiveX, this.negativeX, + this.positiveY, this.negativeY, + this.positiveZ, this.negativeZ]; + } + + setResource(resource, index) + { + var side = this.sides[index]; + side.resource = resource; + + resource.load.then((resource) => { + + if(side.resource === resource) + { + this.width = resource.width; + this.height = resource.height; + // we have not swapped half way! + //side.dirtyId++; + this.validate(); + + this.dirtyId++; + } + + }) + } + + validate() + { + let valid = true; + + if(this.width === -1 || this.height === -1) + { + valid = false; + } + + if(this.sides) + { + for (var i = 0; i < this.sides.length; i++) { + + const side = this.sides[i]; + + if(side.resource && !side.resource.loaded) + { + valid = false; + break; + } + } + } + + + this.valid = valid; + } + + static from(...urls) + { + var cubeTexture = new CubeTexture(); + + for (var i = 0; i < 6; i++) + { + cubeTexture.setResource(ImageResource.from(urls[i % urls.length]), i); + } + + return cubeTexture; } } \ No newline at end of file diff --git a/src/core/textures/new/FrameBuffer.js b/src/core/textures/new/FrameBuffer.js index 004c84f..f67f458 100644 --- a/src/core/textures/new/FrameBuffer.js +++ b/src/core/textures/new/FrameBuffer.js @@ -34,6 +34,7 @@ return this; } + addDepthTexture() { this.depthTexture[0] = new Texture(this.width, this.height, 'depth');// || new Texture(); diff --git a/src/core/textures/new/Texture.js b/src/core/textures/new/Texture.js index ae8db17..a120a09 100644 --- a/src/core/textures/new/Texture.js +++ b/src/core/textures/new/Texture.js @@ -1,4 +1,5 @@ import TextureStyle from './TextureStyle'; +import ImageResource from './resources/ImageResource'; export default class Texture { @@ -7,6 +8,7 @@ this.style = new TextureStyle(); + /** * The width of texture * @@ -30,7 +32,63 @@ this.data = null; this.glTextures = {}; - this.isCube = false; + this._new = true; + + this.resource = null; + + this.type = 3553;// gl.TEXTURE_2D + + this.dirtyId = 0; + + this.valid = false; + + this.validate(); + } + + setResource(resource) + { + this.resource = resource; + + this.resource.load.then((resource) => { + + if(this.resource === resource) + { + this.width = resource.width; + this.height = resource.height; + + this.validate(); + + if(this.valid) + { + // we have not swapped half way! + this.dirtyId++; + } + } + + }) + } + + validate() + { + let valid = true; + + if(this.width === -1 || this.height === -1) + { + valid = false; + } + + this.valid = valid; + } + + static from(url) + { + var texture = new Texture(); + + var image = new Image(); + image.src = url; + texture.setResource(new ImageResource(image)); + + return texture; } } \ No newline at end of file diff --git a/src/core/textures/new/resources/BufferResource.js b/src/core/textures/new/resources/BufferResource.js new file mode 100644 index 0000000..4955d45 --- /dev/null +++ b/src/core/textures/new/resources/BufferResource.js @@ -0,0 +1,24 @@ + +export default class BufferResource +{ + constructor(source) + { + this.source = source; + this.loaded = false; // TODO rename to ready? + this.width = 1; + this.height = 1; + + this.load = new Promise((resolve, reject) => { + + resolve(this); + + }) + } + + static from(array) + { + return new BufferResource(array); + } + + +} \ No newline at end of file diff --git a/src/core/textures/new/resources/ImageResource.js b/src/core/textures/new/resources/ImageResource.js new file mode 100644 index 0000000..07944b6 --- /dev/null +++ b/src/core/textures/new/resources/ImageResource.js @@ -0,0 +1,44 @@ + +export default class ImageResource +{ + constructor(source) + { + this.source = source; + this.loaded = false; // TODO rename to ready? + this.width = 1; + this.height = 1; + + this.load = new Promise((resolve, reject) => { + + const source = this.source; + + source.onload = () => { + this.loaded = true; + source.onload = null; + source.onerror = null; + this.width = source.width; + this.height = source.height; + resolve(this); + } + + if(source.complete && source.src) + { + this.loaded = true; + source.onload = null; + source.onerror = null; + this.width = source.width; + this.height = source.height; + resolve(this); + } + }) + } + + static from(url) + { + var image = new Image(); + image.src = url; + return new ImageResource(image); + } + + +} \ No newline at end of file