/** * Shade/write an array of quads * Called via quad_stage::run() */ static void shade_quads(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) { struct softpipe_context *softpipe = qs->softpipe; struct tgsi_exec_machine *machine = softpipe->fs_machine; unsigned i, nr_quads = 0; tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, softpipe->mapped_constants[PIPE_SHADER_FRAGMENT], softpipe->const_buffer_size[PIPE_SHADER_FRAGMENT]); machine->InterpCoefs = quads[0]->coef; for (i = 0; i < nr; i++) { /* Only omit this quad from the output list if all the fragments * are killed _AND_ it's not the first quad in the list. * The first quad is special in the (optimized) depth-testing code: * the quads' Z coordinates are step-wise interpolated with respect * to the first quad in the list. * For multi-pass algorithms we need to produce exactly the same * Z values in each pass. If interpolation starts with different quads * we can get different Z values for the same (x,y). */ if (!shade_quad(qs, quads[i]) && i > 0) continue; /* quad totally culled/killed */ if (/*do_coverage*/ 0) coverage_quad( qs, quads[i] ); quads[nr_quads++] = quads[i]; } if (nr_quads) qs->next->run(qs->next, quads, nr_quads); }
void shade_bmap( double x0, double y0, float data0, float data1, double z0, double z1, int negative, double dev_x, double dev_y) /* apply current samples with all options to bitmap */ { #define NPTS 4 /* 4 points for the general case here */ double xp[NPTS], yp[NPTS], temp, interp, slope01, slope02, slope12, slope13, slope23, slope03; double slope0, slope1, slope2, slope3; int ix, iy; if (data0 == 0.0 && data1 == 0.0)return; /* probably shouldn't strictly, but pathological enough I dont really want to deal with it! */ interp = 0.0; if ((data0*data1)<0.0){ /* points to plot are on different sides of zero - interpolate to find out where zero is */ interp=z0+data0*((z0-z1)/(data1-data0)); if(((data0<0.0) && negative) || ((data0>0.0)&& !negative)) { /* plot from top to zero */ z1=interp; data1=0.0; } else { z0=interp; data0=0.0; } } GMT_geoz_to_xy (x0+(double)data0*dev_x, y0+(double)data0*dev_y, z0, &xp[0], &yp[0]); /* returns 2 ends of line segment in plot coords */ GMT_geoz_to_xy (x0+(double)data1*dev_x, y0+(double)data1*dev_y, z1, &xp[1], &yp[1]); GMT_geoz_to_xy (x0, y0, z0, &xp[2], &yp[2]); /* to get position of zero at each point*/ GMT_geoz_to_xy (x0, y0, z1, &xp[3], &yp[3]); /* to get position of zero at each point*/ /* now have four corner coordinates - need to sort them */ for (ix=0; ix<NPTS-1; ix++) for (iy=ix+1; iy<NPTS; iy++) if(yp[ix]>yp[iy]){ temp = yp[iy]; yp[iy]=yp[ix]; yp[ix]=temp; temp = xp[iy]; xp[iy]=xp[ix]; xp[ix]=temp; } /* have to fill the quadrilateral defined by 4 points (now ordered, but care with degenerate cases)*/ slope01 = (xp[1]-xp[0])/(yp[1]-yp[0]); slope02 = (xp[2]-xp[0])/(yp[2]-yp[0]); slope12 = (xp[2]-xp[1])/(yp[2]-yp[1]); slope13 = (xp[3]-xp[1])/(yp[3]-yp[1]); slope23 = (xp[3]-xp[2])/(yp[3]-yp[2]); slope03 = (xp[3]-xp[0])/(yp[3]-yp[0]); if ((yp[0]!=yp[1]) && (yp[2]!=yp[3])){ /* simple case: tri-quad-tri */ shade_tri(xp[0], yp[0], yp[1], slope01, slope02); shade_quad(xp[1], yp[1],xp[0]+slope02*(yp[1]-yp[0]), yp[2], slope02, slope13); shade_tri(xp[3], yp[3], yp[2], slope13, slope23); } if ((yp[0]==yp[1]) && (yp[2]!=yp[3])){ if (xp[0]==xp[1]){ /* two triangles based on yp[1],yp[2]. yp[3] */ shade_tri(xp[1], yp[1], yp[2], slope12, slope13); shade_tri(xp[3], yp[3], yp[2], slope23, slope13); }else{ /* quad based on first 3 points, then tri */ slope0 = (((xp[0]<xp[1]) && (xp[3]<xp[2])) || ((xp[0]>xp[1])&&(xp[3]>xp[2])))*slope03 + (((xp[0]<xp[1])&&(xp[2]<xp[3])) || ((xp[0]>xp[1])&&(xp[2]>xp[3])))*slope02; slope1 = (((xp[1]<xp[0]) && (xp[3]<xp[2])) || ((xp[1]>xp[0]) && (xp[3]>xp[2])))*slope13 + (((xp[1]<xp[0])&&(xp[2]<xp[3])) || ((xp[1]>xp[0])&&(xp[2]>xp[3])))*slope12; slope3 = (((xp[1]<xp[0]) && (xp[3]<xp[2])) || ((xp[1]>xp[0]) && (xp[3]>xp[2])))*slope13 + (((xp[0]<xp[1])&&(xp[3]<xp[2])) || ((xp[0]>xp[1])&&(xp[3]>xp[2])))*slope03; shade_quad(xp[0], yp[0], xp[1], yp[2], slope0, slope1); shade_tri(xp[3], yp[3], yp[2], slope23, slope3); } } if ((yp[0]!=yp[1]) && (yp[2]==yp[3])){ if(xp[2]==xp[3]){/* two triangles based on yp[0],yp[1]. yp[2] */ shade_tri(xp[0], yp[0], yp[1], slope01, slope02); shade_tri(xp[2], yp[2], yp[1], slope12, slope02); }else{ /* triangle based on yp[0], yp[1], then quad based on last 3 points */ slope0 = (((xp[0]<xp[1]) && (xp[3]<xp[2])) || ((xp[0]>xp[1]) && (xp[3]>xp[2])))*slope03 + (((xp[0]<xp[1])&&(xp[2]<xp[3])) || ((xp[0]>xp[1])&&(xp[2]>xp[3])))*slope02; shade_tri(xp[0], yp[0], yp[1], slope01, slope0); slope2 = (((xp[0]<xp[1]) && (xp[2]<xp[3])) || ((xp[0]>xp[1]) && (xp[2]>xp[3])))*slope02 + (((xp[0]<xp[1]) && (xp[3]<xp[2])) || ((xp[0]>xp[1]) && (xp[3]>xp[2])))*slope12; slope3 = (((xp[0]<xp[1]) && (xp[3]<xp[2])) || ((xp[0]>xp[1]) && (xp[3]>xp[2])))*slope03 + (((xp[0]<xp[1]) && (xp[2]<xp[3])) || ((xp[0]>xp[1]) && (xp[2]>xp[3])))*slope13; shade_quad(xp[2], yp[2], xp[3], yp[1], slope2, slope3); } } }