home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / 3dgraph / c / chap2_11.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-19  |  7.2 KB  |  299 lines

  1. // chap2_11.cpp;
  2.  
  3. #include <iostream.h>
  4. #include <graphics.h>
  5. #include <math.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <conio.h>
  9.  
  10. #define PI 3.141592654
  11.  
  12.  
  13. const xoffset=640/2;
  14. const yoffset=480/2;
  15. const xscale=1;
  16. const yscale=-1;
  17. const persp=500;
  18.  
  19. struct point
  20. {
  21.     float xw, yw, zw;
  22.     int   xs, ys, zs;
  23. }   vertex[18];
  24.  
  25. typedef float  matrix_4x4[4][4];
  26. int    faces[13][6];  /*First entry is face colour*/
  27. int    face_list[13][2]; /*First entry is face, second is depth*/
  28. int    polygon[10];
  29. FILE   *fp;
  30. int    c, c2;
  31. char   ch;
  32. matrix_4x4   w2v, temp, temp2;
  33.  
  34. void initialise_graphics()
  35. {
  36.      int gdriver=DETECT, gmode, errorcode;
  37.  
  38.      initgraph(&gdriver, &gmode,"");
  39.      errorcode=graphresult();
  40.      if (errorcode!=grOk)
  41.      {
  42.       printf("Graphics Error: %s\n",grapherrormsg(errorcode));
  43.       printf("Program Aborted \n");
  44.       exit(1);
  45.      }
  46.      setlinestyle(0,0,3);
  47.      setcolor(WHITE);
  48.  
  49. }
  50.  
  51. void translate(float x, float y, float z, matrix_4x4 m)
  52. {
  53.      m[0][0]=1; m[1][0]=0; m[2][0]=0; m[3][0]=0;
  54.      m[0][1]=0; m[1][1]=1; m[2][1]=0; m[3][1]=0;
  55.      m[0][2]=0; m[1][2]=0; m[2][2]=1; m[3][2]=0;
  56.      m[0][3]=x; m[1][3]=y; m[2][3]=z; m[3][3]=1;
  57. };
  58.  
  59. void rotate_x(float t, matrix_4x4 m)
  60. {
  61.      m[0][0]=1; m[1][0]=0;       m[2][0]=0;      m[3][0]=0;
  62.      m[0][1]=0; m[1][1]=cos(t);  m[2][1]=sin(t); m[3][1]=0;
  63.      m[0][2]=0; m[1][2]=-sin(t); m[2][2]=cos(t); m[3][2]=0;
  64.      m[0][3]=0; m[1][3]=0;       m[2][3]=0;      m[3][3]=1;
  65. };
  66.  
  67.  
  68. void rotate_y(float t, matrix_4x4 m)
  69. {
  70.      m[0][0]=cos(t); m[1][0]=0; m[2][0]=-sin(t); m[3][0]=0;
  71.      m[0][1]=0;      m[1][1]=1; m[2][1]=0;       m[3][1]=0;
  72.      m[0][2]=sin(t); m[1][2]=0; m[2][2]=cos(t);  m[3][2]=0;
  73.      m[0][3]=0;      m[1][3]=0; m[2][3]=0;       m[3][3]=1;
  74. };
  75.  
  76. void rotate_z(float t, matrix_4x4 m)
  77. {
  78.      m[0][0]=cos(t);  m[1][0]=sin(t); m[2][0]=0; m[3][0]=0;
  79.      m[0][1]=-sin(t); m[1][1]=cos(t); m[2][1]=0; m[3][1]=0;
  80.      m[0][2]=0;       m[1][2]=0;      m[2][2]=1; m[3][2]=0;
  81.      m[0][3]=0;       m[1][3]=0;      m[2][3]=0; m[3][3]=1;
  82. };
  83.  
  84. void copy_4x4(matrix_4x4 in, matrix_4x4 out)
  85. {
  86.       int c, r;
  87.       for (r=0; r<4; r++)
  88.       for (c=0; c<4; c++)
  89.           out[r][c]=in[r][c];
  90. }
  91.  
  92. void mult_4x4(matrix_4x4 a, matrix_4x4 b, matrix_4x4 m)
  93. {
  94.       int c;
  95.       for (c=0; c<4; c++)
  96.       m[c][0]=a[0][0]*b[c][0]+a[1][0]*b[c][1]+a[2][0]*b[c][2]+a[3][0]*b[c][3];
  97.       for (c=0; c<4; c++)
  98.       m[c][1]=a[0][1]*b[c][0]+a[1][1]*b[c][1]+a[2][1]*b[c][2]+a[3][1]*b[c][3];
  99.       for (c=0; c<4; c++)
  100.       m[c][2]=a[0][2]*b[c][0]+a[1][2]*b[c][1]+a[2][2]*b[c][2]+a[3][2]*b[c][3];
  101.       for (c=0; c<4; c++)
  102.       m[c][3]=a[0][3]*b[c][0]+a[1][3]*b[c][1]+a[2][3]*b[c][2]+a[3][3]*b[c][3];
  103. };
  104.  
  105. void draw_face(int face)
  106. {
  107.      int x1,y1,z1,x2,y2,z2;
  108.      int count, c;
  109.      count=0;
  110.      for(c=1; c<6; c++)
  111.      {
  112.       if (faces[face][c]!=0)
  113.       {
  114.            polygon[(c-1)*2]=vertex[faces[face][c]-1].xs;
  115.            polygon[(c-1)*2+1]=vertex[faces[face][c]-1].ys;
  116.            count++;
  117.       };
  118.      };
  119.      setfillstyle(1,(faces[face][0]));
  120.      fillpoly(count,polygon);
  121. };
  122.  
  123. void draw_picture()
  124. {
  125.      int c, c2, max_z;
  126.      short int any_swapped;
  127.      /* Put faces into a list and find each's furthest distance */
  128.      for (c=0; c<13; c++)
  129.      {
  130.       face_list[c][0]=c;
  131.       max_z=-9999;
  132.       for (c2=1; c2<6; c2++)
  133.       {
  134.            if (faces[c][c2]!=0)
  135.           if (vertex[faces[c][c2]-1].zs>max_z) max_z=vertex[faces[c][c2]-1].zs;
  136.       };
  137.       face_list[c][1]=max_z;
  138.      };
  139.  
  140.      /* Bubble sort into decreasing depth order} */
  141.      do
  142.      {
  143.        any_swapped=0;
  144.        for (c=0; c<12; c++)
  145.        {
  146.         if (face_list[c+1][1]>face_list[c][1])
  147.         {
  148.              /* Swap Entries */
  149.              c2=face_list[c+1][1];
  150.              face_list[c+1][1]=face_list[c][1];
  151.              face_list[c][1]=c2;
  152.              c2=face_list[c+1][0];
  153.              face_list[c+1][0]=face_list[c][0];
  154.              face_list[c][0]=c2;
  155.              any_swapped=1;
  156.         };
  157.        };
  158.      }
  159.      while (any_swapped!=0);
  160.  
  161.      cleardevice();
  162.      for (c=0;c<13;c++)
  163.      draw_face(face_list[c][0]);
  164. };
  165.  
  166. void transform(matrix_4x4 m)
  167. {
  168.      for (c=0; c<18; c++)
  169.      {
  170.      vertex[c].zs=(vertex[c].xw*m[2][0]+vertex[c].yw*m[2][1]+vertex[c].zw*m[2][2]+m[2][3]);
  171.      vertex[c].xs=(((vertex[c].xw*m[0][0]+vertex[c].yw*m[0][1]+vertex[c].zw*m[0][2]+m[0][3])
  172.                *(persp/float(vertex[c].zs))*xscale)+xoffset);
  173.      vertex[c].ys=(((vertex[c].xw*m[1][0]+vertex[c].yw*m[1][1]+vertex[c].zw*m[1][2]+m[1][3])
  174.                *(persp/float(vertex[c].zs))*yscale)+yoffset);
  175.      };
  176. };
  177.  
  178. void main()
  179. {
  180. //   Read in vertex data
  181.      if ((fp=fopen("points.dat","r"))==NULL)
  182.      {
  183.       puts("Can't open points.dat");
  184.       exit(0);
  185.      }
  186.      for (c=0; c<18; c++)
  187.      {
  188.       fscanf(fp,"%f %f %f \n",&vertex[c].xw,&vertex[c].yw,&vertex[c].zw);
  189.      }
  190.      fclose(fp);
  191. //   Move to z=500
  192.      for (c=0; c<18; c++)
  193.       vertex[c].zw=vertex[c].zw+500;
  194.  
  195. //   Read in face data
  196.      if ((fp=fopen("faces.dat","r"))==NULL)
  197.      {
  198.       puts("Can't open faces.dat");
  199.       exit(0);
  200.      }
  201.      for (c=0; c<13; c++)
  202.      for (c2=0; c2<6; c2++)
  203.          fscanf(fp,"%d", &faces[c][c2]);
  204.      fclose(fp);
  205.  
  206.      initialise_graphics();
  207.  
  208.      translate(-500,-400,0,w2v);
  209.      rotate_y((PI/5.0),temp);
  210.      mult_4x4(w2v,temp,temp2);
  211.      rotate_x(-PI/6,temp);
  212.      mult_4x4(temp2,temp,w2v);
  213.  
  214.      transform(w2v);
  215.      draw_picture();
  216.      do
  217.      {
  218.        ch=getch();
  219.        switch (ch)
  220.        {
  221.        case '8': {
  222.                translate(0,0,-10,temp);
  223.                mult_4x4(w2v,temp,temp2);
  224.                copy_4x4(temp2,w2v);
  225.                break;
  226.              };
  227.        case    '2': {
  228.                translate(0,0,10,temp);
  229.                mult_4x4(w2v,temp,temp2);
  230.                copy_4x4(temp2,w2v);
  231.                break;
  232.              };
  233.        case    '4': {
  234.                translate(10,0,0,temp);
  235.                mult_4x4(w2v,temp,temp2);
  236.                copy_4x4(temp2,w2v);
  237.                break;
  238.              };
  239.        case    '6': {
  240.                translate(-10,0,0,temp);
  241.                mult_4x4(w2v,temp,temp2);
  242.                copy_4x4(temp2,w2v);
  243.                break;
  244.              };
  245.        case    '1': {
  246.                translate(0,10,0,temp);
  247.                mult_4x4(w2v,temp,temp2);
  248.                copy_4x4(temp2,w2v);
  249.                break;
  250.              };
  251.        case    '7': {
  252.                translate(0,-10,0,temp);
  253.                mult_4x4(w2v,temp,temp2);
  254.                copy_4x4(temp2,w2v);
  255.                break;
  256.              };
  257.        case    ',': {
  258.                rotate_y(PI/180.0,temp);
  259.                mult_4x4(w2v,temp,temp2);
  260.                copy_4x4(temp2,w2v);
  261.                break;
  262.              };
  263.        case    '.': {
  264.                rotate_y(-PI/180.0,temp);
  265.                mult_4x4(w2v,temp,temp2);
  266.                copy_4x4(temp2,w2v);
  267.                break;
  268.              };
  269.        case    'm': {
  270.                rotate_z(PI/180.0,temp);
  271.                mult_4x4(w2v,temp,temp2);
  272.                copy_4x4(temp2,w2v);
  273.                break;
  274.              };
  275.        case    'n': {
  276.                rotate_z(-PI/180.0,temp);
  277.                mult_4x4(w2v,temp,temp2);
  278.                copy_4x4(temp2,w2v);
  279.                break;
  280.              };
  281.        case    'o': {
  282.                rotate_x(PI/180.0,temp);
  283.                mult_4x4(w2v,temp,temp2);
  284.                copy_4x4(temp2,w2v);
  285.                break;
  286.              };
  287.        case    'l': {
  288.                rotate_x(-PI/180.0,temp);
  289.                mult_4x4(w2v,temp,temp2);
  290.                copy_4x4(temp2,w2v);
  291.                break;
  292.              };
  293.        };
  294.        transform(w2v);
  295.        draw_picture();
  296.      }
  297.      while (ch!='q');
  298.      closegraph();
  299. }