📄 s_tritemp.h
字号:
#if TRIANGLE_WALK_DOUBLE
eTop.fsy = CEILF(vMid_fy);
eTop.lines = (GLint) CEILF(vMax_fy - eTop.fsy);
#else
eTop.fsy = FixedCeil(vMid_fy);
eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
#endif
if (eTop.lines > 0) {
eTop.dxdy = eTop.dx / eTop.dy;
#if TRIANGLE_WALK_DOUBLE
eTop.adjy = (eTop.fsy - vMid_fy) * FIXED_SCALE; /* SCALED! */
eTop.fx0 = vMid_fx;
eTop.fsx = eTop.fx0 + (eTop.adjy * eTop.dxdy) / (GLdouble) FIXED_SCALE;
#else
eTop.fdxdy = SignedFloatToFixed(eTop.dxdy);
eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
eTop.fx0 = vMid_fx;
eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy);
#endif
}
#if TRIANGLE_WALK_DOUBLE
eBot.fsy = CEILF(vMin_fy);
eBot.lines = (GLint) CEILF(vMid_fy - eBot.fsy);
#else
eBot.fsy = FixedCeil(vMin_fy);
eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
#endif
if (eBot.lines > 0) {
eBot.dxdy = eBot.dx / eBot.dy;
#if TRIANGLE_WALK_DOUBLE
eBot.adjy = (eBot.fsy - vMin_fy) * FIXED_SCALE; /* SCALED! */
eBot.fx0 = vMin_fx;
eBot.fsx = eBot.fx0 + (eBot.adjy * eBot.dxdy) / (GLdouble) FIXED_SCALE;
#else
eBot.fdxdy = SignedFloatToFixed(eBot.dxdy);
eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */
eBot.fx0 = vMin_fx;
eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy);
#endif
}
}
/*
* Conceptually, we view a triangle as two subtriangles
* separated by a perfectly horizontal line. The edge that is
* intersected by this line is one with maximal absolute dy; we
* call it a ``major'' edge. The other two edges are the
* ``top'' edge (for the upper subtriangle) and the ``bottom''
* edge (for the lower subtriangle). If either of these two
* edges is horizontal or very close to horizontal, the
* corresponding subtriangle might cover zero sample points;
* we take care to handle such cases, for performance as well
* as correctness.
*
* By stepping rasterization parameters along the major edge,
* we can avoid recomputing them at the discontinuity where
* the top and bottom edges meet. However, this forces us to
* be able to scan both left-to-right and right-to-left.
* Also, we must determine whether the major edge is at the
* left or right side of the triangle. We do this by
* computing the magnitude of the cross-product of the major
* and top edges. Since this magnitude depends on the sine of
* the angle between the two edges, its sign tells us whether
* we turn to the left or to the right when travelling along
* the major edge to the top edge, and from this we infer
* whether the major edge is on the left or the right.
*
* Serendipitously, this cross-product magnitude is also a
* value we need to compute the iteration parameter
* derivatives for the triangle, and it can be used to perform
* backface culling because its sign tells us whether the
* triangle is clockwise or counterclockwise. In this code we
* refer to it as ``area'' because it's also proportional to
* the pixel area of the triangle.
*/
{
GLint scan_from_left_to_right; /* true if scanning left-to-right */
#ifdef INTERP_INDEX
GLfloat didx, didy;
#endif
/*
* Execute user-supplied setup code
*/
#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->win[2] - vMin->win[2];
GLfloat eBot_dz = vMid->win[2] - vMin->win[2];
span.dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
if (span.dzdx > maxDepth || span.dzdx < -maxDepth) {
/* probably a sliver triangle */
span.dzdx = 0.0;
span.dzdy = 0.0;
}
else {
span.dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
}
if (depthBits <= 16)
span.zStep = SignedFloatToFixed(span.dzdx);
else
span.zStep = (GLint) span.dzdx;
}
#endif
#ifdef INTERP_W
span.interpMask |= SPAN_W;
{
const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3];
const GLfloat eBot_dw = vMid->win[3] - vMin->win[3];
span.dwdx = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw);
span.dwdy = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx);
}
#endif
#ifdef INTERP_FOG
span.interpMask |= SPAN_FOG;
{
# ifdef INTERP_W
const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
const GLfloat eMaj_dfog = vMax->fog * wMax - vMin->fog * wMin;
const GLfloat eBot_dfog = vMid->fog * wMid - vMin->fog * wMin;
# else
const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
const GLfloat eBot_dfog = vMid->fog - vMin->fog;
# endif
span.dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
span.dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
span.fogStep = span.dfogdx;
}
#endif
#ifdef INTERP_RGB
span.interpMask |= SPAN_RGBA;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_dr = (GLfloat) ((ColorTemp) vMax->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
GLfloat eBot_dr = (GLfloat) ((ColorTemp) vMid->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]);
GLfloat eMaj_dg = (GLfloat) ((ColorTemp) vMax->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
GLfloat eBot_dg = (GLfloat) ((ColorTemp) vMid->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]);
GLfloat eMaj_db = (GLfloat) ((ColorTemp) vMax->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
GLfloat eBot_db = (GLfloat) ((ColorTemp) vMid->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]);
# ifdef INTERP_ALPHA
GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]);
# endif
span.drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
span.drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
span.dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
span.dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
span.dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
span.dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
# if CHAN_TYPE == GL_FLOAT
span.redStep = span.drdx;
span.greenStep = span.dgdx;
span.blueStep = span.dbdx;
# else
span.redStep = SignedFloatToFixed(span.drdx);
span.greenStep = SignedFloatToFixed(span.dgdx);
span.blueStep = SignedFloatToFixed(span.dbdx);
# endif /* GL_FLOAT */
# ifdef INTERP_ALPHA
span.dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
span.dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
# if CHAN_TYPE == GL_FLOAT
span.alphaStep = span.dadx;
# else
span.alphaStep = SignedFloatToFixed(span.dadx);
# endif /* GL_FLOAT */
# endif /* INTERP_ALPHA */
}
else {
ASSERT (ctx->Light.ShadeModel == GL_FLAT);
span.interpMask |= SPAN_FLAT;
span.drdx = span.drdy = 0.0F;
span.dgdx = span.dgdy = 0.0F;
span.dbdx = span.dbdy = 0.0F;
# if CHAN_TYPE == GL_FLOAT
span.redStep = 0.0F;
span.greenStep = 0.0F;
span.blueStep = 0.0F;
# else
span.redStep = 0;
span.greenStep = 0;
span.blueStep = 0;
# endif /* GL_FLOAT */
# ifdef INTERP_ALPHA
span.dadx = span.dady = 0.0F;
# if CHAN_TYPE == GL_FLOAT
span.alphaStep = 0.0F;
# else
span.alphaStep = 0;
# endif /* GL_FLOAT */
# endif
}
#endif /* INTERP_RGB */
#ifdef INTERP_SPEC
span.interpMask |= SPAN_SPEC;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_dsr = (GLfloat) ((ColorTemp) vMax->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
GLfloat eBot_dsr = (GLfloat) ((ColorTemp) vMid->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]);
GLfloat eMaj_dsg = (GLfloat) ((ColorTemp) vMax->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]);
GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]);
span.dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
span.dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
span.dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
span.dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
span.dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
span.dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
# if CHAN_TYPE == GL_FLOAT
span.specRedStep = span.dsrdx;
span.specGreenStep = span.dsgdx;
span.specBlueStep = span.dsbdx;
# else
span.specRedStep = SignedFloatToFixed(span.dsrdx);
span.specGreenStep = SignedFloatToFixed(span.dsgdx);
span.specBlueStep = SignedFloatToFixed(span.dsbdx);
# endif
}
else {
span.dsrdx = span.dsrdy = 0.0F;
span.dsgdx = span.dsgdy = 0.0F;
span.dsbdx = span.dsbdy = 0.0F;
# if CHAN_TYPE == GL_FLOAT
span.specRedStep = 0.0F;
span.specGreenStep = 0.0F;
span.specBlueStep = 0.0F;
# else
span.specRedStep = 0;
span.specGreenStep = 0;
span.specBlueStep = 0;
# endif
}
#endif /* INTERP_SPEC */
#ifdef INTERP_INDEX
span.interpMask |= SPAN_INDEX;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_di = vMax->index - vMin->index;
GLfloat eBot_di = vMid->index - vMin->index;
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
span.interpMask |= SPAN_INT_TEXTURE;
{
GLfloat eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
GLfloat eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
GLfloat eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
GLfloat eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
span.texStepX[0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
span.texStepY[0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
span.texStepX[0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
span.texStepY[0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
span.intTexStep[0] = SignedFloatToFixed(span.texStepX[0][0]);
span.intTexStep[1] = SignedFloatToFixed(span.texStepX[0][1]);
}
#endif
#ifdef INTERP_TEX
span.interpMask |= SPAN_TEXTURE;
{
/* win[3] is 1/W */
const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3];
TEX_UNIT_LOOP(
GLfloat eMaj_ds = vMax->texcoord[u][0] * wMax - vMin->texcoord[u][0] * wMin;
GLfloat eBot_ds = vMid->texcoord[u][0] * wMid - vMin->texcoord[u][0] * wMin;
GLfloat eMaj_dt = vMax->texcoord[u][1] * wMax - vMin->texcoord[u][1] * wMin;
GLfloat eBot_dt = vMid->texcoord[u][1] * wMid - vMin->texcoord[u][1] * wMin;
GLfloat eMaj_du = vMax->texcoord[u][2] * wMax - vMin->texcoord[u][2] * wMin;
GLfloat eBot_du = vMid->texcoord[u][2] * wMid - vMin->texcoord[u][2] * wMin;
GLfloat eMaj_dv = vMax->texcoord[u][3] * wMax - vMin->texcoord[u][3] * wMin;
GLfloat eBot_dv = vMid->texcoord[u][3] * wMid - vMin->texcoord[u][3] * wMin;
span.texStepX[u][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
span.texStepY[u][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
span.texStepX[u][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
span.texStepY[u][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
span.texStepX[u][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
span.texStepY[u][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
span.texStepX[u][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
span.texStepY[u][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
)
}
#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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -