home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vectoper.zip
/
RayTrace.cpp
next >
Wrap
C/C++ Source or Header
|
1996-09-23
|
7KB
|
218 lines
#include <stdio.h>
#include "RTTypes.h"
#include "RTMatMac.h"
#include "RTVecOps.h"
#include "RTObjOps.h"
#include "RTIMOps.h"
#include "RayTrace.h"
#include <calypso.H>
SharedType *shared; // Pointer to shared memory segment
int npix, nscan; // Parameters that define image size
FILE *ofp; // Output file pointer
/*
*******************************************************************************
*
* Name: RT_ThreadSegment
*
* Purpose: this routine contains the code governing the behavior of each
* thread in a parallel step. Its execution is controled by its two
* input parameters. The parameter "numThreads" defines the total
* numberof thread segments to be executed, while the parameter
* "ThreadId"indicates which thread segment is currently being
* executed.
*
* Each parallel step is responsible for rendering a specified scan
* set (from shared->FirstScan to shared->ScanLimit). A given thread
* segment is responsible for rendering some contiguous interval of
* this scan set. It determines this interval based on the scan set
* information and input parameters. All scan intervals are of equal
* size except the last. the size of the final interval may vary if
* the number of thread segments does not evenly divide the number of
* scan lines in the scan set.
*
* TECHNICAL NOTES
* It should noted that each thread segment executes an
* additional scan line beyond the specified scan interval. The
* reason for this is that the algorithm actually calculates
* intensities at pixel corners. The additional scan line is
* necessary for the bottom corners of the last row of pixels.
* It should also be noted that the output buffer in shared
* memory (pix_buf) is overwritten in each parallel step. Therefore
* the first scan of each parallel step is placed in scan zero of the
* output buffer.
*
*
*
*
* Input Parameters
*
* NumThreads - Number of thread segments which use this routine
* ThreadId - thread segment currently executing this routine
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
static void RT_ThreadSegment (int numThreads, int ThreadId)
{
Ray curr_ray;
int pix, scan, scanline;
/*
* Calculate scan interval for this thread segment
* (if this is the last thread segment, the interval may be modified)
*/
int from = shared->FirstScan + (ThreadId * (shared->ScanSetSize/numThreads));
int to = from + (shared->ScanSetSize/numThreads);
if (ThreadId == numThreads-1)
to = shared->ScanLimit + 1;
/*
* initialize ray origin and index into output buffer
*/
curr_ray.origin = shared->vp.F;
scanline = from - shared->FirstScan;
/*
* Determine intensities for pixel corners in specified scan interval
*/
for (scan=from; scan<to; scan++) {
for (pix=0; pix<shared->npix+1; pix++) {
curr_ray.dir = RT_DirectionVector((float) pix, (float) scan);
shared->pix_buf[scanline][pix] = RT_Trace(curr_ray, (float)-1.0, 1);
} /* end -- for pix */
scanline++;
} /* end -- for scan */
}
/*
*******************************************************************************
*
* Name: RayTrace
*
* Purpose: this is the main routine for the parallelized ray tracing
* algorithm. It is designed to render an image in a specified
* number (nIter) of parallel steps. Each parallel step renders a
* contiguous scan line set of an image. All scan lines sets, except
* the last, are of are of equal size. The final set may vary in
* size if the number of parallel steps does not evenly divide the
* number of scan lines in the image.
*
* The algorithm used here determines intensities at pixel corners
* rather than at pixel centers. Therefore, once a given parallel
* step has been completed, it is necessary to average the four
* values in the result buffer (pix_buf) that represent the corners
* of a pixel in order to determine its intensity. These intensity
* values are then converted to RGB values by the routine RT_SetPixel
* which also determines whether the results should be displayed or
* written to an output file.
*
* TECHNICAL NOTES
* It should be noted that the output buffer in shared memory
* (pix_buf) is overwritten in each parallel step. Therefore the
* first scan of each parallel step is placed in scan zero of the
* output buffer.
*
*
*
* Input Parameters
*
* none
*
*
* Output Parameters
*
* none
*
*******************************************************************************
*/
void
RayTrace ()
{
Vector Ipix[1030];
int iter, scan, pix;
/*
* Initialization of parameters for scene to be rendered
*/
RT_SetViewParams();
/*
++++++++++++++++++++++++++++++++++++++++++++++++++
+ Render image in nIter steps
++++++++++++++++++++++++++++++++++++++++++++++++++
*/
for (iter=0; iter<nIter; iter++) {
/*
* calculate scan set parameters for parallel step
* (if this is the last parallel step, the set size may be modified)
*/
shared->FirstScan = iter * (nscan/nIter);
shared->ScanLimit = shared->FirstScan + (nscan/nIter);
if (iter == nIter - 1)
shared->ScanLimit = nscan;
shared->ScanSetSize = shared->ScanLimit - shared->FirstScan;
/*
* calypso library call to handel execution of parallel step
*/
ParallelExec(RT_ThreadSegment, num_T, NULL);
/*
* average pixel corner intensities to get intensity for pixel
*/
for (scan=0; scan<shared->ScanSetSize; scan++) {
for (pix=0; pix<npix; pix++) {
Ipix[pix] = shared->pix_buf[scan][pix];
Ipix[pix] = Vector_Sum(&Ipix[pix], &shared->pix_buf[scan][pix+1]);
Ipix[pix] = Vector_Sum(&Ipix[pix], &shared->pix_buf[scan+1][pix]);
Ipix[pix] = Vector_Sum(&Ipix[pix], &shared->pix_buf[scan+1][pix+1]);
Ipix[pix] = VectorScaler_Division(&Ipix[pix], (float)4.0);
} /* end -- for pix */
/*
* convert pixel intensities to RGB values and display or write to a file
*/
RT_SetPixels (Ipix, shared->FirstScan+scan, npix);
} /* end -- for scan */
} /* end -- for iter */
}