Decreasing polygone count make the app more laggy !

Started by jonalibert, June 13, 2012, 01:02:42 PM

Previous topic - Next topic

jonalibert

Hi,

I have 1445 polygones (30 fps), I decrease the count to 289 and the scene pass to 20fps !

How is it possible ?

I use collision method for an object and a complex wall, I don't think it can be that. collideOffset is set to 20 000, because I create numerous polygons more the scene is old.

Thank you for reading

EgonOlsen

There's no reason why this should happen. It has to be something else in your code that causes this.

jonalibert

Ok... My calculation doesn't exceed 5ms in on draw frame, it just can be a bad parameter or a huge number of polygones... How many polygons can be managed smoothly with 60 fps ?

EgonOlsen

That's impossible to tell. It highly depends on what you do with these polygons (just render static geometry. animate them, vertex shade them, do a collision detection with them,..) as well as on the device and the version of Android.

In your case, i don't get why you are setting the collision offset to 20.000? In which case do you want to check for a collision with polygons/objects that are 20.000 units away from the current position?

jonalibert

Only one moto is moving, others are static because solo mode is activated.

So, the floor with 300poly make the scene more laggy than the floor with 1200 (10 fps difference), I use a Galaxy S2, tested on android ICS and Gingerbread, same result.

In the onCreate :
/*3D*/
master = null;
if (master != null) {
copy(master);
}

super.onCreate(savedInstanceState);

/*Liaison avec OpenGL*/
mGLView = new GLSurfaceView(getApplication());

mGLView.setEGLConfigChooser(new GLSurfaceView.EGLConfigChooser() {
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
// Ensure that we get a 16bit framebuffer. Otherwise, we'll fall
// back to Pixelflinger on some device (read: Samsung I7500)
int[] attributes = new int[] { EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE };
EGLConfig[] configs = new EGLConfig[1];
int[] result = new int[1];
egl.eglChooseConfig(display, attributes, configs, 1, result);
return configs[0];
}
});

/*Moteur de rendu*/
renderer = new MyRenderer();

/*On assigne une vue au moteur de rendu*/
mGLView.setRenderer(renderer);
setContentView(mGLView);


This is the Render class (without onDrawFrame)

