Problem with fps in a randomized 3d world

Started by araghavan, February 26, 2013, 04:19:41 PM

Previous topic - Next topic

araghavan

I'm having trouble finding the best way to create my world. Right now, I created a random 2-D map generator which outputs a bunch of rooms. When I start the game, I create a NxM floor of cubes from primitives, then from there wherever there's a wall shown in my 2D map, I add a few blocks at that position above the floor to gain some height.

It's creating the world fine, and I can navigate it... except that its giving me very few FPS. I'm using cubes of size five, and a 20x20 base 2D map:

/*Load World Map Floor*/
for (int row = 0; row < r.length; row++)
for (int col = 0; col < r[0].length; col++)
{
worldMap[row][col][0] = block.cloneObject();
}

MemoryHelper.compact();
boolean player_location_set = false;
//Load rest of map
for (int h = 1; h < 3; h++)
for (int row = 0; row < r.length; row++)
for (int col = 0; col < r[0].length; col++)
{
if (r[row][col] == RoomData.WALL || r[row][col] == RoomData.PERMWALL){

worldMap[row][col][h] = block.cloneObject();

}
if (r[row][col] == RoomData.ENTRANCE && player_location_set == false){
player_location_set = true;
initial_player_position = new SimpleVector(row * 10, h * 10 + 5, col * 10);
}
}


^Here is how I am creating my map. In the onSurfaceChanged function, I have:


for (int h = 0; h < worldMap[0][0].length; h++)
for (int row = 0; row < worldMap.length; row++)
for (int col = 0; col < worldMap[0].length; col++)
{
//If there is a block
if (worldMap[row][col][h] != null){
block = worldMap[row][col][h];
block.translate(SimpleVector.create(row * 10, h * 10 + 5, col * 10));
block.rotateY((float) (Math.PI/4));
block.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
block.build();
block.strip();
world.addObject(block);
}
}

world.buildAllObjects();
MemoryHelper.compact();


Any advice on how I should go about this? I can't really pre-create the world because it's randomized

Thanks

EgonOlsen

Many (visible) objects in a scene cause an overhead because they require at least as many draw calls as there are objects. How many objects are you using? There are several solutions to this:


  • If it's a wall, make it a wall. Don't use cubes to simulate walls. This doesn't reduce the number of draw calls, but the numbers of polygons and vertices to process.
  • Make the Object3Ds share their mesh and their compiled data. This doesn't reduce the number of draw calls, but is more cache friendly and uses less memory. Don't expect any miracles from this though.
  • Merge objects. This will reduce the number of draw calls. The drawback is, that you can't share mesh data anymore (unless you only merge common patterns of objects and resuse those. If you merge all your objects into one, you'll have one large level. It might consume more memory, but it will render much faster.
  • Don't use Object3Ds for storing the level components, but simple beans and only describe the part's attributes. Then process these beans and select only the ones that might be visible. Assign some views to them from a pool and render only these views. That's what i'm doing for my RPG dungeons. I have to admit that i haven't tried this approach with really large dungeons though...

araghavan

Right, that makes a lot of sense. With this method I'm probably creating over 100 cubes...

A combination of using full walls and merging objects will hopefully smooth things out

Thanks