home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 3 / RISC_DISC_3.iso / resources / etexts / gems / gemsv / ch5_5 / main.cxx < prev    next >
C/C++ Source or Header  |  1995-03-04  |  8KB  |  201 lines

  1. #include <stdio.h>
  2. #include <iostream.h>
  3. #include <fstream.h>
  4. #include <stdlib.h>
  5.  
  6. #include "global.h"
  7.  
  8. //      GLOBAL CONSTANTS
  9.  
  10. int verbose=0;                                      // WHAT TO PRINT OUT
  11.  
  12. //      INPUT FILE CONTAINING RANDOM OBJECTS
  13.  
  14. char* randomfilename="random.pov";
  15.  
  16. int nrandom=0;                          // NUMBER OF RANDOM OBJECTS
  17. double rho=.0001;                       // DEFAULT DENSITY OF RANDOM SPHERES
  18.  
  19. double random(double a, double b) {                     // a<=random(a,b)<=b
  20. //      double r=(double)rand()/(double)RAND_MAX;       // 0.<=r<=1.
  21.         double r=drand48();                             // 0.<=r<=1.
  22.         return a+r*(b-a);
  23. }
  24.  
  25. void randomobjects(char* filename) {                // GENERATE RANDOM SPHERES
  26.         ofstream o(filename, ios::out);
  27.         o<<"#declare WHITE=color rgb<1,1,1>\n";
  28.         o<<"#declare BLACK=color rgb<0,0,0>\n";
  29.         o<<"#declare S=sphere{<0,0,0>,1 pigment{color WHITE}finish{diffuse 1}}\n";
  30.         o<<"\n";
  31.         o<<"camera{location<0,0,0> direction<0,0,1> right<1,0,0> up<0,1,0>}\n";
  32.         o<<"light_source{<0,0,0> color WHITE}\n";
  33.         o<<"light_source{<0,0,0> color WHITE}\n";
  34.         o<<"background {color BLACK}\n";
  35.         o<<"\n";
  36.         double h=pow(nrandom/rho, 1./3.)/2.;        // HALF WIDTH OF SCENE CUBE
  37.         for(register int i=0; i<nrandom; i++) {
  38.                 o<<"object{S "<<"translate<";
  39.                 o<<random(-h,h)<<","<<random(-h,h)<<","<<random(0.,2*h);
  40.                 o<<">}\n";
  41.         }
  42. }
  43.  
  44. //      EXTERNALS
  45.  
  46. extern FILE* inputfile;                             // DEFINED IN THE lex FILE
  47. extern char* inputfilename;                         // DEFINED IN THE lex FILE
  48. extern int yyparse(void);                           // GENERATED BY yacc FILE
  49. extern intensity background;                        // DEFINED IN yacc FILE
  50.  
  51. //      DEBUGGING
  52.  
  53. #ifdef COUNTMEM
  54. extern "C" {void* malloc(size_t); void free(void*);}
  55. long nbytes=0L;
  56. void *operator new(size_t size) {
  57.         nbytes+=size;
  58.         void *p=malloc(size+8); cout<<nbytes<<"\n";
  59.         *(long*)p=size;
  60.         return p+8;
  61. }
  62. void operator delete(void *p) {
  63.         p-=8;
  64.         nbytes-=*(long*)p;
  65.         free(p);
  66. }
  67. #endif
  68.  
  69. //      PICTURE BUFFER
  70.  
  71. const int MAXRES=1024;
  72. icolor buf[MAXRES];                                 // ONE ROW OF R,G,B BYTES
  73. int xres=200, yres=200;                             // ACTUAL RESOLUTION
  74.  
  75. //      OUTPUT FILE
  76.  
  77. char* outputfilename="picture";                     // DEFAULT OUTPUT NAME
  78.  
  79. void outinit(int xres, int yres) {                  // INITIALIZE OUTPUT FILE
  80.         FILE *f;
  81.         if(!(f=fopen(outputfilename,"wb")))
  82.                 return;
  83.         fwrite((void*)&xres, sizeof(int), 1, f);
  84.         fwrite((void*)&yres, sizeof(int), 1, f);
  85.         fclose(f);
  86. }
  87.  
  88. void output(icolor b[]) {                           // OUTPUT ONE ROW
  89.         FILE *f;
  90.         if(!(f=fopen(outputfilename,"ab")))
  91.                 return;
  92.         fwrite((void*)b, sizeof(icolor), xres, f);
  93.         fclose(f);
  94.  
  95. }
  96.  
  97. //      INTERSECTION ACCELERATION METHODS
  98.  
  99. method* query;                                  // ACCELERATION METHOD
  100.  
  101. //      RECURSIVE RAY TRACING
  102.  
  103. int lmax=4;                                     // MAXIMAL LEVEL OF RECURSION
  104.  
  105. intensity trace(ray& r) {
  106.         if(r.l>lmax)
  107.                 return background;
  108.         intersect i=(*query)(r);
  109.         if(!i.o) 
  110.                 return background;
  111.         return i.o->shade(r,i);
  112. }
  113.  
  114. //      MAIN PROGRAM
  115.  
  116. void usage() {
  117.         cout<<"usage: oopov [SWITCHes] {FILENAME | -r #}\n";
  118.         cout<<"where\n";
  119.         cout<<"    SWITCH can be\n";
  120.         cout<<"        -a v             :accelerate via Voronoi-diagram\n";
  121.         cout<<"        -a b             :brute-force intersection (default)\n";
  122.         cout<<"        -o FILENAME      :name of output file\n";
  123.         cout<<"        -r #             :creates # number of random objects\n";
  124.         cout<<"                          (also writes them into random.pov)\n";
  125.         cout<<"        -r -1            :reads objects from random.pov\n";
  126.         cout<<"        -v               :verbose printout\n";
  127.         cout<<"        -x #             :horizontal resolution of image\n";
  128.         cout<<"        -y #             :vertical resolution of image\n";
  129.         cout<<"    # is an integer\n";
  130.         exit(0);
  131. }
  132.  
  133. main(int argc, char** argv) {
  134.         query=new method;                               // DEFAULT BRUTE FORCE
  135.         while(argv[1] && argv[1][0]=='-') {             // PROCESS ARGUMENTS
  136.                 switch(argv[1][1]) {
  137.                     case 'a':                           // ACCELERATION METHOD
  138.                         switch(argv[2][0]) {
  139.                             case 'B': case 'b':         // BRUTE-FORCE
  140.                                 delete query;
  141.                                 query=new method;
  142.                                 break;
  143.                             case 'V': case 'v':         // VIA VORONOI-DIAGRAM
  144.                                 delete query;
  145.                                 query=new voronoi;
  146.                                 break;
  147.                         }
  148.                         argc--; argv++;
  149.                         break;
  150.                     case 'o':                           // OUTPUT FILE NAME
  151.                         outputfilename=argv[2];
  152.                         argc--; argv++;
  153.                         break;
  154.                     case 'r':                           // USE RANDOM OBJECTS
  155.                         nrandom=atoi(argv[2]);
  156.                         argc--; argv++;
  157.                         break;
  158.                     case 'v':                           // VERBOSE OUTPUT
  159.                         verbose=1;
  160.                         break;
  161.                     case 'x':                           // X-RESOLUTION
  162.                         xres=atoi(argv[2]);
  163.                         argc--; argv++;
  164.                         break;
  165.                     case 'y':                           // Y-RESOLUTION
  166.                         yres=atoi(argv[2]);
  167.                         argc--; argv++;
  168.                         break;
  169.                 }
  170.                 argc--;
  171.                 argv++;
  172.         }
  173.         if(argc>1)                                      // NAME OF INPUT FILE
  174.                 inputfilename=argv[1];                  // COMES AS ARGUMENT
  175.         else if(nrandom>0) {
  176.                 inputfilename=randomfilename;           // USE RANDOM OBJECTS
  177.                 randomobjects(inputfilename);           // GENERATE OBJECTS
  178.         } else if(nrandom<0)
  179.                 inputfilename=randomfilename;           // USE RANDOM OBJECTS
  180.         else
  181.                 usage();                                // NOT GIVEN -> QUIT
  182.         inputfile=fopen(inputfilename, "r");            // OPEN INPUT FILE
  183.         if(yyparse()!=0)                                // READ INPUT FILE
  184.                 exit(1);
  185.         fprintf(stderr, "\n");
  186.         query->preprocess(&objects);                    // PREPROCESS OBJECTS
  187.         outinit(xres, yres);                            // INITIALIZE OUTPUT
  188.         for(register int i=0; i<yres; i++) {            // TRACE
  189.                 for(register int j=0; j<xres; j++) {
  190.                         double x=(2*j-xres+0.5)/xres;
  191.                         double y=(yres-2*i-0.5)/yres;
  192.                         intensity I=trace(actcamera.getray(x,y));
  193.                         buf[j]=(icolor)I;
  194.                 }
  195.                 output(buf);
  196.                 fprintf(stderr, "rows remained: %4d\r", yres-i-1);
  197.         }
  198.         fprintf(stderr, "\n");
  199.         exit(0);
  200. }
  201.