home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d513
/
dkbtrace.lha
/
DKBTrace
/
dkb212sr.lzh
/
trace.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-30
|
18KB
|
650 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:
*
* OMX (613) 731-3419
* Mystic (613) 596-4249 or (613) 596-4772
*
* Fidonet: 1:163/109.9
* Internet: dbuck@ccs.carleton.ca
* The "You Can Call Me RAY" BBS (708) 358-5611
*
* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
*
* The "You Can Call Me RAY" BBS (708) 358-5611
* The Information Exchange BBS (708) 945-5575
*
*****************************************************************************/
#include <ctype.h>
#include "frame.h" /* common to ALL modules in this program */
#include "dkbproto.h"
#define MAX_FILE_NAMES 1
unsigned int Options;
int Quality;
FILE *bfp;
extern FRAME Frame;
char Input_File_Name[FILE_NAME_LENGTH], Output_File_Name[FILE_NAME_LENGTH];
#define MAX_LIBRARIES 10
char *Library_Paths[MAX_LIBRARIES];
int Library_Path_Index;
FILE_HANDLE *Output_File_Handle;
int File_Buffer_Size;
static int Number_Of_Files;
DBL VTemp;
DBL Antialias_Threshold;
int First_Line, Last_Line;
int Display_Started = FALSE;
/* 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 Ray_Quartic_Tests, Ray_Quartic_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;
char DisplayFormat, OutputFormat;
void main (argc, argv)
int argc;
char **argv;
{
register int i;
STARTUP_DKB_TRACE
printf ("\n\n DKB Ray Trace Version 2.12\n");
printf (" ----------------------------\n\n");
printf (" Copyright (c) 1991 David K. Buck\n\n");
printf (" Written by:\n");
printf (" David K. Buck (dbuck@ccs.carleton.ca) (CIS: 70521, 1371)\n");
printf (" 22C Sonnet Cr. Nepean, Ontario\n");
printf (" Canada, K2H 8W7\n\n");
printf (" This program is freely distributable.\n\n");
printf (" Conversion to IBM P.C. w/TARGA output and\n");
printf (" other 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");
printf (" Quartic (4th order) Shapes by Alexander Enzmann\n\n");
PRINT_OTHER_CREDITS
/* Parse the command line parameters */
if (argc == 1)
usage();
init_vars();
Output_File_Name[0]='\0';
Library_Paths[0] = NULL;
Library_Path_Index = 0;
/* Read the default parameters from trace.def */
get_defaults();
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;
if (Options & DISKWRITE) {
switch (OutputFormat) {
case '\0':
case 'd':
case 'D':
if ((Output_File_Handle = Get_Dump_File_Handle()) == NULL) {
close_all();
exit(1);
}
break;
/*
case 'i':
case 'I':
if ((Output_File_Handle = Get_Iff_File_Handle()) == NULL) {
close_all();
exit(1);
}
break;
*/
case 'r':
case 'R':
if ((Output_File_Handle = Get_Raw_File_Handle()) == NULL) {
close_all();
exit(1);
}
break;
case 't':
case 'T':
if ((Output_File_Handle = Get_Targa_File_Handle()) == NULL) {
close_all();
exit(1);
}
break;
default:
fprintf (stderr, "Unrecognized output file format %c\n", OutputFormat);
exit(1);
}
if (Output_File_Name[0] == '\0')
strcpy (Output_File_Name, Default_File_Name (Output_File_Handle));
}
Print_Options();
Initialize_Tokenizer(Input_File_Name);
printf ("Parsing...\n");
Parse (&Frame);
Terminate_Tokenizer();
if (Options & DISPLAY)
{
printf ("Displaying...\n");
display_init(Frame.Screen_Width, Frame.Screen_Height);
Display_Started = TRUE;
}
/* Get things ready for ray tracing */
if (Options & DISKWRITE)
if (Options & CONTINUE_TRACE) {
if (Open_File (Output_File_Handle, Output_File_Name,
&Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
READ_MODE) != 1) {
fprintf (stderr, "Error opening output file\n");
close_all();
exit(1);
}
initialize_renderer();
Read_Rendered_Part();
}
else {
if (Open_File (Output_File_Handle, Output_File_Name,
&Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
WRITE_MODE) != 1) {
fprintf (stderr, "Error opening output file\n");
close_all();
exit(1);
}
initialize_renderer();
}
else
initialize_renderer();
pq_init();
Initialize_Noise();
/* Ok, go for it - trace the picture */
if (!(Options & DISPLAY))
printf ("Rendering...\n");
Start_Tracing ();
/* Wait for a CR if the user requested it. */
/* Clean up and leave */
display_finished();
close_all ();
print_stats();
FINISH_DKB_TRACE
}
/* Print out usage error message */
void usage ()
{
printf ("\nUsage:");
printf ("\n trace [+/-] Option1 [+/-] Option2");
printf ("\n");
printf ("\n Options:");
printf ("\n dx = display in format x");
printf ("\n v = verbose");
printf ("\n p = prompt exit");
printf ("\n x = enable early exit by key hit");
printf ("\n fx = write output file in format x");
printf ("\n ft - Uncompressed Targa-24 fd - DKB/QRT Dump fr - 3 Raw Files");
printf ("\n a = perform antialiasing");
printf ("\n c = continue aborted trace");
printf ("\n qx = image quality 0=rough, 9=full");
printf ("\n lxxx = library path prefix");
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(1);
}
void init_vars()
{
Output_File_Handle = 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;
Ray_Quartic_Tests = 0L;
Ray_Quartic_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, "object.dat");
return;
}
/* Close all the stuff that has been opened. */
void close_all ()
{
if ((Options & DISPLAY) && Display_Started)
display_close();
if (Output_File_Handle)
Close_File (Output_File_Handle);
}
/* Read the default parameters from trace.def*/
void get_defaults()
{
FILE *defaults_file;
char Option_String[256], *Option_String_Ptr;
if ((defaults_file = fopen("trace.def", "r")) != NULL) {
while (fgets(Option_String, 256, defaults_file) != NULL)
read_options(Option_String);
fclose (defaults_file);
}
if ((Option_String_Ptr = getenv("DKBOPT")) != NULL)
read_options(Option_String_Ptr);
}
void read_options (Option_Line)
char *Option_Line;
{
register int c, String_Index, Option_Started;
short Option_Line_Index = 0;
char Option_String[80];
String_Index = 0;
Option_Started = FALSE;
while ((c = Option_Line[Option_Line_Index++]) != '\0')
{
if (Option_Started)
if (isspace(c))
{
Option_String[String_Index] = '\0';
parse_option (Option_String);
Option_Started = FALSE;
String_Index = 0;
}
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))
{
fprintf (stderr, "\nBad default file format. Offending char: (%c), val: %d.\n", (char) c, c);
exit (1);
}
}
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 int 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 'C':
case 'c': Option_Number = CONTINUE_TRACE;
break;
case 'D':
case 'd': Option_Number = DISPLAY;
DisplayFormat = (char)toupper(Option_String[1]);
if (DisplayFormat == '\0')
DisplayFormat = '0';
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;
if (isupper(Option_String[1]))
OutputFormat = (char)tolower(Option_String[1]);
else
OutputFormat = Option_String[1];
/* Default the output format to raw. */
if (OutputFormat == '\0')
OutputFormat = DEFAULT_OUTPUT_FORMAT;
break;
case 'P':
case 'p': Option_Number = PROMPTEXIT;
break;
case 'I':
case 'i': strncpy (Input_File_Name, &Option_String[1], FILE_NAME_LENGTH);
Option_Number = 0;
break;
case 'O':
case 'o': strncpy (Output_File_Name, &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 'L':
case 'l': if (Library_Path_Index >= MAX_LIBRARIES) {
fprintf (stderr, "Too many library directories specified\n");
exit(1);
}
Library_Paths [Library_Path_Index] = malloc (strlen(Option_String));
if (Library_Paths [Library_Path_Index] == NULL) {
fprintf (stderr, "Cannot allocate memory for library pathname\n");
exit(1);
}
strcpy (Library_Paths [Library_Path_Index], &Option_String[1]);
Library_Path_Index++;
Option_Number = 0;
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;
/* Turn on debugging print statements. */
case 'Z':
case 'z': Option_Number = DEBUGGING;
break;
default: fprintf (stderr, "\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()
{
int i;
printf ("Options in effect: ");
if (Options & CONTINUE_TRACE)
printf ("+c ");
else
printf ("-c ");
if (Options & DISPLAY)
printf ("+d%c ", DisplayFormat);
else
printf ("-d ");
if (Options & VERBOSE)
printf ("+v ");
else
printf ("-v ");
if (Options & DISKWRITE)
printf ("+f%c ", OutputFormat);
else
printf ("-f ");
if (Options & PROMPTEXIT)
printf ("+p ");
else
printf ("-p ");
if (Options & EXITENABLE)
printf ("+x ");
else
printf ("-x ");
if (Options & ANTIALIAS)
printf ("+a%f ", Antialias_Threshold);
else
printf ("-a ");
if (Options & DEBUGGING)
printf ("+z ");
if (File_Buffer_Size != 0)
printf ("-b%d ", File_Buffer_Size/1024);
printf ("-q%d -w%d -h%d -s%d -e%d\n-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);
for (i = 0 ; i < Library_Path_Index ; i++)
printf ("-l%s ", Library_Paths[i]);
printf ("\n");
}
void parse_file_name (File_Name)
char *File_Name;
{
FILE *defaults_file;
char Option_String[256];
if (++Number_Of_Files > MAX_FILE_NAMES)
{
fprintf (stderr, "\nOnly %d file names are allowed in a command line.",
MAX_FILE_NAMES);
exit(1);
}
if ((defaults_file = fopen(File_Name, "r")) != NULL) {
while (fgets(Option_String, 256, defaults_file) != NULL)
read_options(Option_String);
fclose (defaults_file);
}
}
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 (" Quartic %10ld %10ld\n", Ray_Quartic_Tests, Ray_Quartic_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);
}
/* Find a file in the search path. */
FILE *Locate_File (filename, mode)
char *filename, *mode;
{
FILE *f;
int i;
char pathname[FILE_NAME_LENGTH];
/* Check the current directory first. */
if ((f = fopen (filename, mode)) != NULL)
return (f);
for (i = 0 ; i < Library_Path_Index ; i++) {
strcpy (pathname, Library_Paths[i]);
if (FILENAME_SEPARATOR != NULL)
strcat (pathname, FILENAME_SEPARATOR);
strcat (pathname, filename);
if ((f = fopen (pathname, mode)) != NULL)
return (f);
}
return (NULL);
}