That either means to execute 50000 draw calls each frame (for compiled objects) or processing ~500000 polygons each frame on the CPU in hybrid mode. The former one is GPU, driver and bus intense the latter is cpu intense. I made this test case, which renders 50000+ cubes at a time:
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.opengl.Display;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IPaintListener;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.World;
import com.threed.jpct.WorldProcessor;
import com.threed.jpct.util.Light;
public class CubeRow implements IPaintListener {
private static final long serialVersionUID = 1L;
private FrameBuffer buffer;
private World world;
private Object3D center;
private List<Object3D> objs = new ArrayList<Object3D>();
private int fps = 0;
public static void main(String[] args) {
new CubeRow().loop();
}
public CubeRow() {
Logger.setLogLevel(Logger.LL_DEBUG);
Logger.setOnError(Logger.ON_ERROR_THROW_EXCEPTION);
Config.maxPolysVisible = 500000;
Config.lightMul = 1;
world = new World();
world.setAmbientLight(20, 20, 20);
Object3D obj = null;
Object3D mcube = Primitives.getCube(10);
mcube.build();
center = Object3D.createDummyObj();
for (int z = 0; z < 25; z++) {
for (int x = 0; x < 45; x++) {
for (int i = 0; i < 45; i++) {
obj = new Object3D(mcube, true);
obj.translate((x - 22) * 50, (i - 22) * 50, z * 50);
obj.shareCompiledData(mcube);
//obj.compile(); // Uncomment for compiled mode
obj.build();
obj.addParent(center);
world.addObject(obj);
objs.add(obj);
}
}
}
Config.farPlane = 10000;
world.getCamera().setPosition(50, 0, -4000);
world.setWorldProcessor(new WorldProcessor(8, 16));
Light l1 = new Light(world);
l1.setPosition(new SimpleVector(0, -10, -40));
l1.setIntensity(255, 0, 0);
l1.setAttenuation(-1);
}
private void loop() {
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_NORMAL);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);
buffer.setPaintListener(this);
long s = System.currentTimeMillis();
while (!buffer.isInitialized()) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while (!Display.isCloseRequested()) {
buffer.clear(Color.BLUE);
world.renderScene(buffer);
world.draw(buffer);
buffer.update();
buffer.display(null);
center.rotateX(0.1f);
center.rotateY(0.1f);
if (System.currentTimeMillis() - s >= 1000) {
s = System.currentTimeMillis();
System.out.println(fps + "fps/" + world.getVisibilityList().getSize() + " objects visible");
fps = 0;
}
}
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
System.exit(0);
}
@Override
public void startPainting() {
// TODO Auto-generated method stub
}
@Override
public void finishedPainting() {
fps++;
}
}
On a Core i7@4GHz with a GTX 680, it manages ~ 5fps in hybrid and ~4 fps in compiled mode when using a custom WorldProcessor instance with 8 threads and 16 work units. Hybrid mode is actually faster here, because it batches more draw calls into one at the expense of a higher cpu load. In hybrid mode, you can add Config.useMultipleThreads=true; at the beginning in addition, which brings to up to 6fps...
However, nothing comes close to 30 fps here...and this is the best case, i.e. simple objects that all share the same mesh. I don't see how this is going to work out. It's also not limited by either jPCT or Java but simply by the fact that 50000 draw calls take their time in OpenGL.