Drawing Massive amounts of spheres fast ??? (q about nurbs)

hi,
I’m working on drawing protein molecules, and as some of u might know, protein molecules are made up of 1000’s & 1000’s of atoms.

For a basic representation of these molecules, i’m just rendering each atom as a gluSphere, with 10 slices and 10 stacks.

the problem is, when the number of atoms gets large (say 8000) the frame rate drops down to less than 1 fps.

I have frustum culling, but that only helps when only a small portion of the molecule is on the screen.

i’ve also tried glCullFace(GL_BACK); glEnable(GL_CULL_FACE); but i can’t see any difference (maybe gluSphere is handled differently?)

i’ve also tried to lower the number of slices/stacks depending on how close to the molecule the camera is, but as soon as the slice/stack count is less than 5, even from a distance the “spheres” don’t really look like spheres :stuck_out_tongue:

i’m about to try use a display list for each kind of atom there is (because i plan to make each atom type a different size/color/etc).

but i was also thinking about using NURBS to draw the spheres.
however, i don’t know if it’s even possible to draw spheres using nurbs, and if it is possible, i was unable to make google point me to any good examples. I don’t really know anything about nurbs tho, so i was wondering if anyone thinks this will help me. i assume it would create a more accurate surface, but how much extra work does the computer need to do to make them, compared to say the gluSphere?

anyways, here is the code i use to display the molecules. suggestions, comments, criticisms whatever will be greatly appreciated.
Thanks in advance
–Tristan

/* off somewhere in the init section of code */

glClearColor(0.0f, 0.0f, 0.0f ,0.0f);
glClearDepth(1.0f);
glClearStencil(0);

glShadeModel(GL_SMOOTH);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

glEnable(GL_DEPTH_TEST);
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);

glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

/* ----------------------------------------- */

void OpenGLMolecule::draw()
{

GLUquadric *pObj = gluNewQuadric();
gluQuadricNormals(pObj, GL_SMOOTH);
gluQuadricTexture(pObj, GL_TRUE);

Molecule::Atom tempAtom;

glColor3f(1.0f, 1.0f, 1.0f);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
int count = 0;
for (int i = 0 ; i < getNumberOfAtoms() ; i++) {
tempAtom = getAtom(i);
if (CFrustum::getInstance()->checkSphere(tempAtom.getXpos() - origin.x, tempAtom.getYpos() - origin.y, tempAtom.getZpos() - origin.z, 1.0f)) {
count++;
glPushMatrix();
glTranslatef(tempAtom.getXpos() - origin.x, tempAtom.getYpos() - origin.y, tempAtom.getZpos() - origin.z);
gluSphere(pObj, 1.0f, 10, 10);
glPopMatrix();
}
}
glDisable(GL_CULL_FACE);
gluDeleteQuadric(pObj);

}

[This message has been edited by torisutan (edited 09-05-2003).]

Hi !

When the sphere is far away you might want to try to render it as antialiased GL_POINTS instead, you should alos put one sphere in a display list and render that instead each time you need a spgere, that will improve speed alot.

Using a nurb sphere works fine, but it will not help you, OpenGL (GLU) will convert the nurb surface into a sphere (triangles) anyway so it is not given you anything extra in speed.

Mikael

[This message has been edited by mikael_aronsson (edited 09-05-2003).]

Textured quads + bilboard anyone?

First of all i would put the gluSphere(pObj, 1.0f, 10, 10); in a displaylist atleast… that call both calculates and renders the sphere. if you already have the triangles ready on the card you should get a huge boost.

And you dont need to have each color/size version of the sphere since glScalef and glColor can be outside the list and therefor changed for every sphere

Usually you are transform bound, try to make sphere with tristrips + pull it to VBO. Small strips will give you vertex cache benefit.
But anyway, textured quad is only 4 vertices

Display lists helped, i was able to get a good boost in performance. however the performance still drops down way too much as the number of spheres grows dramatically.

antialised GL_POINTS work… but are damned ugly :stuck_out_tongue:
it’s not worth using points until the spheres are so far away that it isn’t really worth looking at the molecule. and i assume that billboarding would produce the same result.

maybe VBOs are worth a try (as M/\dm/
suggested). does anyone have any quick links to good resources on what VBO does exactly, and how to use it? i haven’t had much luck searching for “Vertex buffer object” on google :stuck_out_tongue:

thanks again everyone
–Tristan

I agree with m/\dm/
's comment about billboards. I use this technique extensively for particulate flow in a fluid simulator. I need to show thousands of objects of varying shapes and sizes, so showing 3d objects was impossible. I can show this many quads no prob …The fps is a bit low (15-20) but this is due to the many calculations going on outside of graphics.

Jeremy

Listen to the M/\dm/
, cause the M/\dm/
knows, but the M/\dm/
needs to 'splain what he means by point billboarding a quad with a sphere texture.

Well, all you need is to render hi-res sphere with lighting & read the rendered image (pow of 2) to texture (render to texture @ www.gametutorials.com)..) Then you render quad with this texture applied to it instead of sphere. Billboarding comes because this quad must be allways facing you to stay real-like. But this thing can be done quite simply by just specifying translations & leaving rotations untouched. Problems will arise if you are using camera transform, you won’t escape without matrix math, tutorials again

M/\dm/
, i’ll give it a go, sounds promissing. is it possible to do this using say a vertex/texture program to remove the need for glBegin() glEnd() ?? (i’ve heard they’re quite slow??)

i don’t really know anything about vertex/texture shading, but i want to learn, and if this can be done much quicker using such things i can justify the time i’ll need to spend learning about them :stuck_out_tongue:

thanks again
–tristan

Well, you can define array with all the vertices, & draw them by using comands glDrawArray/glMultiDrawArray, even more, you can transfer data to vcard by using VBO/VAR (read extension specs & make sure you do not have software vp). About vp/fp, you must check this out yourself, if your CPU is fast and free, has SSE+SSE2| |3D-Now! it may be faster to work with vertices on CPU, as GPU clock is around 300Mhz CPU around 2Ghz. But then again GPU works very fast with float4’s. You’ll have to check this out yourself. BTW, fixed pipe is usually faster than vp. I wouldn’t go for fp.

check nvidia’s “depth sprites” demo!
uses reg.comb., tex.shaders and vp and could render a very big amount of spheres!!!
(some kind of bump-mapped quads, but with depth testing, looks like real-spheres)
p.s. with perpixel lighting!

gvm, that “depth sprites” demo looks like what i want.

the only problem, and i assume it would be the same for normal bilboarding, is that if two spheres intersect, it doesn’t show that (instead, one appears infront of the other)

this could be quite a problem, because it removes part of the complexity of the atoms… however i may beable to mix the sprites with display listed spheres…

aha, lots of fun ahead of me :stuck_out_tongue:

Edit: ah sorry, i just figured out it was that way cause i had “depth sprites” turned off in the demo… with it on it is exactly what i want! thanks gvm
–tristan

[This message has been edited by torisutan (edited 09-15-2003).]