[comp.sys.ibm.pc] Turbo C Ray Traced Beach Ball

wtm@neoucom.UUCP (Bill Mayhew) (03/04/88)

The following software is modeled very closely after the program
that appared in the math coprocessor section of the March '88 Byte
magazine.  To run this, cut out the .PRJ file and the .C file and
make them in your tc environment.  When you run this, you need to
have the EGA driver file present.

Here are some brief test results:

Machine		Without coprocessor		With coprocessor
			mm:ss				mm:ss
---------       -------------------             -----------------
ATT 6300,
V30, 8bit EGA		59:37				 3:08

Epson Equity III
8 MHz			37:36				 N/A

IBM PS/2 mod 80
EGA emulation		16:25				 1:02
VGA, but same # of pixels				 0:48

All three of the above machines were running the 80186/80286 code
gnerated by TC, ver 1.5.  Note that the different mapping of the
bit planes of VGA permitted a more efficient driver to be written,
appently becasue of not needing to keep tinkering with the bit
plane select register as in EGA.

I know.. This program isn't terribly efficent.  It would have been
better to write some inline code to do what putpixel() does, but I
didn't have my EGA programming manual handy when I keyed this in.
Oh well....

By the way, could some enlightend person explain why this program
generates the warning, "function should return a value in function
main".  I can't find where.  It makes the warning when I compile on
the AT&T 6300 and the Epson.  The IBM PS/2 compiles the same code
without a peep.  All machines are running TC 1.5.

--Bill


---------------------cut here for BEACHBAL.PRJ---------------------
BEACHBAL GRAPHICS.LIB
---------------------cut here for BEACHBAL.C-----------------------

/*  Bruce Halloway  .. Witek
 *  Bill Mayhew     .. ported to turbo C.
 */
 
 
#include <graphics.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
 
time_t	*t_loc;
long	start, stop;
float	pi;
int	colors[] = { 3, 6, 10, 13, 6, 3, 10, 13, 6, 3, 13, 10 },
	d[] = { 640 , 350 },
	i, k, x, y, x_min, x_max, y_min, y_max;
unsigned short random;
 
main()
 
{
    float  a, b, c, l0, l1, l2, ln, ln1, n0, n1, n2, p, q, r=128,
           s, t, v[12][3];
    int    n;
    int graphdriver=EGA, graphmode=EGAHI;
 
 
 
    /* EGA High Resolution Mode, standard palette */
    initgraph( &graphdriver, &graphmode, "");
 
    restorecrtmode();
    printf("Fong Shading demo:  Bruce Halloway, Witek Corp.\n");
    printf("                    Bill Mayhew, adapted for Turbo C\n");
    sleep(3);
    setgraphmode( graphmode );
    start=time(t_loc);
 
    /* Pixel aspect ratio */
    a=1.3;
 
    /* Screen center coordinates */
    b=0.5*(d[0]-1);
    c=0.5*(d[1]-1);
 
    /* Unit length light source vector */
    l0=-1/sqrt(3.);
    l1=l0;
    l2=l0;
 
    /* Ratio of circumference to diameter of circle */
    pi=4*atan(1.);
 
    /* A dozen verticies evenly spread over a unit spere. */
    v[0][0]=0;
    v[0][1]=0;
    v[0][2]=1;
    s=sqrt(5.);
    for (i=1;i<11;i++) {
       p=pi*i/5;
       v[i][0]=2*cos(p)/s;
       v[i][1]=2*sin(p)/s;
       v[i][2]=(1.-i%2*2)/s;
    }
    v[11][0]=0;
    v[11][1]=0;
    v[11][2]=-1;
 
    /* Loop to Phong shade every pixel */
    y_max=c+r;
    y_min=2*c-y_max;
    for (y=y_min;y<y_max;y++) {
	s=y-c;
	n1=s/r;
	ln1=l1*n1;
	s=r*r-s*s;
	x_max=b+a*sqrt(s);
	x_min=2*b-x_max;
	for (x=x_min;x<x_max;x++) {
	    t=(x-b)/a;
	    n0=t/r;
	    t=sqrt(s-t*t);
	    n2=t/r;
	    /* compute dot product & clap to pos. values */
	    ln=l0*n0+ln1+l2*n2;
	    if (ln<0) ln=0;
	    /* cos(e.r)**27 */
	    t=ln*n2;
	    t+=t-l2;
	    t*=t*t;
	    t*=t*t;
	    t*=t*t;
	    /* nearest vertex to normal yields max dot prod.  get that color */
	    for (i=0,p=0;i<11;i++)
		if (p<(q=n0*v[i][0]+n1*v[i][1]+n2*v[i][2])) {
		    p=q;
		    k=colors[i];
		}
	    /* Aggregate ambient, diffuse & specular int. & do dither. */
	    i=k-2.5+2.5*ln+t+(random=37*random+1)/65536.;
	    /* clamp values outside range of 3 color levels to blk or wht */
	    if (i<k-2) i=0; else if (i>k) i=15;
	    putpixel(x,y,i);
	}
    }
 
    stop=time(t_loc);
    sound(440);
    delay(250);
    nosound();
    while (! kbhit() );
    (void) getch();
    restorecrtmode();
    printf("Elapsed time to draw sphere is %3.2f sec.\n",
            difftime(stop,start));
}
------end of transmission-----

bobmon@iuvax.cs.indiana.edu ([bob, mon]) (03/06/88)

wtm@neoucom.UUCP (Bill Mayhew) writes:
>
>By the way, could some enlightend person explain why this program
>generates the warning, "function should return a value in function
>main".  I can't find where.  It makes the warning when I compile on
>the AT&T 6300 and the Epson.  The IBM PS/2 compiles the same code
>without a peep.  All machines are running TC 1.5.

The message means that main itself should be returning a value, because it
wasn't declared to be of type void.  (So it defaults to type int.)  I think
this is ANSI-like behavior, and it's one of the warnings that can be turned
on or off.  I suppose that your three machines happen to have different
turboc.cfg/tcconfig.tc (where did they get such mismatched names?) defaults.

--Bob