Performance boost with quadrics

I am creating a scene with 200 spheres and was using the TestUtils.createSphere(float R, int divisions) method to generate the spheres. I set the divisions to 30 and was getting poor performance when animating the scene, around 8 fps.

I was interested to see if quadrics would increase performance and have implemented them in Xith3D and have noticed a substantial difference.

Quadrics use stacks and slices, and I’m not sure how these numbers compare to the divisions parameter, but with stacks = slices = 35, I get 18 fps. My OpenGL book says they should be set to 20 or more, and so with stacks=slices=20, I get 30 fps.

To get the same 30 fps with createSphere, I have to set divisions = 10, which is a much poorer quality sphere.

Therefore, I think Xith3D should support quadrics, although I don’t know exactly what the best way to do this would be, here is how I got them to work.

First I added a QuadricSphere class:

package com.xith3d.scenegraph;
import javax.vecmath.Tuple3f;
public class QuadricSphere extends Geometry{
public NodeComponent cloneNodeComponent(boolean forceDuplicate) {
return null;
}

  public int getVertexCount() {
        return 0;
  }

  public boolean getVertex(int i, Tuple3f pos) {
        return false;
  }

  protected float radius;
  protected int stacks = 20;
  protected int slices = 20;
  public int getStacks()
  {
        return stacks;
  }
  public int getSlices()
  {
        return slices;
  }
  public void setRadius(float r)
  {
        radius = r;
  }
  public float getRadius()
  {
        return radius;
  }
  public QuadricSphere(float r)
  {
        radius = r;
  }

}

Next in the ShapeAtomPeer class I added a member variable:
GLUquadric sphereObject = null;

Then in the renderAtom(CanvasPeer, RenderAtom) method of ShapeAtomPeer I added the code:

    if (((CanvasPeerImpl) canvas).isDebugFrame()) {
        ((CanvasPeerImpl) canvas).debugLog(
                "Rendering a shape with geometry : " +
                geometry.getClass().getName() + " : " + shape.getName());

        OpenGlStateDebug.printState(canvas);
    }

// Begin Quadric Code

if(geometry instanceof QuadricSphere)
{
QuadricSphere sphere = (QuadricSphere)geometry;
if(sphereObject == null)
{
sphereObject = glu.gluNewQuadric();
}
glu.gluQuadricNormals(sphereObject, GLU.GLU_SMOOTH);
glu.gluQuadricDrawStyle(sphereObject,GLU.GLU_FILL);
glu.gluQuadricOrientation(sphereObject, GLU.GLU_OUTSIDE);
glu.gluSphere(sphereObject, sphere.getRadius(), sphere.getSlices(), sphere.getStacks());
return;
}
// End Quadric Code
if (geometry instanceof GeometryArray) {

Then if you want to create a sphere you use:
Appearance a = new Appearance();
Shape3D atomShape = new Shape3D(new QuadricSphere(radius),a);

Spheres and cylinders are VERY important to my application, so I really appreciate any ideas for a better way to do this, and hope that Xith3D can have quadric support.

Thanks,

Jason

Very nice! Many thanks for sharing that information!
I was using 10 divisions as well before, and now they look much smoother!

Prabably Xith should provide a plugin-mechanism-way to add personal features like this? Or is such a feature not intended?

Glad to hear you were able to use the code.

I’m not sure how tied to OpenGL Xith3D should be, so I guess calling the class QuadricSphere may not be a good idea since it makes it more locked into OpenGL. Instead maybe you could just have a Sphere class and have some number that would roughly map to how many divisions you’d like. If the renderer doesn’t have OpenGL support you can render the sphere with triangles, but if it does then you can use quadrics. I think it would be nice to have spheres be part of the regular API, instead of a plugin, so what would the negative consequences be if it was?

Jason

I think the sphere function is intended as a utility, hence it just uses triangles… Quadratics should probably get added as another type of geometry… i.e.

TriangleArray
QuadArray
QuadraticArray

And then a specific person might write a utility that creates a sphere using a QuadraticArray. But as you say this would need to be implemented differently dependant on the renderer.

Kev

I think there was someone already writing a primitive package, at least I read intentions of doing it so in previous threads. Has anyone actually started the task?

I don’t see the harm in adding to Xith basic primitives in addition to the basic datatypes. I know that the aim is to abstract Xith from any rendering platform, so having smart primitives to adapt to whatever it is the version of jogl or directx one might import (I don’t think Xith is theoretically limited to openGL, or is it?) seems good.

I think there should always be basic datatypes that would allow the developer to do everything if using straight openGL/whatever, or offer ways for the developer to extend Geometry and have the ShapeAtomPeer to ‘accept them’. Otherwise we limit xith for no good reason.

It appears to me that TestUtils.createSphere() and your GLU implementation both create the same type of spheres. TestUtils simply sets slices==stacks==divisions. I suspect that its poor performance is due to the use of indexed geometry; a TriangleStripArray might do better. Any thoughts?

As for adding new geometry types, what would be the difference between a QuadricArray and a QuadArray? In other words, a QuadArray specifies each Quad by four vertices; what is a Quadric specified by?

[quote]It appears to me that TestUtils.createSphere() and your GLU implementation both create the same type of spheres. TestUtils simply sets slices==stacks==divisions. I suspect that its poor performance is due to the use of indexed geometry; a TriangleStripArray might do better. Any thoughts?
[/quote]
Not really. Quadrics offer a different approach to describe geometries. Check this page http://www.geom.uiuc.edu/docs/reference/CRC-formulas/node61.html for an overview and some nice pictures. The way I understand is that the Array family of classes describe shapes crudely by defining vertices in 3D space. while Quadrics use second order equations in respect to x,y and z to describe a shape.

Check this screenshot here: http://www.dcs.warwick.ac.uk/~csvnx/tmp/screen1.PNG. I added to a scene two shapes, one is TestUtils.createSphere(5, 10) and the other is QuadricSphere(5,10). The differences in the gometry structure are obvious (basically one is made out of triangles, while the other gets those vertices at run-time according to the equation that describes it)

jkc6n, did you try to use textures with your QuadricSphere?

Could you or someone enlighten me on how this can be done?

I haven’t tried it myself, but there is a OpenGL method:

gluQuadricTexture(GLUquadricObj *quadObj, GLboolean useTextureCoords);

that you probably have to invoke setting the boolean to true, since texture coordinates are turned off by default.

let me know if you get this to work.

Jason

Worked like a charm :slight_smile:

Just added the line you proposed to ShaderAtomPeer, and that was it. Magic!

I actually new about that GLU method, but wouldn’t expect that was the only thing required, but it was :stuck_out_tongue:

thanks for the hint.