home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
dirs
/
dkbtrace_397.lzh
/
DKBTrace
/
DKBSource.LZH
/
trace.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-26
|
15KB
|
540 lines
/*****************************************************************************
*
* trace.c
*
* from DKBTrace (c) 1990 David Buck
*
* This module contains the entry routine for the raytracer and the code to
* parse the parameters on the command line.
*
*
* This software is freely distributable. The source and/or object code may be
* copied or uploaded to communications services so long as this notice remains
* at the top of each file. If any changes are made to the program, you must
* clearly indicate in the documentation and in the programs startup message
* who it was who made the changes. The documentation should also describe what
* those changes were. This software may not be included in whole or in
* part into any commercial package without the express written consent of the
* author. It may, however, be included in other public domain or freely
* distributed software so long as the proper credit for the software is given.
*
* This software is provided as is without any guarantees or warranty. Although
* the author has attempted to find and correct any bugs in the software, he
* is not responsible for any damage caused by the use of the software. The
* author is under no obligation to provide service, corrections, or upgrades
* to this package.
*
* Despite all the legal stuff above, if you do find bugs, I would like to hear
* about them. Also, if you have any comments or questions, you may contact me
* at the following address:
*
* David Buck
* 22C Sonnet Cres.
* Nepean Ontario
* Canada, K2H 8W7
*
* I can also be reached on the following bulleton boards:
*
* ATX (613) 526-4141
* OMX (613) 731-3419
* Mystic (613) 731-0088 or (613) 731-6698
*
* Fidonet: 1:163/109.9
* Internet: David_Buck@Carleton.CA
*
* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
*
* Lattice BBS (708) 916-1200
* The Information Exchange BBS (708) 945-5575
* Stillwaters BBS (708) 403-2826
*
*****************************************************************************/
#include <ctype.h>
#include "frame.h" /* common to ALL modules in this program */
#include "dkbproto.h"
#define MAX_FILE_NAMES 1
unsigned long Options;
int Quality;
FILE *bfp;
FILE *Input_File, *Token_File, *Symbol_File, *Data_File;
extern FRAME Frame;
static char *File_Names[MAX_FILE_NAMES];
char Input_File_Name[FILE_NAME_LENGTH], Output_File_Name[FILE_NAME_LENGTH];
char *Output_File_Buffer;
int File_Buffer_Size;
static int Number_Of_Files;
DBL VTemp;
DBL Antialias_Threshold;
int First_Line, Last_Line;
/* Stats kept by the ray tracer: */
long Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
long Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded;
long Ray_Plane_Tests, Ray_Plane_Tests_Succeeded;
long Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded;
long Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded;
long Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
long Calls_To_Noise, Calls_To_DNoise;
long Shadow_Ray_Tests, Shadow_Rays_Succeeded;
long Reflected_Rays_Traced, Refracted_Rays_Traced;
long Transmitted_Rays_Traced;
void main (argc, argv)
int argc;
char **argv;
{
register int i;
char temp[2];
printf ("\n\n DKB Ray Trace Version 2.01\n");
printf (" ----------------------------\n\n");
printf (" Copyright (c) 1990 David Buck\n\n");
printf (" Written by:\n");
printf (" David K. Buck\n");
printf (" 22C Sonnet Cr. Nepean, Ontario\n");
printf (" Canada, K2H 8W7\n\n");
printf (" This program is freely distributable.\n");
printf ("\n Conversion to IBM P.C. w/TARGA output \n");
printf (" and various improvements by Aaron A. Collins\n\n");
printf (" GIF format file reader by Steve A. Bennett\n\n");
printf (" Noise and DNoise functions by Robert Skinner\n\n");
/* Parse the command line parameters */
if (argc == 1)
{
printf ("\nUsage:");
printf ("\n trace [+/-] Option1 [+/-] Option2");
printf ("\n");
printf ("\n Options:");
printf ("\n d = display");
printf ("\n v = verbose");
printf ("\n p = prompt exit");
printf ("\n x = enable early exit by key hit");
printf ("\n f = write DKB/QRT format output file");
printf ("\n t = write TARGA format output file");
printf ("\n a = perform antialiasing");
/* printf ("\n z = debug mode"); */
printf ("\n qx = image quality 0=rough, 9=full");
printf ("\n wxxx = width of the screen");
printf ("\n hxxx = height of the screen");
printf ("\n sxxx = start at line number xxx");
printf ("\n exxx = end at line number xxx");
printf ("\n bxxx = Use xxx kilobytes for output file buffer space");
printf ("\n ifilename = input file name");
printf ("\n ofilename = output file name");
printf ("\n\n");
exit(0);
}
bfp = NULL;
File_Buffer_Size = 0;
Options = 0;
Quality = 9;
Number_Of_Files = 0;
First_Line = 0;
Last_Line = -1;
Number_Of_Pixels = 0L;
Number_Of_Rays = 0L;
Number_Of_Pixels_Supersampled = 0L;
Ray_Sphere_Tests = 0L;
Ray_Sphere_Tests_Succeeded = 0L;
Ray_Plane_Tests = 0L;
Ray_Plane_Tests_Succeeded = 0L;
Ray_Triangle_Tests = 0L;
Ray_Triangle_Tests_Succeeded = 0L;
Ray_Quadric_Tests = 0L;
Ray_Quadric_Tests_Succeeded = 0L;
Bounding_Region_Tests = 0L;
Bounding_Region_Tests_Succeeded = 0L;
Calls_To_Noise = 0L;
Calls_To_DNoise = 0L;
Shadow_Ray_Tests = 0L;
Shadow_Rays_Succeeded = 0L;
Reflected_Rays_Traced = 0L;
Refracted_Rays_Traced = 0L;
Transmitted_Rays_Traced = 0L;
Frame.Screen_Height = 100;
Frame.Screen_Width = 100;
Antialias_Threshold = 0.3;
strcpy (&Input_File_Name[0], "object.data");
/* Read the default parameters from trace.def */
get_defaults();
strcpy (&Output_File_Name[0], "data.dis");
if (Options & TARGA)
strcpy (&Output_File_Name[0], "data.tga");
for (i = 1 ; i < argc ; i++ )
if ((*argv[i] == '+') || (*argv[i] == '-'))
parse_option(argv[i]);
else
parse_file_name(argv[i]);
if (Last_Line == -1)
Last_Line = Frame.Screen_Height;
Print_Options();
/* Tokenize the input file */
if ((Input_File = fopen (Input_File_Name, "r")) == NULL)
{
printf ("Cannot open input file\n");
exit (0);
}
if ((Token_File = fopen ("Token.data", "w")) == NULL)
{
printf ("Cannot open token file for write\n");
exit (0);
}
if ((Symbol_File = fopen ("Symbols.data", "w")) == NULL)
{
printf ("Cannot open string file for writing\n");
exit(0);
}
printf ("Tokenizing...\n");
Tokenize (Input_File_Name, Input_File, Symbol_File, Token_File);
fclose (Input_File);
fclose (Token_File);
fclose (Symbol_File);
/* parse the tokenize file */
if ((Token_File = fopen ("Token.data", "r")) == NULL)
exit (0);
if ((Symbol_File = fopen ("Symbols.data", "r")) == NULL)
{
printf ("Cannot open string file for reading\n");
exit(0);
}
printf ("Parsing...\n");
Parse (Token_File, &Frame);
fclose (Token_File);
/* Get things ready for ray tracing */
if ((Options & DISKWRITE) || (Options & TARGA)) {
bfp = fopen (&Output_File_Name[0], "wb");
if (bfp == NULL) {
printf ("Cannot open output file\n");
exit (0);
}
if (File_Buffer_Size != 0) {
Output_File_Buffer = malloc (File_Buffer_Size);
setvbuf (bfp, Output_File_Buffer, _IOFBF, File_Buffer_Size);
}
if (Options & TARGA) { /* Prefix TARGA format file header */
for (i = 0; i < 10; i++) /* 00, 00, 02, then 7 00's... */
if (i == 2)
putc(i, bfp);
else putc(0, bfp);
temp[0] = First_Line % 256; /* y origin is set to "First_Line" */
putc (temp[0], bfp);
temp[0] = First_Line / 256;
putc (temp[0], bfp);
}
temp[0] = Frame.Screen_Width % 256; /* write this to either file type */
putc (temp[0], bfp);
temp[0] = Frame.Screen_Width / 256;
putc (temp[0], bfp);
temp[0] = Frame.Screen_Height % 256;
putc (temp[0], bfp);
temp[0] = Frame.Screen_Height / 256;
putc (temp[0], bfp);
if (Options & TARGA) { /* now finish the TARGA format file header */
putc(24, bfp); /* 24 bits/pixel (16 million colors!) */
putc(32, bfp); /* Not sure about this one, "out of 32" ? */
}
}
if (Options & DISPLAY)
{
printf ("Displaying...\n");
display_init();
}
pq_init();
Initialize_Noise();
/* Ok, go for it - trace the picture */
Start_Tracing ();
/* Wait for a CR if the user requested it. */
/* Clean up and leave */
display_finished();
close_all ();
print_stats();
}
/* Close all the stuff that has been opened. */
void close_all ()
{
if (Options & DISPLAY)
display_close();
if (bfp)
fclose (bfp);
}
/* Read the default parameters from trace.def*/
void get_defaults()
{
read_options ("trace.def");
}
void read_options (file_name)
char *file_name;
{
FILE *default_file;
register int c, String_Index, Option_Started;
char Option_String[80];
String_Index = 0;
Option_Started = FALSE;
if (default_file = fopen(file_name, "r"))
while ((c = getc(default_file)) != EOF)
{
if (Option_Started)
if (isspace(c))
{
Option_String[String_Index] = '\0';
parse_option (Option_String);
Option_Started = FALSE;
}
else
Option_String[String_Index++] = (char) c;
else /* Option_Started */
if ((c == (int) '-') || (c == (int) '+'))
{
String_Index = 0;
Option_String[String_Index++] = (char) c;
Option_Started = TRUE;
}
else
if (!isspace(c))
{
printf ("\nBad default file format. Offending char: (%c), val: %d.\n", (char) c, c);
exit (0);
}
}
if (Option_Started)
{
Option_String[String_Index] = '\0';
parse_option (Option_String);
}
}
/* parse the command line parameters */
void parse_option (Option_String)
char *Option_String;
{
register int Add_Option;
unsigned long Option_Number;
DBL threshold;
if (*(Option_String++) == '-')
Add_Option = FALSE;
else
Add_Option = TRUE;
switch (*Option_String)
{
case 'B':
case 'b': sscanf (&Option_String[1], "%d", &File_Buffer_Size);
File_Buffer_Size *= 1024;
if (File_Buffer_Size < BUFSIZ)
File_Buffer_Size = BUFSIZ;
Option_Number = 0;
break;
case 'D':
case 'd': Option_Number = DISPLAY;
break;
case 'V':
case 'v': Option_Number = VERBOSE;
break;
case 'W':
case 'w': sscanf (&Option_String[1], "%d", &Frame.Screen_Width);
Option_Number = 0;
break;
case 'H':
case 'h': sscanf (&Option_String[1], "%d", &Frame.Screen_Height);
Option_Number = 0;
break;
case 'F':
case 'f': Option_Number = DISKWRITE;
break;
case 'P':
case 'p': Option_Number = PROMPTEXIT;
break;
case 'I':
case 'i': strncpy (&Input_File_Name[0], &Option_String[1], FILE_NAME_LENGTH);
Option_Number = 0;
break;
case 'O':
case 'o': strncpy (&Output_File_Name[0], &Option_String[1], FILE_NAME_LENGTH);
Option_Number = 0;
break;
case 'A':
case 'a': Option_Number = ANTIALIAS;
if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &threshold) != EOF)
Antialias_Threshold = threshold;
break;
case 'X':
case 'x': Option_Number = EXITENABLE;
break;
case 'S':
case 's': sscanf (&Option_String[1], "%d", &First_Line);
Option_Number = 0;
break;
case 'E':
case 'e': sscanf (&Option_String[1], "%d", &Last_Line);
Option_Number = 0;
break;
case 'Q':
case 'q': sscanf (&Option_String[1], "%d", &Quality);
Option_Number = 0;
break;
case 'T':
case 't': Option_Number = TARGA;
break;
case 'Z':
case 'z': Option_Number = DEBUGGING;
break;
default: printf ("\nInvalid option: %s\n\n", --Option_String);
Option_Number = 0;
}
if (Option_Number != 0)
if (Add_Option)
Options |= Option_Number;
else Options &= ~Option_Number;
}
void Print_Options()
{
printf ("Options in effect: ");
if (Options & DISPLAY)
printf ("+d ");
else
printf ("-d ");
if (Options & VERBOSE)
printf ("+v ");
else
printf ("-v ");
if (Options & DISKWRITE)
printf ("+f ");
else
printf ("-f ");
if (Options & PROMPTEXIT)
printf ("+p ");
else
printf ("-p ");
if (Options & TARGA)
printf ("+t ");
else
printf ("-t ");
if (Options & EXITENABLE)
printf ("+x ");
else
printf ("-x ");
if (Options & ANTIALIAS)
printf ("+a%f ", Antialias_Threshold);
else
printf ("-a ");
if (File_Buffer_Size != 0)
printf ("-b%d ", File_Buffer_Size/1024);
printf ("-q%d -w%d -h%d -s%d -e%d -i%s ",
Quality, Frame.Screen_Width, Frame.Screen_Height,
First_Line, Last_Line, Input_File_Name);
if (Options & DISKWRITE)
printf ("-o%s", Output_File_Name);
printf ("\n");
}
void parse_file_name (File_Name)
char *File_Name;
{
File_Names [Number_Of_Files++] = File_Name;
if (Number_Of_Files > MAX_FILE_NAMES)
{
printf ("\nOnly %d file names are allowed in a command line.",
MAX_FILE_NAMES);
exit(0);
}
read_options (File_Name);
}
void print_stats()
{
printf (" Statistics\n");
printf (" ----------\n\n");
printf ("# Rays: %10ld # Pixels: %10ld # Pixels supersampled: %10ld\n\n",
Number_Of_Rays, Number_Of_Pixels, Number_Of_Pixels_Supersampled);
printf ("\nIntersection Tests:\n\n");
printf (" Type Tests Succeeded\n");
printf (" ---- ---------- ----------\n\n");
printf (" Sphere %10ld %10ld\n", Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded);
printf (" Plane %10ld %10ld\n", Ray_Plane_Tests, Ray_Plane_Tests_Succeeded);
printf (" Triangle %10ld %10ld\n", Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded);
printf (" Quadric %10ld %10ld\n", Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded);
printf (" Bounds %10ld %10ld\n\n", Bounding_Region_Tests, Bounding_Region_Tests_Succeeded);
printf (" Calls to Noise: %10ld\n", Calls_To_Noise);
printf (" Calls to DNoise: %10ld\n", Calls_To_DNoise);
printf (" Shadow Ray Tests: %10ld Blocking Objects Found: %10ld\n",
Shadow_Ray_Tests, Shadow_Rays_Succeeded);
printf (" Reflected Rays: %10ld\n", Reflected_Rays_Traced);
printf (" Refracted Rays: %10ld\n", Refracted_Rays_Traced);
printf (" Transmitted Rays: %10ld\n", Transmitted_Rays_Traced);
}