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 quad into the zbuffer 26 int i,j; 27 const int *bounds = grid->bounds; 28 const float *vertices = grid->vertices; 29 const int xres = sampleWidth - 1; 30 const int yres = sampleHeight - 1; 31 const int udiv = grid->udiv; 32 const int vdiv = grid->vdiv; 33 const int flags = grid->flags; 34 35 36 37 // Iterate over every quad 38 for (j=0;j<vdiv;j++) { 39 for (i=0;i<udiv;i++,bounds+=4,vertices+=numVertexSamples) { 40 41 // Trivial rejects 42 if (bounds[1] < left) continue; 43 if (bounds[3] < top) continue; 44 if (bounds[0] >= right) continue; 45 if (bounds[2] >= bottom) continue; 46 47 // Extract the quad corners 48 const float *v0 = vertices; 49 const float *v1 = vertices + numVertexSamples; 50 const float *v2 = v1 + udiv*numVertexSamples; 51 const float *v3 = v2 + numVertexSamples; 52 53 int xmin = bounds[0] - left; // Convert the bound into the current bucket 54 int ymin = bounds[2] - top; 55 int xmax = bounds[1] - left; 56 int ymax = bounds[3] - top; 57 58 xmin = max(xmin,0); // Clamp the bound in the current bucket 59 ymin = max(ymin,0); 60 xmax = min(xmax,xres); 61 ymax = min(ymax,yres); 62 63 64 // This macro is used to check whether the sample is inside the quad or not 65 #define checkPixel(__op) \ 66 float aleft,atop,aright,abottom; \ 67 \ 68 if ((atop = area(xcent,ycent,v0[COMP_X],v0[COMP_Y],v1[COMP_X],v1[COMP_Y])) __op 0) continue; \ 69 if ((aright = area(xcent,ycent,v1[COMP_X],v1[COMP_Y],v3[COMP_X],v3[COMP_Y])) __op 0) continue; \ 70 if ((abottom = area(xcent,ycent,v3[COMP_X],v3[COMP_Y],v2[COMP_X],v2[COMP_Y])) __op 0) continue; \ 71 if ((aleft = area(xcent,ycent,v2[COMP_X],v2[COMP_Y],v0[COMP_X],v0[COMP_Y])) __op 0) continue; \ 72 \ 73 const float u = aleft / (aleft + aright); \ 74 const float v = atop / (atop + abottom); \ 75 const float z = (v0[COMP_Z]*(1-u) + v1[COMP_Z]*u)*(1-v) + (v2[COMP_Z]*(1-u) + v3[COMP_Z]*u)*v; 76 77 78 #define recordPixel() \ 79 float *sample = &fb[y][x*SAMPLES_PER_PIXEL]; \ 80 if (z < sample[0] || (flags & RASTER_SHADE_HIDDEN)) { \ 81 if (z > CRenderer::clipMin) { \ 82 if (flags & RASTER_UNSHADED) { \ 83 shadeGrid(grid,FALSE); \ 84 rasterDrawPrimitives(grid); \ 85 return; \ 86 } \ 87 \ 88 sample[0] = z; \ 89 if (flags & RASTER_MATTE ) { \ 90 initv(sample,0); \ 91 } else { \ 92 sample[1] = (v0[3]*(1-u) + v1[3]*u)*(1-v) + (v2[3]*(1-u) + v3[3]*u)*v; \ 93 sample[2] = (v0[4]*(1-u) + v1[4]*u)*(1-v) + (v2[4]*(1-u) + v3[4]*u)*v; \ 94 sample[3] = (v0[5]*(1-u) + v1[5]*u)*(1-v) + (v2[5]*(1-u) + v3[5]*u)*v; \ 95 } \ 96 \ 97 COcclusionNode *cNode = getNode(x,y); \ 98 \ 99 touchNode(cNode,z); \ 100 } \ 101 } 102 103 104 105 float a = area(v0[COMP_X],v0[COMP_Y],v1[COMP_X],v1[COMP_Y],v2[COMP_X],v2[COMP_Y]); 106 if (fabsf(a) < C_EPSILON) a = area(v1[COMP_X],v1[COMP_Y],v3[COMP_X],v3[COMP_Y],v2[COMP_X],v2[COMP_Y]); 107 if (a > 0) { 108 109 if (flags & (RASTER_DRAW_BACK | RASTER_SHADE_BACKFACE)) { 110 111 float xcent,ycent; 112 int x,y; 113 for ( ycent=top+ ymin+0.5001011f,y=ymin;y<=ymax;y++,ycent++) { 114 for ( xcent=left+ xmin+0.5001011f,x=xmin;x<=xmax;x++,xcent++) { 115 116 checkPixel(<); 117 118 recordPixel(); 119 120 } 121 } 122 } 123 } else { 124 if (flags & (RASTER_DRAW_FRONT | RASTER_SHADE_BACKFACE)) { 125 126 float xcent,ycent; 127 int x,y; 128 for ( ycent=top+ ymin+0.5001011f,y=ymin;y<=ymax;y++,ycent++) { 129 for ( xcent=left+ xmin+0.5001011f,x=xmin;x<=xmax;x++,xcent++) { 130 131 checkPixel(>); 132 133 recordPixel(); 134 } 135 } 136 } 137 } 138 139 140 } 141 142 vertices += numVertexSamples; 143 } 144 145