////////////////////////////////////////////////////////////////////// // // Pixie // // Copyright © 1999 - 2003, Okan Arikan // // Contact: okan@cs.berkeley.edu // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // File : zbuffer.cpp // Classes : CZbuffer // Description : The cheap simple rasterizer // //////////////////////////////////////////////////////////////////////// #include #include "zbuffer.h" #include "memory.h" /////////////////////////////////////////////////////////////////////// // Sample 0 -> z // Sample 1 -> r // Sample 2 -> g // Sample 3 -> b #define SAMPLES_PER_PIXEL 4 /////////////////////////////////////////////////////////////////////// // Class : CZbuffer // Method : CZbuffer // Description : Ctor // Return Value : - // Comments : // Date last edited : 7/31/2002 CZbuffer::CZbuffer(COptions *o,CXform *x,SOCKET s) : CReyes(o,x,s,HIDER_RGBAZ_ONLY) , COcclusionCuller() { int i; totalWidth = bucketWidth*pixelXsamples + 2*xSampleOffset; totalHeight = bucketHeight*pixelYsamples + 2*ySampleOffset; // Allocate the framebuffer fb = new float*[totalHeight]; for (i=0;izmax = clipMax; } } resetHierarchy(); } /////////////////////////////////////////////////////////////////////// // Class : CZbuffer // Method : rasterDrawTriangles // Description : Draw rectangles // Return Value : - // Comments : // Date last edited : 7/31/2002 void CZbuffer::rasterDrawPrimitives(CRasterGrid *grid) { const int xres = sampleWidth-1; const int yres = sampleHeight-1; const TRasterPrimitive *cPrimitive; int numPrimitives; // Draw the suckers one by one if (grid->flags & RASTER_POINT) { for (numPrimitives=grid->numPrimitives,cPrimitive=grid->primitives;numPrimitives>0;numPrimitives--,cPrimitive++) { // Trivial rejects for points if (cPrimitive->xbound[1] < left) continue; if (cPrimitive->ybound[1] < top) continue; if (cPrimitive->xbound[0] >= right) continue; if (cPrimitive->ybound[0] >= bottom) continue; #include "zbufferPoint.h" } } else { for (numPrimitives=grid->numPrimitives,cPrimitive=grid->primitives;numPrimitives>0;numPrimitives--,cPrimitive++) { // Trivial rejects for polygons if (cPrimitive->xbound[1] < left) continue; if (cPrimitive->ybound[1] < top) continue; if (cPrimitive->xbound[0] >= right) continue; if (cPrimitive->ybound[0] >= bottom) continue; #include "zbufferTriangle.h" } } } /////////////////////////////////////////////////////////////////////// // Class : CZbuffer // Method : rasterEnd // Description : Retrieve the image // Return Value : - // Comments : // Date last edited : 7/31/2002 void CZbuffer::rasterEnd(float *fb2) { int sx,sy; int i,y; const int xres = width; const int yres = height; const int filterWidth = pixelXsamples + 2*xSampleOffset; const int filterHeight = pixelYsamples + 2*ySampleOffset; const float invPixelXsamples = 1 / (float) pixelXsamples; const float invPixelYsamples = 1 / (float) pixelYsamples; float *tmp; float *pixelFilterWeights; memBegin(); assert(numSamples == 5); for (tmp=fb2,i=xres*yres;i>0;i--) { *tmp++ = 0; *tmp++ = 0; *tmp++ = 0; *tmp++ = 0; *tmp++ = 0; } // Allocate the memory for the pixel filter pixelFilterWeights = (float *) alloca(filterHeight*filterHeight*sizeof(float)); // Evaluate the pixel filter, ignoring the jitter as it is apperently what other renderers do as well { float totalWeight = 0; double invWeight; const float halfFilterWidth = filterWidth / 2.0f; const float halfFilterHeight = filterHeight / 2.0f; for (sy=0;sy marginX) filterResponse *= marginXcoverage; //if (fabs(cy) > marginY) filterResponse *= marginYcoverage; // Record pixelFilterWeights[sy*filterWidth + sx] = filterResponse; totalWeight += filterResponse; } } // Normalize the filter kernel invWeight = 1 / (double) totalWeight; for (i=0;i