home *** CD-ROM | disk | FTP | other *** search
- /*
- * balls1.c - Draw 3-D balls in 320x200x256 (VGA) mode
- *
- * Uses BGI interface
- *
- * Adapted by: Scott J. Walter (GEnie: S.Walter4)
- *
- */
-
- /* INCLUDES */
-
- #include <stdio.h>
- #include <math.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <dos.h>
- #include <time.h>
-
- #include <graphics.h>
-
-
-
- /* DEFINES */
-
- #define TRUE 1
- #define FALSE 0
-
-
-
-
- /* TYPEDEFS */
-
- typedef unsigned char UBYTE;
-
- typedef struct {
- UBYTE Rvalue;
- UBYTE Gvalue;
- UBYTE Bvalue;
- } ColorValue;
-
-
-
-
- /* GLOBALS */
-
- double light[3] = { -2.0, -2.0, 3.0 }; /* light source upr lft */
- int radius = 40;
- ColorValue P[256];
-
-
-
-
- /* FUNCTIONS */
-
- /*
- * Normalize a vector to unit magnitude. Calculate the magnitude as:
- *
- * magnitude = sqrt ( x^2 + y^2 + z^2 )
- *
- * Normalize the vector by dividing each coordinate by the magnitude.
- */
- void normalize(double this_vec[])
- {
- double mag;
- int count;
-
-
- mag = 0.0;
-
- for(count = 0; count < 3; count++)
- mag = mag + (this_vec[count] * this_vec[count]);
-
- mag = sqrt(mag);
-
- for(count = 0; count < 3; count++)
- this_vec [count] = this_vec [count]/mag;
- }
-
-
-
- /* Calculate the cosine of the angle between two vectors.
- *
- * dot product = (x1 * x2) + (y1 * y2) + (z1 * z2)
- */
- double dot_prod(double vec1[], double vec2[])
- {
- double COSINE;
- int count;
-
-
- COSINE = 0.0;
-
- for (count = 0; count < 3; count++)
- COSINE += vec1 [count] * vec2 [count];
-
- return (COSINE);
- }
-
-
-
- void put_atom(int R, int index, int xc, int yc, double l_source[])
- {
- double s_point[3];
- int R2 = R*R, color = 0;
- double x, y, z, r, intensity;
-
-
- normalize(l_source); /* normalize the light source */
-
- for(x=-R;x<=+R;x++) /* scan an area 2R x 2R */
- {
- for(y=-R;y<=+R;y++)
- {
- r = (x*x) + (y*y); /* check that the pixel is within a */
-
- if(r <= R2) /* circle of radius R */
- {
- z = sqrt((R2)-r); /* calculate the altitude of the point */
-
- s_point[0] = x; /* set the normal surface vector to the */
- s_point[1] = y; /* coordinates of the point */
- s_point[2] = z;
-
- intensity = random(100);
- intensity /= 100;
-
- intensity += 64 * dot_prod(s_point,l_source)/R;
-
- color = (int)intensity;
-
- color = color<0 ? 0 : (color> 63 ? 63 : color);
-
- putpixel(x+xc,y+yc,index*64 + color);
- }
- }
- }
- }
-
-
-
- void VGASetAllPalette(void)
- {
- struct REGPACK r;
-
-
- r.r_ax = 0x1012;
- r.r_bx = 0x0000;
- r.r_cx = 0x0100;
- r.r_es = FP_SEG(&P[0]);
- r.r_dx = FP_OFF(&P[0]);
-
- intr(0x10, &r);
- }
-
-
-
- void Hsi2Rgb(float H, float S, float I, int palpos)
- {
- float T, Rv, Gv, Bv;
- float Pi = 3.14159265358979;
-
-
- H = H < 0.0 ? 1.0 + H : (H > 1.0 ? H - 1.0 : H);
- S = S < 0.0 ? 1.0 + S : (S > 1.0 ? S - 1.0 : S);
- I = I < 0.0 ? 1.0 + I : (I > 1.0 ? I - 1.0 : I);
-
- T = 2.0 * Pi * H;
-
- Rv = 1 + S * sin(T - 2 * Pi / 3);
- Gv = 1 + S * sin(T);
- Bv = 1 + S * sin(T + 2 * Pi / 3);
-
- T = 63.999 * I / 2;
-
- P[palpos].Rvalue = (UBYTE)(Rv * T);
- P[palpos].Gvalue = (UBYTE)(Gv * T);
- P[palpos].Bvalue = (UBYTE)(Bv * T);
- }
-
-
-
- int huge DetectVGA256(void)
- {
- int gdriver, gmode;
-
-
- detectgraph(&gdriver, &gmode);
-
- if((gdriver==VGA)||(gdriver==MCGA))
- return 0; /* Default video mode = 0 */
- else
- return grError; /* Couldn't detect hardware */
- }
-
-
-
-
- /* MAIN */
-
- void main(void)
- {
- int Y, Z, ErrorCode, Driver = DETECT, Mode;
-
-
- installuserdriver("VGA256", DetectVGA256);
-
- initgraph(&Driver, &Mode, "");
-
- ErrorCode = graphresult();
-
- if(ErrorCode!=grOk)
- {
- printf("Error: %s\n", grapherrormsg(ErrorCode));
- exit(1);
- }
-
- randomize();
-
- for(Y=0;Y<4;Y++)
- for(Z=0;Z<64;Z++)
- Hsi2Rgb(0.25+(float)Y/5.0, 1.0, (float)Z/64.0, Y*64+Z);
-
- VGASetAllPalette();
-
- for(Y=0;Y<2;Y++)
- for(Z=0;Z<2;Z++)
- put_atom(radius, Y*2+Z, 80+160*Z, 50+100*Y, light);
-
- putch(7);
-
- getch();
-
- closegraph();
- }
-