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 // This is the portion of Pixie that draws a point into the stochastic 26 27 28 int i; 29 const int *bounds = grid->bounds; 30 const float *vertices = grid->vertices; 31 const float *sizes = grid->sizes; 32 const int xres = sampleWidth - 1; 33 const int yres = sampleHeight - 1; 34 35 36 /////////////////////////////////////////////////////////////////////////////////////////// 37 // 38 // Here're some macros that make the rasterization job easier for us 39 // 40 /////////////////////////////////////////////////////////////////////////////////////////// 41 42 // Shade _very_ early if we know we are guaranteed to have to anyway 43 // Points are always facing the screen, so there's no point checking if 44 // they're visible before deciding to shade if RASTER_SHADE_HIDDEN is true 45 46 #ifdef STOCHASTIC_UNSHADED 47 #ifdef STOCHASTIC_UNDERCULL 48 if (grid->flags & RASTER_SHADE_HIDDEN) { 49 shadeGrid(grid,FALSE); 50 rasterDrawPrimitives(grid); 51 return; 52 } 53 #endif 54 #endif 55 56 57 #ifdef STOCHASTIC_EXTRA_SAMPLES 58 #define displacement (10 + CRenderer::numExtraSamples) 59 #else 60 #define displacement 10 61 #endif 62 63 64 65 /////////////////////////////////////////////////////////////////////////////////////////// 66 // This macro checks the pixel LOD against the object LOD level 67 #ifdef STOCHASTIC_LOD 68 const float importance = grid->object->attributes->lodImportance; 69 70 #define lodCheck() \ 71 if (importance >= 0) { \ 72 if (pixel->jimp > importance) continue; \ 73 } else { \ 74 if ((1-pixel->jimp) >= -importance) continue; \ 75 } 76 #else 77 #define lodCheck() 78 #endif 79 80 81 82 83 ////////////////////////////////////////////////////////////////////////////////////////// 84 // The following macro is used to draw extra samples for each pixels if any 85 #ifdef STOCHASTIC_EXTRA_SAMPLES 86 87 #ifdef STOCHASTIC_MOVING 88 #define drawExtraSamples() { \ 89 int currentSample; \ 90 const float *s0 = v0+10; \ 91 float *dest; \ 92 \ 93 for (dest=nSample->extraSamples,currentSample=CRenderer::numExtraSamples;currentSample>0;currentSample--,s0++) { \ 94 *dest++ = (s0[0]*(1-jt)+s0[displacement]*jt); \ 95 } \ 96 } 97 98 #else 99 #define drawExtraSamples() { \ 100 int currentSample; \ 101 const float *s0 = v0+10; \ 102 float *dest; \ 103 \ 104 for (dest=nSample->extraSamples,currentSample=CRenderer::numExtraSamples;currentSample>0;currentSample--,s0++) { \ 105 *dest++ = s0[currentSample]; \ 106 } \ 107 } 108 #endif 109 110 #else 111 #define drawExtraSamples() 112 #endif 113 114 115 116 117 118 ////////////////////////////////////////////////////////////////////////////////////////// 119 // This big ass macro is for computing the final color/opacity of a pixel 120 #ifndef STOCHASTIC_TRANSPARENT 121 // Non transparent 122 #ifndef STOCHASTIC_MOVING 123 // Non Moving 124 #ifndef STOCHASTIC_MATTE 125 // Non Matte 126 #define colorOpacityUpdate() \ 127 movvv(nSample->color,v0 + 3); \ 128 initv(nSample->opacity,1); 129 #else 130 // Matte 131 #define colorOpacityUpdate() \ 132 initv(nSample->color,0); \ 133 initv(nSample->opacity,-1); \ 134 initv(pixel->first.opacity,-1); 135 #endif 136 #else 137 // Moving 138 #ifndef STOCHASTIC_MATTE 139 // Non Matte 140 #define colorOpacityUpdate() \ 141 interpolatev(nSample->color,v0+3,v0+3+displacement,jt); \ 142 initv(nSample->opacity,1); 143 #else 144 // Matte 145 #define colorOpacityUpdate() \ 146 initv(nSample->color,0); \ 147 initv(nSample->color,-1); \ 148 initv(pixel->first.opacity,-1); 149 #endif 150 #endif 151 #else 152 // Transparent 153 #ifndef STOCHASTIC_MOVING 154 // Non Moving 155 #ifndef STOCHASTIC_MATTE 156 // Non Matte 157 #define colorOpacityUpdate() \ 158 movvv(nSample->color,v0+3); \ 159 movvv(nSample->opacity,v0+6); 160 #else 161 // Matte 162 #define colorOpacityUpdate() \ 163 initv(nSample->color,0); \ 164 initv(nSample->opacity,0); \ 165 subvv(nSample->opacity,v0+6); \ 166 movvv(pixel->first.opacity,nSample->opacity); 167 #endif 168 #else 169 // Moving 170 #ifndef STOCHASTIC_MATTE 171 // Non Matte 172 #define colorOpacityUpdate() \ 173 interpolatev(nSample->color,v0+3,v0+3+displacement,jt); \ 174 interpolatev(nSample->opacity,v0+6,v0+6+displacement,jt); 175 #else 176 // Matte 177 #define colorOpacityUpdate() \ 178 initv(nSample->color,0); \ 179 interpolatev(nSample->opacity,v0+6,v0+6+displacement,jt); \ 180 nSample->opacity[0] = -nSample->opacity[0]; \ 181 nSample->opacity[1] = -nSample->opacity[1]; \ 182 nSample->opacity[2] = -nSample->opacity[2]; \ 183 movvv(pixel->first.opacity,nSample->opacity); 184 #endif 185 #endif 186 #endif 187 188 #ifndef STOCHASTIC_TRANSPARENT 189 // Non Transparent 190 #ifndef STOCHASTIC_MOVING 191 // Non Moving 192 #define drawPixel() \ 193 if (z < pixel->z) { \ 194 updateOpaque(); \ 195 nSample = &pixel->last; \ 196 nSample->z = z; \ 197 colorOpacityUpdate(); \ 198 drawExtraSamples(); \ 199 depthFilterIf(); \ 200 pixel->z = z; \ 201 depthFilterTouchNode(); \ 202 } depthFilterElse(); 203 204 205 #else 206 // Moving 207 #define drawPixel() \ 208 if (z < pixel->z) { \ 209 updateOpaque(); \ 210 nSample = &pixel->last; \ 211 nSample->z = z; \ 212 colorOpacityUpdate(); \ 213 drawExtraSamples(); \ 214 depthFilterIf(); \ 215 pixel->z = z; \ 216 depthFilterTouchNode(); \ 217 } depthFilterElse(); 218 219 #endif 220 221 222 #else 223 // Transparent 224 #ifndef STOCHASTIC_MOVING 225 // Non Moving 226 #define drawPixel() \ 227 if (z < pixel->z) { \ 228 findSample(nSample,z); \ 229 nSample->z = z; \ 230 colorOpacityUpdate(); \ 231 drawExtraSamples(); \ 232 updateTransparent(depthFilterIf,depthFilterElse); \ 233 } 234 235 236 #else 237 // Moving 238 #define drawPixel() \ 239 if (z < pixel->z) { \ 240 findSample(nSample,z); \ 241 nSample->z = z; \ 242 colorOpacityUpdate(); \ 243 drawExtraSamples(); \ 244 updateTransparent(depthFilterIf,depthFilterElse); \ 245 } 246 247 #endif 248 249 250 #endif 251 252 253 ////////////////////////////////////////////////////////////////////////////////////////// 254 // These macros decide whether we should draw a guad or not 255 #ifdef STOCHASTIC_UNSHADED 256 // We're not shaded yet, so if we pass the depth test, we need to back and shade the grid 257 // Note: we dealt with RASTER_SHADE_HIDDEN very early, no need to do so here 258 #define drawPixelCheck() \ 259 if (z < pixel->z) { \ 260 shadeGrid(grid,FALSE); \ 261 rasterDrawPrimitives(grid); \ 262 return; \ 263 } depthFilterElse(); 264 #else 265 #define drawPixelCheck() \ 266 CFragment *nSample; \ 267 drawPixel(); 268 #endif 269 270 271 /////////////////////////////////////////////////////////////////////////////////////////// 272 // 273 // Here's the code that actually iterates over the quads and draws them 274 // 275 /////////////////////////////////////////////////////////////////////////////////////////// 276 277 // Iterate over every quad 278 for (i=grid->numVertices;i>0;i--,vertices+=numVertexSamples,bounds+=4,sizes+=2) { 279 280 // Trivial rejects 281 if (bounds[1] < left) continue; 282 if (bounds[3] < top) continue; 283 if (bounds[0] >= right) continue; 284 if (bounds[2] >= bottom) continue; 285 286 int xmin = bounds[0] - left; // Convert the bound into the current bucket 287 int ymin = bounds[2] - top; 288 int xmax = bounds[1] - left; 289 int ymax = bounds[3] - top; 290 291 xmin = max(xmin,0); // Clamp the bound in the current bucket 292 ymin = max(ymin,0); 293 xmax = min(xmax,xres); 294 ymax = min(ymax,yres); 295 296 const float *v0 = vertices; 297 int x,y; 298 for (y=ymin;y<=ymax;y++) { 299 for (x=xmin;x<=xmax;x++) { 300 CPixel *pixel = fb[y]+x; 301 302 lodCheck(); 303 304 const float xcent = pixel->xcent; 305 const float ycent = pixel->ycent; 306 307 308 #ifdef STOCHASTIC_MOVING 309 const float jt = pixel->jt; 310 vector v0movTmp; 311 interpolatev(v0movTmp,v0,(v0+displacement),jt); 312 v0 = v0movTmp; 313 const float size = sizes[0]*(1-jt) + sizes[1]*jt; 314 #else 315 const float size = sizes[0]; 316 #endif 317 318 #ifdef STOCHASTIC_FOCAL_BLUR 319 vector v0focTmp; 320 v0focTmp[COMP_X] = v0[COMP_X] + pixel->jdx*vertices[9]; 321 v0focTmp[COMP_Y] = v0[COMP_Y] + pixel->jdy*vertices[9]; 322 v0focTmp[COMP_Z] = v0[COMP_Z]; 323 v0 = v0focTmp; 324 #endif 325 326 const float dx = xcent - v0[0]; 327 const float dy = ycent - v0[1]; 328 329 v0 = vertices; 330 331 if ((dx*dx + dy*dy) < (size*size)) { 332 const float z = v0[2]; 333 334 drawPixelCheck(); 335 } 336 } 337 } 338 } 339 340 341 342 #undef lodCheck 343 #undef drawPixelCheck 344 #undef drawPixel 345 #undef drawExtraSamples 346 #undef displacement 347 #undef colorOpacityUpdate 348 349