mirror of
https://github.com/OpenTrespasser/JurassicParkTrespasser.git
synced 2024-12-19 23:21:56 +00:00
775 lines
25 KiB
C++
775 lines
25 KiB
C++
/***********************************************************************************************
|
|
*
|
|
* Copyright © DreamWorks Interactive. 1996
|
|
*
|
|
* Contents:
|
|
* Defines CScanline, which is used to render triangles of all formats.
|
|
*
|
|
* Notes:
|
|
* Currently the 'Z' value is calculated without regard to subpixel positioning on either
|
|
* the 'x' or 'y' axis.
|
|
*
|
|
* Virtually any mapping applied to rasterized triangles require subpixel calculations
|
|
* along x, just as edge walking for triangles require subpixel calculations along y.
|
|
*
|
|
* Left and right subpixel calculations must be handled differently:
|
|
*
|
|
* ----------- -----------
|
|
* | | | |
|
|
* | | | \ |
|
|
* | / | | \ |
|
|
* | / * | | * \ |
|
|
* | / | | \ |
|
|
* | / | | \ |
|
|
* |/ | | \|
|
|
* /----------- -----------\
|
|
* |<->| |<->|
|
|
* subpixel subpixel
|
|
* difference difference
|
|
* on left. on right.
|
|
*
|
|
* For the left, it can be seen that the value of the subpixel position along x is the
|
|
* distance from the centre of the pixel to the actual starting position of the scanline,
|
|
* which is:
|
|
*
|
|
* x difference = (0.5 + the integer value of x) - the actual value of x; or
|
|
*
|
|
* x difference = 0.5 - the fraction portion of x.
|
|
*
|
|
* As an optimization, 0.5 has been added to the x value of scanline starting positions
|
|
* so a truncation can be performed instead of rounding. Thus, for the left scanline
|
|
* position:
|
|
*
|
|
* x difference = 0.5 - the fraction portion of x + 0.5; or
|
|
*
|
|
* x difference = 1.0 - the fraction portion of x.
|
|
*
|
|
* For the right, the formula for the starting x difference value is:
|
|
*
|
|
* x difference = the actual value of x - (the integer portion of x + 0.5); or
|
|
*
|
|
* x difference = the fractional portion of x - 0.5.
|
|
*
|
|
* Adding 0.5 for the rounding optimization results in:
|
|
*
|
|
* x difference = the fractional portion of x - 0.5 + 0.5; or
|
|
*
|
|
* x difference = the fractional portion of x.
|
|
*
|
|
* Any value that should be subpixel correct with respect to 'x' (e.g. 'u' and 'v' texture
|
|
* coordinates for texture mapping), can use the x difference value by multiplying the
|
|
* step value for mapping with respect to x by the x difference and adding it to the
|
|
* starting value. For example, for a mapping value 'u':
|
|
*
|
|
* u start = u + (du * x difference).
|
|
*
|
|
* The fractional difference in x from one line to the next changes by a constant amount
|
|
* -- in other words a constant value can be added to the initial subpixel x difference.
|
|
* If the x subpixel difference creates an integer value, that integer value is simply
|
|
* removed and ignored. Maintaining a fractional value only for the x difference is
|
|
* referred to in this, and in dependent modules, as the modulus subtraction.
|
|
*
|
|
* Whenever and integer value is subtracted (i.e. the modulus subtraction is performed),
|
|
* all inherited classes must also perform a modulus subtraction (e.g. du is subtracted
|
|
* from u for texture mapping).
|
|
*
|
|
* Bugs:
|
|
*
|
|
* To do:
|
|
* Examine data locality issues for the scanline rasterizing functions.
|
|
* Incorporate the 'fINV_Z_MULTIPLIER' multiply in the camera class.
|
|
* Add assembly versions of 'DrawFromLeft' and 'DrawFromRight' for specific rasters.
|
|
* Test faster float to int conversions for positive and negative values.
|
|
* Reduce the number of tests to find the modularity of the x difference; e.g. make
|
|
* the fxXDifference value and the increment for fxXDifference both positive.
|
|
*
|
|
***********************************************************************************************
|
|
*
|
|
* $Log:: /JP2_PC/Source/Lib/Renderer/Primitives/Scanline.hpp $
|
|
*
|
|
* 39 98.09.19 12:39a Mmouni
|
|
* Added "forceinline" to many small inline functions.
|
|
* Inlined some functions for speed.
|
|
*
|
|
* 38 8/27/98 9:12p Asouth
|
|
* combinatorical relative operators are a library function
|
|
*
|
|
* 37 8/26/98 11:08a Rvande
|
|
* Added explicit scoping to the fixed data type
|
|
*
|
|
* 36 98.03.24 8:17p Mmouni
|
|
* Made changes to support alternate perspective correction settings.
|
|
*
|
|
* 35 97/11/08 4:47p Pkeet
|
|
* Removed 'DrawLoop.hpp' include.
|
|
*
|
|
* 34 97/11/08 3:41p Pkeet
|
|
* Removed Z template parameters and code.
|
|
*
|
|
* 33 97.10.15 7:41p Mmouni
|
|
* Removed support for right to left scanlines.
|
|
*
|
|
* 32 97/10/12 20:46 Speter
|
|
* Changed TReflectVal to TClutVal.
|
|
*
|
|
* 31 8/18/97 5:46p Bbell
|
|
* Reorganized the 'SetClutAddress' member function to use the CTexture solid colour.
|
|
*
|
|
* 30 97/08/15 12:05 Speter
|
|
* Now set solid colour differently depending on whether clut lookup is enabled.
|
|
*
|
|
* 29 97/08/07 11:35a Pkeet
|
|
* Added interface support for mipmapping.
|
|
*
|
|
* 28 97/08/05 14:19 Speter
|
|
* Slightly optimised polygon vertex setup by adding InitializeVertexData() functions.
|
|
*
|
|
* 27 97/07/16 15:51 Speter
|
|
* InitializeTriangleData now takes two params to use as coefficients in derivative calculation
|
|
* rather than f_invdx. Added AssertRange in scanline template.
|
|
*
|
|
* 26 97/07/07 14:03 Speter
|
|
* Now copy vertices for current polygon locally to arvRasterVertices, which is used rather than
|
|
* rpoly.paprvPolyVertices for most DrawPolygon code. Renamed iY to iYScr, as it's now a union
|
|
* with v3Cam, and set in InitializePolygonData.
|
|
*
|
|
* 25 97/06/27 15:35 Speter
|
|
* Moved code to new InitializePolygonData(), added bIsPlanar(). Removed call to
|
|
* SetBaseIntensity.
|
|
*
|
|
* 24 6/16/97 8:35p Mlange
|
|
* Updated for fixed::fxFromFloat() name change.
|
|
*
|
|
* 23 97/05/25 18:05 Speter
|
|
* Changed CDrawTriangle to CDrawPolygon.
|
|
*
|
|
* 22 97-03-31 22:22 Speter
|
|
* Now use CEdge<> line variables rather than slower pointers.
|
|
* Removed unneeded pdtriTriangle member var.
|
|
*
|
|
* 21 97/02/21 12:47p Pkeet
|
|
* Changed type names for template parameters to meet coding standards.
|
|
*
|
|
* 20 97/02/20 7:16p Pkeet
|
|
* The 'Draw' member function has been deleted in favour of a DrawSubtriangle function.
|
|
*
|
|
* 19 97/02/07 3:20p Pkeet
|
|
* Now uses the constant colour fill.
|
|
*
|
|
* 18 97/01/26 19:54 Speter
|
|
* Moved scanline timing calls from outside scanline call to outside of sub-triangle loop.
|
|
*
|
|
* 17 1/15/97 1:01p Pkeet
|
|
* Removed fog and b_modify parameters.
|
|
*
|
|
* 16 97/01/07 12:05 Speter
|
|
* Updated for ptr_const.
|
|
*
|
|
* 15 96/12/31 17:06 Speter
|
|
* Changed template parameter from raster to pixel type.
|
|
* Updated for rptr.
|
|
*
|
|
* 14 12/13/96 12:22p Pkeet
|
|
* Added timer code back in.
|
|
*
|
|
* 13 12/12/96 12:04p Pkeet
|
|
* Added an extra parameter for calling the CIndex constructor on a per scanline basis.
|
|
*
|
|
* 12 96/12/09 16:17 Speter
|
|
* Renamed tmScanline stat to psPixels.
|
|
*
|
|
* 11 96/12/06 17:58 Speter
|
|
* Changed profile to use new CCycleTimer class and Add() function.
|
|
*
|
|
* 10 12/06/96 5:14p Pkeet
|
|
* Commented out seperate left and right drawing routines.
|
|
*
|
|
* 9 12/06/96 3:52p Pkeet
|
|
* Disabled the self-modifying code portion.
|
|
*
|
|
* 8 96/12/05 16:48 Speter
|
|
* Removed #ifdef on profile calls.
|
|
*
|
|
* 7 12/05/96 1:17p Pkeet
|
|
* Added profiling from the Profile.hpp module.
|
|
*
|
|
* 6 11/12/96 2:46p Pkeet
|
|
* Added support for initializing self-modifying code on a per-triangle basis.
|
|
*
|
|
* 5 10/11/96 12:26p Pkeet
|
|
* Made the pointer to the texture bitmap a global variable.
|
|
*
|
|
* 4 10/11/96 10:31a Pkeet
|
|
* Added 'pvClutConversion' as a global variable instead of a member of 'CDrawTriangle.' No clut
|
|
* pointer is therefore passed to the 'DrawLoop' functions.
|
|
*
|
|
* 3 10/10/96 7:56p Pkeet
|
|
* Modified the 'DrawLoop' parameter list to explicitly pass variables instead of a pointer to
|
|
* the CScanline object.
|
|
*
|
|
* 2 10/10/96 3:11p Pkeet
|
|
* Modified 'pdpixGetClutAddress' to fall through if no associated clut is present.
|
|
*
|
|
* 1 10/09/96 7:17p Pkeet
|
|
* Changed 'CLineFlatZ' to 'CScanline' and moved code from 'LineFlatZ.hpp' to this module.
|
|
*
|
|
* 45 10/04/96 5:34p Pkeet
|
|
* Moved all ZBuffer code from LineFlatZ.hpp to ZBufferT.hpp.
|
|
*
|
|
* 44 10/03/96 6:19p Pkeet
|
|
* Added the 'pdpixGetClut' member function.
|
|
*
|
|
* 43 10/03/96 3:18p Pkeet
|
|
* Added the 'INDEX' template parameter and member variable to the CScanline class. Removed
|
|
* redundant includes found in the 'DrawTriangle.hpp' module.
|
|
*
|
|
* 42 10/02/96 4:40p Pkeet
|
|
* Added the 'INDEX' template parameter. Added full template parameter list to 'CScanline.'
|
|
*
|
|
* 41 10/01/96 3:19p Pkeet
|
|
* Moved the 'DrawLoop' function to the DrawLoop module.
|
|
*
|
|
* 40 9/27/96 4:32p Pkeet
|
|
* Removed the 'LineGouraudZ' template class.
|
|
*
|
|
* 39 96/09/25 19:50 Speter
|
|
* The Big Change.
|
|
* In transforms, replaced TReal with TR, TDefReal with TReal.
|
|
* Replaced all references to transform templates that have <TObjReal> with <>.
|
|
* Replaced TObjReal with TReal, and "or" prefix with "r".
|
|
* Replaced CObjPoint, CObjNormal, and CObjPlacement with equivalent transform types, and
|
|
* prefixes likewise.
|
|
* Removed some unnecessary casts to TReal.
|
|
* Finally, replaced VER_GENERAL_DEBUG_ASSERTS with VER_DEBUG.
|
|
*
|
|
* 38 96/09/25 15:48 Speter
|
|
* Updated for new FogT functions.
|
|
*
|
|
* 37 96/09/12 16:24 Speter
|
|
* Incorporated new TReflectVal usage.
|
|
*
|
|
* 36 9/12/96 3:52p Pkeet
|
|
* Removed static global variables associated with bumpmapping and moved them to "BumpMapT.hpp."
|
|
*
|
|
* 35 9/11/96 11:27a Pkeet
|
|
* Added bumpmapping static global variables.
|
|
*
|
|
* 34 96/09/09 18:30 Speter
|
|
* Made compatible with change of fIntensity to lvIntensity.
|
|
*
|
|
* 33 8/22/96 2:08p Pkeet
|
|
* Removed the 'Fog' member variable in favour of null pointer casts.
|
|
*
|
|
* 32 8/21/96 4:45p Pkeet
|
|
* Added fogging.
|
|
*
|
|
* 31 8/20/96 4:47p Pkeet
|
|
* Initial implementation of fogging.
|
|
*
|
|
* 30 8/16/96 1:01p Pkeet
|
|
* Now performs subpixel correction for 'z.' The 'LineXDifference' module has been removed and
|
|
* its functionality put into the 'LineFlatZ' module.
|
|
*
|
|
* 29 96/08/02 11:04 Speter
|
|
* Swapped SRenderVertex .fInvZ and .v3Screen.tZ values.
|
|
*
|
|
*
|
|
* 28 7/29/96 4:18p Pkeet
|
|
* Added asserts to the DrawFromLeft and DrawFromRight subroutines.
|
|
*
|
|
* 27 7/26/96 6:41p Mlange
|
|
* Updated for CTexture's tpSolid data member name change.
|
|
*
|
|
* 26 96/07/26 18:22 Speter
|
|
* Changed scaling of vertex parameters again. Now all increments are scaled by parameter size,
|
|
* actual values are scaled by parameter size minus one, and 0.5 is added.
|
|
*
|
|
* 25 96/07/24 14:55 Speter
|
|
* Changed rasterising routines to accept lighting and texture parameters in range [0,1], and
|
|
* scale them to the integer/fixed values needed.
|
|
*
|
|
* 24 96/07/22 15:28 Speter
|
|
* Moved pixPixel global var here from DrawTriangle.hpp.
|
|
* Light intensity is now taken from first vertex rather than assumed maximum.
|
|
*
|
|
* 23 7/18/96 5:45p Pkeet
|
|
* Changed asserts to match horizontal range.
|
|
*
|
|
* 22 96/07/18 17:19 Speter
|
|
* Changes affecting zillions of files:
|
|
* Changed SRenderCoord to SRenderVertex.
|
|
* Added SRenderTriangle type, changed drawing primitives to accept it.
|
|
*
|
|
* 21 96/07/15 18:59 Speter
|
|
* Changed u4Data global to ptexTexture.
|
|
* Moved pvClutTable to DrawTriangle.hpp.
|
|
* Removed iDeltaScan and pu1Bytes from CTexture. Now these values are retrieved from
|
|
* CTexture::prasTexture.
|
|
*
|
|
* 20 7/09/96 3:22p Pkeet
|
|
* Moved 'i4DInvZ' to LineFlatZ.hpp.
|
|
*
|
|
* 19 7/08/96 3:23p Pkeet
|
|
* Set two parameters for InitializeAsBase member function.
|
|
*
|
|
* 18 96/07/01 21:34 Speter
|
|
* Updated for CRaster's code review changes.
|
|
*
|
|
* 17 7/01/96 7:51p Pkeet
|
|
* Added 'fX' and 'fXDifference' member variables.
|
|
*
|
|
* 16 6/26/96 2:14p Pkeet
|
|
* Added include for 'LineFlatZScanline.hpp' for P5.
|
|
*
|
|
* 15 6/25/96 2:33p Pkeet
|
|
* Changed member functions to utilize 'u4Data' as a global variable.
|
|
*
|
|
* 14 6/18/96 10:52a Pkeet
|
|
* Added new fast float to fixed conversions. Updated comments in the draw functions.
|
|
*
|
|
* 13 6/17/96 6:42p Pkeet
|
|
* Added 'iFastFloatToInt' use.
|
|
*
|
|
* 12 6/13/96 8:31p Pkeet
|
|
* Eliminated fast float to int conversions for now.
|
|
*
|
|
* 11 6/13/96 3:09p Pkeet
|
|
* Employed 'iIntFromDouble.' Simplified parameter lists for Initialize function. Made
|
|
* 'DrawFromLeft' and 'DrawFromRight' member functions (again). Added 'DrawLoop' function and an
|
|
* assembly version of this function for 8 and 16 bit rasters.
|
|
*
|
|
* 10 6/06/96 7:56p Pkeet
|
|
* Made 'DrawFromLeft' and 'DrawFromRight' separate functions from CScanline so that separate
|
|
* template functions could be specified for separate rasters.
|
|
*
|
|
* 9 6/06/96 4:30p Pkeet
|
|
* Made the 'DrawFromLeft' and 'DrawFromRight' functions member functions. Altered structure to
|
|
* allow use by CDrawTriangle as opposed to CPoly.
|
|
*
|
|
* 8 6/03/96 5:44p Pkeet
|
|
* Updated comments section.
|
|
*
|
|
* 7 6/03/96 5:22p Pkeet
|
|
* Changed 'Line' member variable of CDrawTriangle to 'lineData.' Added additional notes on data
|
|
* locality issues.
|
|
*
|
|
* 6 6/03/96 10:24a Pkeet
|
|
* Added more comments.
|
|
*
|
|
* 5 5/31/96 8:24p Pkeet
|
|
* Added additional comments and asserts.
|
|
*
|
|
* 4 5/31/96 4:09p Pkeet
|
|
* Set templates up to function of of raster type (RAS) only.
|
|
*
|
|
* 3 5/29/96 7:54p Pkeet
|
|
* Fixed tear bug.
|
|
*
|
|
* 2 5/29/96 4:46p Pkeet
|
|
* Initial implementation.
|
|
*
|
|
* 1 5/29/96 4:44p Pkeet
|
|
*
|
|
**********************************************************************************************/
|
|
|
|
#ifndef HEADER_LIB_RENDERER_PRIMITIVES_SCANLINE_HPP
|
|
#define HEADER_LIB_RENDERER_PRIMITIVES_SCANLINE_HPP
|
|
|
|
#ifdef __MWERKS__
|
|
// for >= if only given < and ==
|
|
#include <utility>
|
|
using namespace std::rel_ops;
|
|
#endif
|
|
|
|
//
|
|
// Class definitions.
|
|
//
|
|
|
|
//*********************************************************************************************
|
|
//
|
|
template
|
|
<
|
|
class TPIX, // Destination raster pixel type.
|
|
class GOUR, // Intensity shading format.
|
|
class TRANS, // Transparency switch.
|
|
class MAP, // Source map format.
|
|
class INDEX, // Source index coordinates.
|
|
class CLU // Colour lookup table switch.
|
|
> class CScanline
|
|
//
|
|
// Defines a scanline for a triangle.
|
|
//
|
|
// Prefix: line (uses a generic prefix because it is a template class).
|
|
//
|
|
// Notes:
|
|
// This class is used by CEdge and CDrawPolygon template classes as a type for defining
|
|
// scanline type and raster type.
|
|
//
|
|
//**************************************
|
|
{
|
|
|
|
public:
|
|
|
|
::fixed fxX; // Position of coordinate along the X axis.
|
|
::fixed fxXDifference; // Fixed point version of the difference between the first pixel
|
|
// lit along x and the subpixel position of the raster scanline.
|
|
// This value is used for edge walking.
|
|
float fXDifference; // The floating point version of 'fxXDifference.' This value is
|
|
// used only in initialization.
|
|
GOUR gourIntensity; // Intensity template element.
|
|
INDEX indCoord; // Source texture index coordinates template element.
|
|
|
|
public:
|
|
|
|
//*****************************************************************************************
|
|
//
|
|
// CScanline template access types.
|
|
//
|
|
|
|
typedef TPIX TPixel; // Destination pixel type.
|
|
typedef GOUR TGouraud; // Gouraud shading type.
|
|
typedef TRANS TTrans; // Transparency type.
|
|
typedef MAP TMap; // Mapping type.
|
|
typedef INDEX TIndex; // Indexing type.
|
|
typedef CLU TClu; // Colour lookup type.
|
|
|
|
public:
|
|
|
|
//*****************************************************************************************
|
|
//
|
|
// CScanline member functions.
|
|
//
|
|
|
|
// Force default constructor inline so it is not called.
|
|
forceinline CScanline()
|
|
{
|
|
}
|
|
|
|
//*****************************************************************************************
|
|
//
|
|
forceinline void Initialize
|
|
(
|
|
CEdge< CScanline<TPIX, GOUR, TRANS, MAP, INDEX, CLU> >* pedge
|
|
// Pointer to the edge requiring start and increment values.
|
|
)
|
|
//
|
|
// Initializes the X components of the edge, including the starting position and the edge
|
|
// walking increment.
|
|
//
|
|
// Notes:
|
|
// The subpixel calculation made in CEdge is applied here.
|
|
//
|
|
//**************************************
|
|
{
|
|
Assert(pedge);
|
|
Assert(pedge->prvFrom);
|
|
Assert(pedge->prvTo);
|
|
|
|
//
|
|
// Find the x increment value. The value is calculated from:
|
|
//
|
|
// dx (x1 - x0)
|
|
// x increment = ---- = ---------
|
|
// dy (y1 - y0)
|
|
//
|
|
// but 1 / (y1 - y0) has already been calculated for the edge.
|
|
//
|
|
float f_increment_x = pedge->fInvDY * (pedge->prvTo->v3Screen.tX - pedge->prvFrom->v3Screen.tX);
|
|
pedge->lineIncrement.fxX.fxFromFloat(f_increment_x);
|
|
|
|
//
|
|
// Adjust X to the position where it would intersect the first horizontal line.
|
|
//
|
|
fxX.fxFromPosFloat(pedge->prvFrom->v3Screen.tX + f_increment_x * pedge->fStartYDiff);
|
|
}
|
|
|
|
//*****************************************************************************************
|
|
//
|
|
forceinline void InitializeAsBase
|
|
(
|
|
CEdge< CScanline<TPIX, GOUR, TRANS, MAP, INDEX, CLU> >* pedge,
|
|
// Edge requiring start and increment values.
|
|
const CDrawPolygon< CScanline<TPIX, GOUR, TRANS, MAP, INDEX, CLU> >* pdtri
|
|
// Back pointer to the triangle structure.
|
|
)
|
|
//
|
|
// Initializes the Z components of the edge, including starting position and edge walking
|
|
// increment.
|
|
//
|
|
// Notes:
|
|
// The subpixel calculation made in CEdge is applied here.
|
|
//
|
|
//**************************************
|
|
{
|
|
Assert(pedge);
|
|
Assert(pedge->prvFrom);
|
|
Assert(pedge->prvTo);
|
|
Assert(pdtri);
|
|
|
|
bool b_swap_modsub_sign = false;
|
|
|
|
//
|
|
// Get the fractional portions of the starting x difference and the increment x
|
|
// difference. See the 'Notes' section of this module for an explanation of this
|
|
// implementation.
|
|
//
|
|
fxXDifference = ::fixed(1) - fxX.fxFractional();
|
|
pedge->lineIncrement.fxXDifference = -pedge->lineIncrement.fxX.fxFractional();
|
|
|
|
// Convert x difference and increment to floating point.
|
|
fXDifference = (float)fxXDifference;
|
|
pedge->lineIncrement.fXDifference = (float)pedge->lineIncrement.fxXDifference;
|
|
|
|
// Make sure the modulus subtraction values are set to the right sign.
|
|
b_swap_modsub_sign = pedge->lineIncrement.fXDifference >= 0.0f;
|
|
|
|
// Use the setup routine for Gouraud-shaded base edges.
|
|
gourIntensity.InitializeAsBase
|
|
(
|
|
pedge->prvFrom,
|
|
pedge->prvTo,
|
|
pedge->fInvDY,
|
|
pedge->fStartYDiff,
|
|
fXDifference,
|
|
&pedge->lineIncrement.gourIntensity,
|
|
pedge->lineIncrement.fXDifference
|
|
);
|
|
|
|
// Use the setup routine for indexed coordinates.
|
|
indCoord.InitializeAsBase
|
|
(
|
|
pdtri->ptexTexture,
|
|
pedge->prvFrom,
|
|
pedge->prvTo,
|
|
pedge->lineIncrement.indCoord,
|
|
pedge->fInvDY,
|
|
pedge->lineIncrement.fXDifference,
|
|
fXDifference,
|
|
pedge->fStartYDiff,
|
|
pdtri->prpolyPoly->iMipLevel
|
|
);
|
|
|
|
//
|
|
// If the negate modulus subraction sign is set, negate the modulus subraction sign
|
|
// for all related variables.
|
|
//
|
|
if (b_swap_modsub_sign)
|
|
{
|
|
-gourIntensity;
|
|
-indCoord;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************************
|
|
//
|
|
forceinline bool operator +=
|
|
(
|
|
const CScanline& line // Increment to the current scanline.
|
|
)
|
|
//
|
|
// Adds two CScanline objects together and accumulates it in the calling object.
|
|
//
|
|
// Returns 'true' if a modulus subtraction must be performed.
|
|
//
|
|
//**************************************
|
|
{
|
|
bool b_mod_sub = false; // Modulus subtraction return flag.
|
|
|
|
//
|
|
// Increment the line edge variables by the edgewalking amount.
|
|
fxX += line.fxX;
|
|
fxXDifference += line.fxXDifference;
|
|
gourIntensity += line.gourIntensity;
|
|
indCoord += line.indCoord;
|
|
|
|
// Check if fxXDifference overflows.
|
|
if (fxXDifference >= (::fixed)1)
|
|
{
|
|
fxXDifference -= (::fixed)1;
|
|
b_mod_sub = true;
|
|
}
|
|
else
|
|
{
|
|
// Check if fxXDifference underflows.
|
|
if (fxXDifference < (::fixed)0)
|
|
{
|
|
fxXDifference += (::fixed)1;
|
|
b_mod_sub = true;
|
|
}
|
|
}
|
|
|
|
// Perform modulus subtractions.
|
|
if (b_mod_sub)
|
|
{
|
|
gourIntensity.ModulusSubtract();
|
|
indCoord.ModulusSubtract();
|
|
}
|
|
|
|
// No modulus subtraction.
|
|
return b_mod_sub;
|
|
}
|
|
|
|
//*****************************************************************************************
|
|
//
|
|
void AssertRange
|
|
(
|
|
ptr_const<CTexture> ptex,
|
|
int i_mip_level
|
|
)
|
|
//
|
|
// Tests that the current values of scanline variables are within range.
|
|
// Call this at the end of a scanline.
|
|
//
|
|
//**************************************
|
|
{
|
|
indCoord.AssertRange(ptex, i_mip_level);
|
|
gourIntensity.AssertRange();
|
|
}
|
|
|
|
//*********************************************************************************************
|
|
//
|
|
void AssertXRange
|
|
(
|
|
::fixed fx_linelength // Length of current scanline.
|
|
)
|
|
//
|
|
// Assert that all incremented variables are within range.
|
|
//
|
|
//**********************************
|
|
{
|
|
#if VER_DEBUG
|
|
int i_xrange = int(fxX + fx_linelength) - int(fxX) - 1;
|
|
if (i_xrange >= 0)
|
|
{
|
|
indCoord.AssertXRange(i_xrange);
|
|
gourIntensity.AssertXRange(i_xrange);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//*********************************************************************************************
|
|
//
|
|
static forceinline bool bIsPlanar()
|
|
//
|
|
// Returns:
|
|
// Whether this feature has planar gradients across any polygon.
|
|
//
|
|
//**********************************
|
|
{
|
|
//
|
|
// Currently, linear indexing and Gouraud shading can create gradients which are not
|
|
// planar. This is specified by the individual template classes.
|
|
//
|
|
return INDEX::bIsPlanar() && GOUR::bIsPlanar();
|
|
}
|
|
|
|
//*********************************************************************************************
|
|
//
|
|
forceinline void InitializePolygonData
|
|
(
|
|
CPArray<SRenderVertex*> parv_all, // List of all polygon vertices.
|
|
ptr_const<CTexture> ptex, // Texture for polygon.
|
|
TClutVal cv_face, // Face-wide lighting.
|
|
int i_mip_level // Mipmap level.
|
|
)
|
|
//
|
|
// Set up polygon-wide variables for rasterising; i.e. those not associated with
|
|
// triangle gradients. Also, set needed per-vertex data.
|
|
//
|
|
//**************************************
|
|
{
|
|
// Copy screen coords to our local vertices.
|
|
Assert(parv_all.uLen <= iMAX_RASTER_VERTICES);
|
|
|
|
// Initialize polygon-wide variables for index coordinates.
|
|
indCoord.InitializePolygonData(ptex, i_mip_level);
|
|
|
|
// Initialize polygon-wide variables for Gouraud shading.
|
|
gourIntensity.InitializePolygonData(ptex, cv_face);
|
|
|
|
// Set the base address for the clut.
|
|
SetClutAddress(ptex);
|
|
|
|
for (int i = 0; i < parv_all.uLen; i++)
|
|
{
|
|
arvRasterVertices[i].v3Screen = parv_all[i]->v3Screen;
|
|
arvRasterVertices[i].iYScr = iPosFloatCast(arvRasterVertices[i].v3Screen.tY);
|
|
|
|
indCoord.InitializeVertexData(parv_all[i], &arvRasterVertices[i]);
|
|
gourIntensity.InitializeVertexData(parv_all[i], &arvRasterVertices[i]);
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************************
|
|
//
|
|
forceinline void InitializeTriangleData
|
|
(
|
|
SRenderVertex* prv_1, // First of three non-colinear coordinates describing the
|
|
// plane of the triangle in screen coordinates.
|
|
SRenderVertex* prv_2, // Second coordinate describing the plane.
|
|
SRenderVertex* prv_3, // Third coordinate describing the plane.
|
|
float f_yab_invdx, // Multipliers for gradients.
|
|
float f_yac_invdx,
|
|
ptr_const<CTexture> ptex, // Pointer to source texture.
|
|
bool b_update = false, // Modify the gradients rather than setting them.
|
|
bool b_altpersp = false // Use alternate perspecive settings.
|
|
)
|
|
//
|
|
// Use the class storage structure to for triangle-wide data. This member function
|
|
// should only be called by CDrawPolygon.
|
|
//
|
|
//**************************************
|
|
{
|
|
// Initialize triangle-wide variables for index coordinates.
|
|
indCoord.InitializeTriangleData(prv_1, prv_2, prv_3, ptex, f_yab_invdx, f_yac_invdx, b_update, b_altpersp);
|
|
|
|
// Initialize triangle-wide variables for Gouraud shading.
|
|
gourIntensity.InitializeTriangleData(prv_1, prv_2, prv_3, f_yab_invdx, f_yac_invdx, b_update);
|
|
}
|
|
|
|
//*****************************************************************************************
|
|
//
|
|
forceinline void SetClutAddress
|
|
(
|
|
ptr_const<CTexture> ptex // Pointer to the source texture.
|
|
)
|
|
//
|
|
// Returns a pointer to a position within a clut for use by the source texture.
|
|
//
|
|
//**************************************
|
|
{
|
|
// Set a default value of null for the clut pointer.
|
|
pvClutConversion = 0;
|
|
u4ConstColour = 0;
|
|
|
|
|
|
if (CLU::bUseClut())
|
|
{
|
|
//
|
|
// Check to see if a texture with an associated clut is present. If it isn't present,
|
|
// fall through.
|
|
//
|
|
if (ptex && ptex->ppcePalClut && ptex->ppcePalClut->pclutClut)
|
|
{
|
|
// Call the get address function for the clut.
|
|
pvClutConversion = ptex->ppcePalClut->pclutClut->pvGetConversionAddress
|
|
(
|
|
MAP::u4GetClutBaseColour(ptex),
|
|
iBaseIntensity,
|
|
iDefaultFog
|
|
);
|
|
Assert(pvClutConversion);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If a constant colour can be set, do nothing else.
|
|
MAP::bSetConstColour(ptex, iBaseIntensity, iDefaultFog);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
|
|
#endif
|