diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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 fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 4646716..fdd1886 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -1,8 +1,10 @@ import BaseTexture from './BaseTexture'; import VideoBaseTexture from './VideoBaseTexture'; import ImageResource from './resources/ImageResource'; +import CanvasResource from './resources/CanvasResource'; import TextureUvs from './TextureUvs'; import EventEmitter from 'eventemitter3'; +import settings from '../settings'; import { Rectangle } from '../math'; import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; @@ -443,10 +445,11 @@ { const resource = new ImageResource(source);//.from(imageUrl, crossorigin);// document.createElement('img'); - const baseTexture = new BaseTexture();//image, scaleMode); - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(resource); + const baseTexture = new BaseTexture(resource, + settings.SCALE_MODE, + getResolutionOfUrl(imageUrl)); + console.log(baseTexture) const texture = new Texture(baseTexture); // No name, use imageUrl instead @@ -591,7 +594,7 @@ context.fillStyle = 'white'; context.fillRect(0, 0, 10, 10); - return new Texture(new BaseTexture(canvas)); + return new Texture(new BaseTexture(new CanvasResource(canvas))); } function removeAllHandlers(tex) diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 4646716..fdd1886 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -1,8 +1,10 @@ import BaseTexture from './BaseTexture'; import VideoBaseTexture from './VideoBaseTexture'; import ImageResource from './resources/ImageResource'; +import CanvasResource from './resources/CanvasResource'; import TextureUvs from './TextureUvs'; import EventEmitter from 'eventemitter3'; +import settings from '../settings'; import { Rectangle } from '../math'; import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; @@ -443,10 +445,11 @@ { const resource = new ImageResource(source);//.from(imageUrl, crossorigin);// document.createElement('img'); - const baseTexture = new BaseTexture();//image, scaleMode); - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(resource); + const baseTexture = new BaseTexture(resource, + settings.SCALE_MODE, + getResolutionOfUrl(imageUrl)); + console.log(baseTexture) const texture = new Texture(baseTexture); // No name, use imageUrl instead @@ -591,7 +594,7 @@ context.fillStyle = 'white'; context.fillRect(0, 0, 10, 10); - return new Texture(new BaseTexture(canvas)); + return new Texture(new BaseTexture(new CanvasResource(canvas))); } function removeAllHandlers(tex) diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js deleted file mode 100644 index c3cde40..0000000 --- a/src/core/textures/new/CubeTexture.js +++ /dev/null @@ -1,88 +0,0 @@ -import Texture from '../BaseTexture'; -import ImageResource from '../resources/ImageResource'; - -export default class CubeTexture extends Texture -{ - constructor(width, height, format) - { - super(width, height, format); - - this.target = 34067; // gl.TEXTURE_CUBE_MAP - - 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 fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 4646716..fdd1886 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -1,8 +1,10 @@ import BaseTexture from './BaseTexture'; import VideoBaseTexture from './VideoBaseTexture'; import ImageResource from './resources/ImageResource'; +import CanvasResource from './resources/CanvasResource'; import TextureUvs from './TextureUvs'; import EventEmitter from 'eventemitter3'; +import settings from '../settings'; import { Rectangle } from '../math'; import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; @@ -443,10 +445,11 @@ { const resource = new ImageResource(source);//.from(imageUrl, crossorigin);// document.createElement('img'); - const baseTexture = new BaseTexture();//image, scaleMode); - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(resource); + const baseTexture = new BaseTexture(resource, + settings.SCALE_MODE, + getResolutionOfUrl(imageUrl)); + console.log(baseTexture) const texture = new Texture(baseTexture); // No name, use imageUrl instead @@ -591,7 +594,7 @@ context.fillStyle = 'white'; context.fillRect(0, 0, 10, 10); - return new Texture(new BaseTexture(canvas)); + return new Texture(new BaseTexture(new CanvasResource(canvas))); } function removeAllHandlers(tex) diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js deleted file mode 100644 index c3cde40..0000000 --- a/src/core/textures/new/CubeTexture.js +++ /dev/null @@ -1,88 +0,0 @@ -import Texture from '../BaseTexture'; -import ImageResource from '../resources/ImageResource'; - -export default class CubeTexture extends Texture -{ - constructor(width, height, format) - { - super(width, height, format); - - this.target = 34067; // gl.TEXTURE_CUBE_MAP - - 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 deleted file mode 100644 index 10e7364..0000000 --- a/src/core/textures/new/FrameBuffer.js +++ /dev/null @@ -1,92 +0,0 @@ -import Texture from './Texture' - - -export default class FrameBuffer -{ - constructor(width, height) - { - this.width = width || 100; - this.height = height || 100; - - this.stencil = false; - this.depth = false; - - this.dirtyId = 0; - this.dirtyFormat = 0; - this.dirtySize = 0; - - this.depthTexture = null; - this.colorTextures = []; - - this.glFrameBuffers = {}; - } - - get colorTexture() - { - return this.colorTextures[0]; - } - - addColorTexture(index, texture) - { - // TODO add some validation to the texture - same width / height etc? - this.colorTextures[index || 0] = texture || new Texture(this.width, this.height);// || new Texture(); - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - - addDepthTexture(texture) - { - this.depthTexture = texture || new Texture(this.width, this.height, 6402, 5123)//UNSIGNED_SHORT; - - - this.dirtyId++; - this.dirtyFormat++; - return this; - } - - enableDepth() - { - this.depth = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - enableStencil() - { - this.stencil = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - resize(width, height) - { - if(width === this.width && height === this.height)return; - - this.width = width; - this.height = height; - - this.dirtyId++; - this.dirtySize++; - - for (var i = 0; i < this.colorTextures.length; i++) { - this.colorTextures[i].resize(width, height); - } - - if(this.depthTexture) - { - this.depthTexture.resize(width, height) - } - } - - -} \ No newline at end of file diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 4646716..fdd1886 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -1,8 +1,10 @@ import BaseTexture from './BaseTexture'; import VideoBaseTexture from './VideoBaseTexture'; import ImageResource from './resources/ImageResource'; +import CanvasResource from './resources/CanvasResource'; import TextureUvs from './TextureUvs'; import EventEmitter from 'eventemitter3'; +import settings from '../settings'; import { Rectangle } from '../math'; import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; @@ -443,10 +445,11 @@ { const resource = new ImageResource(source);//.from(imageUrl, crossorigin);// document.createElement('img'); - const baseTexture = new BaseTexture();//image, scaleMode); - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(resource); + const baseTexture = new BaseTexture(resource, + settings.SCALE_MODE, + getResolutionOfUrl(imageUrl)); + console.log(baseTexture) const texture = new Texture(baseTexture); // No name, use imageUrl instead @@ -591,7 +594,7 @@ context.fillStyle = 'white'; context.fillRect(0, 0, 10, 10); - return new Texture(new BaseTexture(canvas)); + return new Texture(new BaseTexture(new CanvasResource(canvas))); } function removeAllHandlers(tex) diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js deleted file mode 100644 index c3cde40..0000000 --- a/src/core/textures/new/CubeTexture.js +++ /dev/null @@ -1,88 +0,0 @@ -import Texture from '../BaseTexture'; -import ImageResource from '../resources/ImageResource'; - -export default class CubeTexture extends Texture -{ - constructor(width, height, format) - { - super(width, height, format); - - this.target = 34067; // gl.TEXTURE_CUBE_MAP - - 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 deleted file mode 100644 index 10e7364..0000000 --- a/src/core/textures/new/FrameBuffer.js +++ /dev/null @@ -1,92 +0,0 @@ -import Texture from './Texture' - - -export default class FrameBuffer -{ - constructor(width, height) - { - this.width = width || 100; - this.height = height || 100; - - this.stencil = false; - this.depth = false; - - this.dirtyId = 0; - this.dirtyFormat = 0; - this.dirtySize = 0; - - this.depthTexture = null; - this.colorTextures = []; - - this.glFrameBuffers = {}; - } - - get colorTexture() - { - return this.colorTextures[0]; - } - - addColorTexture(index, texture) - { - // TODO add some validation to the texture - same width / height etc? - this.colorTextures[index || 0] = texture || new Texture(this.width, this.height);// || new Texture(); - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - - addDepthTexture(texture) - { - this.depthTexture = texture || new Texture(this.width, this.height, 6402, 5123)//UNSIGNED_SHORT; - - - this.dirtyId++; - this.dirtyFormat++; - return this; - } - - enableDepth() - { - this.depth = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - enableStencil() - { - this.stencil = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - resize(width, height) - { - if(width === this.width && height === this.height)return; - - this.width = width; - this.height = height; - - this.dirtyId++; - this.dirtySize++; - - for (var i = 0; i < this.colorTextures.length; i++) { - this.colorTextures[i].resize(width, height); - } - - if(this.depthTexture) - { - this.depthTexture.resize(width, height) - } - } - - -} \ No newline at end of file diff --git a/src/core/textures/new/Texture.js b/src/core/textures/new/Texture.js deleted file mode 100644 index b4d849f..0000000 --- a/src/core/textures/new/Texture.js +++ /dev/null @@ -1,294 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../../utils'; - -import ImageResource from '../resources/ImageResource'; -import BufferResource from '../resources/BufferResource'; -import settings from '../../settings'; -import EventEmitter from 'eventemitter3'; - -export default class Texture extends EventEmitter -{ - constructor(width, height, format, type, resolution) - { - - super(); - - - this.uid = uid(); - - this.touched = 0; - - /** - * The width of texture - * - * @member {Number} - */ - this.width = width || -1; - /** - * The height of texture - * - * @member {Number} - */ - this.height = height || -1; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - /** - * If mipmapping was used for this texture, enable and disable with enableMipmap() - * - * @member {Boolean} - */ - this.mipmap = false;//settings.MIPMAP_TEXTURES; - - /** - * Set to true to enable pre-multiplied alpha - * - * @member {Boolean} - */ - this.premultiplyAlpha = true; - - /** - * [wrapMode description] - * @type {[type]} - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = settings.SCALE_MODE; - - /** - * The pixel format of the texture. defaults to gl.RGBA - * - * @member {Number} - */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE - - this.target = 3553; // gl.TEXTURE_2D - - this.glTextures = {}; - - this._new = true; - - this.resource = null; - - - - this.dirtyId = 0; - - this.valid = false; - - this.validate(); - } - - get realWidth() - { - return this.width / this.resolution; - } - - get realHeight() - { - return this.height / this.resolution; - } - - setResource(resource) - { - this.resource = resource; - - this.resource.load.then((resource) => { - - if(this.resource === resource) - { - if(resource.width !== -1 && resource.hight !== -1) - { - this.width = resource.width; - this.height = resource.height; - } - - this.validate(); - - if(this.valid) - { - // we have not swapped half way! - this.dirtyId++; - } - } - - }) - } - - resize(width, height) - { - this.width = width; - this.height = height; - - this.dirtyId++; - } - - validate() - { - let valid = true; - - if(this.width === -1 || this.height === -1) - { - valid = false; - } - - this.valid = valid; - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const resource = ImageResource.from(imageUrl, crossorigin);// document.createElement('img'); - - baseTexture = new Texture();//image, scaleMode); - - baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(new ImageResource(image)); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } - - static fromFloat32Array(width, height, float32Array) - { - var texture = new Texture(width, height, 6408, 5126); - - float32Array = float32Array || new Float32Array(width*height*4); - - texture.setResource(new BufferResource(float32Array)); - - return texture; - } - - static fromUint8Array(width, height, uint8Array) - { - var texture = new Texture(width, height, 6408, 5121); - - uint8Array = uint8Array || new Uint8Array(width*height*4); - - texture.setResource(new BufferResource(uint8Array)); - - return texture; - } - -} \ No newline at end of file diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 4646716..fdd1886 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -1,8 +1,10 @@ import BaseTexture from './BaseTexture'; import VideoBaseTexture from './VideoBaseTexture'; import ImageResource from './resources/ImageResource'; +import CanvasResource from './resources/CanvasResource'; import TextureUvs from './TextureUvs'; import EventEmitter from 'eventemitter3'; +import settings from '../settings'; import { Rectangle } from '../math'; import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; @@ -443,10 +445,11 @@ { const resource = new ImageResource(source);//.from(imageUrl, crossorigin);// document.createElement('img'); - const baseTexture = new BaseTexture();//image, scaleMode); - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(resource); + const baseTexture = new BaseTexture(resource, + settings.SCALE_MODE, + getResolutionOfUrl(imageUrl)); + console.log(baseTexture) const texture = new Texture(baseTexture); // No name, use imageUrl instead @@ -591,7 +594,7 @@ context.fillStyle = 'white'; context.fillRect(0, 0, 10, 10); - return new Texture(new BaseTexture(canvas)); + return new Texture(new BaseTexture(new CanvasResource(canvas))); } function removeAllHandlers(tex) diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js deleted file mode 100644 index c3cde40..0000000 --- a/src/core/textures/new/CubeTexture.js +++ /dev/null @@ -1,88 +0,0 @@ -import Texture from '../BaseTexture'; -import ImageResource from '../resources/ImageResource'; - -export default class CubeTexture extends Texture -{ - constructor(width, height, format) - { - super(width, height, format); - - this.target = 34067; // gl.TEXTURE_CUBE_MAP - - 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 deleted file mode 100644 index 10e7364..0000000 --- a/src/core/textures/new/FrameBuffer.js +++ /dev/null @@ -1,92 +0,0 @@ -import Texture from './Texture' - - -export default class FrameBuffer -{ - constructor(width, height) - { - this.width = width || 100; - this.height = height || 100; - - this.stencil = false; - this.depth = false; - - this.dirtyId = 0; - this.dirtyFormat = 0; - this.dirtySize = 0; - - this.depthTexture = null; - this.colorTextures = []; - - this.glFrameBuffers = {}; - } - - get colorTexture() - { - return this.colorTextures[0]; - } - - addColorTexture(index, texture) - { - // TODO add some validation to the texture - same width / height etc? - this.colorTextures[index || 0] = texture || new Texture(this.width, this.height);// || new Texture(); - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - - addDepthTexture(texture) - { - this.depthTexture = texture || new Texture(this.width, this.height, 6402, 5123)//UNSIGNED_SHORT; - - - this.dirtyId++; - this.dirtyFormat++; - return this; - } - - enableDepth() - { - this.depth = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - enableStencil() - { - this.stencil = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - resize(width, height) - { - if(width === this.width && height === this.height)return; - - this.width = width; - this.height = height; - - this.dirtyId++; - this.dirtySize++; - - for (var i = 0; i < this.colorTextures.length; i++) { - this.colorTextures[i].resize(width, height); - } - - if(this.depthTexture) - { - this.depthTexture.resize(width, height) - } - } - - -} \ No newline at end of file diff --git a/src/core/textures/new/Texture.js b/src/core/textures/new/Texture.js deleted file mode 100644 index b4d849f..0000000 --- a/src/core/textures/new/Texture.js +++ /dev/null @@ -1,294 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../../utils'; - -import ImageResource from '../resources/ImageResource'; -import BufferResource from '../resources/BufferResource'; -import settings from '../../settings'; -import EventEmitter from 'eventemitter3'; - -export default class Texture extends EventEmitter -{ - constructor(width, height, format, type, resolution) - { - - super(); - - - this.uid = uid(); - - this.touched = 0; - - /** - * The width of texture - * - * @member {Number} - */ - this.width = width || -1; - /** - * The height of texture - * - * @member {Number} - */ - this.height = height || -1; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - /** - * If mipmapping was used for this texture, enable and disable with enableMipmap() - * - * @member {Boolean} - */ - this.mipmap = false;//settings.MIPMAP_TEXTURES; - - /** - * Set to true to enable pre-multiplied alpha - * - * @member {Boolean} - */ - this.premultiplyAlpha = true; - - /** - * [wrapMode description] - * @type {[type]} - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = settings.SCALE_MODE; - - /** - * The pixel format of the texture. defaults to gl.RGBA - * - * @member {Number} - */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE - - this.target = 3553; // gl.TEXTURE_2D - - this.glTextures = {}; - - this._new = true; - - this.resource = null; - - - - this.dirtyId = 0; - - this.valid = false; - - this.validate(); - } - - get realWidth() - { - return this.width / this.resolution; - } - - get realHeight() - { - return this.height / this.resolution; - } - - setResource(resource) - { - this.resource = resource; - - this.resource.load.then((resource) => { - - if(this.resource === resource) - { - if(resource.width !== -1 && resource.hight !== -1) - { - this.width = resource.width; - this.height = resource.height; - } - - this.validate(); - - if(this.valid) - { - // we have not swapped half way! - this.dirtyId++; - } - } - - }) - } - - resize(width, height) - { - this.width = width; - this.height = height; - - this.dirtyId++; - } - - validate() - { - let valid = true; - - if(this.width === -1 || this.height === -1) - { - valid = false; - } - - this.valid = valid; - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const resource = ImageResource.from(imageUrl, crossorigin);// document.createElement('img'); - - baseTexture = new Texture();//image, scaleMode); - - baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(new ImageResource(image)); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } - - static fromFloat32Array(width, height, float32Array) - { - var texture = new Texture(width, height, 6408, 5126); - - float32Array = float32Array || new Float32Array(width*height*4); - - texture.setResource(new BufferResource(float32Array)); - - return texture; - } - - static fromUint8Array(width, height, uint8Array) - { - var texture = new Texture(width, height, 6408, 5121); - - uint8Array = uint8Array || new Uint8Array(width*height*4); - - texture.setResource(new BufferResource(uint8Array)); - - return texture; - } - -} \ No newline at end of file diff --git a/src/core/textures/resources/BufferResource.js b/src/core/textures/resources/BufferResource.js index 72cf410..b872455 100644 --- a/src/core/textures/resources/BufferResource.js +++ b/src/core/textures/resources/BufferResource.js @@ -1,13 +1,10 @@ +import TextureResource from './TextureResource'; -export default class BufferResource +export default class BufferResource extends TextureResource { constructor(source) { - this.source = source; - this.loaded = true; // TODO rename to ready? - this.width = -1; - this.height = -1; - this.uploadable = false; + super(source); this.load = new Promise((resolve, reject) => { diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 4646716..fdd1886 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -1,8 +1,10 @@ import BaseTexture from './BaseTexture'; import VideoBaseTexture from './VideoBaseTexture'; import ImageResource from './resources/ImageResource'; +import CanvasResource from './resources/CanvasResource'; import TextureUvs from './TextureUvs'; import EventEmitter from 'eventemitter3'; +import settings from '../settings'; import { Rectangle } from '../math'; import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; @@ -443,10 +445,11 @@ { const resource = new ImageResource(source);//.from(imageUrl, crossorigin);// document.createElement('img'); - const baseTexture = new BaseTexture();//image, scaleMode); - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(resource); + const baseTexture = new BaseTexture(resource, + settings.SCALE_MODE, + getResolutionOfUrl(imageUrl)); + console.log(baseTexture) const texture = new Texture(baseTexture); // No name, use imageUrl instead @@ -591,7 +594,7 @@ context.fillStyle = 'white'; context.fillRect(0, 0, 10, 10); - return new Texture(new BaseTexture(canvas)); + return new Texture(new BaseTexture(new CanvasResource(canvas))); } function removeAllHandlers(tex) diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js deleted file mode 100644 index c3cde40..0000000 --- a/src/core/textures/new/CubeTexture.js +++ /dev/null @@ -1,88 +0,0 @@ -import Texture from '../BaseTexture'; -import ImageResource from '../resources/ImageResource'; - -export default class CubeTexture extends Texture -{ - constructor(width, height, format) - { - super(width, height, format); - - this.target = 34067; // gl.TEXTURE_CUBE_MAP - - 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 deleted file mode 100644 index 10e7364..0000000 --- a/src/core/textures/new/FrameBuffer.js +++ /dev/null @@ -1,92 +0,0 @@ -import Texture from './Texture' - - -export default class FrameBuffer -{ - constructor(width, height) - { - this.width = width || 100; - this.height = height || 100; - - this.stencil = false; - this.depth = false; - - this.dirtyId = 0; - this.dirtyFormat = 0; - this.dirtySize = 0; - - this.depthTexture = null; - this.colorTextures = []; - - this.glFrameBuffers = {}; - } - - get colorTexture() - { - return this.colorTextures[0]; - } - - addColorTexture(index, texture) - { - // TODO add some validation to the texture - same width / height etc? - this.colorTextures[index || 0] = texture || new Texture(this.width, this.height);// || new Texture(); - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - - addDepthTexture(texture) - { - this.depthTexture = texture || new Texture(this.width, this.height, 6402, 5123)//UNSIGNED_SHORT; - - - this.dirtyId++; - this.dirtyFormat++; - return this; - } - - enableDepth() - { - this.depth = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - enableStencil() - { - this.stencil = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - resize(width, height) - { - if(width === this.width && height === this.height)return; - - this.width = width; - this.height = height; - - this.dirtyId++; - this.dirtySize++; - - for (var i = 0; i < this.colorTextures.length; i++) { - this.colorTextures[i].resize(width, height); - } - - if(this.depthTexture) - { - this.depthTexture.resize(width, height) - } - } - - -} \ No newline at end of file diff --git a/src/core/textures/new/Texture.js b/src/core/textures/new/Texture.js deleted file mode 100644 index b4d849f..0000000 --- a/src/core/textures/new/Texture.js +++ /dev/null @@ -1,294 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../../utils'; - -import ImageResource from '../resources/ImageResource'; -import BufferResource from '../resources/BufferResource'; -import settings from '../../settings'; -import EventEmitter from 'eventemitter3'; - -export default class Texture extends EventEmitter -{ - constructor(width, height, format, type, resolution) - { - - super(); - - - this.uid = uid(); - - this.touched = 0; - - /** - * The width of texture - * - * @member {Number} - */ - this.width = width || -1; - /** - * The height of texture - * - * @member {Number} - */ - this.height = height || -1; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - /** - * If mipmapping was used for this texture, enable and disable with enableMipmap() - * - * @member {Boolean} - */ - this.mipmap = false;//settings.MIPMAP_TEXTURES; - - /** - * Set to true to enable pre-multiplied alpha - * - * @member {Boolean} - */ - this.premultiplyAlpha = true; - - /** - * [wrapMode description] - * @type {[type]} - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = settings.SCALE_MODE; - - /** - * The pixel format of the texture. defaults to gl.RGBA - * - * @member {Number} - */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE - - this.target = 3553; // gl.TEXTURE_2D - - this.glTextures = {}; - - this._new = true; - - this.resource = null; - - - - this.dirtyId = 0; - - this.valid = false; - - this.validate(); - } - - get realWidth() - { - return this.width / this.resolution; - } - - get realHeight() - { - return this.height / this.resolution; - } - - setResource(resource) - { - this.resource = resource; - - this.resource.load.then((resource) => { - - if(this.resource === resource) - { - if(resource.width !== -1 && resource.hight !== -1) - { - this.width = resource.width; - this.height = resource.height; - } - - this.validate(); - - if(this.valid) - { - // we have not swapped half way! - this.dirtyId++; - } - } - - }) - } - - resize(width, height) - { - this.width = width; - this.height = height; - - this.dirtyId++; - } - - validate() - { - let valid = true; - - if(this.width === -1 || this.height === -1) - { - valid = false; - } - - this.valid = valid; - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const resource = ImageResource.from(imageUrl, crossorigin);// document.createElement('img'); - - baseTexture = new Texture();//image, scaleMode); - - baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(new ImageResource(image)); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } - - static fromFloat32Array(width, height, float32Array) - { - var texture = new Texture(width, height, 6408, 5126); - - float32Array = float32Array || new Float32Array(width*height*4); - - texture.setResource(new BufferResource(float32Array)); - - return texture; - } - - static fromUint8Array(width, height, uint8Array) - { - var texture = new Texture(width, height, 6408, 5121); - - uint8Array = uint8Array || new Uint8Array(width*height*4); - - texture.setResource(new BufferResource(uint8Array)); - - return texture; - } - -} \ No newline at end of file diff --git a/src/core/textures/resources/BufferResource.js b/src/core/textures/resources/BufferResource.js index 72cf410..b872455 100644 --- a/src/core/textures/resources/BufferResource.js +++ b/src/core/textures/resources/BufferResource.js @@ -1,13 +1,10 @@ +import TextureResource from './TextureResource'; -export default class BufferResource +export default class BufferResource extends TextureResource { constructor(source) { - this.source = source; - this.loaded = true; // TODO rename to ready? - this.width = -1; - this.height = -1; - this.uploadable = false; + super(source); this.load = new Promise((resolve, reject) => { diff --git a/src/core/textures/resources/CanvasResource.js b/src/core/textures/resources/CanvasResource.js index 0d91551..70c3962 100644 --- a/src/core/textures/resources/CanvasResource.js +++ b/src/core/textures/resources/CanvasResource.js @@ -1,10 +1,11 @@ -import determineCrossOrigin from '../../utils/determineCrossOrigin'; +import TextureResource from './TextureResource'; -export default class CanvasResource +export default class CanvasResource extends TextureResource { constructor(source) { - this.source = source; + super(source); + this.loaded = true; // TODO rename to ready? this.width = source.width; this.height = source.height; @@ -21,6 +22,4 @@ { return new CanvasResource(canvas); } - - } \ No newline at end of file diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 4646716..fdd1886 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -1,8 +1,10 @@ import BaseTexture from './BaseTexture'; import VideoBaseTexture from './VideoBaseTexture'; import ImageResource from './resources/ImageResource'; +import CanvasResource from './resources/CanvasResource'; import TextureUvs from './TextureUvs'; import EventEmitter from 'eventemitter3'; +import settings from '../settings'; import { Rectangle } from '../math'; import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; @@ -443,10 +445,11 @@ { const resource = new ImageResource(source);//.from(imageUrl, crossorigin);// document.createElement('img'); - const baseTexture = new BaseTexture();//image, scaleMode); - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(resource); + const baseTexture = new BaseTexture(resource, + settings.SCALE_MODE, + getResolutionOfUrl(imageUrl)); + console.log(baseTexture) const texture = new Texture(baseTexture); // No name, use imageUrl instead @@ -591,7 +594,7 @@ context.fillStyle = 'white'; context.fillRect(0, 0, 10, 10); - return new Texture(new BaseTexture(canvas)); + return new Texture(new BaseTexture(new CanvasResource(canvas))); } function removeAllHandlers(tex) diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js deleted file mode 100644 index c3cde40..0000000 --- a/src/core/textures/new/CubeTexture.js +++ /dev/null @@ -1,88 +0,0 @@ -import Texture from '../BaseTexture'; -import ImageResource from '../resources/ImageResource'; - -export default class CubeTexture extends Texture -{ - constructor(width, height, format) - { - super(width, height, format); - - this.target = 34067; // gl.TEXTURE_CUBE_MAP - - 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 deleted file mode 100644 index 10e7364..0000000 --- a/src/core/textures/new/FrameBuffer.js +++ /dev/null @@ -1,92 +0,0 @@ -import Texture from './Texture' - - -export default class FrameBuffer -{ - constructor(width, height) - { - this.width = width || 100; - this.height = height || 100; - - this.stencil = false; - this.depth = false; - - this.dirtyId = 0; - this.dirtyFormat = 0; - this.dirtySize = 0; - - this.depthTexture = null; - this.colorTextures = []; - - this.glFrameBuffers = {}; - } - - get colorTexture() - { - return this.colorTextures[0]; - } - - addColorTexture(index, texture) - { - // TODO add some validation to the texture - same width / height etc? - this.colorTextures[index || 0] = texture || new Texture(this.width, this.height);// || new Texture(); - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - - addDepthTexture(texture) - { - this.depthTexture = texture || new Texture(this.width, this.height, 6402, 5123)//UNSIGNED_SHORT; - - - this.dirtyId++; - this.dirtyFormat++; - return this; - } - - enableDepth() - { - this.depth = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - enableStencil() - { - this.stencil = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - resize(width, height) - { - if(width === this.width && height === this.height)return; - - this.width = width; - this.height = height; - - this.dirtyId++; - this.dirtySize++; - - for (var i = 0; i < this.colorTextures.length; i++) { - this.colorTextures[i].resize(width, height); - } - - if(this.depthTexture) - { - this.depthTexture.resize(width, height) - } - } - - -} \ No newline at end of file diff --git a/src/core/textures/new/Texture.js b/src/core/textures/new/Texture.js deleted file mode 100644 index b4d849f..0000000 --- a/src/core/textures/new/Texture.js +++ /dev/null @@ -1,294 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../../utils'; - -import ImageResource from '../resources/ImageResource'; -import BufferResource from '../resources/BufferResource'; -import settings from '../../settings'; -import EventEmitter from 'eventemitter3'; - -export default class Texture extends EventEmitter -{ - constructor(width, height, format, type, resolution) - { - - super(); - - - this.uid = uid(); - - this.touched = 0; - - /** - * The width of texture - * - * @member {Number} - */ - this.width = width || -1; - /** - * The height of texture - * - * @member {Number} - */ - this.height = height || -1; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - /** - * If mipmapping was used for this texture, enable and disable with enableMipmap() - * - * @member {Boolean} - */ - this.mipmap = false;//settings.MIPMAP_TEXTURES; - - /** - * Set to true to enable pre-multiplied alpha - * - * @member {Boolean} - */ - this.premultiplyAlpha = true; - - /** - * [wrapMode description] - * @type {[type]} - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = settings.SCALE_MODE; - - /** - * The pixel format of the texture. defaults to gl.RGBA - * - * @member {Number} - */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE - - this.target = 3553; // gl.TEXTURE_2D - - this.glTextures = {}; - - this._new = true; - - this.resource = null; - - - - this.dirtyId = 0; - - this.valid = false; - - this.validate(); - } - - get realWidth() - { - return this.width / this.resolution; - } - - get realHeight() - { - return this.height / this.resolution; - } - - setResource(resource) - { - this.resource = resource; - - this.resource.load.then((resource) => { - - if(this.resource === resource) - { - if(resource.width !== -1 && resource.hight !== -1) - { - this.width = resource.width; - this.height = resource.height; - } - - this.validate(); - - if(this.valid) - { - // we have not swapped half way! - this.dirtyId++; - } - } - - }) - } - - resize(width, height) - { - this.width = width; - this.height = height; - - this.dirtyId++; - } - - validate() - { - let valid = true; - - if(this.width === -1 || this.height === -1) - { - valid = false; - } - - this.valid = valid; - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const resource = ImageResource.from(imageUrl, crossorigin);// document.createElement('img'); - - baseTexture = new Texture();//image, scaleMode); - - baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(new ImageResource(image)); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } - - static fromFloat32Array(width, height, float32Array) - { - var texture = new Texture(width, height, 6408, 5126); - - float32Array = float32Array || new Float32Array(width*height*4); - - texture.setResource(new BufferResource(float32Array)); - - return texture; - } - - static fromUint8Array(width, height, uint8Array) - { - var texture = new Texture(width, height, 6408, 5121); - - uint8Array = uint8Array || new Uint8Array(width*height*4); - - texture.setResource(new BufferResource(uint8Array)); - - return texture; - } - -} \ No newline at end of file diff --git a/src/core/textures/resources/BufferResource.js b/src/core/textures/resources/BufferResource.js index 72cf410..b872455 100644 --- a/src/core/textures/resources/BufferResource.js +++ b/src/core/textures/resources/BufferResource.js @@ -1,13 +1,10 @@ +import TextureResource from './TextureResource'; -export default class BufferResource +export default class BufferResource extends TextureResource { constructor(source) { - this.source = source; - this.loaded = true; // TODO rename to ready? - this.width = -1; - this.height = -1; - this.uploadable = false; + super(source); this.load = new Promise((resolve, reject) => { diff --git a/src/core/textures/resources/CanvasResource.js b/src/core/textures/resources/CanvasResource.js index 0d91551..70c3962 100644 --- a/src/core/textures/resources/CanvasResource.js +++ b/src/core/textures/resources/CanvasResource.js @@ -1,10 +1,11 @@ -import determineCrossOrigin from '../../utils/determineCrossOrigin'; +import TextureResource from './TextureResource'; -export default class CanvasResource +export default class CanvasResource extends TextureResource { constructor(source) { - this.source = source; + super(source); + this.loaded = true; // TODO rename to ready? this.width = source.width; this.height = source.height; @@ -21,6 +22,4 @@ { return new CanvasResource(canvas); } - - } \ No newline at end of file diff --git a/src/core/textures/resources/ImageResource.js b/src/core/textures/resources/ImageResource.js index c969c15..1ee6312 100644 --- a/src/core/textures/resources/ImageResource.js +++ b/src/core/textures/resources/ImageResource.js @@ -1,15 +1,11 @@ import determineCrossOrigin from '../../utils/determineCrossOrigin'; +import TextureResource from './TextureResource'; -export default class ImageResource +export default class ImageResource extends TextureResource { constructor(source) { - this.source = source; - this.loaded = false; // TODO rename to ready? - this.width = -1; - this.height = -1; - - this.uploadable = true; + super(); this.load = new Promise((resolve, reject) => { diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 4646716..fdd1886 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -1,8 +1,10 @@ import BaseTexture from './BaseTexture'; import VideoBaseTexture from './VideoBaseTexture'; import ImageResource from './resources/ImageResource'; +import CanvasResource from './resources/CanvasResource'; import TextureUvs from './TextureUvs'; import EventEmitter from 'eventemitter3'; +import settings from '../settings'; import { Rectangle } from '../math'; import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; @@ -443,10 +445,11 @@ { const resource = new ImageResource(source);//.from(imageUrl, crossorigin);// document.createElement('img'); - const baseTexture = new BaseTexture();//image, scaleMode); - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(resource); + const baseTexture = new BaseTexture(resource, + settings.SCALE_MODE, + getResolutionOfUrl(imageUrl)); + console.log(baseTexture) const texture = new Texture(baseTexture); // No name, use imageUrl instead @@ -591,7 +594,7 @@ context.fillStyle = 'white'; context.fillRect(0, 0, 10, 10); - return new Texture(new BaseTexture(canvas)); + return new Texture(new BaseTexture(new CanvasResource(canvas))); } function removeAllHandlers(tex) diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js deleted file mode 100644 index c3cde40..0000000 --- a/src/core/textures/new/CubeTexture.js +++ /dev/null @@ -1,88 +0,0 @@ -import Texture from '../BaseTexture'; -import ImageResource from '../resources/ImageResource'; - -export default class CubeTexture extends Texture -{ - constructor(width, height, format) - { - super(width, height, format); - - this.target = 34067; // gl.TEXTURE_CUBE_MAP - - 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 deleted file mode 100644 index 10e7364..0000000 --- a/src/core/textures/new/FrameBuffer.js +++ /dev/null @@ -1,92 +0,0 @@ -import Texture from './Texture' - - -export default class FrameBuffer -{ - constructor(width, height) - { - this.width = width || 100; - this.height = height || 100; - - this.stencil = false; - this.depth = false; - - this.dirtyId = 0; - this.dirtyFormat = 0; - this.dirtySize = 0; - - this.depthTexture = null; - this.colorTextures = []; - - this.glFrameBuffers = {}; - } - - get colorTexture() - { - return this.colorTextures[0]; - } - - addColorTexture(index, texture) - { - // TODO add some validation to the texture - same width / height etc? - this.colorTextures[index || 0] = texture || new Texture(this.width, this.height);// || new Texture(); - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - - addDepthTexture(texture) - { - this.depthTexture = texture || new Texture(this.width, this.height, 6402, 5123)//UNSIGNED_SHORT; - - - this.dirtyId++; - this.dirtyFormat++; - return this; - } - - enableDepth() - { - this.depth = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - enableStencil() - { - this.stencil = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - resize(width, height) - { - if(width === this.width && height === this.height)return; - - this.width = width; - this.height = height; - - this.dirtyId++; - this.dirtySize++; - - for (var i = 0; i < this.colorTextures.length; i++) { - this.colorTextures[i].resize(width, height); - } - - if(this.depthTexture) - { - this.depthTexture.resize(width, height) - } - } - - -} \ No newline at end of file diff --git a/src/core/textures/new/Texture.js b/src/core/textures/new/Texture.js deleted file mode 100644 index b4d849f..0000000 --- a/src/core/textures/new/Texture.js +++ /dev/null @@ -1,294 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../../utils'; - -import ImageResource from '../resources/ImageResource'; -import BufferResource from '../resources/BufferResource'; -import settings from '../../settings'; -import EventEmitter from 'eventemitter3'; - -export default class Texture extends EventEmitter -{ - constructor(width, height, format, type, resolution) - { - - super(); - - - this.uid = uid(); - - this.touched = 0; - - /** - * The width of texture - * - * @member {Number} - */ - this.width = width || -1; - /** - * The height of texture - * - * @member {Number} - */ - this.height = height || -1; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - /** - * If mipmapping was used for this texture, enable and disable with enableMipmap() - * - * @member {Boolean} - */ - this.mipmap = false;//settings.MIPMAP_TEXTURES; - - /** - * Set to true to enable pre-multiplied alpha - * - * @member {Boolean} - */ - this.premultiplyAlpha = true; - - /** - * [wrapMode description] - * @type {[type]} - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = settings.SCALE_MODE; - - /** - * The pixel format of the texture. defaults to gl.RGBA - * - * @member {Number} - */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE - - this.target = 3553; // gl.TEXTURE_2D - - this.glTextures = {}; - - this._new = true; - - this.resource = null; - - - - this.dirtyId = 0; - - this.valid = false; - - this.validate(); - } - - get realWidth() - { - return this.width / this.resolution; - } - - get realHeight() - { - return this.height / this.resolution; - } - - setResource(resource) - { - this.resource = resource; - - this.resource.load.then((resource) => { - - if(this.resource === resource) - { - if(resource.width !== -1 && resource.hight !== -1) - { - this.width = resource.width; - this.height = resource.height; - } - - this.validate(); - - if(this.valid) - { - // we have not swapped half way! - this.dirtyId++; - } - } - - }) - } - - resize(width, height) - { - this.width = width; - this.height = height; - - this.dirtyId++; - } - - validate() - { - let valid = true; - - if(this.width === -1 || this.height === -1) - { - valid = false; - } - - this.valid = valid; - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const resource = ImageResource.from(imageUrl, crossorigin);// document.createElement('img'); - - baseTexture = new Texture();//image, scaleMode); - - baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(new ImageResource(image)); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } - - static fromFloat32Array(width, height, float32Array) - { - var texture = new Texture(width, height, 6408, 5126); - - float32Array = float32Array || new Float32Array(width*height*4); - - texture.setResource(new BufferResource(float32Array)); - - return texture; - } - - static fromUint8Array(width, height, uint8Array) - { - var texture = new Texture(width, height, 6408, 5121); - - uint8Array = uint8Array || new Uint8Array(width*height*4); - - texture.setResource(new BufferResource(uint8Array)); - - return texture; - } - -} \ No newline at end of file diff --git a/src/core/textures/resources/BufferResource.js b/src/core/textures/resources/BufferResource.js index 72cf410..b872455 100644 --- a/src/core/textures/resources/BufferResource.js +++ b/src/core/textures/resources/BufferResource.js @@ -1,13 +1,10 @@ +import TextureResource from './TextureResource'; -export default class BufferResource +export default class BufferResource extends TextureResource { constructor(source) { - this.source = source; - this.loaded = true; // TODO rename to ready? - this.width = -1; - this.height = -1; - this.uploadable = false; + super(source); this.load = new Promise((resolve, reject) => { diff --git a/src/core/textures/resources/CanvasResource.js b/src/core/textures/resources/CanvasResource.js index 0d91551..70c3962 100644 --- a/src/core/textures/resources/CanvasResource.js +++ b/src/core/textures/resources/CanvasResource.js @@ -1,10 +1,11 @@ -import determineCrossOrigin from '../../utils/determineCrossOrigin'; +import TextureResource from './TextureResource'; -export default class CanvasResource +export default class CanvasResource extends TextureResource { constructor(source) { - this.source = source; + super(source); + this.loaded = true; // TODO rename to ready? this.width = source.width; this.height = source.height; @@ -21,6 +22,4 @@ { return new CanvasResource(canvas); } - - } \ No newline at end of file diff --git a/src/core/textures/resources/ImageResource.js b/src/core/textures/resources/ImageResource.js index c969c15..1ee6312 100644 --- a/src/core/textures/resources/ImageResource.js +++ b/src/core/textures/resources/ImageResource.js @@ -1,15 +1,11 @@ import determineCrossOrigin from '../../utils/determineCrossOrigin'; +import TextureResource from './TextureResource'; -export default class ImageResource +export default class ImageResource extends TextureResource { constructor(source) { - this.source = source; - this.loaded = false; // TODO rename to ready? - this.width = -1; - this.height = -1; - - this.uploadable = true; + super(); this.load = new Promise((resolve, reject) => { diff --git a/src/core/textures/resources/SVGResource.js b/src/core/textures/resources/SVGResource.js index f00fee0..29a5810 100644 --- a/src/core/textures/resources/SVGResource.js +++ b/src/core/textures/resources/SVGResource.js @@ -1,4 +1,3 @@ -import determineCrossOrigin from '../../utils/determineCrossOrigin'; import { decomposeDataUri, getSvgSize, uid } from '../../utils'; @@ -7,11 +6,7 @@ { constructor(svgSource, scale) { - - this.source = null;//source; - this.loaded = false; // TODO rename to ready? - this.width = -1; - this.height = -1; + super(); this.svgSource = svgSource; this.scale = 1 || scale; diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 4646716..fdd1886 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -1,8 +1,10 @@ import BaseTexture from './BaseTexture'; import VideoBaseTexture from './VideoBaseTexture'; import ImageResource from './resources/ImageResource'; +import CanvasResource from './resources/CanvasResource'; import TextureUvs from './TextureUvs'; import EventEmitter from 'eventemitter3'; +import settings from '../settings'; import { Rectangle } from '../math'; import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; @@ -443,10 +445,11 @@ { const resource = new ImageResource(source);//.from(imageUrl, crossorigin);// document.createElement('img'); - const baseTexture = new BaseTexture();//image, scaleMode); - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(resource); + const baseTexture = new BaseTexture(resource, + settings.SCALE_MODE, + getResolutionOfUrl(imageUrl)); + console.log(baseTexture) const texture = new Texture(baseTexture); // No name, use imageUrl instead @@ -591,7 +594,7 @@ context.fillStyle = 'white'; context.fillRect(0, 0, 10, 10); - return new Texture(new BaseTexture(canvas)); + return new Texture(new BaseTexture(new CanvasResource(canvas))); } function removeAllHandlers(tex) diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js deleted file mode 100644 index c3cde40..0000000 --- a/src/core/textures/new/CubeTexture.js +++ /dev/null @@ -1,88 +0,0 @@ -import Texture from '../BaseTexture'; -import ImageResource from '../resources/ImageResource'; - -export default class CubeTexture extends Texture -{ - constructor(width, height, format) - { - super(width, height, format); - - this.target = 34067; // gl.TEXTURE_CUBE_MAP - - 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 deleted file mode 100644 index 10e7364..0000000 --- a/src/core/textures/new/FrameBuffer.js +++ /dev/null @@ -1,92 +0,0 @@ -import Texture from './Texture' - - -export default class FrameBuffer -{ - constructor(width, height) - { - this.width = width || 100; - this.height = height || 100; - - this.stencil = false; - this.depth = false; - - this.dirtyId = 0; - this.dirtyFormat = 0; - this.dirtySize = 0; - - this.depthTexture = null; - this.colorTextures = []; - - this.glFrameBuffers = {}; - } - - get colorTexture() - { - return this.colorTextures[0]; - } - - addColorTexture(index, texture) - { - // TODO add some validation to the texture - same width / height etc? - this.colorTextures[index || 0] = texture || new Texture(this.width, this.height);// || new Texture(); - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - - addDepthTexture(texture) - { - this.depthTexture = texture || new Texture(this.width, this.height, 6402, 5123)//UNSIGNED_SHORT; - - - this.dirtyId++; - this.dirtyFormat++; - return this; - } - - enableDepth() - { - this.depth = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - enableStencil() - { - this.stencil = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - resize(width, height) - { - if(width === this.width && height === this.height)return; - - this.width = width; - this.height = height; - - this.dirtyId++; - this.dirtySize++; - - for (var i = 0; i < this.colorTextures.length; i++) { - this.colorTextures[i].resize(width, height); - } - - if(this.depthTexture) - { - this.depthTexture.resize(width, height) - } - } - - -} \ No newline at end of file diff --git a/src/core/textures/new/Texture.js b/src/core/textures/new/Texture.js deleted file mode 100644 index b4d849f..0000000 --- a/src/core/textures/new/Texture.js +++ /dev/null @@ -1,294 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../../utils'; - -import ImageResource from '../resources/ImageResource'; -import BufferResource from '../resources/BufferResource'; -import settings from '../../settings'; -import EventEmitter from 'eventemitter3'; - -export default class Texture extends EventEmitter -{ - constructor(width, height, format, type, resolution) - { - - super(); - - - this.uid = uid(); - - this.touched = 0; - - /** - * The width of texture - * - * @member {Number} - */ - this.width = width || -1; - /** - * The height of texture - * - * @member {Number} - */ - this.height = height || -1; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - /** - * If mipmapping was used for this texture, enable and disable with enableMipmap() - * - * @member {Boolean} - */ - this.mipmap = false;//settings.MIPMAP_TEXTURES; - - /** - * Set to true to enable pre-multiplied alpha - * - * @member {Boolean} - */ - this.premultiplyAlpha = true; - - /** - * [wrapMode description] - * @type {[type]} - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = settings.SCALE_MODE; - - /** - * The pixel format of the texture. defaults to gl.RGBA - * - * @member {Number} - */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE - - this.target = 3553; // gl.TEXTURE_2D - - this.glTextures = {}; - - this._new = true; - - this.resource = null; - - - - this.dirtyId = 0; - - this.valid = false; - - this.validate(); - } - - get realWidth() - { - return this.width / this.resolution; - } - - get realHeight() - { - return this.height / this.resolution; - } - - setResource(resource) - { - this.resource = resource; - - this.resource.load.then((resource) => { - - if(this.resource === resource) - { - if(resource.width !== -1 && resource.hight !== -1) - { - this.width = resource.width; - this.height = resource.height; - } - - this.validate(); - - if(this.valid) - { - // we have not swapped half way! - this.dirtyId++; - } - } - - }) - } - - resize(width, height) - { - this.width = width; - this.height = height; - - this.dirtyId++; - } - - validate() - { - let valid = true; - - if(this.width === -1 || this.height === -1) - { - valid = false; - } - - this.valid = valid; - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const resource = ImageResource.from(imageUrl, crossorigin);// document.createElement('img'); - - baseTexture = new Texture();//image, scaleMode); - - baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(new ImageResource(image)); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } - - static fromFloat32Array(width, height, float32Array) - { - var texture = new Texture(width, height, 6408, 5126); - - float32Array = float32Array || new Float32Array(width*height*4); - - texture.setResource(new BufferResource(float32Array)); - - return texture; - } - - static fromUint8Array(width, height, uint8Array) - { - var texture = new Texture(width, height, 6408, 5121); - - uint8Array = uint8Array || new Uint8Array(width*height*4); - - texture.setResource(new BufferResource(uint8Array)); - - return texture; - } - -} \ No newline at end of file diff --git a/src/core/textures/resources/BufferResource.js b/src/core/textures/resources/BufferResource.js index 72cf410..b872455 100644 --- a/src/core/textures/resources/BufferResource.js +++ b/src/core/textures/resources/BufferResource.js @@ -1,13 +1,10 @@ +import TextureResource from './TextureResource'; -export default class BufferResource +export default class BufferResource extends TextureResource { constructor(source) { - this.source = source; - this.loaded = true; // TODO rename to ready? - this.width = -1; - this.height = -1; - this.uploadable = false; + super(source); this.load = new Promise((resolve, reject) => { diff --git a/src/core/textures/resources/CanvasResource.js b/src/core/textures/resources/CanvasResource.js index 0d91551..70c3962 100644 --- a/src/core/textures/resources/CanvasResource.js +++ b/src/core/textures/resources/CanvasResource.js @@ -1,10 +1,11 @@ -import determineCrossOrigin from '../../utils/determineCrossOrigin'; +import TextureResource from './TextureResource'; -export default class CanvasResource +export default class CanvasResource extends TextureResource { constructor(source) { - this.source = source; + super(source); + this.loaded = true; // TODO rename to ready? this.width = source.width; this.height = source.height; @@ -21,6 +22,4 @@ { return new CanvasResource(canvas); } - - } \ No newline at end of file diff --git a/src/core/textures/resources/ImageResource.js b/src/core/textures/resources/ImageResource.js index c969c15..1ee6312 100644 --- a/src/core/textures/resources/ImageResource.js +++ b/src/core/textures/resources/ImageResource.js @@ -1,15 +1,11 @@ import determineCrossOrigin from '../../utils/determineCrossOrigin'; +import TextureResource from './TextureResource'; -export default class ImageResource +export default class ImageResource extends TextureResource { constructor(source) { - this.source = source; - this.loaded = false; // TODO rename to ready? - this.width = -1; - this.height = -1; - - this.uploadable = true; + super(); this.load = new Promise((resolve, reject) => { diff --git a/src/core/textures/resources/SVGResource.js b/src/core/textures/resources/SVGResource.js index f00fee0..29a5810 100644 --- a/src/core/textures/resources/SVGResource.js +++ b/src/core/textures/resources/SVGResource.js @@ -1,4 +1,3 @@ -import determineCrossOrigin from '../../utils/determineCrossOrigin'; import { decomposeDataUri, getSvgSize, uid } from '../../utils'; @@ -7,11 +6,7 @@ { constructor(svgSource, scale) { - - this.source = null;//source; - this.loaded = false; // TODO rename to ready? - this.width = -1; - this.height = -1; + super(); this.svgSource = svgSource; this.scale = 1 || scale; diff --git a/src/core/textures/resources/TextureResource.js b/src/core/textures/resources/TextureResource.js new file mode 100644 index 0000000..c21ad7f --- /dev/null +++ b/src/core/textures/resources/TextureResource.js @@ -0,0 +1,21 @@ +import Runner from 'mini-runner'; + +export default class TextureResource +{ + constructor(source) + { + this.source = source; + + this.loaded = false; // TODO rename to ready? + + this.width = -1; + this.height = -1; + + this.uploadable = true; + + this.updated = new Runner('resourceUpdated'); + + // create a prommise.. + this.load = null; + } +} \ No newline at end of file diff --git a/src/core/const.js b/src/core/const.js index fffad5b..b9e99ae 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -134,12 +134,37 @@ TRIANGLE_FAN: 6, }; -export const TYPES = { - FLOAT: 5126, - UNSIGNED_SHORT: 5123, - UNSIGNED_BYTE: 5121, +export const FORMATS = { + RGBA: 6408, + RGB: 6407, + ALPHA: 6406, + LUMINANCE: 6409, + LUMINANCE_ALPHA: 6410, + DEPTH_COMPONENT: 6402, + DEPTH_STENCIL: 34041, }; +export const TARGETS = { + TEXTURE_2D:3553, + TEXTURE_CUBE_MAP:34067, + TEXTURE_CUBE_MAP_POSITIVE_X:34069, + TEXTURE_CUBE_MAP_NEGATIVE_X:34070, + TEXTURE_CUBE_MAP_POSITIVE_Y:34071, + TEXTURE_CUBE_MAP_NEGATIVE_Y:34072, + TEXTURE_CUBE_MAP_POSITIVE_Z:34073, + TEXTURE_CUBE_MAP_NEGATIVE_Z:34074, +}; + +export const TYPES = { + UNSIGNED_BYTE:5121, + UNSIGNED_SHORT: 5123, + UNSIGNED_SHORT_5_6_5:33635, + UNSIGNED_SHORT_4_4_4_4:32819, + UNSIGNED_SHORT_5_5_5_1:32820, + FLOAT:5126, + HALF_FLOAT:36193, +} + /** * The scale modes that are supported by pixi. * diff --git a/src/core/index.js b/src/core/index.js index f282dd9..4cb6778 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -32,9 +32,9 @@ export { default as CanvasGraphicsRenderer } from './graphics/canvas/CanvasGraphicsRenderer'; export { default as Spritesheet } from './textures/Spritesheet'; export { default as Texture } from './textures/Texture'; -export { default as NewTexture } from './textures/new/Texture'; -export { default as NewFrameBuffer } from './textures/new/FrameBuffer'; -export { default as NewCubeTexture } from './textures/new/CubeTexture'; +export { default as NewTexture } from './textures/BaseTexture'; +export { default as NewFrameBuffer } from './textures/FrameBuffer'; +export { default as NewCubeTexture } from './textures/CubeTexture'; export { default as BaseTexture } from './textures/BaseTexture'; export { default as RenderTexture } from './textures/RenderTexture'; export { default as BaseRenderTexture } from './textures/BaseRenderTexture'; diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 1f8dd95..12bcbee 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -570,9 +570,8 @@ { this.newTextureManager.bindTexture(texture._newTexture, location); glTexture = texture._newTexture.glTextures[this.CONTEXT_UID]; - console.log("!!!") - return; + return location; } if (!glTexture) diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index 1638b70..a6b2e19 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -157,7 +157,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_CUBE_MAP_NEGATIVE_X + texture.side, - texture.texture.glTextures[this.CONTEXT_UID].texture, + texture.texture._glTextures[this.CONTEXT_UID].texture, 0); } else @@ -167,7 +167,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.TEXTURE_2D, - texture.glTextures[this.CONTEXT_UID].texture, + texture._glTextures[this.CONTEXT_UID].texture, 0); } @@ -192,7 +192,7 @@ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, - depthTexture.glTextures[this.CONTEXT_UID].texture, + depthTexture._glTextures[this.CONTEXT_UID].texture, 0); } } diff --git a/src/core/text/Text.js b/src/core/text/Text.js index cec8c32..5a4edda 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -345,11 +345,9 @@ const texture = this._texture; const style = this._style; - texture.baseTexture.hasLoaded = true; + texture.baseTexture.valid = true; texture.baseTexture.resolution = this.resolution; - texture.baseTexture.realWidth = this.canvas.width; - texture.baseTexture.realHeight = this.canvas.height; texture.baseTexture.width = this.canvas.width / this.resolution; texture.baseTexture.height = this.canvas.height / this.resolution; texture.trim.width = texture._frame.width = this.canvas.width / this.resolution; @@ -364,7 +362,7 @@ // call sprite onTextureUpdate to update scale if _width or _height were set this._onTextureUpdate(); - texture.baseTexture.emit('update', texture.baseTexture); + texture.baseTexture.update();//emit('update', texture.baseTexture); this.dirty = false; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index aa727f0..f227ae0 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -50,17 +50,8 @@ */ constructor(width = 100, height = 100, scaleMode, resolution) { - super(null, scaleMode); + super(null, scaleMode, resolution, width, height); - this.resolution = resolution || settings.RESOLUTION; - - this.width = width; - this.height = height; - - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; this.hasLoaded = true; /** @@ -105,9 +96,6 @@ this.width = width; this.height = height; - this.realWidth = this.width * this.resolution; - this.realHeight = this.height * this.resolution; - if (!this.valid) { return; diff --git a/src/core/textures/BaseTexture.js b/src/core/textures/BaseTexture.js index 8955233..364de1a 100644 --- a/src/core/textures/BaseTexture.js +++ b/src/core/textures/BaseTexture.js @@ -3,10 +3,12 @@ getResolutionOfUrl, BaseTextureCache, TextureCache, } from '../utils'; +import {FORMATS, TARGETS, TYPES, SCALE_MODES} from '../const'; import ImageResource from './resources/ImageResource'; import BufferResource from './resources/BufferResource'; import CanvasResource from './resources/CanvasResource'; import SVGResource from './resources/SVGResource'; +import createResource from './resources/createResource'; import settings from '../settings'; import EventEmitter from 'eventemitter3'; @@ -14,12 +16,10 @@ export default class BaseTexture extends EventEmitter { - constructor(width, height, format, type, resolution) + constructor(resource, scaleMode, resolution, width, height, format, type, mipmap) { - super(); - this.uid = uid(); this.touched = 0; @@ -81,30 +81,35 @@ * @default PIXI.settings.SCALE_MODE * @see PIXI.SCALE_MODES */ - this.scaleMode = settings.SCALE_MODE; + this.scaleMode = scaleMode || settings.SCALE_MODE; /** * The pixel format of the texture. defaults to gl.RGBA * * @member {Number} */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE + this.format = format || FORMATS.RGBA; + this.type = type || TYPES.UNSIGNED_BYTE; //UNSIGNED_BYTE - this.target = 3553; // gl.TEXTURE_2D + this.target = TARGETS.TEXTURE_2D; // gl.TEXTURE_2D this._glTextures = {}; this._new = true; - this.resource = null; - - - this.dirtyId = 0; this.valid = false; + this.resource = null; + + if(resource) + { + // lets convert this to a resource.. + resource = createResource(resource); + this.setResource(resource); + } + this.validate(); } @@ -137,6 +142,11 @@ }) } + update() + { + this.dirtyId++; + } + resize(width, height) { this.width = width; @@ -209,7 +219,7 @@ { const resource = CanvasResource.from(canvas);// document.createElement('img'); - + console.log() baseTexture = new BaseTexture(); baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; baseTexture.setResource(resource); @@ -245,6 +255,7 @@ return baseTexture; } + get realWidth() { return this.width * this.resolution; @@ -276,6 +287,15 @@ return texture; } + static getResource(source) + { + if (typeof source === 'string') + { + // // + + } + } + /** * Helper function that creates a base texture based on the source you provide. * The source can be - image url, image element, canvas element. @@ -326,23 +346,29 @@ static fromFloat32Array(width, height, float32Array) { - var texture = new Texture(width, height, 6408, 5126); - float32Array = float32Array || new Float32Array(width*height*4); - texture.setResource(new BufferResource(float32Array)); - + var texture = new BaseTexture(new BufferResource(float32Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.FLOAT); return texture; } static fromUint8Array(width, height, uint8Array) { - var texture = new Texture(width, height, 6408, 5121); - uint8Array = uint8Array || new Uint8Array(width*height*4); - texture.setResource(new BufferResource(uint8Array)); - + var texture = new BaseTexture(new BufferResource(uint8Array), + SCALE_MODES.NEAREST, + 1, + width, + height, + FORMATS.RGBA, + TYPES.UNSIGNED_BYTE); return texture; } diff --git a/src/core/textures/BaseTexture_old.js b/src/core/textures/BaseTexture_old.js deleted file mode 100644 index 51b15a5..0000000 --- a/src/core/textures/BaseTexture_old.js +++ /dev/null @@ -1,751 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../utils'; -import settings from '../settings'; -import EventEmitter from 'eventemitter3'; -import determineCrossOrigin from '../utils/determineCrossOrigin'; -import bitTwiddle from 'bit-twiddle'; - -/** - * A texture stores the information that represents an image. All textures have a base texture. - * - * @class - * @extends EventEmitter - * @memberof PIXI - */ -export default class BaseTexture extends EventEmitter -{ - /** - * @param {HTMLImageElement|HTMLCanvasElement} [source] - the source object of the texture. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [resolution=1] - The resolution / device pixel ratio of the texture - */ - constructor(source, scaleMode, resolution) - { - super(); - - this.uid = uid(); - - this.touched = 0; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * The width of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.width = 100; - - /** - * The height of the base texture set when the image has loaded - * - * @readonly - * @member {number} - */ - this.height = 100; - - // TODO docs - // used to store the actual dimensions of the source - /** - * Used to store the actual width of the source of this texture - * - * @readonly - * @member {number} - */ - this.realWidth = 100; - /** - * Used to store the actual height of the source of this texture - * - * @readonly - * @member {number} - */ - this.realHeight = 100; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = scaleMode !== undefined ? scaleMode : settings.SCALE_MODE; - - /** - * Set to true once the base texture has successfully loaded. - * - * This is never true if the underlying source fails to load or has no texture data. - * - * @readonly - * @member {boolean} - */ - this.hasLoaded = false; - - /** - * Set to true if the source is currently loading. - * - * If an Image source is loading the 'loaded' or 'error' event will be - * dispatched when the operation ends. An underyling source that is - * immediately-available bypasses loading entirely. - * - * @readonly - * @member {boolean} - */ - this.isLoading = false; - - /** - * The image source that is used to create the texture. - * - * TODO: Make this a setter that calls loadSource(); - * - * @readonly - * @member {HTMLImageElement|HTMLCanvasElement} - */ - this.source = null; // set in loadSource, if at all - - /** - * The image source that is used to create the texture. This is used to - * store the original Svg source when it is replaced with a canvas element. - * - * TODO: Currently not in use but could be used when re-scaling svg. - * - * @readonly - * @member {Image} - */ - this.origSource = null; // set in loadSvg, if at all - - /** - * Type of image defined in source, eg. `png` or `svg` - * - * @readonly - * @member {string} - */ - this.imageType = null; // set in updateImageType - - /** - * Scale for source image. Used with Svg images to scale them before rasterization. - * - * @readonly - * @member {number} - */ - this.sourceScale = 1.0; - - /** - * Controls if RGB channels should be pre-multiplied by Alpha (WebGL only) - * All blend modes, and shaders written for default value. Change it on your own risk. - * - * @member {boolean} - * @default true - */ - this.premultipliedAlpha = true; - - /** - * The image url of the texture - * - * @member {string} - */ - this.imageUrl = null; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - // used for webGL - - /** - * - * Set this to true if a mipmap of this texture needs to be generated. This value needs - * to be set before the texture is used - * Also the texture must be a power of two size to work - * - * @member {boolean} - * @see PIXI.MIPMAP_TEXTURES - */ - this.mipmap = settings.MIPMAP_TEXTURES; - - /** - * - * WebGL Texture wrap mode - * - * @member {number} - * @see PIXI.WRAP_MODES - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * A map of renderer IDs to webgl textures - * - * @private - * @member {object} - */ - this._glTextures = {}; - - // 0 = color : 1 = depth : 2 = cube; - - this.type = 0; - - - this._enabled = 0; - this._virtalBoundId = -1; - - - // if no source passed don't try to load - if (source) - { - this.loadSource(source); - } - - /** - * Fired when a not-immediately-available source finishes loading. - * - * @protected - * @event loaded - * @memberof PIXI.BaseTexture# - */ - - /** - * Fired when a not-immediately-available source fails to load. - * - * @protected - * @event error - * @memberof PIXI.BaseTexture# - */ - } - - /** - * Updates the texture on all the webgl renderers, this also assumes the src has changed. - * - * @fires update - */ - update() - { - // Svg size is handled during load - if (this.imageType !== 'svg') - { - this.realWidth = this.source.naturalWidth || this.source.videoWidth || this.source.width; - this.realHeight = this.source.naturalHeight || this.source.videoHeight || this.source.height; - - this._updateDimensions(); - } - - this.emit('update', this); - } - - /** - * Update dimensions from real values - */ - _updateDimensions() - { - this.width = this.realWidth / this.resolution; - this.height = this.realHeight / this.resolution; - - this.isPowerOfTwo = bitTwiddle.isPow2(this.realWidth) && bitTwiddle.isPow2(this.realHeight); - } - - /** - * Load a source. - * - * If the source is not-immediately-available, such as an image that needs to be - * downloaded, then the 'loaded' or 'error' event will be dispatched in the future - * and `hasLoaded` will remain false after this call. - * - * The logic state after calling `loadSource` directly or indirectly (eg. `fromImage`, `new BaseTexture`) is: - * - * if (texture.hasLoaded) { - * // texture ready for use - * } else if (texture.isLoading) { - * // listen to 'loaded' and/or 'error' events on texture - * } else { - * // not loading, not going to load UNLESS the source is reloaded - * // (it may still make sense to listen to the events) - * } - * - * @protected - * @param {HTMLImageElement|HTMLCanvasElement} source - the source object of the texture. - */ - loadSource(source) - { - const wasLoading = this.isLoading; - - this.hasLoaded = false; - this.isLoading = false; - - if (wasLoading && this.source) - { - this.source.onload = null; - this.source.onerror = null; - } - - const firstSourceLoaded = !this.source; - - this.source = source; - - // Apply source if loaded. Otherwise setup appropriate loading monitors. - if (((source.src && source.complete) || source.getContext) && source.width && source.height) - { - this._updateImageType(); - - if (this.imageType === 'svg') - { - this._loadSvgSource(); - } - else - { - this._sourceLoaded(); - } - - if (firstSourceLoaded) - { - // send loaded event if previous source was null and we have been passed a pre-loaded IMG element - this.emit('loaded', this); - } - } - else if (!source.getContext) - { - // Image fail / not ready - this.isLoading = true; - - const scope = this; - - source.onload = () => - { - scope._updateImageType(); - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope._sourceLoaded(); - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - scope.emit('loaded', scope); - }; - - source.onerror = () => - { - source.onload = null; - source.onerror = null; - - if (!scope.isLoading) - { - return; - } - - scope.isLoading = false; - scope.emit('error', scope); - }; - - // Per http://www.w3.org/TR/html5/embedded-content-0.html#the-img-element - // "The value of `complete` can thus change while a script is executing." - // So complete needs to be re-checked after the callbacks have been added.. - // NOTE: complete will be true if the image has no src so best to check if the src is set. - if (source.complete && source.src) - { - // ..and if we're complete now, no need for callbacks - source.onload = null; - source.onerror = null; - - if (scope.imageType === 'svg') - { - scope._loadSvgSource(); - - return; - } - - this.isLoading = false; - - if (source.width && source.height) - { - this._sourceLoaded(); - - // If any previous subscribers possible - if (wasLoading) - { - this.emit('loaded', this); - } - } - // If any previous subscribers possible - else if (wasLoading) - { - this.emit('error', this); - } - } - } - } - - /** - * Updates type of the source image. - */ - _updateImageType() - { - if (!this.imageUrl) - { - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - let imageType; - - if (dataUri && dataUri.mediaType === 'image') - { - // Check for subType validity - const firstSubType = dataUri.subType.split('+')[0]; - - imageType = getUrlFileExtension(`.${firstSubType}`); - - if (!imageType) - { - throw new Error('Invalid image type in data URI.'); - } - } - else - { - imageType = getUrlFileExtension(this.imageUrl); - - if (!imageType) - { - imageType = 'png'; - } - } - - this.imageType = imageType; - } - - /** - * Checks if `source` is an SVG image and whether it's loaded via a URL or a data URI. Then calls - * `_loadSvgSourceUsingDataUri` or `_loadSvgSourceUsingXhr`. - */ - _loadSvgSource() - { - if (this.imageType !== 'svg') - { - // Do nothing if source is not svg - return; - } - - const dataUri = decomposeDataUri(this.imageUrl); - - if (dataUri) - { - this._loadSvgSourceUsingDataUri(dataUri); - } - else - { - // We got an URL, so we need to do an XHR to check the svg size - this._loadSvgSourceUsingXhr(); - } - } - - /** - * Reads an SVG string from data URI and then calls `_loadSvgSourceUsingString`. - * - * @param {string} dataUri - The data uri to load from. - */ - _loadSvgSourceUsingDataUri(dataUri) - { - let svgString; - - if (dataUri.encoding === 'base64') - { - if (!atob) - { - throw new Error('Your browser doesn\'t support base64 conversions.'); - } - svgString = atob(dataUri.data); - } - else - { - svgString = dataUri.data; - } - - this._loadSvgSourceUsingString(svgString); - } - - /** - * Loads an SVG string from `imageUrl` using XHR and then calls `_loadSvgSourceUsingString`. - */ - _loadSvgSourceUsingXhr() - { - const svgXhr = new XMLHttpRequest(); - - // This throws error on IE, so SVG Document can't be used - // svgXhr.responseType = 'document'; - - // This is not needed since we load the svg as string (breaks IE too) - // but overrideMimeType() can be used to force the response to be parsed as XML - // svgXhr.overrideMimeType('image/svg+xml'); - - svgXhr.onload = () => - { - if (svgXhr.readyState !== svgXhr.DONE || svgXhr.status !== 200) - { - throw new Error('Failed to load SVG using XHR.'); - } - - this._loadSvgSourceUsingString(svgXhr.response); - }; - - svgXhr.onerror = () => this.emit('error', this); - - svgXhr.open('GET', this.imageUrl, true); - svgXhr.send(); - } - - /** - * Loads texture using an SVG string. The original SVG Image is stored as `origSource` and the - * created canvas is the new `source`. The SVG is scaled using `sourceScale`. Called by - * `_loadSvgSourceUsingXhr` or `_loadSvgSourceUsingDataUri`. - * - * @param {string} svgString SVG source as string - * - * @fires loaded - */ - _loadSvgSourceUsingString(svgString) - { - const svgSize = getSvgSize(svgString); - - const svgWidth = svgSize.width; - const svgHeight = svgSize.height; - - if (!svgWidth || !svgHeight) - { - throw new Error('The SVG image must have width and height defined (in pixels), canvas API needs them.'); - } - - // Scale realWidth and realHeight - this.realWidth = Math.round(svgWidth * this.sourceScale); - this.realHeight = Math.round(svgHeight * this.sourceScale); - - this._updateDimensions(); - - // Create a canvas element - const canvas = document.createElement('canvas'); - - canvas.width = this.realWidth; - canvas.height = this.realHeight; - canvas._pixiId = `canvas_${uid()}`; - - // Draw the Svg to the canvas - canvas - .getContext('2d') - .drawImage(this.source, 0, 0, svgWidth, svgHeight, 0, 0, this.realWidth, this.realHeight); - - // Replace the original source image with the canvas - this.origSource = this.source; - this.source = canvas; - - // Add also the canvas in cache (destroy clears by `imageUrl` and `source._pixiId`) - BaseTextureCache[canvas._pixiId] = this; - - this.isLoading = false; - this._sourceLoaded(); - this.emit('loaded', this); - } - - /** - * Used internally to update the width, height, and some other tracking vars once - * a source has successfully loaded. - * - * @private - */ - _sourceLoaded() - { - this.hasLoaded = true; - this.update(); - } - - /** - * Destroys this base texture - * - */ - destroy() - { - if (this.imageUrl) - { - delete BaseTextureCache[this.imageUrl]; - delete TextureCache[this.imageUrl]; - - this.imageUrl = null; - - if (!navigator.isCocoonJS) - { - this.source.src = ''; - } - } - // An svg source has both `imageUrl` and `__pixiId`, so no `else if` here - if (this.source && this.source._pixiId) - { - delete BaseTextureCache[this.source._pixiId]; - } - - this.source = null; - - this.dispose(); - } - - /** - * Frees the texture from WebGL memory without destroying this texture object. - * This means you can still use the texture later which will upload it to GPU - * memory again. - * - */ - dispose() - { - this.emit('dispose', this); - } - - /** - * Changes the source image of the texture. - * The original source must be an Image element. - * - * @param {string} newSrc - the path of the image - */ - updateSourceImage(newSrc) - { - this.source.src = newSrc; - - this.loadSource(this.source); - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode, sourceScale) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const image = new Image();// document.createElement('img'); - - if (crossorigin === undefined && imageUrl.indexOf('data:') !== 0) - { - image.crossOrigin = determineCrossOrigin(imageUrl); - } - - baseTexture = new BaseTexture(image, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } -} diff --git a/src/core/textures/CubeTexture.js b/src/core/textures/CubeTexture.js new file mode 100644 index 0000000..5a66a1f --- /dev/null +++ b/src/core/textures/CubeTexture.js @@ -0,0 +1,88 @@ +import Texture from './BaseTexture'; +import ImageResource from './resources/ImageResource'; +import {TARGETS} from './../const'; + +export default class CubeTexture extends Texture +{ + constructor(width, height, format) + { + super(null, 0, 1, width, height, format); + + this.target = TARGETS.TEXTURE_CUBE_MAP; // gl.TEXTURE_CUBE_MAP + + 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/FrameBuffer.js b/src/core/textures/FrameBuffer.js new file mode 100644 index 0000000..0d8796b --- /dev/null +++ b/src/core/textures/FrameBuffer.js @@ -0,0 +1,91 @@ +import Texture from './BaseTexture' +import {FORMATS, TYPES} from './../const'; + +export default class FrameBuffer +{ + constructor(width, height) + { + this.width = width || 100; + this.height = height || 100; + + this.stencil = false; + this.depth = false; + + this.dirtyId = 0; + this.dirtyFormat = 0; + this.dirtySize = 0; + + this.depthTexture = null; + this.colorTextures = []; + + this.glFrameBuffers = {}; + } + + get colorTexture() + { + return this.colorTextures[0]; + } + + addColorTexture(index, texture) + { + // TODO add some validation to the texture - same width / height etc? + this.colorTextures[index || 0] = texture || new Texture(null, 0, 1, this.width, this.height);// || new Texture(); + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + + addDepthTexture(texture) + { + this.depthTexture = texture || new Texture(null, 0, 1, this.width, this.height, FORMATS.DEPTH_COMPONENT, TYPES.UNSIGNED_SHORT);//UNSIGNED_SHORT; + + this.dirtyId++; + this.dirtyFormat++; + return this; + } + + enableDepth() + { + this.depth = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + enableStencil() + { + this.stencil = true; + + this.dirtyId++; + this.dirtyFormat++; + + return this; + } + + resize(width, height) + { + if(width === this.width && height === this.height)return; + + this.width = width; + this.height = height; + + this.dirtyId++; + this.dirtySize++; + + for (var i = 0; i < this.colorTextures.length; i++) { + this.colorTextures[i].resize(width, height); + } + + if(this.depthTexture) + { + this.depthTexture.resize(width, height) + } + } + + +} \ No newline at end of file diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 4646716..fdd1886 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -1,8 +1,10 @@ import BaseTexture from './BaseTexture'; import VideoBaseTexture from './VideoBaseTexture'; import ImageResource from './resources/ImageResource'; +import CanvasResource from './resources/CanvasResource'; import TextureUvs from './TextureUvs'; import EventEmitter from 'eventemitter3'; +import settings from '../settings'; import { Rectangle } from '../math'; import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; @@ -443,10 +445,11 @@ { const resource = new ImageResource(source);//.from(imageUrl, crossorigin);// document.createElement('img'); - const baseTexture = new BaseTexture();//image, scaleMode); - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(resource); + const baseTexture = new BaseTexture(resource, + settings.SCALE_MODE, + getResolutionOfUrl(imageUrl)); + console.log(baseTexture) const texture = new Texture(baseTexture); // No name, use imageUrl instead @@ -591,7 +594,7 @@ context.fillStyle = 'white'; context.fillRect(0, 0, 10, 10); - return new Texture(new BaseTexture(canvas)); + return new Texture(new BaseTexture(new CanvasResource(canvas))); } function removeAllHandlers(tex) diff --git a/src/core/textures/new/CubeTexture.js b/src/core/textures/new/CubeTexture.js deleted file mode 100644 index c3cde40..0000000 --- a/src/core/textures/new/CubeTexture.js +++ /dev/null @@ -1,88 +0,0 @@ -import Texture from '../BaseTexture'; -import ImageResource from '../resources/ImageResource'; - -export default class CubeTexture extends Texture -{ - constructor(width, height, format) - { - super(width, height, format); - - this.target = 34067; // gl.TEXTURE_CUBE_MAP - - 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 deleted file mode 100644 index 10e7364..0000000 --- a/src/core/textures/new/FrameBuffer.js +++ /dev/null @@ -1,92 +0,0 @@ -import Texture from './Texture' - - -export default class FrameBuffer -{ - constructor(width, height) - { - this.width = width || 100; - this.height = height || 100; - - this.stencil = false; - this.depth = false; - - this.dirtyId = 0; - this.dirtyFormat = 0; - this.dirtySize = 0; - - this.depthTexture = null; - this.colorTextures = []; - - this.glFrameBuffers = {}; - } - - get colorTexture() - { - return this.colorTextures[0]; - } - - addColorTexture(index, texture) - { - // TODO add some validation to the texture - same width / height etc? - this.colorTextures[index || 0] = texture || new Texture(this.width, this.height);// || new Texture(); - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - - addDepthTexture(texture) - { - this.depthTexture = texture || new Texture(this.width, this.height, 6402, 5123)//UNSIGNED_SHORT; - - - this.dirtyId++; - this.dirtyFormat++; - return this; - } - - enableDepth() - { - this.depth = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - enableStencil() - { - this.stencil = true; - - this.dirtyId++; - this.dirtyFormat++; - - return this; - } - - resize(width, height) - { - if(width === this.width && height === this.height)return; - - this.width = width; - this.height = height; - - this.dirtyId++; - this.dirtySize++; - - for (var i = 0; i < this.colorTextures.length; i++) { - this.colorTextures[i].resize(width, height); - } - - if(this.depthTexture) - { - this.depthTexture.resize(width, height) - } - } - - -} \ No newline at end of file diff --git a/src/core/textures/new/Texture.js b/src/core/textures/new/Texture.js deleted file mode 100644 index b4d849f..0000000 --- a/src/core/textures/new/Texture.js +++ /dev/null @@ -1,294 +0,0 @@ -import { - uid, getUrlFileExtension, decomposeDataUri, getSvgSize, - getResolutionOfUrl, BaseTextureCache, TextureCache, -} from '../../utils'; - -import ImageResource from '../resources/ImageResource'; -import BufferResource from '../resources/BufferResource'; -import settings from '../../settings'; -import EventEmitter from 'eventemitter3'; - -export default class Texture extends EventEmitter -{ - constructor(width, height, format, type, resolution) - { - - super(); - - - this.uid = uid(); - - this.touched = 0; - - /** - * The width of texture - * - * @member {Number} - */ - this.width = width || -1; - /** - * The height of texture - * - * @member {Number} - */ - this.height = height || -1; - - /** - * The resolution / device pixel ratio of the texture - * - * @member {number} - * @default 1 - */ - this.resolution = resolution || settings.RESOLUTION; - - /** - * Whether or not the texture is a power of two, try to use power of two textures as much - * as you can - * - * @private - * @member {boolean} - */ - this.isPowerOfTwo = false; - - /** - * If mipmapping was used for this texture, enable and disable with enableMipmap() - * - * @member {Boolean} - */ - this.mipmap = false;//settings.MIPMAP_TEXTURES; - - /** - * Set to true to enable pre-multiplied alpha - * - * @member {Boolean} - */ - this.premultiplyAlpha = true; - - /** - * [wrapMode description] - * @type {[type]} - */ - this.wrapMode = settings.WRAP_MODE; - - /** - * The scale mode to apply when scaling this texture - * - * @member {number} - * @default PIXI.settings.SCALE_MODE - * @see PIXI.SCALE_MODES - */ - this.scaleMode = settings.SCALE_MODE; - - /** - * The pixel format of the texture. defaults to gl.RGBA - * - * @member {Number} - */ - this.format = format || 6408//gl.RGBA; - this.type = type || 5121; //UNSIGNED_BYTE - - this.target = 3553; // gl.TEXTURE_2D - - this.glTextures = {}; - - this._new = true; - - this.resource = null; - - - - this.dirtyId = 0; - - this.valid = false; - - this.validate(); - } - - get realWidth() - { - return this.width / this.resolution; - } - - get realHeight() - { - return this.height / this.resolution; - } - - setResource(resource) - { - this.resource = resource; - - this.resource.load.then((resource) => { - - if(this.resource === resource) - { - if(resource.width !== -1 && resource.hight !== -1) - { - this.width = resource.width; - this.height = resource.height; - } - - this.validate(); - - if(this.valid) - { - // we have not swapped half way! - this.dirtyId++; - } - } - - }) - } - - resize(width, height) - { - this.width = width; - this.height = height; - - this.dirtyId++; - } - - validate() - { - let valid = true; - - if(this.width === -1 || this.height === -1) - { - valid = false; - } - - this.valid = valid; - } - - /** - * Helper function that creates a base texture from the given image url. - * If the image is not in the base texture cache it will be created and loaded. - * - * @static - * @param {string} imageUrl - The image url of the texture - * @param {boolean} [crossorigin=(auto)] - Should use anonymous CORS? Defaults to true if the URL is not a data-URI. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromImage(imageUrl, crossorigin, scaleMode) - { - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - const resource = ImageResource.from(imageUrl, crossorigin);// document.createElement('img'); - - baseTexture = new Texture();//image, scaleMode); - - baseTexture.scaleMode = scaleMode || baseTexture.scaleMode; - baseTexture.resolution = getResolutionOfUrl(imageUrl); - baseTexture.setResource(new ImageResource(image)); - - image.src = imageUrl; // Setting this triggers load - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture from the given canvas element. - * - * @static - * @param {HTMLCanvasElement} canvas - The canvas element source of the texture - * @param {number} scaleMode - See {@link PIXI.SCALE_MODES} for possible values - * @return {PIXI.BaseTexture} The new base texture. - */ - static fromCanvas(canvas, scaleMode) - { - - if (!canvas._pixiId) - { - canvas._pixiId = `canvas_${uid()}`; - } - - let baseTexture = BaseTextureCache[canvas._pixiId]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(canvas, scaleMode); - BaseTextureCache[canvas._pixiId] = baseTexture; - } - - return baseTexture; - } - - /** - * Helper function that creates a base texture based on the source you provide. - * The source can be - image url, image element, canvas element. - * - * @static - * @param {string|HTMLImageElement|HTMLCanvasElement} source - The source to create base texture from. - * @param {number} [scaleMode=PIXI.settings.SCALE_MODE] - See {@link PIXI.SCALE_MODES} for possible values - * @param {number} [sourceScale=(auto)] - Scale for the original image, used with Svg images. - * @return {PIXI.BaseTexture} The new base texture. - */ - static from(source, scaleMode, sourceScale) - { - if (typeof source === 'string') - { - return BaseTexture.fromImage(source, undefined, scaleMode, sourceScale); - } - else if (source instanceof HTMLImageElement) - { - const imageUrl = source.src; - let baseTexture = BaseTextureCache[imageUrl]; - - if (!baseTexture) - { - baseTexture = new BaseTexture(source, scaleMode); - baseTexture.imageUrl = imageUrl; - - if (sourceScale) - { - baseTexture.sourceScale = sourceScale; - } - - // if there is an @2x at the end of the url we are going to assume its a highres image - baseTexture.resolution = getResolutionOfUrl(imageUrl); - - BaseTextureCache[imageUrl] = baseTexture; - } - - return baseTexture; - } - else if (source instanceof HTMLCanvasElement) - { - return BaseTexture.fromCanvas(source, scaleMode); - } - - // lets assume its a base texture! - return source; - } - - static fromFloat32Array(width, height, float32Array) - { - var texture = new Texture(width, height, 6408, 5126); - - float32Array = float32Array || new Float32Array(width*height*4); - - texture.setResource(new BufferResource(float32Array)); - - return texture; - } - - static fromUint8Array(width, height, uint8Array) - { - var texture = new Texture(width, height, 6408, 5121); - - uint8Array = uint8Array || new Uint8Array(width*height*4); - - texture.setResource(new BufferResource(uint8Array)); - - return texture; - } - -} \ No newline at end of file diff --git a/src/core/textures/resources/BufferResource.js b/src/core/textures/resources/BufferResource.js index 72cf410..b872455 100644 --- a/src/core/textures/resources/BufferResource.js +++ b/src/core/textures/resources/BufferResource.js @@ -1,13 +1,10 @@ +import TextureResource from './TextureResource'; -export default class BufferResource +export default class BufferResource extends TextureResource { constructor(source) { - this.source = source; - this.loaded = true; // TODO rename to ready? - this.width = -1; - this.height = -1; - this.uploadable = false; + super(source); this.load = new Promise((resolve, reject) => { diff --git a/src/core/textures/resources/CanvasResource.js b/src/core/textures/resources/CanvasResource.js index 0d91551..70c3962 100644 --- a/src/core/textures/resources/CanvasResource.js +++ b/src/core/textures/resources/CanvasResource.js @@ -1,10 +1,11 @@ -import determineCrossOrigin from '../../utils/determineCrossOrigin'; +import TextureResource from './TextureResource'; -export default class CanvasResource +export default class CanvasResource extends TextureResource { constructor(source) { - this.source = source; + super(source); + this.loaded = true; // TODO rename to ready? this.width = source.width; this.height = source.height; @@ -21,6 +22,4 @@ { return new CanvasResource(canvas); } - - } \ No newline at end of file diff --git a/src/core/textures/resources/ImageResource.js b/src/core/textures/resources/ImageResource.js index c969c15..1ee6312 100644 --- a/src/core/textures/resources/ImageResource.js +++ b/src/core/textures/resources/ImageResource.js @@ -1,15 +1,11 @@ import determineCrossOrigin from '../../utils/determineCrossOrigin'; +import TextureResource from './TextureResource'; -export default class ImageResource +export default class ImageResource extends TextureResource { constructor(source) { - this.source = source; - this.loaded = false; // TODO rename to ready? - this.width = -1; - this.height = -1; - - this.uploadable = true; + super(); this.load = new Promise((resolve, reject) => { diff --git a/src/core/textures/resources/SVGResource.js b/src/core/textures/resources/SVGResource.js index f00fee0..29a5810 100644 --- a/src/core/textures/resources/SVGResource.js +++ b/src/core/textures/resources/SVGResource.js @@ -1,4 +1,3 @@ -import determineCrossOrigin from '../../utils/determineCrossOrigin'; import { decomposeDataUri, getSvgSize, uid } from '../../utils'; @@ -7,11 +6,7 @@ { constructor(svgSource, scale) { - - this.source = null;//source; - this.loaded = false; // TODO rename to ready? - this.width = -1; - this.height = -1; + super(); this.svgSource = svgSource; this.scale = 1 || scale; diff --git a/src/core/textures/resources/TextureResource.js b/src/core/textures/resources/TextureResource.js new file mode 100644 index 0000000..c21ad7f --- /dev/null +++ b/src/core/textures/resources/TextureResource.js @@ -0,0 +1,21 @@ +import Runner from 'mini-runner'; + +export default class TextureResource +{ + constructor(source) + { + this.source = source; + + this.loaded = false; // TODO rename to ready? + + this.width = -1; + this.height = -1; + + this.uploadable = true; + + this.updated = new Runner('resourceUpdated'); + + // create a prommise.. + this.load = null; + } +} \ No newline at end of file diff --git a/src/extras/webgl/TilingSpriteRenderer.js b/src/extras/webgl/TilingSpriteRenderer.js index bf3aeb5..5c1a80b 100644 --- a/src/extras/webgl/TilingSpriteRenderer.js +++ b/src/extras/webgl/TilingSpriteRenderer.js @@ -151,8 +151,7 @@ color[3] = ts.worldAlpha; shader.uniforms.uColor = color; shader.uniforms.translationMatrix = ts.transform.worldTransform.toArray(true); - - shader.uniforms.uSampler = renderer.bindTexture(tex); + shader.uniforms.uSampler = renderer.texture.bind(tex.baseTexture, 0); renderer.setBlendMode(ts.blendMode);