www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/04/03/22:14:08

From: ellman AT xs4all DOT nl ()
Newsgroups: comp.os.msdos.djgpp
Subject: Allegro Spheres (was: Re: Z-bufering)
Date: 3 Apr 1997 21:36:53 GMT
Organization: XS4ALL
Message-ID: <5i17tl$h97$1@news0.xs4all.nl>
References: <33414D32 DOT 147D AT geocities DOT com> <5htheu$cf0$1 AT news0 DOT xs4all DOT nl> <33433811 DOT 455 AT cam DOT org>
NNTP-Posting-Host: xs2.xs4all.nl
Lines: 63
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

In article <33433811 DOT 455 AT cam DOT org>, Tudor  <tudor AT cam DOT org> wrote:
>ellman AT xs4all DOT nl wrote:
>> PS. I've just written some code to draw a sphere lit from a single
>> lightsource, but it's too slow,

>1) How did you produce the sphere? I was thinking how the **** you can
>automatically make one, like give it the center ,radius, number of
>"stripes" and then it builds itself. But no luck so far... 

The spheres I'm using don't have "stripes". They're real spheres.

The function is given the x, y, z co-ordinates of the sphere in screen-space,
the radius, the light-source vector, the mimimum intensity colour, and the
maximum intensity colour (this corresponds to the GCOL type polygon in Allegro).
I could expand it to have multiple lightsources of different colours, but that
will slow it down too much, as a dot product is done once for every pixel for 
every lightsource.

What I've done is pinched the filled circle drawing code from Allegro's
implementation and modified the bit that draws the horizontal lines of pixels. 
For each pixel in the sphere, the negative Z value is calculated using the
equasion z^2=r^2-x^2-y^2 (I could also use Hardenburgh's circle algorithm, but
that only gives integer Z values, which are less accurate than fixed or
floating Zs which come in handy for Z buffering). I have used Allegro's
lookup-table sqare-root function and pre-calculated r^2-y^2.
Using that Z and the X and Y, I get the vector from the middle of the sphere to
the point I've just calculated. This is divided by the radius (or multiplied
by 1/radius which can be calculated outside the loop) to get the
unit vector (the Y component is normalised outside the loop for drawing a
line of pixels). I then take the dot product of this vector and the reversed
unit light direction, and this gives us the intensity of light for each point.
This intensity is normalised to [0..1] by doing
(result_of_dot_product>>1) + (1<<15)
The colour of the sphere pixel (using the mode that corresponds to
POLYTYPE_GCOL) is calculated by
dark_colour + (light_colour-dark_colour)*intensity.
It's up to the programmer to set up the palette correctly with a smooth colour
gradiend (and perhaps a gamma corrected). When I get round to doing the
POLYTYPE_RGB version, gamma-correction could mean serious CPU usage.

The implementation of the algorithm I described is turns out to be slow, and on
a 100MhZ pentium, it takes a few frames just to draw a sphere of radius 100.

I have speeded up the algorithm by mirroring the calculated Z value in the
X and Y axes, but that just speeds up Z value calculation, and I still have to
do a dot product for each point.

>2) About textures..that seems a tough one. Thinking you'll have dozens
>or hundreds of polys in a sphere you'll gonna have to find a smart algo
>to texturing it... Something like Quake's skins? (like you have a single
>bitmap for the guy and the engine will know how to wrap it up around
>him..)

It's even tougher for 'real-spheres' :-(

AE.

--
Andrei Ellman - URL: http://www.xs4all.nl/~ellman/ae-a - ae1 AT york DOT ac DOT uk
"All I wanna do is have some fun     :-)     || ae-a AT minster DOT york DOT ac DOT uk
 I've got the feeling I'm not the only one"  || mailto:ellman AT xs4all DOT nl
     -- Sheryl Crow      :-)    ||       It's what you make of it.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019