class MyRenderer implements GLSurfaceView.Renderer {


private long time;

private long prectime=System.currentTimeMillis();

private boolean lost=false;


public MyRenderer() {
}

public void onSurfaceChanged(GL10 gl, int w, int h) {
/*initialisation*/
time=System.currentTimeMillis();
if (fb != null) {
fb.dispose();
}

fb = new FrameBuffer(gl, w, h);

if (master == null) {

prectime=System.currentTimeMillis();
world = new World();
world.setAmbientLight(250,250,250);

Config.collideOffset=20000;

Texture rouge = new Texture(1,1,new RGBColor(255, 0, 0));
TextureManager.getInstance().addTexture("rouge", rouge);

Texture vert = new Texture(1,1,new RGBColor(0, 255, 0));
TextureManager.getInstance().addTexture("vert", vert);

Texture bleu = new Texture(1,1,new RGBColor(0, 0, 255));
TextureManager.getInstance().addTexture("bleu", bleu);

Texture jaune = new Texture(1,1,new RGBColor(255, 255, 0));
TextureManager.getInstance().addTexture("jaune", jaune);

AssetManager assetManager = getApplicationContext().getAssets();
InputStream  is = null;
InputStream  is2 = null;

/*déserialisation*/
try {
is=assetManager.open("floor.3ds");
} catch (IOException e) {
e.printStackTrace();
}



/*déserialisation*/
try {
is=assetManager.open("floor.obj");
} catch (IOException e) {


e.printStackTrace();
}

try {
is2=assetManager.open("floor.mtl");
} catch (IOException e) {

e.printStackTrace();
}

floor = Loader.loadOBJ(is,is2,1);
for(int i=0; i<floor.length;++i)
{
floor[i].strip();
floor[i].build();
floor[i].scale(0.5f);
world.addObject(floor[i]);
floor[i].translate(new SimpleVector(-floor[i].getCenter().x/2,-floor[i].getCenter().y/2,0));

}

/*déserialisation*/
try {
is=assetManager.open("wall.obj");
} catch (IOException e) {



e.printStackTrace();
}

try {
is2=assetManager.open("wall.mtl");
} catch (IOException e) {




e.printStackTrace();
}

wall = Loader.loadOBJ(is,is2,1);
for(int i=0; i<wall.length;++i)
{

wall[i].setTransparency(5);

wall[i].strip();
wall[i].build();

world.addObject(wall[i]);
wall[i].setCollisionMode(Object3D.COLLISION_CHECK_SELF|Object3D.COLLISION_CHECK_OTHERS);

}






/*déserialisation*/
try {
is=assetManager.open("mo.obj");
} catch (IOException e) {


e.printStackTrace();
}

try {
is2=assetManager.open("mo.mtl");
} catch (IOException e) {

e.printStackTrace();
}

cycle = Loader.loadOBJ(is,is2,1);

motos[0]=new Object3D[cycle.length];
motos[1]=new Object3D[cycle.length];
motos[2]=new Object3D[cycle.length];
motos[3]=new Object3D[cycle.length];

for(int i=0; i<cycle.length;++i)
{
motos[0][i]=new Object3D(cycle[i]);
motos[1][i]=new Object3D(cycle[i]);
motos[2][i]=new Object3D(cycle[i]);
motos[3][i]=new Object3D(cycle[i]);

if(i!=0)
{
motos[0][i-1].addChild(motos[0][i]);
motos[1][i-1].addChild(motos[1][i]);
motos[2][i-1].addChild(motos[2][i]);
motos[3][i-1].addChild(motos[3][i]);

cycle[i-1].addChild(cycle[i]);
}


motos[0][i].build();
motos[1][i].build();
motos[2][i].build();
motos[3][i].build();

cycle[i].build();


world.addObject(motos[0][i]);
world.addObject(motos[1][i]);
world.addObject(motos[2][i]);
world.addObject(motos[3][i]);

world.addObject(cycle[i]);

}

cycle[COLLIDER].setCollisionMode(Object3D.COLLISION_CHECK_SELF|Object3D.COLLISION_CHECK_OTHERS);

motos[0][0].rotateZ((float) Math.PI);
motos[1][0].rotateZ((float) (Math.PI-1*(Math.PI/2)));
motos[2][0].rotateZ((float) (Math.PI-2*(Math.PI/2)));
motos[3][0].rotateZ((float) (Math.PI-3*(Math.PI/2)));

cycle[0].rotateZ((float) Math.PI);

motos[0][0].translate(new SimpleVector(1000,1000,0));
motos[1][0].translate(new SimpleVector(1000,1000,0));
motos[2][0].translate(new SimpleVector(1000,1000,0));
motos[3][0].translate(new SimpleVector(1000,1000,0));

cycle[0].translate(new SimpleVector(1000,1000,0));

SimpleVector initVect = new SimpleVector(0,-60,0);

motos[0][0].translate(initVect);
initVect.rotateZ((float)Math.PI/2);
motos[1][0].translate(initVect);
initVect.rotateZ((float)Math.PI/2);
motos[2][0].translate(initVect);
initVect.rotateZ((float)Math.PI/2);
motos[3][0].translate(initVect);


precPos=new SimpleVector(cycle[0].getTransformedCenter());
mCam = world.getCamera();

mCam.moveCamera(cycle[3].getTransformedCenter(), 1);
mCam.moveCamera(new SimpleVector(mCam.getPosition().x, mCam.getPosition().y+200, mCam.getPosition().z+100), 1);

SimpleVector upOld = world.getCamera().getUpVector();

SimpleVector dirOld = world.getCamera().getDirection();

SimpleVector rotation = new SimpleVector(-(float)(0.65*Math.PI/2),-(float)Math.PI, 0);
upOld = upOld.rotate(rotation);
dirOld = dirOld.rotate(rotation);
world.getCamera().setOrientation(dirOld, upOld);

/* Light pos*/
SimpleVector sv = new SimpleVector();
sv.set(floor[0].getTransformedCenter());
sv.x += 100;
sv.y += 100;
sv.z +=100;

MemoryHelper.compact();

if (master == null) {
Logger.log("Saving master Activity!");
master = GameActivity.this;
}

cpd.hide();
}
}


So do you think (particularely for initialisation, loading of objects) there is an error of my part ? For the offset its a mistake, my english is too poor, and I thought it was the maximal size of a polygon.

jonalibert

I just do some rotations and translations, and I have around 5000 polygones.

EgonOlsen

Hard to tell from a distance. How's performance if you remove the collision detection calls? Is the performance drop related to this calls or not? And if i got you right, your polygons are up to 20.000 units in size? If so, then that pretty damn huge...you might run into some issues with the mobile GPU's accuracy that way.

jonalibert

Ok. There is no performance impact when I turn off collisions. In practice, if I do not have this parameter to 20000 offset collision, collisions are not detected on this huge wall (2000 units, maybe should I add more polygons?).

If I delete the wall I have the same performance problems. I try to adjust clipping too...

With Ogre for Android and a scene with 10 times polygons (50 000) their is no lag :'(. I prefere your 3D Engine because it is light and and because you track your work seems very nice and sharp!

TY another time for reading !

EgonOlsen

Rendering of static geometry is solely done on the gpu. It doesn't depend on the engine except for issuing the draw calls. If performance suffers for larger polygons, this is most likely related to the GPU having problems with such large structures...may it be cache trashing or something else. If increasing the polygon count fixes this, then why not simply do it...?

jonalibert

#9
I don't fix the problem, 30 fps on a galaxy S2, it's just too poor, because I add 6 polygons every seconds... Other phones will not be able to run it :(. I can't imagine that my 3D models are too complexe.

EgonOlsen

#10
As i've no idea what you are doing exactly, i can't comment on that. If you want, you can send me a test case and i'll have a look.

Edit: Before creating a test case, you might want to post some log output of the app running. Maybe you are doing something that triggers garbage collection a lot or something like this.