home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / grafik / tc_3d / tc-10.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-13  |  16.1 KB  |  399 lines

  1. /* tc-10.c */
  2. /* Draws a computer-shaded 3d solid cube using the
  3.     plane equation method of hidden surface removal
  4.     and the surface normal method of halftone shading */
  5.  
  6. /* ----------------------------------------------------------------------- */
  7. /* INCLUDE FILES */
  8. #include <process.h>
  9. #include <bios.h>
  10. #include <stdio.h>
  11. #include <graphics.h>
  12. #include <math.h>
  13.  
  14. /* DECLARATIONS */
  15.  
  16. float        x=0.0,y=0.0,z=0.0;                                              /* world coordinates */
  17. float        x1=0.0,x2=0.0,x3=0.0;                                        /* polygon vertices */
  18. float        y01=0.0,y2=0.0,y3=0.0;                                        /* polygon vertices */
  19. float        z1=0.0,z2=0.0,z3=0.0;                                        /* polygon vertices */
  20. float        sx1=0.0,sx2=0.0,sx3=0.0,sx4=0.0,sx5=0.0;                /* display coordinaes */
  21. float        sy1=0.0,sy2=0.0,sy3=0.0,sy4=0.0,sy5=0.0;                /* display coordinates */
  22. float        sx=0.0,sy=0.0;                                                    /* output of 3d perspective formulas */
  23. float        xa=0.0,ya=0.0,za=0.0;                                        /* temporary values in 3d formulas */
  24. float        d=1200.0;                                                        /* angular perspective value */
  25. double    r1=5.68319;                                                        /* yaw angle in radians */
  26. double    r2=6.28319;                                                        /* roll angle in radians */
  27. double    r3=5.79778;                                                        /* pitch angle in radians */
  28. double    sr1=0.0,sr2=0.0,sr3=0.0;                                    /* sine rotation factors */
  29. double    cr1=0.0,cr2=0.0,cr3=0.0;                                    /* cosine rotation factors */
  30. float        mx=0.0,my=0.0,mz=-350.0;                                    /* viewpoint position */
  31. int        maxx=639,minx=0,maxy=199,miny=0;                            /* scaling viewport */
  32. float        screen_x=639,screen_y=199;                                    /* dimensions of screen mode */
  33. int        C0=0,C1=1,C2=2,C3=3,C4=4,C5=5,C6=6,C7=7,C8=8,        /* color varariables */
  34.             C9=9,C10=10,C11=11,C12=12,C13=13,C14=14,C15=15,
  35.             mode_flag=0;
  36. float        rx=0.0,ry=0.0;                                                    /* scaling values used in mapping routine */
  37. int        t=0,t1=0,t2=0;                                                    /* loop counters */
  38. int        p1=0;                                                                /* array indexer */
  39. int        key_matte_clr=6;                                                /* exclusive key matte color */
  40. int        edge_clr=7;                                                        /* used to draw edges on models */
  41. int        solid_clr=0;                                                    /* used to fill surfaces on solid models */
  42. int        design_clr=1;                                                    /* used to draw the design on the model */
  43. float        x_res,y_res;                                                    /* used for 2d mappinf from 640*480 template */
  44. float        sp=0.0;                                                            /* visibility factor in hidden surface routine */
  45. float        sp1=0.0,sp2=0.0,sp3=0.0;                                    /* temporary values of sp */
  46.  
  47. int        NORM_HUE=0;                                                        /* halftoning color */
  48. int        BASE_CLR=0;                                                        /* prep cooor for dithering */
  49. int        CC4=0;                                                            /* underlay color for dithering */
  50. int        CC5=0;                                                            /* overlay color for dithering */
  51. unsigned short CC6=0xffff;                                                /* pattern for dithering */
  52. float        xx1=0,yy1=.60711,zz1=.70771;                        /* location of light source - elevation 45 degrees, compas 135 degrees {{REDIFINED !!}}*/
  53. float        v4=0.0;                                                            /* illumination factor 0 to 1 range */
  54. int        v5=0;                                                                /* illumination factor base 1 range */
  55. int        v6=11;                                                            /* VGA and EGA illumination range */
  56. int        v7=0;                                                                /* temporary varaible used for illumination range */
  57. float        xu=0.0,yu=0.0,zu=0.0;                                        /* vector from vertex one to vertex two */
  58. float        xv=0.0,yv=0.0,zv=0.0;                                        /* vector from vertex 1 to vertex 3 */
  59. float        xn=0.0,y0n=0.0,zn=0.0;                                        /* surface perpendicular factor */
  60. float        v1=0.0,v2=0.0;                                                    /* length of surface perpendicular vector */
  61. float        v3=0.0;                                                            /* ratio of length to unit vector magnitude */
  62. float        xw=0.0,yw=0.0,zw=0.0;                                        /* surface perpendicual unit vector */
  63. int        polary[4][2];  /* used in my 3d solid polygon draw routine */
  64.  
  65. /* define halftone codes */
  66. char fill_0[]={0,0,0,0,0,0,0,0};                                        /* 0% fill */
  67. char fill_3[]={0,32,0,0,0,2,0,0};                                    /* 3% fill */
  68. char fill_6[]={32,0,2,0,128,0,8,0};                                    /* 6% fill */
  69. char fill_12[]={32,2,128,8,32,2,128,8};                            /* 12% fill */
  70. char fill_25[]={68,17,68,17,68,17,68,17};                            /* 25% fill */
  71. char fill_37[]={170,68,170,17,170,68,170,17};                    /* 37% fill */
  72. char fill_50[]={85,170,85,170,85,170,85,170};                    /* 50% fill */
  73. char fill_62[]={85,187,85,238,85,187,85,238};                    /* 62% fill */
  74. char fill_75[]={187,238,187,238,187,238,187,238};                /* 75% fill */
  75. char fill_87[]={223,253,127,247,223,253,127,247};                /* 87% fill */
  76. char fill_93[]={255,223,255,223,255,223,255,223};                /* 93% fill */
  77. char fill_100[]={255,255,255,255,255,255,255,255};                /* 100% fill */
  78.  
  79. /* database of vertices for 3d model */
  80. int        array1[][3]={
  81.             30,-30,30,    30,30,30,    -30,30,30,    -30,-30,30,    30,30,-30,
  82.             -30,30,-30,    -30,-30,-30,    30,-30,-30};
  83.  
  84. /* database for fill origins of 3d models */
  85. int        array2[][3]={
  86. 0,-30,0,    0,0,-30,    -30,0,0,    0,0,30,    30,0,0,    0,30,0};
  87.  
  88. float        B1[8][3];                                                        /* array of 8 sets of xyz view coordinates */
  89. float        B2[8][2];                                                        /* array of 8 sets of sx,sy display coordinates */
  90. float        B3[6][2];                                                        /* array of 6 sets of sx,sy fill coordinates */
  91.  
  92. /* declare global subroutines */
  93. void keyboard(void);void quit_pgm(void);void calc_3d(void);
  94. void rotation(void);void window(void);void graphics_setup(void);
  95. void coords(void);void draw_poly(void);void notice(int x,int y);
  96. void visibility_test(void);void store_coords(void);
  97. void illumination(void);void dither(void);void shade(void);
  98. void values(void);
  99.  
  100. /* ----------------------------------------------------------------------- */
  101. /* MAIN ROUTINE */
  102.  
  103. main(){
  104. graphics_setup();
  105. setviewport(0,0,maxx,maxy,1);
  106. key_matte_clr=C6;
  107. edge_clr=C7;solid_clr=C0;
  108. NORM_HUE=C11;                                                                /* define shading color */
  109. store_coords();                                                            /* calculate and store 3d coords in arrays */
  110.  
  111. surface0:
  112. x1=B1[7][0];y01=B1[7][1];z1=B1[7][2];x2=B1[0][0];y2=B1[0][1];
  113. z2=B1[0][2];x3=B1[3][0];y3=B1[3][1];z3=B1[3][2];visibility_test();
  114. if (sp>0) goto surface1;
  115. sx1=B2[7][0];sy1=B2[7][1];sx2=B2[0][0];sy2=B2[0][1];sx3=B2[3][0];
  116. sy3=B2[3][1];sx4=B2[6][0];sy4=B2[6][1];sx5=B3[0][0];sy5=B3[0][1];
  117. draw_poly();illumination();shade();dither();
  118.  
  119. surface1:
  120. x1=B1[6][0];y01=B1[6][1];z1=B1[6][2];x2=B1[5][0];y2=B1[5][1];
  121. z2=B1[5][2];x3=B1[4][0];y3=B1[4][1];z3=B1[4][2];visibility_test();
  122. if (sp>0) goto surface2;
  123. sx1=B2[6][0];sy1=B2[6][1];sx2=B2[5][0];sy2=B2[5][1];sx3=B2[4][0];
  124. sy3=B2[4][1];sx4=B2[7][0];sy4=B2[7][1];sx5=B3[1][0];sy5=B3[1][1];
  125. draw_poly();illumination();shade();dither();
  126.  
  127. surface2:
  128. x1=B1[3][0];y01=B1[3][1];z1=B1[3][2];x2=B1[2][0];y2=B1[2][1];
  129. z2=B1[2][2];x3=B1[5][0];y3=B1[5][1];z3=B1[5][2];visibility_test();
  130. if (sp>0) goto surface3;
  131. sx1=B2[3][0];sy1=B2[3][1];sx2=B2[2][0];sy2=B2[2][1];sx3=B2[5][0];
  132. sy3=B2[5][1];sx4=B2[6][0];sy4=B2[6][1];sx5=B3[2][0];sy5=B3[2][1];
  133. draw_poly();illumination();shade();dither();
  134.  
  135. surface3:
  136. x1=B1[0][0];y01=B1[0][1];z1=B1[0][2];x2=B1[1][0];y2=B1[1][1];
  137. z2=B1[1][2];x3=B1[2][0];y3=B1[2][1];z3=B1[2][2];visibility_test();
  138. if (sp>0) goto surface4;
  139. sx1=B2[0][0];sy1=B2[0][1];sx2=B2[1][0];sy2=B2[1][1];sx3=B2[2][0];
  140. sy3=B2[2][1];sx4=B2[3][0];sy4=B2[3][1];sx5=B3[3][0];sy5=B3[3][1];
  141. draw_poly();illumination();shade();dither();
  142.  
  143. surface4:
  144. x1=B1[7][0];y01=B1[7][1];z1=B1[7][2];x2=B1[4][0];y2=B1[4][1];
  145. z2=B1[4][2];x3=B1[1][0];y3=B1[1][1];z3=B1[1][2];visibility_test();
  146. if (sp>0) goto surface5;
  147. sx1=B2[7][0];sy1=B2[7][1];sx2=B2[4][0];sy2=B2[4][1];sx3=B2[1][0];
  148. sy3=B2[1][1];sx4=B2[0][0];sy4=B2[0][1];sx5=B3[4][0];sy5=B3[4][1];
  149. draw_poly();illumination();shade();dither();
  150.  
  151. surface5:
  152. x1=B1[1][0];y01=B1[1][1];z1=B1[1][2];x2=B1[4][0];y2=B1[4][1];
  153. z2=B1[4][2];x3=B1[5][0];y3=B1[5][1];z3=B1[5][2];visibility_test();
  154. if (sp>0) goto surfaces_done;
  155. sx1=B2[1][0];sy1=B2[1][1];sx2=B2[4][0];sy2=B2[4][1];sx3=B2[5][0];
  156. sy3=B2[5][1];sx4=B2[2][0];sy4=B2[2][1];sx5=B3[5][0];sy5=B3[5][1];
  157. draw_poly();illumination();shade();dither();
  158.  
  159. surfaces_done:setcolor(C7);notice(0,0);
  160. for (t1=1;t1!=2;) keyboard();
  161. quit_pgm();
  162. }
  163.  
  164. /* ----------------------------------------------------------------------- */
  165. /* SUBROUTINE: CALCULATE SIN,COS FACTORS */
  166.  
  167. void rotation(void){
  168. sr1=sin(r1);sr2=sin(r2);sr3=sin(r3);cr1=cos(r1);cr2=cos(r2);
  169. cr3=cos(r3);return;}
  170.  
  171. /* ----------------------------------------------------------------------- */
  172. /* SUBROUTINE: STANDARD 3D FORMULAS */
  173. /* Pass: x,y,z cartesian world coordinates.
  174.    Returns: sx,sy cartesian display coordinates.
  175.           x,y,z catesian view coordinates */
  176.  
  177. void calc_3d(void){
  178. x=(-1)*x;xa=cr1*x-sr1*z;za=sr1*x+cr1*z;x=cr2*xa+sr2*y;
  179. ya=cr2*y-sr2*xa;z=cr3*za-sr3*ya;y=sr3*za+cr3*ya;x=x+mx;y=y+my;
  180. z=z+mz;sx=d*x/z;sy=d*y/z;return;}
  181.  
  182. /* ----------------------------------------------------------------------- */
  183. /* SUBROUTINE: CALCULATE AND STORE VIEW COORDINATES & DISPLAY COORDS */
  184.  
  185. void store_coords(void){
  186. rotation();
  187. for (t=0;t<=7;t++){
  188.     x=array1[t][0];y=array1[t][1];z=array1[t][2];
  189.     calc_3d();window();
  190.     B1[t][0]=x;B1[t][1]=y;B1[t][2]=z;
  191.     B2[t][0]=sx;B2[t][1]=sy;
  192.     };
  193.  
  194. for (t=0;t<=5;t++){
  195.     x=array2[t][0];y=array2[t][1];z=array2[t][2];
  196.     calc_3d();window();
  197.     B3[t][0]=sx;B3[t][1]=sy;
  198.     };
  199. return;
  200. }
  201.  
  202. /* ----------------------------------------------------------------------- */
  203. /* HIDDEN SURFACE VISIBILTY TEST */
  204. void visibility_test(void){
  205. sp1=x1*(y2*z3-y3*z2);sp1=(-1)*sp1;sp2=x2*(y3*z1-y01*z3);
  206. sp3=x3*(y01*z2-y2*z1);sp=sp1-sp2-sp3;return;}
  207.  
  208. /* ----------------------------------------------------------------------- */
  209. /* SUBROUTINE: DRAW 4-SIDED SOLID POLYGON IN 3D SPACE */
  210.  
  211. void draw_poly(void){
  212. setlinestyle(USERBIT_LINE,0xffff,NORM_WIDTH);
  213. setfillstyle(SOLID_FILL,solid_clr);
  214. setcolor(edge_clr);
  215.  
  216. polary[0][0]=sx1;polary[0][1]=sy1;polary[1][0]=sx2;polary[1][1]=sy2;
  217. polary[2][0]=sx3;polary[2][1]=sy3;polary[3][0]=sx4;polary[3][1]=sy4;
  218.  
  219. fillpoly (4,(int far*) polary);
  220. return;
  221. }
  222.  
  223. /* ----------------------------------------------------------------------- */
  224. /* SUBROUTINES: CALCULATE ILLUMINATION LEVEL */
  225.  
  226. void illumination(void){
  227. xu=x2-x1;yu=y2-y01;zu=z2-z1;                                        /* vector from vertex 1 to vertex 2 */
  228. xv=x3-x1;yv=y3-y01;zv=z3-z1;                                        /* vector from vertex 1 to vertex 3 */
  229. xn=(yu*zv)-(zu*yv);y0n=(zu*xv)-(xu*zv);
  230.     zn=(xu*yv)-(yu*xv);                                                /* surface perpendicular vector */
  231. y0n=y0n*(-1);zn=zn*(-1);                                            /* convert to cartesian system */
  232. v1=(xn*xn)+(y0n*y0n)+(zn*zn);
  233. v2=sqrt(v1);                                                            /* magnitude of surface perpendicular vector */
  234. v3=1/v2;                                                                    /* ratio of magnitude to length of unit vector */
  235. xw=v3*xn;yw=v3*y0n;zw=v3*zn;                                        /* surface perpendicular to unit vector */
  236. v4=(xw*xx1)+(yw*yy1)+(zw*zz1);                                    /* illumination factor 0 to 1 */
  237. v4=v4*v6;                                                                /* expand illumination range from base 0 */
  238. v7=v4;                                                                    /* convert illumination range to integer */
  239. v5=v7+1;                                                                    /* illumination range from base 1 */
  240. return;
  241. }
  242.  
  243. /* ----------------------------------------------------------------------- */
  244. /* SUBROUTINE: ILLUMINATION MATRIX */
  245.  
  246. void shade(void){
  247. switch (v5){
  248.     case 1:setfillpattern(fill_6,NORM_HUE);CC6=0x1010;values();return;
  249.     case 2:setfillpattern(fill_6,NORM_HUE);CC6=0x1010;values();return;
  250.     case 3:setfillpattern(fill_6,NORM_HUE);CC6=0x1010;values();return;
  251.     case 4:setfillpattern(fill_12,NORM_HUE);CC6=0x2020;values();return;
  252.     case 5:setfillpattern(fill_25,NORM_HUE);CC6=0x2222;values();return;
  253.     case 6:setfillpattern(fill_37,NORM_HUE);CC6=0xaaaa;values();return;
  254.     case 7:setfillpattern(fill_50,NORM_HUE);CC6=0xaaaa;values();return;
  255.     case 8:setfillpattern(fill_62,NORM_HUE);CC6=0xaaaa;values();return;
  256.     case 9:setfillpattern(fill_75,NORM_HUE);CC6=0xbbbb;values();return;
  257.     case 10:setfillpattern(fill_87,NORM_HUE);CC6=0xdddd;values();return;
  258.     case 11:setfillpattern(fill_93,NORM_HUE);CC6=0xefef;values();return;
  259.     case 12:setfillpattern(fill_100,NORM_HUE);CC6=0xffff;values();return;
  260.     defualt:setfillpattern(fill_6,NORM_HUE);CC6=0x1010;values();}
  261. return;}
  262.  
  263. /* ----------------------------------------------------------------------- */
  264. /* LOCAL SUBROUTINE: prep fill and set dithering variables */
  265. void values(void){
  266. floodfill(sx5,sy5,edge_clr);CC4=BASE_CLR;CC5=NORM_HUE;return;}
  267.  
  268. /* ----------------------------------------------------------------------- */
  269. /* SUBROUTINE: APPLY DITHERING */
  270.  
  271. void dither(void){
  272. setlinestyle(USERBIT_LINE,0xffff,NORM_WIDTH);setcolor(CC4);
  273. moveto (sx1,sy1);lineto(sx2,sy2);lineto(sx3,sy3);
  274. lineto(sx4,sy4);lineto(sx1,sy1);
  275. setlinestyle(USERBIT_LINE,CC6,NORM_WIDTH);setcolor(CC5);
  276. moveto(sx1,sy1);lineto(sx2,sy2);lineto(sx3,sy3);
  277. lineto(sx4,sy4);lineto(sx1,sy1);
  278. return;
  279. }
  280.  
  281. /* ----------------------------------------------------------------------- */
  282. /* SUBROUTINE: MAP CARTESIAN COORDS TO PHYSICAL SCREEN COORDS */
  283.  
  284. void window(void){
  285. sx=sx+399;sy=sy+299;rx=screen_x/799;ry=screen_y/599;sx=sx*rx;
  286. sy=sy*ry;return;}
  287.  
  288. /* ----------------------------------------------------------------------- */
  289. /* SUBROUTINE: CHACK THE KEYBOARD BUFFER */
  290. void keyboard(void){
  291. if (bioskey(1)==0) return; else quit_pgm();}
  292.  
  293. /* ----------------------------------------------------------------------- */
  294. /* SUBROUTINE: GRACEFUL EXIT FROM PROGRAM */
  295.  
  296. void quit_pgm(void){
  297. cleardevice();restorecrtmode();exit(0);}
  298.  
  299. /* ----------------------------------------------------------------------- */
  300. /* SUBROUTINE: VGA/EGA/MCGA/CGA COMPATIBILITY MODULE */
  301.  
  302. void graphics_setup(void){
  303. int graphics_adapter,graphics_mode;
  304. detectgraph(&graphics_adapter,&graphics_mode);
  305. if (graphics_adapter==VGA) goto VGA_mode;
  306. if (graphics_mode==EGAHI) goto EGA_ECD_mode;
  307. if (graphics_mode==EGALO) goto EGA_SCD_mode;
  308. if (graphics_adapter==CGA) goto CGA_mode;
  309. if (graphics_adapter==MCGA) goto CGA_mode;
  310. goto abort_message;
  311.  
  312. VGA_mode:
  313. graphics_adapter=VGA;graphics_mode=VGAHI;
  314. initgraph(&graphics_adapter,&graphics_mode,"");
  315. x_res=640;y_res=480;mode_flag=1;
  316.         maxx=639;minx=0;maxy=479;miny=0;screen_x=639;screen_y=479;
  317.         setcolor(7);moveto(0,472);
  318.           outtext("Revisions by A. Helder");
  319.         moveto(472,472);
  320.         outtext("Press any key to quit");
  321.         moveto(160,0);
  322.         outtext("USING C TO GENERATE A 3D WIRE FRAME CUBE");
  323.         return;
  324.  
  325. EGA_ECD_mode:
  326. graphics_adapter=EGA;graphics_mode=EGAHI;
  327. initgraph(&graphics_adapter,&graphics_mode,"");
  328. x_res=640;y_res=350;mode_flag=2;
  329.         maxx=639;minx=0;maxy=349;miny=0;screen_x=639;screen_y=349;
  330.         setcolor(7);moveto(0,342);
  331.           outtext("Revisions by A. Helder");
  332.         moveto(472,342);
  333.         outtext ("Press any key to quit");
  334.         moveto(160,0);
  335.         outtext("USING C TO GENERATE A 3D WIRE FRAME CUBE");
  336.         return;
  337.  
  338. EGA_SCD_mode:
  339. graphics_adapter=EGA;graphics_mode=EGALO;
  340. initgraph(&graphics_adapter,&graphics_mode,"");
  341. x_res=640;y_res=200;mode_flag=3;
  342.         maxx=639;minx=0;maxy=199;miny=0;screen_x=639;screen_y=199;
  343.         setcolor(7);moveto(0,192);
  344.           outtext("Revisions by A. Helder");
  345.         moveto(472,192);
  346.         outtext("PRESS ANY KEY TO QUIT");
  347.         moveto(160,0);
  348.         outtext("USING C TO GENERATE A 3D WIRE FRAME CUBE");
  349.         return;
  350.  
  351. CGA_mode:
  352. graphics_adapter=CGA;graphics_mode=CGAC3;
  353. initgraph(&graphics_adapter,&graphics_mode,"");
  354. x_res=320;y_res=200;mode_flag=1;C7=3;
  355.         maxx=319;minx=0;maxy=199;miny=0;screen_x=319;screen_y=199;
  356.         setcolor(3);moveto(48,192);
  357.           outtext("Revisions by A. Helder");
  358.         moveto(88,0);
  359.         outtext ("3D WIRE FRAME CUBE");
  360.         return;
  361.  
  362. abort_message:
  363. printf("\n\nUnable to proceed - Requires VGA,EGA,CGA or MCGA adapter");
  364. printf("\nWith appropriate monitor");
  365. exit(0);
  366. }
  367.  
  368. /* ----------------------------------------------------------------------- */
  369. /* SUBROUTINE: MAP 640*480 TEMPLATE TO 2D SCREEN */
  370. void coords(void)
  371. {
  372. sx=sx*(x_res/640);sy=sy*(y_res/480);return;
  373. }
  374.  
  375. /* ----------------------------------------------------------------------- */
  376. /* SUBROUTINE: COPYRIGHT NOTICE */
  377.  
  378. int copyright[][3]={0x7c00,0x0000,0x0000,0x8231,
  379. 0x819c,0x645e,0xba4a,0x4252,0x96d0,0xa231,0x8252,0x955e,0xba4a,
  380. 0x43d2,0xf442,0x8231,0x825c,0x945e,0x7c00,0x0000,0x0000};
  381.  
  382. void notice(int x, int y){
  383. int a,b,c; int t1=0;
  384.  
  385. for (t1=0;t1<=6;t1++)
  386.     {
  387.     a=copyright[t1][0];b=copyright[t1][1];
  388.     c=copyright[t1][2];
  389.     setlinestyle(USERBIT_LINE,a,NORM_WIDTH);
  390.     moveto(x,y);lineto(x+15,y);
  391.     setlinestyle(USERBIT_LINE,b,NORM_WIDTH);
  392.     moveto(x+16,y);lineto(x+31,y);
  393.     setlinestyle(USERBIT_LINE,c,NORM_WIDTH);
  394.     moveto(x+32,y);lineto(x+47,y);y++;
  395.     };
  396. setlinestyle(USERBIT_LINE,0xFFFF,NORM_WIDTH);
  397. return;}
  398.  
  399.