Am I using ofFbo objects in the wrong way?

Hi everyone, first question.

I have been building an indie style game in OF, and drawing fbo’s has become quite slow. Currently I am trying to draw a tiled grid for the background. There are these little characters that can “take” tiles, so each tile needs the ability to change.

The block of code below is a draw function for my tile grid, which loops through each tile and draws the correct piece. The vector, turfFbos contains six pre-rendered fbos, that are draw for the tiles.

I am using a similar technique to draw the little characters, there are normally a few hundred of these creatures in the game at any given time. It takes about 900 microseconds to draw all of the creatures. However to draw this grid once takes around 10, 000 microseconds. For the life of me I can’t figure out how this is so much more expensive, or how to optimize.

I have used ofElapsedTimeMicros() to get these statistics. Can anyone suggest reasons for this to be so slow, or other ways of drawing out many pre-rendered fbos? (Please).

Many thanks in advance.

Rich.

  
  
for(int x=0; x<COLUMNS; x++) {  
    for(int y=0; y<ROWS; y++) {  
        
      int tileNum = grid[x][y].form;  
      int rotNum = grid[x][y].rot;  
      int back = -TILESIZE *0.5;  
        
      int xPos = x * TILESIZE + TILESIZE * 0.5;   
      int yPos = y * TILESIZE + TILESIZE * 0.5;  
  
      ofSetColor(col, 55);  
      ofPushMatrix();  
      ofTranslate(xPos, yPos);  
      ofRotate(rotNum * 90 + 180);  
  
      // Draw tile.  
      turfFbos->at(tileNum)->draw(back, back, TILESIZE, TILESIZE);  
  
      ofPopMatrix();  
        
     }  
}  
  

Just a thought: I’m not sure if I’m understanding you quite right but it sounds like you should be using textures for the character not FBOs. Usually you use an FBO to render objects and multiple textures into, tiles are usually just textures, they’ll update much more quickly because they’re more lightweight.

Oh right, so are the ofTextures loaded in the graphics memory when they are instanced?

The reason I have been using an FBO is that they load straight into the graphics memory, making it very inexpensive to draw, as there is very little to pass from CPU to GPU (this is what my openGL buddy claims anyway, I really haven’t had the time to work it out properly myself).

My grid is 48 by 30 tiles, so I need to draw 1440 tiles, made from the 6 fbos / soon to be textures. I also have something like 500 to 1000 creatures, which are drawn as one fbo / soon to be texture each. Is this a reasonable expectation, or should I rethink?

(Note: the tile textures are loaded in setup, and once made never need to change their content, just been draw in different places with different rotations, a lot).

I think the problem may be in all the push/pop + translate and rotate operations. Those are expensive when they are called a lot since they involve calls to the graphics card.

I guess you can avoid some by not pushing/poping the matrix everytime and instead making the translation relative to the previous and also creating 4 versions of the fbos with the different rotations so you choose the correct fbo instead of rotating it. Something like:

  
  
ofPushMatrix();  
for(int y=0; y<ROWS; y++) {  
    for(int x=0; x<COLUMNS; x++) {  
      int tileNum = grid[x][y].form;  
      int rotNum = grid[x][y].rot;  
  
      ofSetColor(col, 55);  
      ofTranslate(TILESIZE + TILESIZE * 0.5, 0);  
        
      // Draw tile.  
      turfFbos->at->(rot)->at(tileNum)->draw(back, back, tSize, tSize);  
    }  
    ofTranslate(-(TILESIZE + TILESIZE * 0.5)*COLUMNS,TILESIZE + TILESIZE * 0.5);  
}  
ofPopMatrix();  
  

where turfFbos is a vector< vector > and the first vector is a 4 position vector, one for each posible rotation for all the tiles.

Another possible solution is to create ofVboMeshes that already contain the translations and rotations then bind the appropriate fbo texture before drawing them, that way you almost don’t have any gpu calls which should be the fastest

Also binding and unbinding the texture can be expensive if you do it a lot of times, a good way to avoid it is to use a texture atlas, a big texture with all your tiles in it. Then generate the texture coordinates to match the corresponding tiles.

Hey again, thanks for the suggestions there.

The image above is some work in progress. You can see the tile grid in the background there with some of my characters on it. The teams of creatures move over the grid and take tiles, so it’s kind of like a turf war game. However this means that the atlas would have to be updated once every few frames, sometimes every frame, as once a creature reaches a grid location it will swap the tile for one of it’s own color.

Would it still be an optimization in this case?

For now I will implement the suggestion you made there, thanks again.

Well, you don’t update the atlas, instead you update the texture coordinates of the tiles to match certain parts of the atlas. Instead of drawing each tile using a different texture you draw each tile using one part of the big texture that it’s the atlas. For that you can pre-generate ofVboMesh which texture coordinates correspond to those parts in the texture atlas.

But yes, try first to get rid of as much transformations as possible to confirm that the problem is there, then if you need more speed you can optimize further

ps. that looks great btw : )

Ok great, I understand, I will try get this done for tomorrow (got reviews and things).

Hey thanks for the compliment there. It’s a twitter game that I making for my final project in a digital design degree. The artwork might be something a little like this:

But the turf, grid tiles, should be more a zerg style goo. (I used a modified marching squares to algorithm to work out what tiles go where, and what rotation each one should have). :slight_smile:

The game is really just a simulation that trawls a player’s twitter accounts (you can see gamer tags in the bottom of the work in progress image). The twitter data derives a evolutionary behavior for the creatures, which determines who wins/loses etc. OF is a great tool for developing such things IMO, just a little tricky coming from python, but that’s more a c++ thing. Anyway, thanks again.

Yeah, there’s some nice info on texture atlases in this gamasutra article http://www.gamasutra.com/view/feature/2530/practical-texture-atlases.php

Maybe that can help. And I second Arturos thinking about the push/pop calls. I’ve had that slow things down before.

Yeah, I never considered the push/pop being that heavy, but looking at it now I guess it makes much more sense to do it that way, as the tiles will always be in the same place, right. I also didn’t know they where called on the GPU.

I’ll have a go at the atlas, seems fun.