CardMaker questions...

Hey all.

I’m using CardMaker and generating perhaps thirty cards. They’re all the same thing, but they all need to be able to rotate independently. Currently, they’re pretty expensive for a set of untextured polys - adding them to my scene costs me about 20 FPS.

Any tips for making them faster?

CardMaker does no magic - it really just creates two triangles. Unlikely that it causes a bottleneck.

The problem might be that all your cards are spread over many batches. You might look at this poorly written manual page: … any_Meshes

You can see if this is the problem by calling parentnode.analyze() and checking the Geom count. Or in PStats.

I suspect you are running into the Geom limit. Each independently-transformable object has to be sent to the graphics card as a separate Geom, but there is a severe limit to the number of individual Geoms you can have.

I’m actually a little surprised you’re running into this limit after adding only thirty cards or so, but it’s possible, I guess, depending on the rest of your scene. (A typical rule of thumb is you should aim for 300-600 Geoms in the entire scene.) It also depends on the frame rates you’re talking about: speaking of a 20 fps cost isn’t actually a qualitative measurement, because the difference between 150 fps and 170 fps (0.78 ms) is waaaay different than the difference between 20 fps and 40 fps (25 ms). For performance measurements, it’s usually best to speak in terms of milliseconds, which are in the same scale no matter what the frame rate.

If you’re up in the 60+ fps range, every little tenth of a millisecond cost will make a big difference in your measured frame rate, so be careful you don’t get too obsessed about over-optimizing too early. On the other hand, keeping things up in the 60+ fps range is a challenge, because there’s not a lot of elbow room up there; so if your goal is to produce a product that remains 60+ fps throughout, then it will be important to pay close attention to every millisecond.

As to the problem at hand, you have hit upon the fundamental conflict between game designers (who want lots of independently-controllable objects) and hardware manufacturers (who want everything to be one big static object). There are a few tricks you can use to help, but they mostly involve a compromise of one form or another.

First, I’d try putting all of your cards under one node, and calling flattenStrong() on that node. This should convert the collection of cards into a single Geom (assuming they all have the same texture and render state). It will also remove your ability to control them independently, of course, but the idea is to see just how much you’re paying for the convenience of independent Geoms.

If that makes a big difference in performance, then you have to figure out how to get the controllability back. One easy thing to try is to put them all under a RigidBodyCombiner, which will manage the vertices on the CPU and send a single Geom to the graphics card. This can end up being a tradeoff between CPU and GPU, so whether it comes out as a win for you depends heavily on what your CPU and GPU burdens already are (and this might change as you continue to develop your application).

If the RigidBodyCombiner isn’t a win, you might need to do something more elaborate, such as using a particle system or the MeshDrawer class, depending on your precise needs; or if the cards move only infrequently, you can keep a flattened version of the cards in the scene, and a non-flattened version offstage; and when you need to move a card you can duplicate and flatten it into the scene.


Wow. I love this forum. Thanks guys.

Yes, I’m currently sitting at 170-180 FPS. My concern comes mostly from the knowledge that I a) need to stay at 30+ on non-recent hardware and b) I’m going to be adding far, far more expensive things than thirty cards. I’ll try not to get obsessed about optimizing too early - it’s something I tend to stay away from, with good results for the last decade or so - but I’m definitely outside my comfort zone. If this was an AI or NLP system in C++ I’d be cool. :slight_smile: Both Python and 3D rendering are familiar subjects but not exactly my forte.

I will try the techniques you mention. I found yesterday that I gained a more thorough knowledge of the engine through tracking down and trying what you were saying. I’m sure today will be another productive day in that respect.

Thanks again. I’ll post how it goes.

OK. Note that the set of things that are expensive on recent cards is not the same as the set of things that are expensive on older cards–and sometimes they are exactly the opposite things. In general, high-end cards want to have a small number of Geoms and can tolerate a high number of vertices; low-end cards can often do better with a higher number of Geoms (because culling is more effective) but you need to watch the number of vertices.

If your goal is to support a particular frame rate on a particular target platform, you would do well to get an example of that target platform in front of you, and do all of your performance measurements on that.


Thanks guys. I’ve tried some of your suggestions - they’ve worked well.