📄 s_tritemp.h
字号:
* 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; GLinterp fxLeftEdge = 0, fxRightEdge = 0; GLinterp fdxLeftEdge = 0, fdxRightEdge = 0; GLinterp 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_W GLfloat wLeft = 0, dwOuter = 0, dwInner;#endif#ifdef INTERP_FOG GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;#endif#ifdef INTERP_RGB ColorTemp rLeft = 0, fdrOuter = 0, fdrInner; ColorTemp gLeft = 0, fdgOuter = 0, fdgInner; ColorTemp bLeft = 0, fdbOuter = 0, fdbInner;#endif#ifdef INTERP_ALPHA ColorTemp aLeft = 0, fdaOuter = 0, fdaInner;#endif#ifdef INTERP_SPEC ColorTemp srLeft=0, dsrOuter=0, dsrInner; ColorTemp sgLeft=0, dsgOuter=0, dsgInner; ColorTemp sbLeft=0, dsbOuter=0, dsbInner;#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_TEX GLfloat sLeft[MAX_TEXTURE_COORD_UNITS]; GLfloat tLeft[MAX_TEXTURE_COORD_UNITS]; GLfloat uLeft[MAX_TEXTURE_COORD_UNITS]; GLfloat vLeft[MAX_TEXTURE_COORD_UNITS]; GLfloat dsOuter[MAX_TEXTURE_COORD_UNITS], dsInner[MAX_TEXTURE_COORD_UNITS]; GLfloat dtOuter[MAX_TEXTURE_COORD_UNITS], dtInner[MAX_TEXTURE_COORD_UNITS]; GLfloat duOuter[MAX_TEXTURE_COORD_UNITS], duInner[MAX_TEXTURE_COORD_UNITS]; GLfloat dvOuter[MAX_TEXTURE_COORD_UNITS], dvInner[MAX_TEXTURE_COORD_UNITS];#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;#if TRIANGLE_WALK_DOUBLE const GLdouble fsy = eLeft->fsy; const GLdouble fsx = eLeft->fsx; const GLdouble fx = CEILF(fsx); const GLdouble adjx = (fx - eLeft->fx0) * FIXED_SCALE; /* SCALED! */#else const GLfixed fsy = eLeft->fsy; const GLfixed fsx = eLeft->fsx; /* no fractional part */ const GLfixed fx = FixedCeil(fsx); /* no fractional part */ const GLfixed adjx = (GLinterp) (fx - eLeft->fx0); /* SCALED! */#endif const GLinterp adjy = (GLinterp) eLeft->adjy; /* SCALED! */ GLint idxOuter;#if TRIANGLE_WALK_DOUBLE GLdouble dxOuter; fError = fx - fsx - 1.0; fxLeftEdge = fsx; fdxLeftEdge = eLeft->dxdy; dxOuter = FLOORF(fdxLeftEdge); fdError = dxOuter - fdxLeftEdge + 1.0; idxOuter = (GLint) dxOuter; span.y = (GLint) fsy;#else 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);#endif /* silence warnings on some compilers */ (void) dxOuter; (void) adjx; (void) adjy; (void) vLower;#ifdef PIXEL_ADDRESS { pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(InterpToInt(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->win[2]; if (depthBits <= 16) { /* interpolate fixed-pt values */ GLfloat tmp = (z0 * FIXED_SCALE + span.dzdx * adjx + span.dzdy * adjy) + FIXED_HALF; if (tmp < MAX_GLUINT / 2) zLeft = (GLfixed) tmp; else zLeft = MAX_GLUINT / 2; fdzOuter = SignedFloatToFixed(span.dzdy + dxOuter * span.dzdx); } else { /* interpolate depth values w/out scaling */ zLeft = (GLuint) (z0 + span.dzdx * FixedToFloat(adjx) + span.dzdy * FixedToFloat(adjy)); fdzOuter = (GLint) (span.dzdy + dxOuter * span.dzdx); }# ifdef DEPTH_TYPE zRow = (DEPTH_TYPE *) zrb->GetPointer(ctx, zrb, InterpToInt(fxLeftEdge), span.y); dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);# endif }#endif#ifdef INTERP_W wLeft = vLower->win[3] + (span.dwdx * adjx + span.dwdy * adjy) * (1.0F/FIXED_SCALE); dwOuter = span.dwdy + dxOuter * span.dwdx;#endif#ifdef INTERP_FOG# ifdef INTERP_W fogLeft = vLower->fog * vLower->win[3] + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE);# else fogLeft = vLower->fog + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE);# endif dfogOuter = span.dfogdy + dxOuter * span.dfogdx;#endif#ifdef INTERP_RGB if (ctx->Light.ShadeModel == GL_SMOOTH) {# if CHAN_TYPE == GL_FLOAT rLeft = vLower->color[RCOMP] + (span.drdx * adjx + span.drdy * adjy) * (1.0F / FIXED_SCALE); gLeft = vLower->color[GCOMP] + (span.dgdx * adjx + span.dgdy * adjy) * (1.0F / FIXED_SCALE); bLeft = vLower->color[BCOMP] + (span.dbdx * adjx + span.dbdy * adjy) * (1.0F / FIXED_SCALE); fdrOuter = span.drdy + dxOuter * span.drdx; fdgOuter = span.dgdy + dxOuter * span.dgdx; fdbOuter = span.dbdy + dxOuter * span.dbdx;# else rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.drdx * adjx + span.drdy * adjy) + FIXED_HALF; gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.dgdx * adjx + span.dgdy * adjy) + FIXED_HALF; bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.dbdx * adjx + span.dbdy * adjy) + FIXED_HALF; fdrOuter = SignedFloatToFixed(span.drdy + dxOuter * span.drdx); fdgOuter = SignedFloatToFixed(span.dgdy + dxOuter * span.dgdx); fdbOuter = SignedFloatToFixed(span.dbdy + dxOuter * span.dbdx);# endif# ifdef INTERP_ALPHA# if CHAN_TYPE == GL_FLOAT aLeft = vLower->color[ACOMP] + (span.dadx * adjx + span.dady * adjy) * (1.0F / FIXED_SCALE); fdaOuter = span.dady + dxOuter * span.dadx;# else aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.dadx * adjx + span.dady * adjy) + FIXED_HALF; fdaOuter = SignedFloatToFixed(span.dady + dxOuter * span.dadx);# endif# endif } else { ASSERT(ctx->Light.ShadeModel == GL_FLAT);# if CHAN_TYPE == GL_FLOAT rLeft = v2->color[RCOMP]; gLeft = v2->color[GCOMP]; bLeft = v2->color[BCOMP]; fdrOuter = fdgOuter = fdbOuter = 0.0F;# else rLeft = ChanToFixed(v2->color[RCOMP]); gLeft = ChanToFixed(v2->color[GCOMP]); bLeft = ChanToFixed(v2->color[BCOMP]); fdrOuter = fdgOuter = fdbOuter = 0;# endif# ifdef INTERP_ALPHA# if CHAN_TYPE == GL_FLOAT aLeft = v2->color[ACOMP]; fdaOuter = 0.0F;# else aLeft = ChanToFixed(v2->color[ACOMP]); fdaOuter = 0;# endif# endif }#endif /* INTERP_RGB */#ifdef INTERP_SPEC if (ctx->Light.ShadeModel == GL_SMOOTH) {# if CHAN_TYPE == GL_FLOAT srLeft = vLower->specular[RCOMP] + (span.dsrdx * adjx + span.dsrdy * adjy) * (1.0F / FIXED_SCALE); sgLeft = vLower->specular[GCOMP] + (span.dsgdx * adjx + span.dsgdy * adjy) * (1.0F / FIXED_SCALE); sbLeft = vLower->specular[BCOMP] + (span.dsbdx * adjx + span.dsbdy * adjy) * (1.0F / FIXED_SCALE); dsrOuter = span.dsrdy + dxOuter * span.dsrdx; dsgOuter = span.dsgdy + dxOuter * span.dsgdx; dsbOuter = span.dsbdy + dxOuter * span.dsbdx;# else srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.dsrdx * adjx + span.dsrdy * adjy) + FIXED_HALF; sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.dsgdx * adjx + span.dsgdy * adjy) + FIXED_HALF; sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.dsbdx * adjx + span.dsbdy * adjy) + FIXED_HALF; dsrOuter = SignedFloatToFixed(span.dsrdy + dxOuter * span.dsrdx); dsgOuter = SignedFloatToFixed(span.dsgdy + dxOuter * span.dsgdx); dsbOuter = SignedFloatToFixed(span.dsbdy + dxOuter * span.dsbdx);# endif } else { ASSERT(ctx->Light.ShadeModel == GL_FLAT);#if CHAN_TYPE == GL_FLOAT srLeft = v2->specular[RCOMP]; sgLeft = v2->specular[GCOMP]; sbLeft = v2->specular[BCOMP]; dsrOuter = dsgOuter = dsbOuter = 0.0F;# else srLeft = ChanToFixed(v2->specular[RCOMP]); sgLeft = ChanToFixed(v2->specular[GCOMP]); sbLeft = ChanToFixed(v2->specular[BCOMP]); dsrOuter = dsgOuter = dsbOuter = 0;# endif }#endif#ifdef INTERP_INDEX if (ctx->Light.ShadeModel == GL_SMOOTH) { iLeft = (GLfixed)(vLower->index * FIXED_SCALE + didx * adjx + didy * adjy) + FIXED_HALF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -