1 ////////////////////////////////////////////////////////////////////// 2 // 3 // Pixie 4 // 5 // Copyright � 1999 - 2003, Okan Arikan 6 // 7 // Contact: okan@cs.utexas.edu 8 // 9 // This library is free software; you can redistribute it and/or 10 // modify it under the terms of the GNU Lesser General Public 11 // License as published by the Free Software Foundation; either 12 // version 2.1 of the License, or (at your option) any later version. 13 // 14 // This library is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 // Lesser General Public License for more details. 18 // 19 // You should have received a copy of the GNU Lesser General Public 20 // License along with this library; if not, write to the Free Software 21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 // 23 /////////////////////////////////////////////////////////////////////// 24 /////////////////////////////////////////////////////////////////////// 25 // 26 // File : reyes.h 27 // Classes : CReyes 28 // Description : The rasterizer class 29 // 30 //////////////////////////////////////////////////////////////////////// 31 #ifndef REYES_H 32 #define REYES_H 33 34 #include "common/global.h" 35 #include "shading.h" 36 #include "object.h" 37 #include "renderer.h" 38 #include "ri_config.h" 39 40 // Note: 41 // The low bits are spliced with the zfilter mode and used to dispatch in stochastic hider 42 // high bits are used in the primitive rasterization code to modify behavior 43 44 const unsigned int RASTER_MOVING = 1 << 0; // The primitive is moving 45 const unsigned int RASTER_TRANSPARENT = 1 << 1; // The primitive is transparent 46 const unsigned int RASTER_POINT = 1 << 2; // The primitive is a point 47 const unsigned int RASTER_UNSHADED = 1 << 3; // The primitive has not been shaded (only displaced) 48 const unsigned int RASTER_FOCALBLUR = 1 << 4; // The primitive has focalblur 49 const unsigned int RASTER_EXTRASAMPLES = 1 << 5; // The primitive has extra samples to compute 50 const unsigned int RASTER_MATTE = 1 << 6; // The primitive is a matte 51 const unsigned int RASTER_LOD = 1 << 7; // The primitive has LOD 52 const unsigned int RASTER_UNDERCULL = 1 << 8; // The primitive requires underculling 53 const unsigned int RASTER_XTREME = 1 << 9; // The primitive has extreme motion blur/depth of field 54 const unsigned int RASTER_GLOBAL_MASK = (1 << 10) - 1;// This mask is used to block the lower fields 55 56 const unsigned int RASTER_HIGHBITS_SHIFT = 10; // The shift needed to put bits in the higher fields 57 const unsigned int RASTER_DEPTHFILT_MASK = 1; 58 59 const unsigned int RASTER_DRAW_FRONT = 1 << 10; // Draw the front of the primitive 60 const unsigned int RASTER_DRAW_BACK = 1 << 11; // Draw the back of the primitive 61 const unsigned int RASTER_SHADE_HIDDEN = 1 << 12; // Shade the primitive even if occluded 62 const unsigned int RASTER_SHADE_BACKFACE = 1 << 13; // Shade the primitive even if backfacing 63 64 65 /////////////////////////////////////////////////////////////////////// 66 // Class : CReyes 67 // Description : This class is implementes a REYES like scan 68 // line renderer 69 // Comments : 70 class CReyes : public CShadingContext { 71 protected: 72 73 /////////////////////////////////////////////////////////////////////// 74 // Class : CRasterPatch 75 // Description : Holds an object associated with a bucket 76 // Comments : The same instance of this class may be associated with multiple buckets in multiple threads 77 class CRasterObject { 78 public: 79 CObject *object; // The object 80 CRasterObject **next; // The next object (one for each thread) 81 int refCount; // The number of threads working on this object 82 int diced; // TRUE if this object has already been diced 83 int grid; // TRUE if this is a grid 84 int cached; // TRUE if this is a cached object 85 86 int xbound[2],ybound[2]; // The bound of the object on the screen, in samples 87 float zmin; // The minimum z coordinate of the object (used for occlusion culling) 88 TMutex mutex; // To secure the object 89 90 }; 91 92 /////////////////////////////////////////////////////////////////////// 93 // Class : CRasterGrid 94 // Description : This class encapsulates a shading grid 95 // line renderer 96 // Comments : 97 class CRasterGrid : public CRasterObject { 98 public: 99 float *vertices; // Array of vertices 100 int *bounds; // The bound of the primitive (4 numbers per primitive) 101 float *sizes; // The size of the primitive (only makes sense for points) 102 EShadingDim dim; // Dimensionality (0,1 or 2) 103 float umin,umax,vmin,vmax; // The parametric range 104 int udiv,vdiv; // The number of division 105 int numVertices; // The number of vertices 106 int flags; // The primitive flags 107 }; 108 109 110 /////////////////////////////////////////////////////////////////////// 111 // Class : CPqueue 112 // Description : Priority queue specifically written for CRasterObject 113 // Comments : I could have used the template in containers.h, but this one allows me to defer objects directly 114 class CPqueue { 115 public: 116 CPqueue(int ss=100) { 117 stepSize = ss; 118 maxItems = stepSize; 119 numItems = 1; 120 allItems = new CRasterObject*[maxItems]; 121 } 122 ~CPqueue()123 ~CPqueue() { 124 delete [] allItems; 125 } 126 insert(CRasterObject * cObject)127 void insert(CRasterObject *cObject) { 128 int i,j; 129 130 // Expand the buffer 131 if (numItems >= maxItems) { 132 CRasterObject **newItems; 133 maxItems += stepSize; 134 newItems = new CRasterObject*[maxItems+1]; 135 memcpy(newItems,allItems,numItems*sizeof(CRasterObject*)); 136 delete [] allItems; 137 allItems = newItems; 138 stepSize *= 2; 139 } 140 141 // Insert the item 142 i = numItems++; 143 j = i >> 1; 144 while ((i > 1) && (cObject->zmin < allItems[j]->zmin)) { 145 allItems[i] = allItems[j]; 146 i = j; 147 j = i >> 1; 148 149 } 150 151 allItems[i] = cObject; 152 } 153 get(TMutex & mutex)154 CRasterObject *get(TMutex &mutex) { 155 int i = 1, j; 156 CRasterObject *lItem,*cItem; 157 158 osLock(mutex); 159 160 if (numItems <= 1) { 161 cItem = NULL; 162 } else { 163 cItem = allItems[1]; 164 165 numItems--; 166 lItem = allItems[numItems]; 167 168 while (i <= numItems / 2) { 169 j = 2 * i; 170 if (j >= numItems) break; 171 172 if ((j < (numItems-1)) && (allItems[j]->zmin > allItems[j+1]->zmin)) 173 j++; 174 175 if (allItems[j]->zmin > lItem->zmin) 176 break; 177 178 allItems[i] = allItems[j]; 179 i = j; 180 } 181 allItems[i] = lItem; 182 } 183 184 if (cItem != NULL) osUnlock(mutex); 185 186 return cItem; 187 } 188 189 CRasterObject **allItems; // Array of the heap 190 int numItems,maxItems,stepSize; // Misc junk 191 }; 192 193 194 /////////////////////////////////////////////////////////////////////// 195 // Class : CBucket 196 // Description : Holds a bucket 197 // Comments : 198 class CBucket { 199 public: 200 CBucket(); 201 ~CBucket(); 202 203 CRasterObject *objects; // The list of objects waiting to be rendered 204 CPqueue *queue; // If this is not null, we're currently rendering this bucket 205 }; 206 207 208 public: 209 210 CReyes(int thread); 211 ~CReyes(); 212 213 // This function is called to to render 214 void renderingLoop(); 215 216 // The following functions must be overriden by the child rasterizer 217 virtual void rasterBegin(int,int,int,int,int) = 0; 218 virtual void rasterDrawPrimitives(CRasterGrid *) = 0; 219 virtual void rasterEnd(float *,int) = 0; 220 221 // The following can be called from the "dice" function to insert an object into the scene 222 void drawObject(CObject *); // Draw an object 223 void drawGrid(CSurface *,int,int,float,float,float,float); // Draw a grid 224 void drawPoints(CSurface *,int); // Draw points (RiPoints) 225 226 // Some stats 227 int numGridsRendered; 228 int numQuadsRendered; 229 int numGridsShaded; 230 int numGridsCreated; 231 int numVerticesCreated; 232 protected: 233 float maxDepth; // The maximum opaque depth in the current bucket 234 235 static int extraPrimitiveFlags; // These are the extra primitive flags 236 static int numVertexSamples; // The number of samples per pixel 237 238 void shadeGrid(CRasterGrid *,int); // Called by the child to force the shading of a grid 239 probeArea(int * xbound,int * ybound,int bw,int bh,int bl,int bt,float zmin)240 virtual int probeArea(int *xbound,int *ybound, int bw, int bh, int bl, int bt, float zmin) { 241 return TRUE; 242 } 243 244 private: 245 void copyPoints(int,float **,float *,int); // Data movement (copy P only) 246 void copySamples(int,float **,float *,int); // Data movement (copy the color + opacity + extra samples) 247 248 void insertObject(CRasterObject *object); // Add an object into the system 249 void insertGrid(CRasterGrid *,int); // Insert a grid into the correct bucket 250 251 CRasterObject *newObject(CObject *); // Create a new object 252 CRasterGrid *newGrid(CSurface *,int,int,int); // Create a new grid 253 void deleteObject(CRasterObject *); // Delete an object (the object can also be a grid) 254 255 void render(); // Render the current bucket 256 void skip(); // Skip the current bucket 257 258 CBucket ***buckets; // All buckets 259 TMutex bucketMutex; // Controls the accesses to the buckets 260 261 int bucketPixelLeft; // Left of the current bucket in pixels 262 int bucketPixelTop; // Top of the current bucket in pixels 263 int bucketPixelWidth; // Width of the current bucket in pixels 264 int bucketPixelHeight; // Height of the current bucket in pixels 265 int tbucketLeft; // Left of the current bucket in samples 266 int tbucketTop; // Right of the current bucket in samples 267 int tbucketRight; 268 int tbucketBottom; 269 270 271 /////////////////////////////////////////////////////////////////////// 272 // Class : CReyes 273 // Method : distance2samples 274 // Description : Project distances into the sample space 275 // Return Value : 276 // Comments : (inline for speed) distance2samples(int n,float * dist,float * P)277 inline void distance2samples(int n,float *dist,float *P) { 278 if(CRenderer::projection == OPTIONS_PROJECTION_PERSPECTIVE) { 279 for (;n>0;n--,P+=3,dist++) { 280 *dist = CRenderer::dSampledx*CRenderer::imagePlane*dist[0]/P[COMP_Z]; 281 } 282 } else { 283 for (;n>0;n--,P+=3,dist++) { 284 *dist = CRenderer::dSampledx*dist[0]; 285 } 286 } 287 } 288 289 /////////////////////////////////////////////////////////////////////// 290 // Class : CReyes 291 // Method : camera2samples 292 // Description : Project from camera space into the sample space 293 // Return Value : 294 // Comments : (inline for speed) camera2samples(int n,float * P)295 inline void camera2samples(int n,float *P) { 296 if(CRenderer::projection == OPTIONS_PROJECTION_PERSPECTIVE) { 297 for (;n>0;n--,P+=3) { 298 P[COMP_X] = (CRenderer::imagePlane*P[COMP_X]/P[COMP_Z] - CRenderer::pixelLeft)*CRenderer::dSampledx; 299 P[COMP_Y] = (CRenderer::imagePlane*P[COMP_Y]/P[COMP_Z] - CRenderer::pixelTop)*CRenderer::dSampledy; 300 } 301 } else { 302 for (;n>0;n--,P+=3) { 303 P[COMP_X] = (P[COMP_X] - CRenderer::pixelLeft)*CRenderer::dSampledx; 304 P[COMP_Y] = (P[COMP_Y] - CRenderer::pixelTop)*CRenderer::dSampledy; 305 } 306 } 307 } 308 309 /////////////////////////////////////////////////////////////////////// 310 // Class : CReyes 311 // Method : camera2samples 312 // Description : Project from camera space into the sample space 313 // Return Value : 314 // Comments : (inline for speed) camera2samples(float * P)315 inline void camera2samples(float *P) { 316 if(CRenderer::projection == OPTIONS_PROJECTION_PERSPECTIVE) { 317 P[COMP_X] = CRenderer::imagePlane*P[COMP_X]/P[COMP_Z]; 318 P[COMP_Y] = CRenderer::imagePlane*P[COMP_Y]/P[COMP_Z]; 319 } 320 321 P[COMP_X] = (P[COMP_X] - CRenderer::pixelLeft)*CRenderer::dSampledx; 322 P[COMP_Y] = (P[COMP_Y] - CRenderer::pixelTop)*CRenderer::dSampledy; 323 } 324 325 }; 326 327 #endif 328 329