home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
RISC DISC 3
/
RISC_DISC_3.iso
/
resources
/
etexts
/
gems
/
gemsv
/
ch5_5
/
main.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-04
|
8KB
|
201 lines
#include <stdio.h>
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include "global.h"
// GLOBAL CONSTANTS
int verbose=0; // WHAT TO PRINT OUT
// INPUT FILE CONTAINING RANDOM OBJECTS
char* randomfilename="random.pov";
int nrandom=0; // NUMBER OF RANDOM OBJECTS
double rho=.0001; // DEFAULT DENSITY OF RANDOM SPHERES
double random(double a, double b) { // a<=random(a,b)<=b
// double r=(double)rand()/(double)RAND_MAX; // 0.<=r<=1.
double r=drand48(); // 0.<=r<=1.
return a+r*(b-a);
}
void randomobjects(char* filename) { // GENERATE RANDOM SPHERES
ofstream o(filename, ios::out);
o<<"#declare WHITE=color rgb<1,1,1>\n";
o<<"#declare BLACK=color rgb<0,0,0>\n";
o<<"#declare S=sphere{<0,0,0>,1 pigment{color WHITE}finish{diffuse 1}}\n";
o<<"\n";
o<<"camera{location<0,0,0> direction<0,0,1> right<1,0,0> up<0,1,0>}\n";
o<<"light_source{<0,0,0> color WHITE}\n";
o<<"light_source{<0,0,0> color WHITE}\n";
o<<"background {color BLACK}\n";
o<<"\n";
double h=pow(nrandom/rho, 1./3.)/2.; // HALF WIDTH OF SCENE CUBE
for(register int i=0; i<nrandom; i++) {
o<<"object{S "<<"translate<";
o<<random(-h,h)<<","<<random(-h,h)<<","<<random(0.,2*h);
o<<">}\n";
}
}
// EXTERNALS
extern FILE* inputfile; // DEFINED IN THE lex FILE
extern char* inputfilename; // DEFINED IN THE lex FILE
extern int yyparse(void); // GENERATED BY yacc FILE
extern intensity background; // DEFINED IN yacc FILE
// DEBUGGING
#ifdef COUNTMEM
extern "C" {void* malloc(size_t); void free(void*);}
long nbytes=0L;
void *operator new(size_t size) {
nbytes+=size;
void *p=malloc(size+8); cout<<nbytes<<"\n";
*(long*)p=size;
return p+8;
}
void operator delete(void *p) {
p-=8;
nbytes-=*(long*)p;
free(p);
}
#endif
// PICTURE BUFFER
const int MAXRES=1024;
icolor buf[MAXRES]; // ONE ROW OF R,G,B BYTES
int xres=200, yres=200; // ACTUAL RESOLUTION
// OUTPUT FILE
char* outputfilename="picture"; // DEFAULT OUTPUT NAME
void outinit(int xres, int yres) { // INITIALIZE OUTPUT FILE
FILE *f;
if(!(f=fopen(outputfilename,"wb")))
return;
fwrite((void*)&xres, sizeof(int), 1, f);
fwrite((void*)&yres, sizeof(int), 1, f);
fclose(f);
}
void output(icolor b[]) { // OUTPUT ONE ROW
FILE *f;
if(!(f=fopen(outputfilename,"ab")))
return;
fwrite((void*)b, sizeof(icolor), xres, f);
fclose(f);
}
// INTERSECTION ACCELERATION METHODS
method* query; // ACCELERATION METHOD
// RECURSIVE RAY TRACING
int lmax=4; // MAXIMAL LEVEL OF RECURSION
intensity trace(ray& r) {
if(r.l>lmax)
return background;
intersect i=(*query)(r);
if(!i.o)
return background;
return i.o->shade(r,i);
}
// MAIN PROGRAM
void usage() {
cout<<"usage: oopov [SWITCHes] {FILENAME | -r #}\n";
cout<<"where\n";
cout<<" SWITCH can be\n";
cout<<" -a v :accelerate via Voronoi-diagram\n";
cout<<" -a b :brute-force intersection (default)\n";
cout<<" -o FILENAME :name of output file\n";
cout<<" -r # :creates # number of random objects\n";
cout<<" (also writes them into random.pov)\n";
cout<<" -r -1 :reads objects from random.pov\n";
cout<<" -v :verbose printout\n";
cout<<" -x # :horizontal resolution of image\n";
cout<<" -y # :vertical resolution of image\n";
cout<<" # is an integer\n";
exit(0);
}
main(int argc, char** argv) {
query=new method; // DEFAULT BRUTE FORCE
while(argv[1] && argv[1][0]=='-') { // PROCESS ARGUMENTS
switch(argv[1][1]) {
case 'a': // ACCELERATION METHOD
switch(argv[2][0]) {
case 'B': case 'b': // BRUTE-FORCE
delete query;
query=new method;
break;
case 'V': case 'v': // VIA VORONOI-DIAGRAM
delete query;
query=new voronoi;
break;
}
argc--; argv++;
break;
case 'o': // OUTPUT FILE NAME
outputfilename=argv[2];
argc--; argv++;
break;
case 'r': // USE RANDOM OBJECTS
nrandom=atoi(argv[2]);
argc--; argv++;
break;
case 'v': // VERBOSE OUTPUT
verbose=1;
break;
case 'x': // X-RESOLUTION
xres=atoi(argv[2]);
argc--; argv++;
break;
case 'y': // Y-RESOLUTION
yres=atoi(argv[2]);
argc--; argv++;
break;
}
argc--;
argv++;
}
if(argc>1) // NAME OF INPUT FILE
inputfilename=argv[1]; // COMES AS ARGUMENT
else if(nrandom>0) {
inputfilename=randomfilename; // USE RANDOM OBJECTS
randomobjects(inputfilename); // GENERATE OBJECTS
} else if(nrandom<0)
inputfilename=randomfilename; // USE RANDOM OBJECTS
else
usage(); // NOT GIVEN -> QUIT
inputfile=fopen(inputfilename, "r"); // OPEN INPUT FILE
if(yyparse()!=0) // READ INPUT FILE
exit(1);
fprintf(stderr, "\n");
query->preprocess(&objects); // PREPROCESS OBJECTS
outinit(xres, yres); // INITIALIZE OUTPUT
for(register int i=0; i<yres; i++) { // TRACE
for(register int j=0; j<xres; j++) {
double x=(2*j-xres+0.5)/xres;
double y=(yres-2*i-0.5)/yres;
intensity I=trace(actcamera.getray(x,y));
buf[j]=(icolor)I;
}
output(buf);
fprintf(stderr, "rows remained: %4d\r", yres-i-1);
}
fprintf(stderr, "\n");
exit(0);
}