📄 s_tritemp.h
字号:
*/#ifdef SETUP_CODE SETUP_CODE#endif scan_from_left_to_right = (oneOverArea < 0.0F); /* compute d?/dx and d?/dy derivatives */#ifdef INTERP_Z span.interpMask |= SPAN_Z; { GLfloat eMaj_dz = vMax->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2]; GLfloat eBot_dz = vMid->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2]; span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth || span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) { /* probably a sliver triangle */ span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0; span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0; } else { span.attrStepY[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); } if (depthBits <= 16) span.zStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_WPOS][2]); else span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2]; }#endif#ifdef INTERP_RGB span.interpMask |= SPAN_RGBA; if (ctx->Light.ShadeModel == GL_SMOOTH) { GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]); GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]); GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]); GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]); GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]); GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]);# ifdef INTERP_ALPHA GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]); GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]);# endif span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); span.attrStepX[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); span.redStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]); span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]); span.blueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]);# ifdef INTERP_ALPHA span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); span.attrStepY[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]);# endif /* INTERP_ALPHA */ } else { ASSERT(ctx->Light.ShadeModel == GL_FLAT); span.interpMask |= SPAN_FLAT; span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F; span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F; span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F; span.redStep = 0; span.greenStep = 0; span.blueStep = 0;# ifdef INTERP_ALPHA span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepY[FRAG_ATTRIB_COL0][3] = 0.0F; span.alphaStep = 0;# endif }#endif /* INTERP_RGB */#ifdef INTERP_INDEX span.interpMask |= SPAN_INDEX; if (ctx->Light.ShadeModel == GL_SMOOTH) { GLfloat eMaj_di = vMax->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0]; GLfloat eBot_di = vMid->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0]; didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di); didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx); span.indexStep = SignedFloatToFixed(didx); } else { span.interpMask |= SPAN_FLAT; didx = didy = 0.0F; span.indexStep = 0; }#endif#ifdef INTERP_INT_TEX { GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE; GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE; GLfloat eMaj_dt = (vMax->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE; GLfloat eBot_dt = (vMid->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE; span.attrStepX[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); span.attrStepY[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); span.attrStepX[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); span.attrStepY[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][0]); span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][1]); }#endif#ifdef INTERP_ATTRIBS { /* attrib[FRAG_ATTRIB_WPOS][3] is 1/W */ const GLfloat wMax = vMax->attrib[FRAG_ATTRIB_WPOS][3]; const GLfloat wMin = vMin->attrib[FRAG_ATTRIB_WPOS][3]; const GLfloat wMid = vMid->attrib[FRAG_ATTRIB_WPOS][3]; { const GLfloat eMaj_dw = wMax - wMin; const GLfloat eBot_dw = wMid - wMin; span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); } ATTRIB_LOOP_BEGIN if (swrast->_InterpMode[attr] == GL_FLAT) { ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0); ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0); } else { GLuint c; for (c = 0; c < 4; c++) { GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin; GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin; span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); } } ATTRIB_LOOP_END }#endif /* * We always sample at pixel centers. However, we avoid * explicit half-pixel offsets in this code by incorporating * the proper offset in each of x and y during the * transformation to window coordinates. * * We also apply the usual rasterization rules to prevent * cracks and overlaps. A pixel is considered inside a * subtriangle if it meets all of four conditions: it is on or * to the right of the left edge, strictly to the left of the * right edge, on or below the top edge, and strictly above * the bottom edge. (Some edges may be degenerate.) * * The following discussion assumes left-to-right scanning * (that is, the major edge is on the left); the right-to-left * case is a straightforward variation. * * We start by finding the half-integral y coordinate that is * at or below the top of the triangle. This gives us the * first scan line that could possibly contain pixels that are * inside the triangle. * * Next we creep down the major edge until we reach that y, * and compute the corresponding x coordinate on the edge. * Then we find the half-integral x that lies on or just * inside the edge. This is the first pixel that might lie in * the interior of the triangle. (We won't know for sure * until we check the other edges.) * * As we rasterize the triangle, we'll step down the major * edge. For each step in y, we'll move an integer number * of steps in x. There are two possible x step sizes, which * we'll call the ``inner'' step (guaranteed to land on the * edge or inside it) and the ``outer'' step (guaranteed to * land on the edge or outside it). The inner and outer steps * differ by one. During rasterization we maintain an error * term that indicates our distance from the true edge, and * select either the inner step or the outer step, whichever * gets us to the first pixel that falls inside the triangle. * * All parameters (z, red, etc.) as well as the buffer * addresses for color and z have inner and outer step values, * so that we can increment them appropriately. This method * eliminates the need to adjust parameters by creeping a * sub-pixel amount into the triangle at each scanline. */ { GLint subTriangle; GLfixed fxLeftEdge = 0, fxRightEdge = 0; GLfixed fdxLeftEdge = 0, fdxRightEdge = 0; GLfixed fError = 0, fdError = 0;#ifdef PIXEL_ADDRESS PIXEL_TYPE *pRow = NULL; GLint dPRowOuter = 0, dPRowInner; /* offset in bytes */#endif#ifdef INTERP_Z# ifdef DEPTH_TYPE struct gl_renderbuffer *zrb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; DEPTH_TYPE *zRow = NULL; GLint dZRowOuter = 0, dZRowInner; /* offset in bytes */# endif GLuint zLeft = 0; GLfixed fdzOuter = 0, fdzInner;#endif#ifdef INTERP_RGB GLint rLeft = 0, fdrOuter = 0, fdrInner; GLint gLeft = 0, fdgOuter = 0, fdgInner; GLint bLeft = 0, fdbOuter = 0, fdbInner;#endif#ifdef INTERP_ALPHA GLint aLeft = 0, fdaOuter = 0, fdaInner;#endif#ifdef INTERP_INDEX GLfixed iLeft=0, diOuter=0, diInner;#endif#ifdef INTERP_INT_TEX GLfixed sLeft=0, dsOuter=0, dsInner; GLfixed tLeft=0, dtOuter=0, dtInner;#endif#ifdef INTERP_ATTRIBS GLfloat wLeft = 0, dwOuter = 0, dwInner; GLfloat attrLeft[FRAG_ATTRIB_MAX][4]; GLfloat daOuter[FRAG_ATTRIB_MAX][4], daInner[FRAG_ATTRIB_MAX][4];#endif for (subTriangle=0; subTriangle<=1; subTriangle++) { EdgeT *eLeft, *eRight; int setupLeft, setupRight; int lines; if (subTriangle==0) { /* bottom half */ if (scan_from_left_to_right) { eLeft = &eMaj; eRight = &eBot; lines = eRight->lines; setupLeft = 1; setupRight = 1; } else { eLeft = &eBot; eRight = &eMaj; lines = eLeft->lines; setupLeft = 1; setupRight = 1; } } else { /* top half */ if (scan_from_left_to_right) { eLeft = &eMaj; eRight = &eTop; lines = eRight->lines; setupLeft = 0; setupRight = 1; } else { eLeft = &eTop; eRight = &eMaj; lines = eLeft->lines; setupLeft = 1; setupRight = 0; } if (lines == 0) return; } if (setupLeft && eLeft->lines > 0) { const SWvertex *vLower = eLeft->v0; const GLfixed fsy = eLeft->fsy; const GLfixed fsx = eLeft->fsx; /* no fractional part */ const GLfixed fx = FixedCeil(fsx); /* no fractional part */ const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */ const GLfixed adjy = (GLfixed) eLeft->adjy; /* SCALED! */ GLint idxOuter; GLfloat dxOuter; GLfixed fdxOuter; fError = fx - fsx - FIXED_ONE; fxLeftEdge = fsx - FIXED_EPSILON; fdxLeftEdge = eLeft->fdxdy; fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON); fdError = fdxOuter - fdxLeftEdge + FIXED_ONE; idxOuter = FixedToInt(fdxOuter); dxOuter = (GLfloat) idxOuter; span.y = FixedToInt(fsy); /* silence warnings on some compilers */ (void) dxOuter; (void) adjx; (void) adjy; (void) vLower;#ifdef PIXEL_ADDRESS { pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y); dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE); /* negative because Y=0 at bottom and increases upward */ }#endif /* * Now we need the set of parameter (z, color, etc.) values at * the point (fx, fsy). This gives us properly-sampled parameter * values that we can step from pixel to pixel. Furthermore, * although we might have intermediate results that overflow * the normal parameter range when we step temporarily outside * the triangle, we shouldn't overflow or underflow for any * pixel that's actually inside the triangle. */#ifdef INTERP_Z { GLfloat z0 = vLower->attrib[FRAG_ATTRIB_WPOS][2]; if (depthBits <= 16) { /* interpolate fixed-pt values */ GLfloat tmp = (z0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_WPOS][2] * adjx + span.attrStepY[FRAG_ATTRIB_WPOS][2] * adjy) + FIXED_HALF; if (tmp < MAX_GLUINT / 2) zLeft = (GLfixed) tmp; else zLeft = MAX_GLUINT / 2; fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); } else { /* interpolate depth values w/out scaling */ zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx) + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy)); fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); }# ifdef DEPTH_TYPE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -