home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / graphics / ftpovstc / render.c < prev    next >
Text File  |  1994-07-25  |  17KB  |  620 lines

  1. /****************************************************************************
  2. *
  3. *  ATTENTION!!!
  4. *
  5. *  THIS FILE HAS BEEN MODIFIED!!! IT IS NOT PART OF THE OFFICAL
  6. *  POV-RAY 2.2 DISTRIBUTION!!!
  7. *
  8. *  THIS FILE IS PART OF "FASTER THAN POV-RAY" (VERSION 1.1),
  9. *  A SPED-UP VERSION OF POV-RAY 2.2. USE AT YOUR OWN RISK!!!!!!
  10. *
  11. *  New files: addon0.c, addon1.c, addon2.c, addon3.c, addon.h
  12. *
  13. *  The additional modules were written by Dieter Bayer.
  14. *
  15. *  Send comments, suggestions, bugs, ideas ... to:
  16. *
  17. *  dieter@cip.e-technik.uni-erlangen.de
  18. *
  19. *  All changed/added lines are enclosed in #ifdef DB_CODE ... #endif
  20. *
  21. *  The vista projection was taken from:
  22. *
  23. *    A. Hashimoto, T. Akimoto, K. Mase, and Y. Suenaga, 
  24. *    "Vista Ray-Tracing: High Speed Ray Tracing Using Perspective
  25. *    Projection Image", New Advances in Computer Graphics, Proceedings
  26. *    of CG International '89, R. A. Earnshaw, B. Wyvill (Eds.), 
  27. *    Springer, ..., pp. 549-560
  28. *
  29. *  The idea for the light buffer was taken from:
  30. *
  31. *    E. Haines and D. Greenberg, "The Light Buffer: A Shadow-Testing 
  32. *    Accelerator", IEEE CG&A, Vol. 6, No. 9, Sept. 1986, pp. 6-16
  33. *
  34. *****************************************************************************/
  35.  
  36. /****************************************************************************
  37. *                   render.c
  38. *
  39. *  This module implements the main raytracing loop.
  40. *
  41. * 08/07/92 lsk    Changed the normal antialiasing function to use a loop 
  42. *                 where the number of rays per pixel when antialiasing can 
  43. *                 be sepcified.
  44. *
  45. *  from Persistence of Vision Raytracer
  46. *  Copyright 1993 Persistence of Vision Team
  47. *---------------------------------------------------------------------------
  48. *  NOTICE: This source code file is provided so that users may experiment
  49. *  with enhancements to POV-Ray and to port the software to platforms other
  50. *  than those supported by the POV-Ray Team.  There are strict rules under
  51. *  which you are permitted to use this file.  The rules are in the file
  52. *  named POVLEGAL.DOC which should be distributed with this file. If
  53. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  54. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  55. *  Forum.  The latest version of POV-Ray may be found there as well.
  56. *
  57. * This program is based on the popular DKB raytracer version 2.12.
  58. * DKBTrace was originally written by David K. Buck.
  59. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  60. *
  61. ******************************************************************************/
  62.  
  63. #include "frame.h"
  64. #include "vector.h"
  65. #include "povproto.h"
  66. #ifdef DB_CODE
  67. #include "addon.h"
  68. #endif
  69.  
  70. extern FILE_HANDLE *Output_File_Handle;
  71. extern char Output_File_Name[FILE_NAME_LENGTH];
  72. extern char Input_File_Name[FILE_NAME_LENGTH];
  73. extern char Stat_File_Name[FILE_NAME_LENGTH];
  74. extern char OutputFormat, Color_Bits, PaletteOption;
  75. extern char VerboseFormat;
  76. extern unsigned int Options;
  77. extern int File_Buffer_Size;
  78. extern int Use_Slabs;
  79. volatile int Stop_Flag;
  80. extern int First_Line, Last_Line;
  81. extern int First_Column, Last_Column;
  82. extern long Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
  83. extern short *hashTable;
  84. extern unsigned short crctab[256];
  85. extern OBJECT *Root_Object;
  86. extern long AntialiasDepth;
  87. extern DBL JitterScale;
  88. #ifdef DB_CODE
  89. extern unsigned int Extended_Options;
  90. #endif
  91.  
  92. #define rand3d(a,b) crctab[(int)(hashTable[(int)(hashTable[(int)((a)&0xfff)]^(b))&0xfff])&0xff]
  93.  
  94. FRAME Frame;
  95. RAY *CM_Ray;
  96. int Trace_Level, SuperSampleCount;
  97.  
  98. DBL Max_Trace_Level = 5;
  99. DBL maxclr;
  100.  
  101. static void check_stats PARAMS((int y));
  102. static void do_anti_aliasing PARAMS((int x, int y, COLOUR *Colour));
  103. static void output_line PARAMS((int y));
  104.  
  105. COLOUR *Previous_Line, *Current_Line;
  106.  
  107. char *Previous_Line_Antialiased_Flags, *Current_Line_Antialiased_Flags;
  108. RAY Ray;
  109.  
  110. void Create_Ray (ray, width, height, x, y)
  111. RAY *ray;
  112. int width, height;
  113. DBL x, y;
  114.   {
  115.   register DBL X_Scalar, Y_Scalar;
  116.   VECTOR Temp_Vect_1, Temp_Vect_2;
  117.  
  118.   /* Convert the X Coordinate to be a DBL from 0.0 to 1.0 */
  119.   X_Scalar = (x - (DBL) width / 2.0) / (DBL) width;
  120.  
  121.   /* Convert the Y Coordinate to be a DBL from 0.0 to 1.0 */
  122.   Y_Scalar = (( (DBL)(Frame.Screen_Height - 1) - y) -
  123.     (DBL) height / 2.0) / (DBL) height;
  124.  
  125.   VScale (Temp_Vect_1, Frame.Camera->Up, Y_Scalar);
  126.   VScale (Temp_Vect_2, Frame.Camera->Right, X_Scalar);
  127.   VAdd (ray->Direction, Temp_Vect_1, Temp_Vect_2);
  128.   VAdd (ray->Direction, ray->Direction, Frame.Camera->Direction);
  129.   VNormalize (ray->Direction, ray->Direction);
  130.   Initialize_Ray_Containers (ray);
  131.   ray->Quadric_Constants_Cached = FALSE;
  132.   }
  133.  
  134. void Read_Rendered_Part()
  135.   {
  136.   int rc, x, line_number;
  137.   unsigned char Red, Green, Blue;
  138.   DBL grey;
  139.  
  140.   maxclr = (DBL)(1 << Color_Bits) - 1.0;
  141.   while ((rc = Read_Line(Output_File_Handle, Previous_Line, &line_number)) == 1)
  142.     {
  143.     if (Options & DISPLAY)
  144.       for (x = 0 ; x < Frame.Screen_Width ; x++)
  145.       {
  146.       if (PaletteOption == GREY)
  147.     {
  148.     grey = Previous_Line[x].Red * 0.287 +
  149.     Previous_Line[x].Green * 0.589 +
  150.     Previous_Line[x].Blue * 0.114;
  151.     Red = Green = Blue = (unsigned char)(grey * maxclr);
  152.     }
  153.       else
  154.     {
  155.     Red = (unsigned char) (Previous_Line[x].Red * maxclr);
  156.     Green = (unsigned char) (Previous_Line[x].Green * maxclr);
  157.     Blue = (unsigned char) (Previous_Line[x].Blue * maxclr);
  158.     }
  159.       display_plot (x, line_number, Red, Green, Blue);
  160.       COOPERATE     /* Moved inside loop JLN 12/91 */
  161.     }
  162.       }
  163.  
  164.     First_Line = line_number+1;
  165.  
  166.   if (rc == 0) 
  167.     {
  168.     Close_File(Output_File_Handle);
  169.     if (Open_File (Output_File_Handle, Output_File_Name,
  170.       &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  171.       APPEND_MODE) != 1) 
  172.       {
  173.       fprintf (stderr, "Error opening output file\n");
  174.       fflush(stdout);
  175.       close_all();
  176.       exit(1);
  177.       }
  178.     return;
  179.     }
  180.  
  181.   fprintf (stderr, "Error reading aborted data file\n");
  182.   }
  183.  
  184. void Start_Tracing ()
  185.   {
  186.   COLOUR Colour;
  187.   register int x, y;
  188.   unsigned char Red, Green, Blue;
  189.   DBL grey;
  190.  
  191.   for (y = (Options & ANTIALIAS)?First_Line-1:First_Line; y<Last_Line; y++)
  192.     {
  193.  
  194.     check_stats(y);
  195.  
  196. #ifdef DB_CODE
  197.     /* Necessary for vista buffer. */
  198.     if (Extended_Options & USE_VISTA_BUFFER)
  199.     {
  200.       Prune_Vista_Tree(y);
  201.     }
  202. #endif
  203.  
  204.     for (x = First_Column ; x < Last_Column ; x++)
  205.       {
  206.       Check_User_Abort(1);
  207.  
  208.       Number_Of_Pixels++;
  209.  
  210. #ifdef DB_CODE
  211.       /* Necessary for vista buffer. */
  212.       Create_Ray(CM_Ray, Frame.Screen_Width, Frame.Screen_Height, (DBL) x, (DBL) y);
  213.  
  214.       Trace_Level = 0;
  215.  
  216.       if (Extended_Options & USE_VISTA_BUFFER)
  217.     Trace_Primary_Ray (&Ray, &Colour, x);
  218.       else
  219.     Trace (&Ray, &Colour);
  220. #else
  221.       Create_Ray (CM_Ray, Frame.Screen_Width, Frame.Screen_Height, (DBL) x, (DBL) y);
  222.       Trace_Level = 0;
  223.       Trace (&Ray, &Colour);
  224. #endif
  225.       Clip_Colour (&Colour, &Colour);
  226.  
  227.       Current_Line[x] = Colour;
  228.  
  229.       if (Options & ANTIALIAS)
  230.     do_anti_aliasing(x, y, &Colour);
  231.  
  232.       if (y != First_Line-1)
  233.     {
  234.  
  235.     if (PaletteOption == GREY)
  236.       {
  237.       grey = Colour.Red * 0.287 +
  238.       Colour.Green * 0.589 +
  239.       Colour.Blue * 0.114;
  240.       Red = Green = Blue = (unsigned char)(grey * maxclr);
  241.       }
  242.     else
  243.       {
  244.       Red = (unsigned char) (Colour.Red * maxclr);
  245.       Green = (unsigned char) (Colour.Green * maxclr);
  246.       Blue = (unsigned char) (Colour.Blue * maxclr);
  247.       }
  248.     if (Options & DISPLAY)
  249.       display_plot (x, y, Red, Green, Blue);
  250.     }
  251.       }
  252.     output_line(y);
  253.     }
  254.  
  255.   if (Options & DISKWRITE)
  256.     {
  257.     if (Last_Line != First_Line)
  258.     Write_Line (Output_File_Handle, Previous_Line, Last_Line - 1);
  259.     }
  260.   }
  261.  
  262. static void check_stats(y)
  263. register int y;
  264.   {
  265.   FILE *stat_file;
  266.  
  267.   /* New verbose options CdW */
  268.   if (Options & VERBOSE && VerboseFormat=='0')
  269.     {
  270.     printf ("\nRendering %s to %s",Input_File_Name,Output_File_Name);
  271.     if((First_Line != 0) || (Last_Line != Frame.Screen_Height))
  272.       printf(" from %4d to %4d:\n",First_Line+1, Last_Line);
  273.     else
  274.       printf (":\n");
  275.     printf ("Size: %4d x %4d : Tracing line %4d of %4d",Frame.Screen_Width, Frame.Screen_Height, (y-First_Line)+1, Last_Line-First_Line);
  276.     if (!(Options & ANTIALIAS))
  277.       printf(".");
  278.     }
  279.   if (Options & VERBOSE_FILE)
  280.     {
  281.     stat_file = fopen(Stat_File_Name,"w+t");
  282.     fprintf (stat_file,"Line %4d.\n", y);
  283.     fclose(stat_file);
  284.     }
  285.  
  286.   /* Use -vO for Old style verbose */
  287.   if (Options & VERBOSE && (VerboseFormat=='O'))
  288.     {
  289.     printf ("Line %4d", y);
  290.     }
  291.   if (Options & VERBOSE && VerboseFormat=='1')
  292.     {
  293.     fprintf (stderr,"Size: %4d x %4d : Tracing line %4d of %4d",Frame.Screen_Width, Frame.Screen_Height, (y-First_Line)+1, Last_Line-First_Line);
  294.     if (!(Options & ANTIALIAS))
  295.       fprintf(stderr,".");
  296.     }
  297.  
  298.   if (Options & ANTIALIAS)
  299.     SuperSampleCount = 0;
  300.   }
  301.  
  302. static void do_anti_aliasing(x, y, Colour)
  303. register int x, y;
  304. COLOUR *Colour;
  305.   {
  306.   char Antialias_Center_Flag = 0;
  307.  
  308.   Current_Line_Antialiased_Flags[x] = 0;
  309.  
  310.   if (x != 0)
  311.     {
  312.     if (Colour_Distance (&Current_Line[x-1], &Current_Line[x])
  313.       >= Frame.Antialias_Threshold)
  314.       {
  315.       Antialias_Center_Flag = 1;
  316.       if (!(Current_Line_Antialiased_Flags[x-1]))
  317.     {
  318.     Supersample (&Current_Line[x-1],
  319.       x-1, y, Frame.Screen_Width, Frame.Screen_Height);
  320.     Current_Line_Antialiased_Flags[x-1] = 1;
  321.     SuperSampleCount++;
  322.     }
  323.       }
  324.     }
  325.  
  326.   if (y != First_Line-1)
  327.     {
  328.     if (Colour_Distance (&Previous_Line[x], &Current_Line[x])
  329.       >= Frame.Antialias_Threshold)
  330.       {
  331.       Antialias_Center_Flag = 1;
  332.       if (!(Previous_Line_Antialiased_Flags[x]))
  333.     {
  334.     Supersample (&Previous_Line[x],
  335.       x, y-1, Frame.Screen_Width, Frame.Screen_Height);
  336.     Previous_Line_Antialiased_Flags[x] = 1;
  337.     SuperSampleCount++;
  338.     }
  339.       }
  340.     }
  341.  
  342.   if (Antialias_Center_Flag)
  343.     {
  344.     Supersample (&Current_Line[x],
  345.       x, y, Frame.Screen_Width, Frame.Screen_Height);
  346.     Current_Line_Antialiased_Flags[x] = 1;
  347.     *Colour = Current_Line[x];
  348.     SuperSampleCount++;
  349.     }
  350.  
  351.   return;
  352.   }
  353.  
  354.  
  355. void Initialize_Renderer PARAMS((void))
  356.   {
  357.   register int i;
  358.  
  359.   CM_Ray = &Ray;
  360.  
  361.   maxclr = (DBL)(1 << Color_Bits) - 1.0;
  362.  
  363.   /* These malloc's are never freed! Why ? Need a Deinit_Renderer() ?*/
  364.   Previous_Line = (COLOUR *) malloc (sizeof (COLOUR)*(Frame.Screen_Width + 1));
  365.   Current_Line = (COLOUR *) malloc (sizeof (COLOUR)*(Frame.Screen_Width + 1));
  366.  
  367.   for (i = 0 ; i <= Frame.Screen_Width ; i++)
  368.     {
  369.     Previous_Line[i].Red = 0.0;
  370.     Previous_Line[i].Green = 0.0;
  371.     Previous_Line[i].Blue = 0.0;
  372.     Current_Line[i].Red = 0.0;
  373.     Current_Line[i].Green = 0.0;
  374.     Current_Line[i].Blue = 0.0;
  375.     }
  376.  
  377.   if (Options & ANTIALIAS)
  378.     {
  379.     Previous_Line_Antialiased_Flags =
  380.     (char *) malloc (sizeof (char)*(Frame.Screen_Width + 1));
  381.     Current_Line_Antialiased_Flags =
  382.     (char *)  malloc (sizeof (char)*(Frame.Screen_Width + 1));
  383.  
  384.     for (i = 0 ; i <= Frame.Screen_Width ; i++) 
  385.       {
  386.       (Previous_Line_Antialiased_Flags)[i] = 0;
  387.       (Current_Line_Antialiased_Flags)[i] = 0;
  388.       }
  389.     }
  390.  
  391.   Ray.Initial = Frame.Camera->Location;
  392.   return;
  393.   }
  394.  
  395. static void output_line (y)
  396. register int y;
  397.   {
  398.   COLOUR *Temp_Colour_Ptr;
  399.   char *Temp_Char_Ptr;
  400.  
  401.   if (Options & DISKWRITE)
  402.     if (y > First_Line) 
  403.     {
  404.     Write_Line (Output_File_Handle, Previous_Line, y-1);
  405.     }
  406.  
  407.   if (Options & VERBOSE)
  408.     {
  409.     if (Options & ANTIALIAS && VerboseFormat != '1')
  410.       printf (" supersampled %d times.", SuperSampleCount);
  411.  
  412.     if (Options & ANTIALIAS && VerboseFormat == '1')
  413.       {
  414.       fprintf (stderr," supersampled %d times.", SuperSampleCount);
  415.  
  416.       }
  417.     if (VerboseFormat == '1')
  418.       fprintf (stderr,"\r");
  419.     else
  420.       fprintf (stderr,"\n");
  421.     }
  422.   Temp_Colour_Ptr = Previous_Line;
  423.   Previous_Line = Current_Line;
  424.   Current_Line = Temp_Colour_Ptr;
  425.  
  426.   Temp_Char_Ptr = Previous_Line_Antialiased_Flags;
  427.   Previous_Line_Antialiased_Flags = Current_Line_Antialiased_Flags;
  428.   Current_Line_Antialiased_Flags = Temp_Char_Ptr;
  429.  
  430.   return;
  431.   }
  432.  
  433. void Trace (Ray, Colour)
  434. RAY *Ray;
  435. COLOUR *Colour;
  436.   {
  437.   OBJECT *Object;
  438.   INTERSECTION Best_Intersection, New_Intersection;
  439.   register int Intersection_Found;
  440.  
  441.   COOPERATE
  442.   Number_Of_Rays++;
  443.   Make_Colour (Colour, 0.0, 0.0, 0.0);
  444.  
  445.   if (Trace_Level > (int) Max_Trace_Level)
  446.     return;
  447.  
  448.   Intersection_Found = FALSE;
  449.   Best_Intersection.Depth = BOUND_HUGE;
  450.  
  451.     /* What objects does this ray intersect? */
  452.   if (!Use_Slabs)
  453.     for (Object = Frame.Objects ;
  454.      Object != NULL ;
  455.      Object = Object -> Sibling)
  456.     {
  457.     if (Intersection (&New_Intersection, Object, Ray))
  458.       if (New_Intersection.Depth < Best_Intersection.Depth)
  459.     {
  460.     Best_Intersection = New_Intersection;
  461.     Intersection_Found = TRUE;
  462.     }
  463.     }
  464.   else
  465.     Intersection_Found = Bounds_Intersect(Root_Object, Ray,
  466.       &Best_Intersection,&Object);
  467.  
  468.   if (Intersection_Found)
  469.     Determine_Apparent_Colour (&Best_Intersection, Colour, Ray);
  470.   else
  471.     if (Frame.Fog_Distance > 0.0)
  472.       *Colour = Frame.Fog_Colour;
  473.     else
  474.       *Colour = Frame.Background_Colour;
  475.   }
  476.  
  477. /* exit with error if image not completed/user abort*/
  478. void Check_User_Abort (Do_Stats)
  479. int Do_Stats;
  480.   {
  481.   TEST_ABORT
  482.   if (Stop_Flag)
  483.     {
  484.     close_all();
  485.     if (Do_Stats)
  486.       {
  487.       PRINT_STATS
  488.       }
  489.     exit(2);
  490.     }
  491.   }
  492.  
  493. /*---------------  Standard sampling in loop  -----------------------*/
  494.  
  495. unsigned short JRanges[] = {1,1,1,1,3,2,5,3,7,4}; /* LSK */
  496.  
  497. void Supersample (result, x, y, Width, Height)
  498. COLOUR *result;
  499. int x, y, Width, Height;
  500.   {
  501.   COLOUR colour;
  502.   register DBL dx, dy, Jitter_X, Jitter_Y;
  503.   register int Jitt_Offset;
  504.   unsigned char Red, Green, Blue;
  505.   int JRange;                               /* LSK */
  506.   int JSteps;                               /* LSK */
  507.   DBL JScale;                               /* LSK */
  508.   DBL JSize,JOffset;                        /* LSK */
  509.   int i,j;                                  /* LSK */
  510.  
  511.   dx = (DBL) x;                             /* LSK */
  512.   dy = (DBL) y;                             /* LSK */
  513.   Jitt_Offset = 10;
  514.  
  515.   Number_Of_Pixels_Supersampled++;
  516.  
  517.   Make_Colour (result, 0.0, 0.0, 0.0);
  518.  
  519.   if (AntialiasDepth>1)                                           /* LSK */
  520.     {                                                             /* LSK */
  521.     /* JSize is the size of the jitter scattering area */
  522.     JSize = 1.0/AntialiasDepth;                                   /* LSK */
  523.  
  524.     /* JOffset is the 'radius' of the jitter scatter area */
  525.     JOffset = JSize/2.0;                                        /* LSK */
  526.  
  527.     /* JSteps is either 1 or 2 depending on whether the number of samples
  528.     is odd or even. This is because the loop need to either run through
  529.     or over 0
  530.      */
  531.     JSteps = 2-(AntialiasDepth % 2);                              /* LSK */
  532.  
  533.     /* JRange is the range that the loop will run through. I couldn't
  534.     come up with a function describing the values, so I used an array
  535.     for 2x2 up to 9x9.
  536.      */
  537.     JRange = JRanges[AntialiasDepth];                             /* LSK */
  538.  
  539.     /* JScale is the scaling value for the color resulting from the
  540.     ray before adding to the resultant color
  541.      */
  542.     JScale = 1.0/(DBL)(AntialiasDepth*AntialiasDepth);              /* LSK */
  543.  
  544.     for (i= -JRange;i<=JRange;i+=JSteps)
  545.       for (j= -JRange;j<=JRange;j+=JSteps)
  546.       {
  547.       if (Options & JITTER)
  548.     {
  549.     Jitter_X = (rand3d(x+Jitt_Offset, y) & 0x7FFF) / 32768.0 * JSize - JOffset;
  550.     Jitt_Offset++;
  551.     Jitter_Y = (rand3d(x+Jitt_Offset, y) & 0x7FFF) / 32768.0 * JSize - JOffset;
  552.     Jitt_Offset++;
  553.     }
  554.       else
  555.     {
  556.     Jitter_X=Jitter_Y=0.0;
  557.     }
  558.       Jitter_X*=JitterScale;
  559.       Jitter_Y*=JitterScale;
  560.  
  561. #ifdef DB_CODE
  562.       /* Necessary for vista buffer. */
  563.       Create_Ray (CM_Ray, Frame.Screen_Width, Frame.Screen_Height,
  564.         dx + Jitter_X + i * JSize/JSteps,
  565.         dy + Jitter_Y + j * JSize/JSteps);
  566.  
  567.       Trace_Level = 0;
  568.  
  569.       if (Extended_Options & USE_VISTA_BUFFER)
  570.     Trace_Primary_Ray (CM_Ray, &colour, x);
  571.       else
  572.     Trace (CM_Ray, &colour);
  573. #else
  574.       Create_Ray (CM_Ray, Frame.Screen_Width, Frame.Screen_Height,
  575.     dx + Jitter_X + i * JSize/JSteps,
  576.     dy + Jitter_Y + j * JSize/JSteps );
  577.  
  578.       Trace_Level = 0;
  579.       Trace (CM_Ray, &colour);
  580. #endif
  581.       Clip_Colour (&colour, &colour);
  582.       Scale_Colour (&colour, &colour, JScale );
  583.       Add_Colour (result, result, &colour);
  584.  
  585.       }
  586.     }                                       /* LSK */
  587.   else   /* 1x1 specified! */
  588.     {
  589. #ifdef DB_CODE
  590.     /* Necessary for vista buffer. */
  591.     Create_Ray (CM_Ray, Frame.Screen_Width, Frame.Screen_Height,dx,dy);
  592.  
  593.     Trace_Level = 0;
  594.  
  595.     if (Extended_Options & USE_VISTA_BUFFER)
  596.       Trace_Primary_Ray (CM_Ray, &colour, x);
  597.     else
  598.       Trace (CM_Ray, &colour);
  599. #else
  600.     Create_Ray (CM_Ray, Frame.Screen_Width, Frame.Screen_Height,dx,dy );
  601.  
  602.     Trace_Level = 0;
  603.     Trace (CM_Ray, &colour);
  604. #endif
  605.     Clip_Colour (&colour, &colour);
  606.     Add_Colour (result, result, &colour);
  607.     Jitt_Offset += 10;
  608.     }
  609.  
  610.   if ((y != First_Line - 1) && (Options & DISPLAY))
  611.     {
  612.     Red = (unsigned char)(result->Red * maxclr);
  613.     Green = (unsigned char)(result->Green * maxclr);
  614.     Blue = (unsigned char)(result->Blue * maxclr);
  615.     display_plot (x, y, Red, Green, Blue);
  616.     }
  617.  
  618.   }
  619.  
  620.