From a5b9a8efb14e934a3601734a81eb82c0af8e10b0 Mon Sep 17 00:00:00 2001 From: xingsenma Date: Tue, 10 Dec 2013 17:01:50 +0800 Subject: [PATCH 1/3] closed #3349: add ClippingNode for canvas mode --- cocos2d/misc_nodes/CCClippingNode.js | 96 ++++++++++++++++++- extensions/CocoStudio/GUI/Layouts/UILayout.js | 50 +--------- 2 files changed, 96 insertions(+), 50 deletions(-) diff --git a/cocos2d/misc_nodes/CCClippingNode.js b/cocos2d/misc_nodes/CCClippingNode.js index c9d3f08985..5d10a0dc82 100644 --- a/cocos2d/misc_nodes/CCClippingNode.js +++ b/cocos2d/misc_nodes/CCClippingNode.js @@ -65,7 +65,9 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{ * The stencil node will be retained, and its parent will be set to this clipping node. * @param {cc.Node} [stencil=null] */ - init:function(stencil){ + init:null, + + _initForWebGL:function(stencil){ this._stencil = stencil; this._alphaThreshold = 1; @@ -81,6 +83,12 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{ return true; }, + _initForCanvas:function(stencil){ + this._stencil = stencil; + this._alphaThreshold = 1; + this._inverted = false; + }, + onEnter:function(){ cc.Node.prototype.onEnter.call(this); this._stencil.onEnter(); @@ -101,7 +109,9 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{ cc.Node.prototype.onExit.call(this); }, - visit:function(ctx){ + visit:null, + + _visitForWebGL:function(ctx){ var gl = ctx || cc.renderContext; // if stencil buffer disabled @@ -270,6 +280,46 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{ cc.ClippingNode._layer--; }, + _visitForCanvas:function(ctx){ + // return fast (draw nothing, or draw everything if in inverted mode) if: + // - nil stencil node + // - or stencil node invisible: + if (!this._stencil || !this._stencil.isVisible()) { + if (this._inverted) + cc.Node.prototype.visit.call(this, ctx); // draw everything + return; + } + + //visit for canvas + var context = ctx || cc.renderContext, i; + var children = this._children, locChild; + context.save(); + this.transform(context); + + this._stencil.visit(ctx); + context.clip(); + + var len = children.length; + if (len > 0) { + this.sortAllChildren(); + // draw children zOrder < 0 + for (i = 0; i < len; i++) { + locChild = children[i]; + if (locChild._zOrder < 0) + locChild.visit(context); + else + break; + } + this.draw(context); + for (; i < len; i++) { + children[i].visit(context); + } + } else + this.draw(context); + + context.restore(); + }, + /** * The cc.Node to use as a stencil to do the clipping.
* The stencil node will be retained. This default to nil. @@ -282,10 +332,39 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{ /** * @param {cc.Node} stencil */ - setStencil:function(stencil){ + setStencil:null, + + _setStencilForWebGL:function(stencil){ this._stencil = stencil; }, + _setStencilForCanvas: function (stencil) { + this._stencil = stencil; + var locEGL_ScaleX = cc.EGLView.getInstance().getScaleX(), locEGL_ScaleY = cc.EGLView.getInstance().getScaleY(); + var locContext = cc.renderContext; + //rewrite the draw of stencil ,only init the clip path and draw nothing. + if (stencil instanceof cc.DrawNode) { + stencil.draw = function () { + for (var i = 0; i < stencil._buffer.length; i++) { + var element = stencil._buffer[i]; + var vertices = element.verts; + var firstPoint = vertices[0]; + locContext.beginPath(); + locContext.moveTo(firstPoint.x * locEGL_ScaleX, -firstPoint.y * locEGL_ScaleY); + for (var j = 1, len = vertices.length; j < len; j++) + locContext.lineTo(vertices[j].x * locEGL_ScaleX, -vertices[j].y * locEGL_ScaleY); + } + } + } else if (stencil instanceof cc.Node) { + stencil.draw = function () { + var locSize = stencil.getContentSize(); + var locRect = cc.rect(0, 0, locSize.width * locEGL_ScaleX, locSize.height * locEGL_ScaleY); + locContext.beginPath(); + locContext.rect(locRect.x, locRect.y, locRect.width, -locRect.height); + } + } + }, + /** *

* The alpha threshold.
@@ -329,6 +408,17 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{ } }); +if(cc.Browser.supportWebGL){ + //WebGL + cc.ClippingNode.prototype.init = cc.ClippingNode.prototype._initForWebGL; + cc.ClippingNode.prototype.visit = cc.ClippingNode.prototype._visitForWebGL; + cc.ClippingNode.prototype.setStencil = cc.ClippingNode.prototype._setStencilForWebGL; +}else{ + cc.ClippingNode.prototype.init = cc.ClippingNode.prototype._initForCanvas; + cc.ClippingNode.prototype.visit = cc.ClippingNode.prototype._visitForCanvas; + cc.ClippingNode.prototype.setStencil = cc.ClippingNode.prototype._setStencilForCanvas; +} + cc.ClippingNode._init_once = null; cc.ClippingNode._visit_once = null; cc.ClippingNode._layer = null; diff --git a/extensions/CocoStudio/GUI/Layouts/UILayout.js b/extensions/CocoStudio/GUI/Layouts/UILayout.js index 116668c7ea..41eb8ba8d9 100644 --- a/extensions/CocoStudio/GUI/Layouts/UILayout.js +++ b/extensions/CocoStudio/GUI/Layouts/UILayout.js @@ -1035,7 +1035,8 @@ ccs.UIRectClippingNode = cc.ClippingNode.extend({ this._arrRect[3] = cc.p(0, this._clippingSize.height); var green = cc.c4f(0, 1, 0, 1); this._innerStencil.clear(); - //this._innerStencil.drawPoly(this._arrRect, green, 0, green); + this._innerStencil.drawPoly(this._arrRect, green, 0, green); + this.setStencil(this._innerStencil); }, setClippingEnabled: function (enabled) { @@ -1047,58 +1048,13 @@ ccs.UIRectClippingNode = cc.ClippingNode.extend({ return; } if (this._clippingEnabled) { - if (cc.Browser.supportWebGL) { - cc.ClippingNode.prototype.visit.call(this, ctx); - } else { - this.visitCanvas(ctx); - } + cc.ClippingNode.prototype.visit.call(this, ctx); } else { cc.Node.prototype.visit.call(this, ctx); } }, - visitCanvas: function (ctx) { - // quick return if not visible - if (!this._visible) - return; - - //visit for canvas - var context = ctx || cc.renderContext, i; - var children = this._children, locChild; - context.save(); - this.transform(context); - context.beginPath(); - var locContentSize = this.getContentSize(); - var locRect = cc.rect(0, 0, locContentSize.width, locContentSize.height); - var locEGL_ScaleX = cc.EGLView.getInstance().getScaleX(), locEGL_ScaleY = cc.EGLView.getInstance().getScaleY(); - - context.rect(locRect.x * locEGL_ScaleX, locRect.y * locEGL_ScaleY, locRect.width * locEGL_ScaleX, -locRect.height * locEGL_ScaleY); - context.clip(); - context.closePath(); - var len = children.length; - if (len > 0) { - this.sortAllChildren(); - // draw children zOrder < 0 - for (i = 0; i < len; i++) { - locChild = children[i]; - if (locChild._zOrder < 0) - locChild.visit(context); - else - break; - } - this.draw(context); - for (; i < len; i++) { - children[i].visit(context); - } - } else - this.draw(context); - - this._orderOfArrival = 0; - context.restore(); - this._stencil.visit(); - }, - setEnabled: function (enabled) { this._enabled = enabled; }, From 2f44d46ca233d32c26257c569bb2a107da95d658 Mon Sep 17 00:00:00 2001 From: xingsenma Date: Tue, 10 Dec 2013 17:40:07 +0800 Subject: [PATCH 2/3] issue #3349: add ClippingNode for canvas mode --- cocos2d/misc_nodes/CCClippingNode.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cocos2d/misc_nodes/CCClippingNode.js b/cocos2d/misc_nodes/CCClippingNode.js index 5d10a0dc82..821b864968 100644 --- a/cocos2d/misc_nodes/CCClippingNode.js +++ b/cocos2d/misc_nodes/CCClippingNode.js @@ -358,9 +358,8 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{ } else if (stencil instanceof cc.Node) { stencil.draw = function () { var locSize = stencil.getContentSize(); - var locRect = cc.rect(0, 0, locSize.width * locEGL_ScaleX, locSize.height * locEGL_ScaleY); locContext.beginPath(); - locContext.rect(locRect.x, locRect.y, locRect.width, -locRect.height); + locContext.rect(0, 0, locSize.width, -locSize.height); } } }, From e4b259cdf2c4b0e5146fe24f61cc6cb756132f04 Mon Sep 17 00:00:00 2001 From: xingsenma Date: Tue, 10 Dec 2013 17:43:28 +0800 Subject: [PATCH 3/3] issue #3349: add ClippingNode for canvas mode --- cocos2d/misc_nodes/CCClippingNode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cocos2d/misc_nodes/CCClippingNode.js b/cocos2d/misc_nodes/CCClippingNode.js index 821b864968..382291cb24 100644 --- a/cocos2d/misc_nodes/CCClippingNode.js +++ b/cocos2d/misc_nodes/CCClippingNode.js @@ -359,7 +359,7 @@ cc.ClippingNode = cc.Node.extend(/** @lends cc.ClippingNode# */{ stencil.draw = function () { var locSize = stencil.getContentSize(); locContext.beginPath(); - locContext.rect(0, 0, locSize.width, -locSize.height); + locContext.rect(0, 0, locSize.width * locEGL_ScaleX, -locSize.height * locEGL_ScaleY); } } },