From: Tim Freeman (tim_at_infoscreen.com)
Date: Thu Jul 20 2000 - 07:40:33 CDT

From: John Stone <johns_at_ks.uiuc.edu>
>One of the problems with using the tricks involving pre-computed
>sphere images is that you have to re-compute the template image every
>time the lighting conditions or rendered materials change. If you use
>40 different colors to render your scene, you have to generate sphere
>template images for each of the colors. If you vary the lighting
>parameters or material characteristics of the spheres, then those have
>to be re-computed as well. (you you need to build a big lookup table
>with pre-computed spheres..) These aren't so bad if you limit your
>color changes and materials changes per scene draw, but if you start
>taking into account things like scaling your template images to the
>correct size for the radius of the atom being drawn, and then having
>to correct the depth image accordingly, it really starts to chisel
>into the performance that you work so hard to get out of it.

My present algorithm uses an orthographic projection, so recomputing
the spheres to scale for the depth isn't an issue. I don't scale the
template to suit the atom size and color; instead I just recompute it
from scratch. Usually there are a small number of small templates
that are used very many times so this doesn't perceptibly slow things
down when I zoom the scene.

By the way, glCopyPixels supports pixel zoom, so if I were using
OpenGL and perspective I could tell the graphics hardware to do the
scaling. Mip-mapping would help. There ought to be plenty of space
to store templates, since I have ~1 megapixel per screen, 16 bits per
pixel, so that's 4M bytes for a double-buffered screen, and 32M bytes
of memory on the graphics card.

>Perhaps one could use a non-visible section of framebuffer memory
>to perform glCopyPixels() for drawing spheres, this would be a nice trick
>that would mostly eliminate eliminate the CPU to framebuffer bus on well
>designed graphics boards.

Yes, that's a good idea, and new to me. Maybe after Fungimol gets
better physics I should examine this route. Having hardware graphics
and paying for about one polygon per sphere should make the rendering
very fast. (I had thought until now that I could accomplish the same
thing by incorporating glDrawPixels into a display list, but the OGL
1.1 reference manual says that's not an option.)

>Another problem I thought of with the
>glDrawPixels() method of drawing spheres, is that the OpenGL Z-buffer
>isn't linear, so if you render the spheres with glDrawPixels() and
>you render other geometry in the same scene using the standard OpenGL
>primitives, the hidden surface removal may not work out correctly.

I'm using an orthographic projection, so if I switched to OpenGL and
was still willing to settle for an orthographic projection, I think
I'd have a linear depth buffer and this wouldn't be a problem.
(Please correct me if you know this is wrong.) If I were doing
perspective, I could probably could come close to doing the right
thing by scaling and biasing the depth pixels as they're copied, at
the risk of failing totally by either doing operations that they
didn't bother to accelerate with hardware or doing operations that are
broken because they're too obscure for them to bother testing the
graphics driver.

>By the way, I would love to know what sorts of frame rates you are able
>to achieve with the glDrawPixels() method that you've implemented.
>How fast for a scene with 10,000 spheres or so? Have you come up with
>a good way to deal with handling many different colors/materials using
>the glDrawPixels() method?

Having glDrawPixels copy depth buffers didn't display correctly with
my graphics card and driver combination. There are newer revisions
available that I haven't tried. I don't know what would happen if I
tried it with current software. Doing it in software on a 600 Mhz
Pentium 3, and using tricks to avoid drawing spheres that aren't
visible and parts of the black background that don't change from frame
to frame, I can draw an ~8000 sphere figure in 166 ms. A fair race
between the graphics hardware and the CPU-based approaches would use
MMX instructions in the CPU-based approach, which I am not doing yet
(or, likely, any time soon).

>One beautiful aspect of the glDrawPixels() method is that you can render
>your pre-computed spheres at very very high geometric resolution,
>(or ray trace them for that matter!) and get some awesome looking images.

Agreed. I do a fairly sloppy algorithm that computes each pixel in
the template from scratch using straightforward floating point, and
the templates are small enough and few enough that it doesn't matter.

>One of the things I miss about the "bad old days" of graphics is that
>it used to be a lot of fun to write custom graphics algorithms in software
>where the only consideration was CPU time used, and bandwidth to the
>framebuffer :-)

Agreed. I have a not-yet-implemented scheme for doing fast software
cylinders that should look almost as good as "true" cylinders ("true"
in the sense that each pixel is correct), but I can't imagine doing an
OpenGL implementation of it.

>...I love this topic though...

I do too, but I have to admit that for me now it's focusing on the
wrong thing. Fungimol's rendering is fast enough, but its physics is
uninteresting and it's Linux-only.

-- 
Tim Freeman       
tim_at_infoscreen.com