Shadow overlapping

Hello!

I have this code:

var drawNode = new cc.DrawNode();
drawNode.drawRect(cc.p(100,100), cc.p(300,300), cc.color(255, 0, 0, 100), -1);
drawNode.drawRect(cc.p(200,200), cc.p(400,400), cc.color(255, 0, 0, 100), -1);

And I have this result:

But I want this result:

In which way I can do this?

This is caused by alpha blending.

In this instance you could make the alpha 255 and lower the red value accordingly.

Alternatively you could change the alpha blending mode (lua, not used JS bindings, I should imagine they’re similar)

cc.DrawNode:setBlendFunc(cc.blendFunc(gl.ONE, gl.ZERO))

Hope this helps!

@almax27 thanks for your answer. It’s works well for rects. But when I use segments another trouble happens. Now I have this code:

var drawNode = new cc.DrawNode();
drawNode.setBlendFunc(cc.ONE, cc.ZERO);
drawNode.drawSegment(cc.p(100,100), cc.p(200,200), 30, cc.color(255,0,0,100));
drawNode.drawSegment(cc.p(200,200), cc.p(300,300), 30, cc.color(255,0,0,100));

And this result:

Seems this is cocos engine problem. This code for drawSegment function:

 drawSegment: function (from, to, lineWidth, color) {
     lineWidth = lineWidth || this._lineWidth;
     color = color || this.getDrawColor();
     if (color.a == null)
        color.a = 255;
     var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_POLY);
     element.verts = [from, to];
     element.lineWidth = lineWidth * 2;
     element.lineColor = color;
     element.isStroke = true;
     element.lineCap = "round";
     this._buffer.push(element);
 },

I think creates DrawNodeElement without transparency:

cc._DrawNodeElement = function (type, verts, fillColor, lineWidth, lineColor, lineCap, isClosePolygon, isFill, isStroke) {
    var _t = this;
    _t.type = type;
    _t.verts = verts || null;
    _t.fillColor = fillColor || null;
    _t.lineWidth = lineWidth || 0;
    _t.lineColor = lineColor || null;
    _t.lineCap = lineCap || "butt";
    _t.isClosePolygon = isClosePolygon || false;
    _t.isFill = isFill || false;
    _t.isStroke = isStroke || false;
};

I don’t know how to set transparency for this node.

@pandamicro can you help?

What you’re seeing here is a result of ONE/ZERO blending. The lower sprite is drawn first and the upper one is drawn over the top. ONE/ZERO takes the alpha from source and discards what was rendered before.

Assuming you don’t require these objects to be actually transparent I recommend you set their alpha to 255 and lower the intensity of the red colour component. i.e. something like cc.color(100,0,0,255)

For more information on blending
https://www.opengl.org/wiki/Blending
http://www.marmoset.co/toolbag/learn/blending

And here’s a cool little online demo of the effects of each blending equation
http://www.andersriggelsen.dk/glblendfunc.php

@almax27 It’s interesting trick but actually I have background, and two lines (shine on beam). Transparency is needed in this case.

draw all of your shapes with full alpha onto a render-texture, then draw the render-texture with transparency

@Wuhao In which way I can do this?

I have this code:

var drawNode = new cc.DrawNode();
drawNode.drawSegment(cc.p(100,100), cc.p(200,200), 30, cc.color(255,0,0,255));
drawNode.drawSegment(cc.p(200,200), cc.p(300,300), 30, cc.color(255,0,0,255));
drawNode.setOpacity(100);

But nothing happens. I have my shapes with full opacity.

im pretty sure setOpacity() is 0-255, not 100

@Wuhao I know it. It is just example. I want value of opacity 100 from 255.

what i mean is that you draw those drawnodes with 255 opacity and default blendmode onto a RenderTexture node,

then you can set the renderTexture’s opacity to anything you want

Wuhao’s solution of rendering to texture is nice way to go, especially if the objects don’t move often. If you’re only rendering a few shapes it’s pretty heavy on fill-rate though.

http://cocos2d-x.org/wiki/Render_To_Texture

@Wuhao yes, You are clearly understand me. Now I have this code:

var renderTexture = new cc.RenderTexture(500, 500);
renderTexture.x = 100;
renderTexture.y = 100;
	
var drawNode = new cc.DrawNode();
drawNode.drawSegment(cc.p(100,100), cc.p(200,200), 30, cc.color(255,0,0,255));
drawNode.drawSegment(cc.p(200,200), cc.p(300,300), 30, cc.color(255,0,0,255));
drawNode.setOpacity(100);
	
renderTexture.setAutoDraw(true);
renderTexture.addChild(drawNode);
renderTexture.setOpacity(100);
	
this.addChild(renderTexture);

But opacity is does not change and I have this result:

RenderTexture does not render itself, it has an internal sprite instance, you will need to set the opacity of this instead

renderTexture.getSprite().setOpacity(100);

@almax27 It doesn’t work. Or maybe I should add draw node with help other method.

you are not using rendertexture correctly, drawnode does not need to be added to the scene (needs retain on jsb)

rendertexture need to call begin(), then you will need to manually call visit on your drawnodes
and afterthat, you need to call end()