File: /home/lindsay/xeolabs/xeogl-next/xeogl/src/lighting/cubeTexture.js
- /**
- A **CubeTexture** specifies a cube texture map.
-
- ## Overview
-
- See {{#crossLink "Lights"}}{{/crossLink}} for an example of how to use CubeTextures for light and reflection mapping.
-
- @class CubeTexture
- @module xeogl
- @submodule lighting
- @constructor
- @param [owner] {Component} Owner component. When destroyed, the owner will destroy this component as well. Creates this component within the default {{#crossLink "Scene"}}{{/crossLink}} when omitted.
- @param [cfg] {*} Configs
- @param [cfg.id] {String} Optional ID for this CubeTexture, unique among all components in the parent scene, generated automatically when omitted.
- @param [cfg.meta] {String:Object} Optional map of user-defined metadata to attach to this CubeTexture.
- @param [cfg.src=null] {Array of String} Paths to six image files to load into this CubeTexture.
- @param [cfg.flipY=false] {Boolean} Flips this CubeTexture's source data along its vertical axis when true.
- @param [cfg.encoding="linear"] {String} Encoding format. See the {{#crossLink "CubeTexture/encoding:property"}}{{/crossLink}} property for more info.
- @extends Component
- */
- import {Component} from '../component.js';
- import {State} from '../renderer/state.js';
- import {Texture2D} from '../renderer/texture2d.js';
- import {stats} from './../stats.js';
- import {componentClasses} from "./../componentClasses.js";
-
- const type = "xeogl.CubeTexture";
-
- function ensureImageSizePowerOfTwo(image) {
- if (!isPowerOfTwo(image.width) || !isPowerOfTwo(image.height)) {
- const canvas = document.createElement("canvas");
- canvas.width = nextHighestPowerOfTwo(image.width);
- canvas.height = nextHighestPowerOfTwo(image.height);
- const ctx = canvas.getContext("2d");
- ctx.drawImage(image,
- 0, 0, image.width, image.height,
- 0, 0, canvas.width, canvas.height);
- image = canvas;
- }
- return image;
- }
-
- function isPowerOfTwo(x) {
- return (x & (x - 1)) === 0;
- }
-
- function nextHighestPowerOfTwo(x) {
- --x;
- for (let i = 1; i < 32; i <<= 1) {
- x = x | x >> i;
- }
- return x + 1;
- }
-
- class CubeTexture extends Component{
-
- /**
- JavaScript class name for this Component.
-
- For example: "xeogl.AmbientLight", "xeogl.MetallicMaterial" etc.
-
- @property type
- @type String
- @final
- */
- get type() {
- return type;
- }
-
- init(cfg) {
-
- super.init(cfg);
-
- const gl = this.scene.canvas.gl;
-
- this._state = new State({
- texture: new Texture2D(gl, gl.TEXTURE_CUBE_MAP),
- flipY: this._checkFlipY(cfg.minFilter),
- encoding: this._checkEncoding(cfg.encoding),
- minFilter: "linearMipmapLinear",
- magFilter: "linear",
- wrapS: "clampToEdge",
- wrapT: "clampToEdge",
- mipmaps: true
- });
-
- this._src = cfg.src;
- this._images = [];
-
- this._loadSrc(cfg.src);
-
- stats.memory.textures++;
- }
-
- _checkFlipY(value) {
- return !!value;
- }
-
- _checkEncoding (value) {
- value = value || "linear";
- if (value !== "linear" && value !== "sRGB" && value !== "gamma") {
- this.error("Unsupported value for 'encoding': '" + value + "' - supported values are 'linear', 'sRGB', 'gamma'. Defaulting to 'linear'.");
- value = "linear";
- }
- return value;
- }
-
- _webglContextRestored () {
- const gl = this.scene.canvas.gl;
- this._state.texture = null;
- // if (this._images.length > 0) {
- // this._state.texture = new xeogl.renderer.Texture2D(gl, gl.TEXTURE_CUBE_MAP);
- // this._state.texture.setImage(this._images, this._state);
- // this._state.texture.setProps(this._state);
- // } else
- if (this._src) {
- this._loadSrc(this._src);
- }
- }
-
- _loadSrc (src) {
- const self = this;
- const gl = this.scene.canvas.gl;
- this._images = [];
- let loadFailed = false;
- let numLoaded = 0;
- for (let i = 0; i < src.length; i++) {
- const image = new Image();
- image.onload = (function () {
- let _image = image;
- const index = i;
- return function () {
- if (loadFailed) {
- return;
- }
- _image = ensureImageSizePowerOfTwo(_image);
- self._images[index] = _image;
- numLoaded++;
- if (numLoaded === 6) {
- let texture = self._state.texture;
- if (!texture) {
- texture = new Texture2D(gl, gl.TEXTURE_CUBE_MAP);
- self._state.texture = texture;
- }
- texture.setImage(self._images, self._state);
- texture.setProps(self._state);
- /**
- * Fired whenever this CubeTexture has loaded the
- * image files that its {{#crossLink "CubeTexture/src:property"}}{{/crossLink}} property currently points to.
- * @event loaded
- * @param value {HTML Image} The value of the {{#crossLink "CubeTexture/src:property"}}{{/crossLink}} property
- */
- self.fire("loaded", self._src);
- }
- };
- })();
- image.onerror = function () {
- loadFailed = true;
- };
- image.src = src[i];
- }
- }
-
- destroy() {
- super.destroy();
- if (this._state.texture) {
- this._state.texture.destroy();
- }
- stats.memory.textures--;
- this._state.destroy();
- }
- }
-
- componentClasses[type] = CubeTexture;
-
- export {CubeTexture};
-