cc.DrawnNode acts weird in the latest version 3.14.1

cc.DrawnNode acts weird in the latest version 3.14.1
0.0 0

#1

Environment:

cocos2d-x 3.14.1

Mac / Chrome Version 56.0.2924.87 (64-bit)
Mac / Safari Version 9.0.1 (11601.2.7.2)

webgl mode

It is hard to describe the problem I can only say that If I try to use a cc.Drawnode instance to draw something each frame and what I draw will become a mess randomly. And it seems to have something to do with using multi cc.DrawNode instance in the game and draw something with them at the same time.

I know that drawPoly can can only handle the Convex poly so I only test with Convex poly.

And the most important thing is the demo works fine with cocos2d-x 3.13.1 and cocos2d-x 3.12 !

So it seem like it is a bug caused in the latest version of cocos2d-x since I found this point in the change log:

cocos2d-x-3.14 Dec 22 2016

[REFINE]        Web: Reimplement a much faster cc.DrawNode WebGL renderer

I have uploaded a simple demo in the attachment, I hope you guys can run and test it I think it is easy to reproduce the problem.

I have also uploaded two gif two show how to reproduce the problem. (One named 3.14.1.gif shows the problem and the one named 3.13.1.gif shows it works fine doing the same thing in cocos2d-x 3.13.1)

cocos2d-x 3.13.1:

cocos2d-x 3.14.1

js-template-default.zip (1.5 MB)

sample code:

this._shapeEditorVerticesArray = [];
this._drawNodeVertices = new cc.DrawNode(); // all the vertexs
this._drawNodeEdge = new cc.DrawNode(); // the current edge
this._drawNodeEdges = new cc.DrawNode(); // all the edges 
this._drawNodePoly = new cc.DrawNode(); // draw the poly
this.addChild(this._drawNodePoly);
this.addChild(this._drawNodeVertices);
this.addChild(this._drawNodeEdge);
this.addChild(this._drawNodeEdges);

var self = this;
this._shapeEditorEvent = cc.eventManager.addListener({
    event: cc.EventListener.TOUCH_ONE_BY_ONE,
    swallowTouches: true,
    onTouchBegan: function (touch, event) {
        var location = touch.getLocation();
        if (self._shapeEditorVerticesArray.length == 0) {
            self._drawNodeVertices.drawDot(location, 5, cc.color.GREEN);
            self._shapeEditorVerticesArray.push(location);
        }
        else {
            self._drawNodeEdge.drawSegment(self._shapeEditorVerticesArray[self._shapeEditorVerticesArray.length - 1], location, 3, cc.color.YELLOW);
        }
        self._plot(location);
        return true;
    },
    onTouchMoved: function (touch, event) {
        if (self._shapeEditorVerticesArray.length > 0) {
            var location = touch.getLocation();
            self._drawNodeEdge.clear();
            self._drawNodeEdge.drawSegment(self._shapeEditorVerticesArray[self._shapeEditorVerticesArray.length - 1], location, 3, cc.color.YELLOW);
            self._plot(location);
        }
    },
    onTouchEnded: function (touch, event) {
        if (self._shapeEditorVerticesArray.length > 0) {
            var location = touch.getLocation();
            // 
            self._drawNodeEdge.clear();
            self._drawNodeEdges.drawSegment(self._shapeEditorVerticesArray[self._shapeEditorVerticesArray.length - 1], location, 3, cc.color.YELLOW);
            self._drawNodeVertices.drawDot(location, 5, cc.color.GREEN);
            self._shapeEditorVerticesArray.push(location);
            self._plot();
        }
    }
}, this);

_plot:function(position) {
    if (this._shapeEditorVerticesArray.length > 2 || (position && this._shapeEditorVerticesArray.length > 1)) {
        this._drawNodePoly.clear();

        if (position) {
            var ppp = this._shapeEditorVerticesArray.slice();
            ppp.push(position);
            this._drawNodePoly.drawPoly(ppp, cc.color.RED, 0, cc.color(0, 0, 0, 0));
        }
        else {
            this._drawNodePoly.drawPoly(this._shapeEditorVerticesArray, cc.color.RED, cc.FLT_EPSILON, cc.color(0, 255, 0, 255));
        }
    }        
}

#2

I think I have similar problem with webgl and no solution so far. For now, Iā€™m just using canvas mode that does not produce this problem. If I am not wrong, this problem is due to unexpected interference between drawnode instance of polygon, drawnode instance of dots, and drawnode instance of line segment in the case above.


#3

Thanks for your rely :slight_smile:

I also tried the canvas mode and the problem did not occur. But for me the canvas mode is way too slow so I still need to find a way to solve this in webgl mode.

Hope the official will look into this issue ā€¦


#4

Meanwhile apart from this problem. If you need, you can draw even concave polygons using a combination of triangulation and draw node: Here is an example:

requirements:

  • a triangulation method. I used this library flawlessly: https://github.com/mapbox/earcut

  • you have to flatten your array of vertices to feed them to earcut function such as:

    function flatten(nestedXY) { // nestedXY is like [cc.p(0, 80), cc.p(20, 90), ā€¦ cc.p(200, 70) ]
    var result = [];
    for(i=0; i<nestedXY.length; i++){
    result.push(nestedXY[i].x);
    result.push(nestedXY[i].y);
    }
    return result; // result is like: [0, 80, 20, 90, ā€¦ 200, 70 ]
    }

    function triangulate(vertices){
    var data = flatten(vertices);
    var triangles = earcut(data); // earcut func from https://github.com/mapbox/earcut
    return triangles;
    }

    ā€¦
    var triangles = triangulate(nestedXY );
    var n_tri = triangles.length/3;

          var d_node = new cc.DrawNode();
          for(i=0; i<n_tri; i++){
              var a_triangle = [cc.p(nestedXY[triangles[3*i]]), cc.p(nestedXY[triangles[3*i+1]]), cc.p(nestedXY[triangles[3*i+2]])];
              d_node.drawPoly(a_triangle, cc.color(0,255,0,200), 0,  cc.color(0,0,0,0));
          }
          // now you can display your d_node like:
          this.region.addChild(d_node);
    

    ā€¦


#5

Does it work correctly on mobile ?