/***************************************************************************** * Z buffer creation,manipulation and access * ****************************************************************************** * (C) Gershon Elber, Technion, Israel Institute of Technology * ****************************************************************************** * Written by: David Shafrir & Alex Reicher Ver 0.3, Sep. 2003 * *****************************************************************************/ #include "rndr_loc.h" #include "zbuffer.h" #include "filt.h" #include "polyline.h" #define COLOR_QUANTIZE(Clr, n) ((int) (Clr * n)) / ((RealType) n); static void ZBufferCalcColors(ZBufferStruct *Buffer); static int ThisLittleEndianHardware(void); static ZPointStruct *AddPoint(ZBufferStruct *Buffer, int x, int y, InterpolStruct *i); static void PolyEdgeIncr(EdgeStruct *PEdge); /***************************************************************************** * DESCRIPTION: M * Clears the context of the z-buffer. M * * * PARAMETERS: M * Buffer: IN, OUT, Pointer to the z-buffer. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * ZBufferClear, clear buffer M *****************************************************************************/ void ZBufferClear(ZBufferStruct *Buffer) { int x, y; ZListStruct Dummy; Dummy.Stencil = 0; Dummy.First.Next = NULL; Dummy.First.z = (IRndrZDepthType) FAREST_Z; Dummy.First.Transp = (ZTranspType) 0; for (y = 0; y < Buffer -> SizeY; y++) { for (x = 0; x < Buffer -> SizeX; x++) { memcpy(&Buffer -> z[y][x], &Dummy, sizeof(ZListStruct)); } } FastAllocDestroy(Buffer -> PointsAlloc); Buffer -> PointsAlloc = FastAllocInit( sizeof(ZPointStruct), sizeof(ZPointStruct) << 10, 2, 0); Buffer -> ColorsValid = FALSE; } /***************************************************************************** * DESCRIPTION: M * Initialize a newly created z-buffer. M * * * PARAMETERS: M * Buffer: IN, OUT, Pointer to the z-buffer. M * Scene: IN, Pointer to the related scene object. M * SuperSize: IN, Super sampling size. M * ColorQuantization: IN, non zero to quantize the generated colors to M * ColorQuantization levels of colors. M * * * RETURN VALUE: M * int: 0 if successfull. M * * * KEYWORDS: M * ZBufferInit, initialize, create buffer M *****************************************************************************/ int ZBufferInit(ZBufferStruct *Buffer, SceneStruct *Scene, int SuperSize, int ColorQuantization) { ZListStruct **z, Dummy; int x, y; Dummy.First.Next = NULL; Dummy.First.z = (IRndrZDepthType) FAREST_Z; Dummy.First.Transp = (ZTranspType) 0; Buffer -> Scene = Scene; Buffer -> TargetSizeX = Scene -> SizeX / SuperSize; Buffer -> TargetSizeY = Scene -> SizeY / SuperSize; Buffer -> SizeX = Scene -> SizeX; Buffer -> SizeY = Scene -> SizeY; Buffer -> ColorQuantization = ColorQuantization; PT_COPY(&Buffer -> BackgroundColor, Scene -> BackgroundColor); if (SuperSize > 1) { Buffer -> Filter = MALLOC(FilterType, 1); Buffer -> Filter -> SuperSize = SuperSize; Buffer -> Filter -> Name=NULL; } else Buffer -> Filter = NULL; z = MALLOC(ZListStruct*, Buffer -> SizeY); SET_COL_FROM_REAL(Dummy.First.Color, Buffer -> BackgroundColor); for (y = 0; y < Buffer -> SizeY; y++) { z[y] = MALLOC(ZListStruct, Buffer -> SizeX); for (x = 0; x < Buffer -> SizeX; x++) { memcpy(&z[y][x], &Dummy, sizeof(ZListStruct)); } } Buffer -> z = z; Buffer -> ColorsValid = FALSE; Buffer -> UseTransparency = 0; Buffer -> AccessMode = ZBUFFER_ACCESS_FILTERED; Buffer -> PointsAlloc = FastAllocInit(sizeof(ZPointStruct), sizeof(ZPointStruct) << 10, 2, 0); Buffer -> LineColors = MALLOC(IRndrColorType, Buffer -> TargetSizeX); Buffer -> LineAlpha = MALLOC(ByteType, Buffer -> TargetSizeX); Buffer -> LinePixels = MALLOC(IrtImgPixelStruct, Buffer -> TargetSizeX); Buffer -> ZPol = NULL; Buffer -> PreZCmpClbk = NULL; Buffer -> ZPassClbk = NULL; Buffer -> ZFailClbk = NULL; return 0; } /***************************************************************************** * DESCRIPTION: M * Manually adds a single pixel. M * * * PARAMETERS: M * Buffer: IN, OUT, pointer to z-buffer. M * x: IN, the column number. M * y: IN, the line number. M * z: IN, the pixel's depth. M * Transparency: IN, the pixel's transparency value. M * Color: IN, the new color of pixel at (x, y). M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * ZBufferPutPixel, put pixel M *****************************************************************************/ void ZBufferPutPixel(ZBufferStruct *Buffer, int x, int y, RealType z, RealType Transparency, IRndrColorType Color) { ZPointStruct *Point = NULL; if (Buffer -> UseTransparency) { InterpolStruct Interpol; Interpol.z = z; Interpol.HasColor = FALSE; Point = AddPoint(Buffer, x, y, &Interpol); } else { ZListStruct *CurrZ = &Buffer -> z[y][x]; if (Buffer -> ZPol && Buffer -> ZPol(x, y, CurrZ -> First.z, z)) { Point = &CurrZ -> First; } else if (!Buffer -> ZPol && z NEAR_THAN CurrZ -> First.z) { Point = &CurrZ -> First; } } if (!Point ) return; Point -> Transp = (ZTranspType) Transparency; Point -> z = (IRndrZDepthType) z; SET_COL_FROM_REAL(Point -> Color, Color); Buffer -> ColorsValid = FALSE; } /***************************************************************************** * DESCRIPTION: M * Scan converts a triagle object into the z-buffer. M * * * PARAMETERS: M * Buffer: IN, OUT, pointer to the z-buffer. M * Tri: IN, pointer to the Triangle object. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * ZBufferScanTri, scan convert M *****************************************************************************/ void ZBufferScanTri(ZBufferStruct *Buffer, TriangleStruct *Tri) { STATIC_DATA IntensivityStruct *Intens[3] = {NULL, NULL, NULL}; int x, y, i, dx; EdgeStruct **Edges = Tri -> SortedEdge; ZPointStruct *NewPoint; ZListStruct *CurrZ; InterpolStruct DeltaVal, Val, TmpVal; Buffer -> ColorsValid = FALSE; if (!Intens[0]) { /* Space recycling. */ for (i = 0; i < 3; i++) { Intens[i] = MALLOC(IntensivityStruct, MAX_LIGHTS_NUM); } } DeltaVal.i = Intens[0]; Val.i = Intens[1]; TmpVal.i = Intens[2]; if (!Edges[1]) { _IRndrReportError(IRIT_EXP_STR("No right edge in triangle")); return; } /* Start scan conversion. */ for (y = Tri -> YMin; y <= Tri -> YMax -1 && y < Buffer -> SizeY; y++) { if (Edges[2]) { if (!IN(y, Edges[0] -> YMin, Edges[0] -> YMin + Edges[0] -> dy - 1)) { if (Edges[0] -> x == Edges[2] -> x) { Edges[0] = Edges[2]; } } if (!IN(y, Edges[1] -> YMin, Edges[1] -> YMin + Edges[1] -> dy - 1)) { if (Edges[1] -> x == Edges[2] -> x) { Edges[1] = Edges[2]; } } } /* Edge[0] is the start of interpolation. */ InterpolCopy(&Val, &Edges[0] -> Value); /* Dx is scan line length. */ dx = Edges[1] -> x - Edges[0] -> x; if (dx < 0) { _IRndrReportError(IRIT_EXP_STR("dx < 0, dx = %d"), dx); } InterpolDelta(&DeltaVal, &Edges[1] -> Value, &Edges[0] -> Value, dx - 1); /* Scan over dx. */ if (y >= 0) { for (x = Edges[0] -> x; x <= Edges[1] -> x-1; x++) { CurrZ = &Buffer -> z[y][x]; if (IN(x, 0, Buffer -> SizeX - 1)) { /* Inside of Image. */ IRndrColorType NewColor; NewPoint = NULL; if (Buffer -> UseTransparency) { NewPoint = AddPoint(Buffer, x, y, &Val); } else { if (Buffer -> PreZCmpClbk) { IRndrColorType PrevColor; SET_REAL_FROM_COL(PrevColor, CurrZ -> First.Color); Buffer -> PreZCmpClbk(x, y, PrevColor, CurrZ -> First.z); } if (StencilTest(&Buffer -> StencilCfg, CurrZ -> Stencil)) { if (Buffer -> ZPol) { if (Buffer -> ZPol(x, y, CurrZ -> First.z, Val.z)) { NewPoint = &CurrZ -> First; } } else if (Val.z NEAR_THAN CurrZ -> First.z) { NewPoint = &CurrZ -> First; } } else { StencilOpFail(&Buffer -> StencilCfg, &CurrZ -> Stencil); } } if (NewPoint) { NewPoint -> Transp = (ZTranspType) Tri -> Object -> Transp; NewPoint -> z = (IRndrZDepthType) Val.z; InterpolCopy(&TmpVal, &Val); TriangleColorEval(Tri -> Poly, x, y, Tri -> Object, Buffer -> Scene, &TmpVal, NewColor); SET_COL_FROM_REAL(NewPoint -> Color, NewColor); if (!Buffer -> UseTransparency) { StencilOpZPass(&Buffer -> StencilCfg, &CurrZ -> Stencil); if (Buffer -> ZPassClbk) Buffer -> ZPassClbk(x, y, NewColor, CurrZ -> First.z); } } else if (!Buffer -> UseTransparency) { StencilOpZFail(&Buffer -> StencilCfg, &CurrZ -> Stencil); if (Buffer -> ZFailClbk) { IRndrColorType PrevColor; SET_REAL_FROM_COL(PrevColor, CurrZ -> First.Color); Buffer -> ZFailClbk(x, y, PrevColor, CurrZ -> First.z); } } } InterpolIncr(&Val, &DeltaVal); } } /* Advance to next line. */ PolyEdgeIncr(Edges[0]); PolyEdgeIncr(Edges[1]); } } /***************************************************************************** * DESCRIPTION: M * Release the memory taken by the z-buffer. M * * * PARAMETERS: M * Buffer: IN,OUT, pointer to the z-buffer. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * ZBufferRelease, memory free, release M *****************************************************************************/ void ZBufferRelease(ZBufferStruct *Buffer) { int y; for (y = 0; y < Buffer -> SizeY; ++y) { FREE(Buffer -> z[y]); } FastAllocDestroy(Buffer -> PointsAlloc); FREE(Buffer -> LineColors); FREE(Buffer -> LineAlpha); FREE(Buffer -> LinePixels); } /***************************************************************************** * DESCRIPTION: * * Calulate the final color of all points, using transparncy attributes. * * * * PARAMETERS: * * Buffer: IN, OUT, The z-buffer. * * * * RETURN VALUE: * * void * *****************************************************************************/ static void ZBufferCalcColors(ZBufferStruct *Buffer) { int x, y; IRndrColorType c, ResultColor; ZPointStruct *p; RealType t, s; if (Buffer -> UseTransparency && Buffer -> ColorsValid == FALSE) { for (y = 0; y < Buffer -> SizeY; ++y) { for (x = 0; x < Buffer -> SizeX; x++) { PT_COPY(ResultColor, Buffer -> BackgroundColor); /* The first link is always background - it has deepest Z. */ p = Buffer -> z[y][x].First.Next; while (p != NULL) { SET_REAL_FROM_COL(c, p -> Color); t = p -> Transp; s = 1 - t; ResultColor[RED_CLR] = s * c[RED_CLR] + t * ResultColor[RED_CLR]; ResultColor[GREEN_CLR] = s * c[GREEN_CLR] + t * ResultColor[GREEN_CLR]; ResultColor[BLUE_CLR] = s * c[BLUE_CLR] + t * ResultColor[BLUE_CLR]; p = p -> Next; } SET_COL_FROM_REAL(Buffer -> z[y][x].First.Color, ResultColor); } } } Buffer -> ColorsValid = TRUE; } /***************************************************************************** * DESCRIPTION: * * Routine to test little vs. big endian style of packing bytes. * * Test is done by placing a none zero byte into the first place of a zero * * integer. * * * * PARAMETERS: * * None * * * * RETURN VALUE: * * int: TRUE/FALSE for little/big endian style. * *****************************************************************************/ static int ThisLittleEndianHardware(void) { STATIC_DATA int Style = -1; if (Style < 0) { int i = 0; char *c = (char *) &i; *c = 1; /* i == 16777216 on HPUX, SUN, SGI etc. */ /* i == 1 on IBM PC based systems (OS2/Windows NT). */ Style = i == 1; } return Style; } /***************************************************************************** * DESCRIPTION: M * Saves the context of the z-buffer into a file r. M * * * PARAMETERS: M * Buffer: IN, OUT, pointer to the z-buffer. M * BaseDirectory: IN, the directory where the file is to be saved. M * OutFileName: IN, the file name. M * FileType: IN, the file type. M * DataType: IN, where to save color/z-depth/stencil data. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * ZBufferSaveFile, save, persist M *****************************************************************************/ void ZBufferSaveFile(ZBufferStruct *Buffer, char *BaseDirectory, char *OutFileName, char *FileType, ZBufferDataType DataType) { int x, y, SizeX, SizeY, SuperSize, OldAccessMode = Buffer -> AccessMode; IRndrColorType Color, *Colors = Buffer -> LineColors; char *ImageTypeStr; ByteType *Alpha = Buffer -> LineAlpha; IrtImgPixelStruct *Pixels = Buffer -> LinePixels; ImageTypeStr = FileType ? FileType : (OutFileName ? strrchr(OutFileName, '.') + 1 : "ppm"); SuperSize = Buffer -> Filter ? Buffer -> Filter -> SuperSize : 1; SizeX = Buffer -> TargetSizeX; SizeY = Buffer -> TargetSizeY; Buffer -> AccessMode = ZBUFFER_ACCESS_FILTERED; if (DataType == ZBUFFER_DATA_COLOR) ZBufferCalcColors(Buffer); if (IrtImgWriteSetType(ImageTypeStr) == IRIT_IMAGE_UNKNOWN_TYPE) _IRndrReportFatal(IRIT_EXP_STR("Image type \"%s\" is unknown."), ImageTypeStr); if (!IrtImgWriteOpenFile(&BaseDirectory, OutFileName, TRUE, Buffer -> TargetSizeX, Buffer -> TargetSizeY)) _IRndrReportFatal(IRIT_EXP_STR("Failed to open output image file \"%s\"."), OutFileName); for (y = 0; y < SizeY; y++) { if ((DataType == ZBUFFER_DATA_COLOR) && (Buffer -> Filter)) { ZBufferGetLineColor(Buffer, 0, Buffer -> TargetSizeX, y, Colors); } for (x = 0; x < SizeX; x++) { if (DataType == ZBUFFER_DATA_COLOR) { if (Buffer -> Filter) { PT_COPY(&Color, Colors[x]); } else { SET_REAL_FROM_COL(Color, Buffer -> z[y][x].First.Color); } if (Buffer -> ColorQuantization > 0) { int cq = Buffer -> ColorQuantization; Color[RED_CLR] = COLOR_QUANTIZE(Color[RED_CLR], cq); Color[GREEN_CLR] = COLOR_QUANTIZE(Color[GREEN_CLR], cq); Color[BLUE_CLR] = COLOR_QUANTIZE(Color[BLUE_CLR], cq); } Pixels[x].r = REAL_TO_BYTE(Color[RED_CLR]); Pixels[x].g = REAL_TO_BYTE(Color[GREEN_CLR]); Pixels[x].b = REAL_TO_BYTE(Color[BLUE_CLR]); Alpha[x] = Buffer -> z[y * SuperSize][x * SuperSize].Stencil > 0 ? 0xff : 0; } /* Stencil or depth. */ else { float DataZ; char *Bytes; int i, DataI, Len = 0; if (DataType == ZBUFFER_DATA_ZDEPTH) { DataZ = (float) (Buffer -> z[y * SuperSize][x * SuperSize].First.z); Bytes = (char *) &DataZ; Len = sizeof(DataZ); } else { DataI = (int) (Buffer -> z[y * SuperSize][x * SuperSize].Stencil); Bytes = (char *) &DataI; Len = sizeof(DataI); } if (ThisLittleEndianHardware()) { i = 0; Pixels[x].r = i < Len ? Bytes[i++] : 0; Pixels[x].g = i < Len ? Bytes[i++] : 0; Pixels[x].b = i < Len ? Bytes[i++] : 0; Alpha[x] = i < Len ? Bytes[i++] : 0; } else { i = Len - 1; Pixels[x].r = i >= 0 ? Bytes[i--] : 0; Pixels[x].g = i >= 0 ? Bytes[i--] : 0; Pixels[x].b = i >= 0 ? Bytes[i--] : 0; Alpha[x] = i >= 0 ? Bytes[i--] : 0; } } } IrtImgWritePutLine(Alpha, Pixels); } Buffer -> AccessMode = OldAccessMode; IrtImgWriteCloseFile(); } /***************************************************************************** * DESCRIPTION: * * For a polygon point on the current scan line, allocates and inserts into * * sorted list data structure element describing it. It is used when trans- * * parancy mode is on to store information about all polygons owning the * * same point on the scan line. * * * * PARAMETERS: * * Buffer: IN OUT, pointer to the z-buffer. * * x: IN, cloumn number. * * y: IN, row number. * * i: IN, interpolation value for the point. * * * * RETURN VALUE: * * ZPointStruct * : the newly created point. * *****************************************************************************/ static ZPointStruct *AddPoint(ZBufferStruct *Buffer, int x, int y, InterpolStruct *i) { ZPointStruct *New, *p; ZListStruct *z = &Buffer -> z[y][x]; /* Find the place in sorted list. */ if (Buffer -> ZPol) { for (p = &z -> First; p -> Next != NULL && Buffer -> ZPol(x, y, p -> Next -> z, i -> z); p = p -> Next); } else { for (p = &z -> First; p -> Next != NULL && (i -> z NEAR_THAN p -> Next -> z); p = p -> Next); } New = FastAllocNew(Buffer -> PointsAlloc); New -> Next = p -> Next; p -> Next = New; return New; } /***************************************************************************** * DESCRIPTION: M * Retrives color information of a specific line. M * The line should be allocated by the caller. M * * * PARAMETERS: M * Buffer: IN, OUT, pointer to the z-buffer M * x0: IN, minimal x coordinate. M * x1: IN, maximal x coordinate. M * y: IN, line number. M * Result: OUT, the color values of the line. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * ZBufferGetLineColor, color access M *****************************************************************************/ void ZBufferGetLineColor(ZBufferStruct *Buffer, int x0, int x1, int y, IRndrColorType *Result) { int x, SizeX, SizeY; IRndrColorType Color; ZBufferCalcColors(Buffer); if (!Buffer -> Filter || Buffer -> AccessMode == ZBUFFER_ACCESS_RAW) { for (x = x0; x < x1; x++, Result++) { SET_REAL_FROM_COL(*Result, Buffer -> z[y][x].First.Color); } } else { int SuperSize = Buffer -> Filter -> SuperSize; RealType **Filter = Buffer -> Filter -> FilterData; for (x = x0; x < x1; x++, Result++) { PT_RESET(*Result); for (SizeY = 0; SizeY < SuperSize; SizeY++) { for (SizeX = 0; SizeX < SuperSize; SizeX++) { SET_REAL_FROM_COL(Color, Buffer -> z[y*SuperSize + SizeY] [x*SuperSize + SizeX].First.Color); PT_SCALE(Color, Filter[SizeY][SizeX]); PT_ADD(*Result, *Result, Color); } } } } } /***************************************************************************** * DESCRIPTION: M * Retrives z information of a specific line. M * The line should be allocated by the caller. M * * * PARAMETERS: M * Buffer: IN, OUT, pointer to the z-buffer M * x0: IN, minimal x coordinate. M * x1: IN, maximal x coordinate. M * y: IN, line number. M * Result: OUT, the z values of the line. M * * * RETURN VALUE: M * int: whether operation succeded. M * * * KEYWORDS: M * ZBufferGetLineDepth, z depth access M *****************************************************************************/ int ZBufferGetLineDepth(ZBufferStruct *Buffer, int x0, int x1, int y, RealType *Result) { int x, SizeX, SizeY; if (Buffer -> UseTransparency) return 0; if (!Buffer -> Filter || Buffer -> AccessMode == ZBUFFER_ACCESS_RAW) { for (x = x0; x < x1; x++, Result++) { *Result = Buffer -> z[y][x].First.z; } } else { /* Compute average of supersampled points. */ int SuperSize = Buffer -> Filter -> SuperSize; RealType **Filter = Buffer -> Filter -> FilterData; for (x = x0; x < x1; x++, Result++) { *Result = 0; for (SizeY = 0; SizeY < SuperSize; SizeY++) { for (SizeX = 0; SizeX < SuperSize; SizeX++) { *Result += Buffer -> z[y*SuperSize + SizeY] [x*SuperSize + SizeX].First.z * Filter[SizeY][SizeX]; } } } } return 1; } /***************************************************************************** * DESCRIPTION: M * Retrives stencil information of a specific line. M * The line should be allocated by the caller. M * * * PARAMETERS: M * Buffer: IN, OUT, pointer to the z-buffer. M * x0: IN, minimal x coordinate. M * x1: IN, maximal x coordinate. M * y: IN, line number. M * Result: OUT, the stencil values of the line. M * * * RETURN VALUE: M * int: whether operation succeded. M * * * KEYWORDS: M * ZBufferGetLineStencil, stencil access M *****************************************************************************/ int ZBufferGetLineStencil(ZBufferStruct *Buffer, int x0, int x1, int y, int *Result) { int x, SizeX, SizeY, Stencil; if (!Buffer -> Filter || Buffer -> AccessMode == ZBUFFER_ACCESS_RAW) { for (x = x0; x < x1; x++, Result++) { *Result = Buffer -> z[y][x].Stencil; } } else { /* Compute maximum of super sampled points. */ int SuperSize = Buffer -> Filter -> SuperSize; RealType **Filter = Buffer -> Filter -> FilterData; for (x = x0; x < x1; x++, Result++) { *Result = 0; for (SizeY = 0; SizeY < SuperSize; SizeY++) { for (SizeX = 0; SizeX < SuperSize; SizeX++) { Stencil = Buffer -> z[y*SuperSize + SizeY] [x*SuperSize + SizeX].Stencil; if (Stencil > *Result) { *Result = Stencil; } } } } } return 1; } /***************************************************************************** * DESCRIPTION: M * Routine to set the filter before any antialias M * processing could be done. M * * * PARAMETERS: M * Buffer: Pointer to the z-buffer. M * FilterName: String representing the filter name. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * ZBufferSetFilter, antialias, AntialiasLine, Utah filter package M *****************************************************************************/ void ZBufferSetFilter(ZBufferStruct *Buffer, char *FilterName) { int i, j, SuperSize; RealType x, y, r; Filt *f; if (!FilterName || !Buffer -> Filter ) return; SuperSize = Buffer -> Filter -> SuperSize; if (!(f = filt_find(FilterName))) { f = filt_find(FilterName = "sinc"); _IRndrReportWarning(IRIT_EXP_STR("unknown filter name, %s used\n"), FilterName); } Buffer -> Filter -> FilterData = MALLOC(RealType *, SuperSize); for (i = 0; i < SuperSize; i++) { Buffer -> Filter -> FilterData[i] = MALLOC(RealType, SuperSize); } Buffer -> Filter -> TotalWeight = 0; if (f -> windowme) { f -> supp = 1; f = filt_window(f, "hanning"); } r = f -> supp / M_SQRT2; for (i = 0; i < SuperSize; i++) { y = (i + 1) * 2 * r / (SuperSize + 1) - r; for (j = 0; j < SuperSize; j++) { x = (j + 1) * 2 * r / (SuperSize + 1) - r; Buffer -> Filter -> TotalWeight += (Buffer -> Filter -> FilterData[i][j] = filt_func(f, (sqrt(SQR(y) + SQR(x))))); } } for (i = 0; i < SuperSize; i++) { for (j = 0; j < SuperSize; j++) { Buffer -> Filter -> FilterData[i][j] /= Buffer -> Filter -> TotalWeight; /* Normalize the filter.*/ } } } /***************************************************************************** * DESCRIPTION: M * Routine to clear the z depth information M * * * PARAMETERS: M * Buffer: Pointer to the z-buffer. M * ClearZ: Depth to clear the ZBuffer to. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * ZBufferClearDepth, Z coordinate, depth, clear M *****************************************************************************/ void ZBufferClearDepth(ZBufferStruct *Buffer, IRndrZDepthType ClearZ) { int x, y; for (y = 0; y < Buffer -> SizeY; y++) { for (x = 0; x < Buffer -> SizeX; x++) { Buffer -> z[y][x].First.z = ClearZ; } } } /***************************************************************************** * DESCRIPTION: M * Routine to clear the Stencil information M * * * PARAMETERS: M * Buffer: Pointer to the z-buffer. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * ZBufferClearStencil, clear, Stencil M *****************************************************************************/ void ZBufferClearStencil(ZBufferStruct *Buffer) { int x, y; for (y = 0; y < Buffer -> SizeY; y++) { for (x = 0; x < Buffer -> SizeX; x++) { Buffer -> z[y][x].Stencil = 0; } } } /***************************************************************************** * DESCRIPTION: M * Routine to clear the color information. M * * * PARAMETERS: M * Buffer: Pointer to the z-buffer. M * * * RETURN VALUE: M * void M * * * KEYWORDS: M * ZBufferClearColor, clear, background, color, reset M *****************************************************************************/ void ZBufferClearColor(ZBufferStruct *Buffer) { int x, y; IRndrColorType bg; PT_COPY(bg, Buffer -> BackgroundColor); for (y = 0; y < Buffer -> SizeY; y++) { for (x = 0; x < Buffer -> SizeX; x++) { PT_COPY(Buffer -> z[y][x].First.Color, bg); } } } /***************************************************************************** * DESCRIPTION: * * Increments all interpolation values and coordinate of intersection * * with respect to the next scan line. * * * * PARAMETERS: * * PEdge: IN, pointer to the polygon edge on the current scan-line. * * * * RETURN VALUE: * * void * *****************************************************************************/ static void PolyEdgeIncr(EdgeStruct *PEdge) { int Sign = SIGN(PEdge -> dx), Numerator = abs(PEdge -> dx), Denumerator = PEdge -> dy; InterpolIncr(&PEdge -> Value, &PEdge -> dValue); if (Numerator < Denumerator) { /* Slope is > 1. */ PEdge -> Inc += Numerator; } else { if (Denumerator != 0) { PEdge -> x += PEdge -> dx / Denumerator; PEdge -> Inc += Numerator % Denumerator; } } if (PEdge -> Inc > Denumerator) { PEdge -> x += Sign; PEdge -> Inc -= Denumerator; } }