CCDrawNode is extremely slow.

Hi.
My game utilizes Box2d, so I require a debug renderer. I have found someone’s implementation months ago, but I was not comfortable with the fact that it draws each primitive with a separate draw call. So I’ve rewritten the renderer and now it uses CCDrawNode and draws all primitives with a single draw call. And you know what? It takes more than 50 ms on my Android device to push triangles into the buffer (if your profiler shows correct information; anyways, fps is around 15). With the previous version of debug renderer which uses a separate draw call per primitive the framerate is bound to v-sync frequency. I understand that CCDrawNode was not designed to be dynamically changed every frame, but actually there are no sane reasons that updating the buffer is SO slow.
I have fixed several issues in Cocos2d-x, but currently I have no time for this one. So I hope the developers will pay attention on it someday.

1 Like

No one again??

The same poor performance in v.3.

Do you have some code which shows that CCDrawNode is slower than drawing primitives like before?

Surely I have the code, but it’s integrated in the other codebase of the game.

Actually it’s quite easy to reproduce:

  1. create a DrawNode
  2. on each frame clear the DrawNode and fill it with the new primitives.

When I met this problem first I started to profile the corresponding code and as far as I remember the majority of time is spent in this part (DrawNode::drawPolygon):

for (int i = 0; i < count; i++)
{
	Vertex2F v0 = __v2f(verts[(i-1+count)%count]);
	Vertex2F v1 = __v2f(verts[i]);
	Vertex2F v2 = __v2f(verts[(i+1)%count]);
    
	Vertex2F n1 = v2fnormalize(v2fperp(v2fsub(v1, v0)));
	Vertex2F n2 = v2fnormalize(v2fperp(v2fsub(v2, v1)));
	
	Vertex2F offset = v2fmult(v2fadd(n1, n2), 1.0/(v2fdot(n1, n2) + 1.0));
    struct ExtrudeVerts tmp = {offset, n2};
	extrude[i] = tmp;
}

Mostly

Vertex2F v0 = __v2f(verts[(i-1+count)%count]);
Vertex2F v1 = __v2f(verts[i]);
Vertex2F v2 = __v2f(verts[(i+1)%count]);

Well, at least it seems to be a CPU problem, not a GPU one (much easier to fix :stuck_out_tongue: ).

For my game i’m thinking about subclassing DrawNode and rewriting DrawNode::drawX methods to avoid this type of problems (and adding some new functionality).

Are you drawing polygons with borders? If not, you should try to copy DrawNode::drawTriangle to create a method for drawing polygons without a border. A LOT of DrawNode::drawPolygon code it’s not needed if you draw them without borders :wink: .

Yeah, I don’t need borders. This stuff is not for the game itself, it’s for physics debug drawing.

If you try my idea please post the result :slight_smile:

there is a class called physics debug node

@Wuhao wrote:

there is a class called physics debug node

Sorry, but your comment is not helpful at all.

  1. PhysicsDebugNode supports Chipmunk only. If you read my first post carefully, you’d see that I use Box2d.
  2. PhysicsDebugNode utilizes DrawNode. If you read my first and third posts carefully, you’d see that I already tried using DrawNode (even the title of the topic says the same).

@dotsquid I faced same issue recently.

Do you think draw with opengl directly will be fast?

here is my github project for how to use opengl in cocos2d-x

thanks

Yes, my current dumb implementation which draws each shape with a separate draw call is faster .
I’d wish to write a single draw call solution, by I have no time for this non-priority task.