Drawing Graphics Without using the Scene Graph

Background
I have some old C++ games that I’d like to port to Android. They use a custom 2d game library and run on Windows, Mac and iOS… I don’t want to write the Android port from scratch because I’ve heard so many stories from developers about how fragmented and hellish it is to develop for Android. Soooo, I’ve stumbled upon Cocos2dx as a well tested, popular C++ game engine. My plan is to plug Cocos2d into my existing engine, thereby adding Android support to all my games. One small problem is that Cocos2d is a higher level SDK than what I need. I just need basic 2d graphic rendering, audio playing, input, etc. I don’t want or need a scene graph, animations, actions, etc, because my games already handles all that.

Current Problem
I’m currently struggling with the best way to draw the graphics. The Sprite class does most of what I need - rotate, scale, and colorize graphics… but it has to be added to a scene graph and it looks like it is designed to continue to exist over multiple frames. I want something more like Texture2d and Texture2d::drawAtPoint - load the graphic once, and then just draw it as many times as I want without managing the instances of it. That would replicate the functionality in my existing engine. However Texture2d doesn’t support rotation or color, which I need.

So right now I’m considering two ways to go.

  1. Using the Sprite class but removeAllChildren every frame, then recreate the sprites that I need every frame. This seems like it would have a huge amount of overhead. I did some quick tests, and it’s not completely horrible, also their might be ways to optimize it using some sort of reusable “sprite pools”.
  2. Using Sprite class but figuring out how to use it without the scene graph… I haven’t figured that out yet though and I’m not sure if it’s possible. I tried using a single Sprite without adding it to the scene graph. I set its position and rotation, then did Sprite:updateTransform(), then did Sprite::draw. However I could only draw the sprite one time per frame when doing this (I would want to use one Sprite to draw multiple times at different positions/scale/rotations.).
  3. Use Texture2d, but add all the features that I need to it. Rotated, scaled, colored, etc. I’m not sure how difficult this would be, or if it will require a lot of testing and bug fixes across different Android devices (the main thing that I’m trying to avoid by using Cocos2dx in the first place). Also, I saw another post about Texture2d::drawAtPoint being depracated… so this may be totally the wrong way to go.

Any thoughts on this? I just started using Cocos2dx - so I might be missing the obvious/standard way to do this. Cheers!

TBF it sounds like you might have an easier time porting to SDL or Kore, which are lower level C/C++ platform libraries instead of full blown engines like Cocos. Both will allow you to portably blit textures with scaling, rotation, colouring etc. but without the need for a scene graph or other persistent things.

SDL definitely maps to our library better - so you are right, porting might be easier. The reason I’ve been leaning towards Cocos2d is that Android support seems like a real focus. There have been many popular games released on Android using it. The same cannot be said about SDL or other C++ game libraries. Android support might exist, but there is a lack of games that have actually been released using it - this has me questioning how good the Android support actually is… it might work on my Android phone, but then I’ll release it into the wild and find out that it doesn’t work on 50% of user’s devices.

I could be wrong about this… If anyone agrees or disagrees, I’d love to hear your experience.

As for my original question. I’m looking into TrianglesCommand right now.

I can’t speak from much experience, but any time I’ve experimented with SDL or Kore on any mobile device (iOS, Android and yes even Windows Phone) they have worked without issue. My impression is that SDL is a very mature library and is constantly updated. If you go that route, also check out SDL_gpu. I’ve wrung stupendous sprite performance from Kore on iOS, and the same code worked without changes on Android and WP.

I’ve had success with “custom rendering” on cocos-objc integrating some raw OpenGL code in with engine sprites, so perhaps something like this would be a solution for you.

Off the top of my head, what about having a pool of Sprites and changing their UV/XY etc. every frame as required by your game? Or somehow tying a Sprite to your existing game entities or whatever. I’d try to keep add/removeChild to a minimum is all.

Thanks, I appreciate the feedback.

It’s a tough call to make and I’ve probably spent too much time researching it already, rather than just diving in. SDL is appealing to me because it’s been around so long, I trust its support on most other platform, so I could potentially shift my releases to using SDL for all platforms (Windows game controller support in particular looks pretty awesome compared to what I’ve been doing). I looked at Kore briefly, and the clean design appeals to me, also the development seems to be very active.

However for this porting project, the only thing that I’m looking for is amazing Android compatibility. In my experience, compatibility is hard, it’s boring, it takes time, real users, and actual hardware to get right. Android, especially NDK Android, is notoriously hard to have good compatibility on. The best metrics I have for SDK compatibility are the number of real games made with it, looking at user reviews for problems, etc… Cocos2d wins on compatibility, as far as I can tell.

Of course I can only use Cocos2d if I can make the Cocos API fit into my existing game library. I’m porting 4 games over, so minimal changes to the actual game code is essential (so adding the Cocos2d Sprites as persistent objects is a non-starter as that would require significant alterations to game code in all 4 games).

I’ve done a lot of tests. As a baseline I added 1000 sprites and did some rotating/scaling/coloring. I can’t actually use this technique in my games, but it’s the Cocos2d “way of doing things” so I figure it’s good comparison point. I compared it against a few techniques that would work in my games:

  1. Adding/removing all sprites every frame is indeed quite slow. About 100% slower than baseline test. Actually not as bad as I would have thought, but I can’t afford to lose that performance.
  2. The idea of Sprite pools is workable - by this I mean adding a bunch of sprites to the engine and then changing their visibility and texture every frame based on draw calls I send the system. It’s about 15% slower than the baseline. I’m not sure where the overhead comes from or if it’s possible to reduce. My guess is it comes from SetTexture every frame.
  3. Using TrianglesCommand performs similarly to the baseline.

So I’m going with TrianglesCommand. It’s abstracted from OpenGL and provides sprite batching. I like that. I’ll have to implement the basic sprite drawing stuff myself. At least one of my games uses some more unique functions that will need TrianglesCommand anyways (drawing arbitrarily shaped textured quads, drawing textured triangle mesh).

I welcome any comments, cheers!