diff --git a/src/mesh/Mesh.js b/src/mesh/Mesh.js index 14dc947..b8738ed 100644 --- a/src/mesh/Mesh.js +++ b/src/mesh/Mesh.js @@ -84,6 +84,13 @@ // run texture setter; this.texture = texture; + + /** + * The default shader that is used if a mesh doesn't have a more specific one. + * + * @member {PIXI.Shader} + */ + this.shader = null; } // constructor diff --git a/src/mesh/Mesh.js b/src/mesh/Mesh.js index 14dc947..b8738ed 100644 --- a/src/mesh/Mesh.js +++ b/src/mesh/Mesh.js @@ -84,6 +84,13 @@ // run texture setter; this.texture = texture; + + /** + * The default shader that is used if a mesh doesn't have a more specific one. + * + * @member {PIXI.Shader} + */ + this.shader = null; } // constructor diff --git a/src/mesh/Plane.js b/src/mesh/Plane.js new file mode 100644 index 0000000..6debabc --- /dev/null +++ b/src/mesh/Plane.js @@ -0,0 +1,123 @@ +var Mesh = require('./Mesh'); +var core = require('../core'); + +/** + * The Plane allows you to draw a texture across several points and them manipulate these points + * + *```js + * for (var i = 0; i < 20; i++) { + * points.push(new PIXI.Point(i * 50, 0)); + * }; + * var Plane = new PIXI.Plane(PIXI.Texture.fromImage("snake.png"), points); + * ``` + * + * @class + * @extends PIXI.mesh.Mesh + * @memberof PIXI.mesh + * @param {PIXI.Texture} texture - The texture to use on the Plane. + * @param {int} segmentsX - The number ox x segments + * @param {int} segmentsY - The number of y segments + * + */ +function Plane(texture, segmentsX, segmentsY) +{ + Mesh.call(this, texture); + + /** + * Tracker for if the Plane is ready to be drawn. Needed because Mesh ctor can + * call _onTextureUpdated which could call refresh too early. + * + * @member {boolean} + * @private + */ + this._ready = true; + + this.segmentsX = segmentsX || 10; + this.segmentsY = segmentsY || 10; + + this.drawMode = Mesh.DRAW_MODES.TRIANGLES; + this.refresh(); + +} + + +// constructor +Plane.prototype = Object.create( Mesh.prototype ); +Plane.prototype.constructor = Plane; +module.exports = Plane; + +/** + * Refreshes + * + */ +Plane.prototype.refresh = function() +{ + var total = this.segmentsX * this.segmentsY; + var verts = []; + var colors = []; + var uvs = []; + var indices = []; + var texture = this.texture; + + // texture.width = 800 texture.width || 800; + // texture.height = 800//texture.height || 800; + + var segmentsXSub = this.segmentsX - 1; + var segmentsYSub = this.segmentsY - 1; + + // TODO MAP UVS.. + var sizeX = texture.width / segmentsXSub; + var sizeY = texture.height / segmentsYSub; + + for (var i = 0; i < total; i++) { + + var x = (i % this.segmentsX); + var y = ( (i / this.segmentsX ) | 0 ) + + + verts.push((x * sizeX), + (y * sizeY)) + + uvs.push(x / (this.segmentsX-1), y/ (this.segmentsY-1)); + }; + + // cons + + var totalSub = segmentsXSub * segmentsYSub; + + for (var i = 0; i < totalSub; i++) { + + var xpos = i % segmentsXSub; + var ypos = (i / segmentsXSub ) | 0; + + + var value = (ypos * this.segmentsX) + xpos; + var value2 = (ypos * this.segmentsX) + xpos + 1; + var value3 = ((ypos+1) * this.segmentsX) + xpos; + var value4 = ((ypos+1) * this.segmentsX) + xpos + 1; + + indices.push(value, value2, value3); + indices.push(value2, value4, value3); + } + + + //console.log(indices) + this.vertices = new Float32Array(verts); + this.uvs = new Float32Array(uvs); + this.colors = new Float32Array(colors); + this.indices = new Uint16Array(indices); +} +/** + * Clear texture UVs when new texture is set + * + * @private + */ +Plane.prototype._onTextureUpdate = function () +{ + Mesh.prototype._onTextureUpdate.call(this); + + // wait for the Plane ctor to finish before calling refresh + if (this._ready) { + this.refresh(); + } +}; diff --git a/src/mesh/Mesh.js b/src/mesh/Mesh.js index 14dc947..b8738ed 100644 --- a/src/mesh/Mesh.js +++ b/src/mesh/Mesh.js @@ -84,6 +84,13 @@ // run texture setter; this.texture = texture; + + /** + * The default shader that is used if a mesh doesn't have a more specific one. + * + * @member {PIXI.Shader} + */ + this.shader = null; } // constructor diff --git a/src/mesh/Plane.js b/src/mesh/Plane.js new file mode 100644 index 0000000..6debabc --- /dev/null +++ b/src/mesh/Plane.js @@ -0,0 +1,123 @@ +var Mesh = require('./Mesh'); +var core = require('../core'); + +/** + * The Plane allows you to draw a texture across several points and them manipulate these points + * + *```js + * for (var i = 0; i < 20; i++) { + * points.push(new PIXI.Point(i * 50, 0)); + * }; + * var Plane = new PIXI.Plane(PIXI.Texture.fromImage("snake.png"), points); + * ``` + * + * @class + * @extends PIXI.mesh.Mesh + * @memberof PIXI.mesh + * @param {PIXI.Texture} texture - The texture to use on the Plane. + * @param {int} segmentsX - The number ox x segments + * @param {int} segmentsY - The number of y segments + * + */ +function Plane(texture, segmentsX, segmentsY) +{ + Mesh.call(this, texture); + + /** + * Tracker for if the Plane is ready to be drawn. Needed because Mesh ctor can + * call _onTextureUpdated which could call refresh too early. + * + * @member {boolean} + * @private + */ + this._ready = true; + + this.segmentsX = segmentsX || 10; + this.segmentsY = segmentsY || 10; + + this.drawMode = Mesh.DRAW_MODES.TRIANGLES; + this.refresh(); + +} + + +// constructor +Plane.prototype = Object.create( Mesh.prototype ); +Plane.prototype.constructor = Plane; +module.exports = Plane; + +/** + * Refreshes + * + */ +Plane.prototype.refresh = function() +{ + var total = this.segmentsX * this.segmentsY; + var verts = []; + var colors = []; + var uvs = []; + var indices = []; + var texture = this.texture; + + // texture.width = 800 texture.width || 800; + // texture.height = 800//texture.height || 800; + + var segmentsXSub = this.segmentsX - 1; + var segmentsYSub = this.segmentsY - 1; + + // TODO MAP UVS.. + var sizeX = texture.width / segmentsXSub; + var sizeY = texture.height / segmentsYSub; + + for (var i = 0; i < total; i++) { + + var x = (i % this.segmentsX); + var y = ( (i / this.segmentsX ) | 0 ) + + + verts.push((x * sizeX), + (y * sizeY)) + + uvs.push(x / (this.segmentsX-1), y/ (this.segmentsY-1)); + }; + + // cons + + var totalSub = segmentsXSub * segmentsYSub; + + for (var i = 0; i < totalSub; i++) { + + var xpos = i % segmentsXSub; + var ypos = (i / segmentsXSub ) | 0; + + + var value = (ypos * this.segmentsX) + xpos; + var value2 = (ypos * this.segmentsX) + xpos + 1; + var value3 = ((ypos+1) * this.segmentsX) + xpos; + var value4 = ((ypos+1) * this.segmentsX) + xpos + 1; + + indices.push(value, value2, value3); + indices.push(value2, value4, value3); + } + + + //console.log(indices) + this.vertices = new Float32Array(verts); + this.uvs = new Float32Array(uvs); + this.colors = new Float32Array(colors); + this.indices = new Uint16Array(indices); +} +/** + * Clear texture UVs when new texture is set + * + * @private + */ +Plane.prototype._onTextureUpdate = function () +{ + Mesh.prototype._onTextureUpdate.call(this); + + // wait for the Plane ctor to finish before calling refresh + if (this._ready) { + this.refresh(); + } +}; diff --git a/src/mesh/index.js b/src/mesh/index.js index 819c45b..38a3f41 100644 --- a/src/mesh/index.js +++ b/src/mesh/index.js @@ -10,6 +10,7 @@ */ module.exports = { Mesh: require('./Mesh'), + Plane: require('./Plane'), Rope: require('./Rope'), MeshRenderer: require('./webgl/MeshRenderer'), MeshShader: require('./webgl/MeshShader') diff --git a/src/mesh/Mesh.js b/src/mesh/Mesh.js index 14dc947..b8738ed 100644 --- a/src/mesh/Mesh.js +++ b/src/mesh/Mesh.js @@ -84,6 +84,13 @@ // run texture setter; this.texture = texture; + + /** + * The default shader that is used if a mesh doesn't have a more specific one. + * + * @member {PIXI.Shader} + */ + this.shader = null; } // constructor diff --git a/src/mesh/Plane.js b/src/mesh/Plane.js new file mode 100644 index 0000000..6debabc --- /dev/null +++ b/src/mesh/Plane.js @@ -0,0 +1,123 @@ +var Mesh = require('./Mesh'); +var core = require('../core'); + +/** + * The Plane allows you to draw a texture across several points and them manipulate these points + * + *```js + * for (var i = 0; i < 20; i++) { + * points.push(new PIXI.Point(i * 50, 0)); + * }; + * var Plane = new PIXI.Plane(PIXI.Texture.fromImage("snake.png"), points); + * ``` + * + * @class + * @extends PIXI.mesh.Mesh + * @memberof PIXI.mesh + * @param {PIXI.Texture} texture - The texture to use on the Plane. + * @param {int} segmentsX - The number ox x segments + * @param {int} segmentsY - The number of y segments + * + */ +function Plane(texture, segmentsX, segmentsY) +{ + Mesh.call(this, texture); + + /** + * Tracker for if the Plane is ready to be drawn. Needed because Mesh ctor can + * call _onTextureUpdated which could call refresh too early. + * + * @member {boolean} + * @private + */ + this._ready = true; + + this.segmentsX = segmentsX || 10; + this.segmentsY = segmentsY || 10; + + this.drawMode = Mesh.DRAW_MODES.TRIANGLES; + this.refresh(); + +} + + +// constructor +Plane.prototype = Object.create( Mesh.prototype ); +Plane.prototype.constructor = Plane; +module.exports = Plane; + +/** + * Refreshes + * + */ +Plane.prototype.refresh = function() +{ + var total = this.segmentsX * this.segmentsY; + var verts = []; + var colors = []; + var uvs = []; + var indices = []; + var texture = this.texture; + + // texture.width = 800 texture.width || 800; + // texture.height = 800//texture.height || 800; + + var segmentsXSub = this.segmentsX - 1; + var segmentsYSub = this.segmentsY - 1; + + // TODO MAP UVS.. + var sizeX = texture.width / segmentsXSub; + var sizeY = texture.height / segmentsYSub; + + for (var i = 0; i < total; i++) { + + var x = (i % this.segmentsX); + var y = ( (i / this.segmentsX ) | 0 ) + + + verts.push((x * sizeX), + (y * sizeY)) + + uvs.push(x / (this.segmentsX-1), y/ (this.segmentsY-1)); + }; + + // cons + + var totalSub = segmentsXSub * segmentsYSub; + + for (var i = 0; i < totalSub; i++) { + + var xpos = i % segmentsXSub; + var ypos = (i / segmentsXSub ) | 0; + + + var value = (ypos * this.segmentsX) + xpos; + var value2 = (ypos * this.segmentsX) + xpos + 1; + var value3 = ((ypos+1) * this.segmentsX) + xpos; + var value4 = ((ypos+1) * this.segmentsX) + xpos + 1; + + indices.push(value, value2, value3); + indices.push(value2, value4, value3); + } + + + //console.log(indices) + this.vertices = new Float32Array(verts); + this.uvs = new Float32Array(uvs); + this.colors = new Float32Array(colors); + this.indices = new Uint16Array(indices); +} +/** + * Clear texture UVs when new texture is set + * + * @private + */ +Plane.prototype._onTextureUpdate = function () +{ + Mesh.prototype._onTextureUpdate.call(this); + + // wait for the Plane ctor to finish before calling refresh + if (this._ready) { + this.refresh(); + } +}; diff --git a/src/mesh/index.js b/src/mesh/index.js index 819c45b..38a3f41 100644 --- a/src/mesh/index.js +++ b/src/mesh/index.js @@ -10,6 +10,7 @@ */ module.exports = { Mesh: require('./Mesh'), + Plane: require('./Plane'), Rope: require('./Rope'), MeshRenderer: require('./webgl/MeshRenderer'), MeshShader: require('./webgl/MeshShader') diff --git a/src/mesh/webgl/MeshRenderer.js b/src/mesh/webgl/MeshRenderer.js index 1e85087..0eade84 100644 --- a/src/mesh/webgl/MeshRenderer.js +++ b/src/mesh/webgl/MeshRenderer.js @@ -30,6 +30,7 @@ * * @member {Uint16Array} */ + this.indices = new Uint16Array(15000); //TODO this could be a single buffer shared amongst all renderers as we reuse this set up in most renderers @@ -42,6 +43,8 @@ this.indices[i + 4] = j + 2; this.indices[i + 5] = j + 3; } + + this.currentShader = null; } MeshRenderer.prototype = Object.create(core.ObjectRenderer.prototype); @@ -76,18 +79,29 @@ var renderer = this.renderer, gl = renderer.gl, texture = mesh._texture.baseTexture, - shader = renderer.shaderManager.plugins.meshShader; + shader = mesh.shader;// || renderer.shaderManager.plugins.meshShader; var drawMode = mesh.drawMode === Mesh.DRAW_MODES.TRIANGLE_MESH ? gl.TRIANGLE_STRIP : gl.TRIANGLES; renderer.blendModeManager.setBlendMode(mesh.blendMode); + //TODO cache custom state.. + if (!shader) + { + shader = renderer.shaderManager.plugins.meshShader; + } + else + { + shader = shader.shaders[gl.id] || shader.getShader(renderer);// : shader; + } - // set uniforms - gl.uniformMatrix3fv(shader.uniforms.translationMatrix._location, false, mesh.worldTransform.toArray(true)); + this.renderer.shaderManager.setShader(shader); - gl.uniformMatrix3fv(shader.uniforms.projectionMatrix._location, false, renderer.currentRenderTarget.projectionMatrix.toArray(true)); - gl.uniform1f(shader.uniforms.alpha._location, mesh.worldAlpha); + shader.uniforms.translationMatrix.value = mesh.worldTransform.toArray(true); + shader.uniforms.projectionMatrix.value = renderer.currentRenderTarget.projectionMatrix.toArray(true); + shader.uniforms.alpha.value = mesh.worldAlpha; + + shader.syncUniforms(); if (!mesh.dirty) { @@ -198,9 +212,9 @@ */ MeshRenderer.prototype.start = function () { - var shader = this.renderer.shaderManager.plugins.meshShader; + - this.renderer.shaderManager.setShader(shader); + this.currentShader = null; }; /**