In Alite, I ran across the same problem, and in the end, I copied the approach from "Celestia" (
http://www.shatters.net/celestia/): They use "depth buckets", which is essentially similar to cim's idea. You order your objects by z and iterate over them (farthest away from the camera first). Now, you add objects to your current "bucket", while the distance spanned by all objects in the bucket is smaller than X. If the new object is so far away from the last object that the radius of the bucket would be bigger than X, you start a new bucket.
When rendering the buckets, you clear your depth buffer before each bucket. In Alite, the partition implementation looks like that (slightly simplified; note that "allMyObjects" are already sorted along the z axis (= "distance" to the camera)):
Code:
private final void partitionDepths(final List <DepthBucket> sortedObjectsToDraw) {
DepthBucket currentBucket = null;
DepthBucket behind = new DepthBucket();
behind.near = -1;
behind.far = -1;
for (Object p: allMyObjects) {
float dist = p.distance; // Can be negative, relative to camera
float size = p.getBoundingSphereRadius();
if (dist < -size) {
behind.sortedObjects.add(p);
continue;
}
float near = dist - size;
float far = dist + size;
if (near < 1.0f && far > 1.0f) {
near = 1.0f;
}
if (currentBucket == null) {
currentBucket = new DepthBucket();
currentBucket.near = near;
currentBucket.far = far;
currentBucket.sortedObjects.add(p);
} else {
if (far > currentBucket.near) {
currentBucket.sortedObjects.add(p);
if (currentBucket.near > near) {
currentBucket.near = near;
}
if (currentBucket.far < far) {
currentBucket.far = far;
}
} else {
sortedObjectsToDraw.add(currentBucket);
float newFar = currentBucket.near;
currentBucket = new DepthBucket();
currentBucket.near = near;
currentBucket.far = newFar;
currentBucket.sortedObjects.add(p.object);
}
}
if (currentBucket != null) {
sortedObjectsToDraw.add(currentBucket);
}
if (behind.sortedObjects.size() > 0) {
sortedObjectsToDraw.add(behind);
}
}
And for rendering:
Code:
for (DepthBucket bucket: buckets) {
GLES11.glClear(GLES11.GL_DEPTH_BUFFER_BIT);
for (AliteObject go: bucket.sortedObjects) {
go.render();
}
}
Maybe this helps a little...