windows-nt/Source/XPSP1/NT/multimedia/opengl/server/soft/so_polyd.c
2020-09-26 16:20:57 +08:00

833 lines
29 KiB
C

/*
** Copyright 1991, 1992, 1993, Silicon Graphics, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of Silicon Graphics, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
*/
#include "precomp.h"
#pragma hdrstop
#include <fixed.h>
/* This routine sets gc->polygon.shader.cfb to gc->drawBuffer */
static void FASTCALL FillSubTriangle(__GLcontext *gc, GLint iyBottom, GLint iyTop)
{
GLint ixLeft, ixRight;
GLint ixLeftFrac, ixRightFrac;
GLint dxLeftFrac, dxRightFrac;
GLint dxLeftLittle, dxRightLittle;
GLint dxLeftBig, dxRightBig;
GLint spanWidth, clipY0, clipY1;
GLuint modeFlags;
#ifdef NT
__GLstippleWord stackWords[__GL_MAX_STACK_STIPPLE_WORDS];
__GLstippleWord *words;
__GLcolor colors[__GL_MAX_STACKED_COLORS>>1];
__GLcolor fbcolors[__GL_MAX_STACKED_COLORS>>1];
__GLcolor *vColors, *vFbcolors;
int iMaxWidth, iDy, dxLeft, dxRight;
ixLeft = gc->polygon.shader.ixLeft;
dxLeft = (gc->polygon.shader.dxLeftBig < gc->polygon.shader.dxLeftLittle) ?
gc->polygon.shader.dxLeftBig : gc->polygon.shader.dxLeftLittle;
ixRight = gc->polygon.shader.ixRight;
dxRight = (gc->polygon.shader.dxRightBig > gc->polygon.shader.dxRightLittle) ?
gc->polygon.shader.dxRightBig : gc->polygon.shader.dxRightLittle;
iMaxWidth = ixRight - ixLeft;
iDy = iyTop - iyBottom - 1;
ixRight += dxRight * iDy;
ixLeft += dxLeft * iDy;
iMaxWidth = (iMaxWidth < (ixRight - ixLeft)) ? ixRight - ixLeft :
iMaxWidth;
if (iMaxWidth > __GL_MAX_STACK_STIPPLE_BITS)
{
words = gcTempAlloc(gc, (iMaxWidth+__GL_STIPPLE_BITS-1)/8);
if (words == NULL)
{
return;
}
}
else
{
words = stackWords;
}
if (iMaxWidth > (__GL_MAX_STACKED_COLORS>>1))
{
vColors = (__GLcolor *) gcTempAlloc(gc, iMaxWidth * sizeof(__GLcolor));
if (NULL == vColors)
{
if (iMaxWidth > __GL_MAX_STACK_STIPPLE_BITS)
{
gcTempFree(gc, words);
}
return;
}
vFbcolors = (__GLcolor *) gcTempAlloc(gc, iMaxWidth * sizeof(__GLcolor));
if (NULL == vFbcolors) {
if (iMaxWidth > __GL_MAX_STACK_STIPPLE_BITS)
{
gcTempFree(gc, words);
}
gcTempFree(gc, vColors);
return;
}
}
else
{
vColors = colors;
vFbcolors = fbcolors;
}
#else
__GLstippleWord words[__GL_MAX_STIPPLE_WORDS];
__GLcolor vColors[__GL_MAX_MAX_VIEWPORT];/*XXX oink */
__GLcolor vFbcolors[__GL_MAX_MAX_VIEWPORT];/*XXX oink */
#endif
ixLeft = gc->polygon.shader.ixLeft;
ixLeftFrac = gc->polygon.shader.ixLeftFrac;
ixRight = gc->polygon.shader.ixRight;
ixRightFrac = gc->polygon.shader.ixRightFrac;
clipY0 = gc->transform.clipY0;
clipY1 = gc->transform.clipY1;
dxLeftFrac = gc->polygon.shader.dxLeftFrac;
dxLeftBig = gc->polygon.shader.dxLeftBig;
dxLeftLittle = gc->polygon.shader.dxLeftLittle;
dxRightFrac = gc->polygon.shader.dxRightFrac;
dxRightBig = gc->polygon.shader.dxRightBig;
dxRightLittle = gc->polygon.shader.dxRightLittle;
modeFlags = gc->polygon.shader.modeFlags;
gc->polygon.shader.colors = vColors;
gc->polygon.shader.fbcolors = vFbcolors;
gc->polygon.shader.stipplePat = words;
if (modeFlags & __GL_SHADE_STENCIL_TEST) {
gc->polygon.shader.sbuf =
__GL_STENCIL_ADDR(&gc->stencilBuffer, (__GLstencilCell*),
ixLeft, iyBottom);
}
if (modeFlags & __GL_SHADE_DEPTH_TEST) {
#ifdef NT
if( gc->modes.depthBits == 32 )
gc->polygon.shader.zbuf = (__GLzValue *)
__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),
ixLeft, iyBottom);
else
gc->polygon.shader.zbuf = (__GLzValue *)
__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLz16Value*),
ixLeft, iyBottom);
#else
gc->polygon.shader.zbuf =
__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),
ixLeft, iyBottom);
#endif
}
gc->polygon.shader.cfb = gc->drawBuffer;
while (iyBottom < iyTop) {
spanWidth = ixRight - ixLeft;
/*
** Only render spans that have non-zero width and which are
** not scissored out vertically.
*/
if ((spanWidth > 0) && (iyBottom >= clipY0) && (iyBottom < clipY1)) {
gc->polygon.shader.frag.x = ixLeft;
gc->polygon.shader.frag.y = iyBottom;
gc->polygon.shader.length = spanWidth;
(*gc->procs.span.processSpan)(gc);
}
/* Advance right edge fixed point, adjusting for carry */
ixRightFrac += dxRightFrac;
if (ixRightFrac < 0) {
/* Carry/Borrow'd. Use large step */
ixRight += dxRightBig;
ixRightFrac &= ~0x80000000;
} else {
ixRight += dxRightLittle;
}
iyBottom++;
ixLeftFrac += dxLeftFrac;
if (ixLeftFrac < 0) {
/* Carry/Borrow'd. Use large step */
ixLeft += dxLeftBig;
ixLeftFrac &= ~0x80000000;
if (modeFlags & __GL_SHADE_RGB) {
if (modeFlags & __GL_SHADE_SMOOTH) {
gc->polygon.shader.frag.color.r += gc->polygon.shader.rBig;
gc->polygon.shader.frag.color.g += gc->polygon.shader.gBig;
gc->polygon.shader.frag.color.b += gc->polygon.shader.bBig;
gc->polygon.shader.frag.color.a += gc->polygon.shader.aBig;
}
if (modeFlags & __GL_SHADE_TEXTURE) {
gc->polygon.shader.frag.s += gc->polygon.shader.sBig;
gc->polygon.shader.frag.t += gc->polygon.shader.tBig;
gc->polygon.shader.frag.qw += gc->polygon.shader.qwBig;
}
} else {
if (modeFlags & __GL_SHADE_SMOOTH) {
gc->polygon.shader.frag.color.r += gc->polygon.shader.rBig;
}
}
if (modeFlags & __GL_SHADE_STENCIL_TEST) {
/* The implicit multiply is taken out of the loop */
gc->polygon.shader.sbuf = (__GLstencilCell*)
((GLubyte*) gc->polygon.shader.sbuf
+ gc->polygon.shader.sbufBig);
}
if (modeFlags & __GL_SHADE_DEPTH_ITER) {
gc->polygon.shader.frag.z += gc->polygon.shader.zBig;
}
if (modeFlags & __GL_SHADE_DEPTH_TEST) {
/* The implicit multiply is taken out of the loop */
gc->polygon.shader.zbuf = (__GLzValue*)
((GLubyte*) gc->polygon.shader.zbuf
+ gc->polygon.shader.zbufBig);
}
if (modeFlags & (__GL_SHADE_COMPUTE_FOG | __GL_SHADE_INTERP_FOG))
{
gc->polygon.shader.frag.f += gc->polygon.shader.fBig;
}
} else {
/* Use small step */
ixLeft += dxLeftLittle;
if (modeFlags & __GL_SHADE_RGB) {
if (modeFlags & __GL_SHADE_SMOOTH) {
gc->polygon.shader.frag.color.r += gc->polygon.shader.rLittle;
gc->polygon.shader.frag.color.g += gc->polygon.shader.gLittle;
gc->polygon.shader.frag.color.b += gc->polygon.shader.bLittle;
gc->polygon.shader.frag.color.a += gc->polygon.shader.aLittle;
}
if (modeFlags & __GL_SHADE_TEXTURE) {
gc->polygon.shader.frag.s += gc->polygon.shader.sLittle;
gc->polygon.shader.frag.t += gc->polygon.shader.tLittle;
gc->polygon.shader.frag.qw += gc->polygon.shader.qwLittle;
}
} else {
if (modeFlags & __GL_SHADE_SMOOTH) {
gc->polygon.shader.frag.color.r += gc->polygon.shader.rLittle;
}
}
if (modeFlags & __GL_SHADE_STENCIL_TEST) {
/* The implicit multiply is taken out of the loop */
gc->polygon.shader.sbuf = (__GLstencilCell*)
((GLubyte*) gc->polygon.shader.sbuf
+ gc->polygon.shader.sbufLittle);
}
if (modeFlags & __GL_SHADE_DEPTH_ITER) {
gc->polygon.shader.frag.z += gc->polygon.shader.zLittle;
}
if (modeFlags & __GL_SHADE_DEPTH_TEST) {
/* The implicit multiply is taken out of the loop */
gc->polygon.shader.zbuf = (__GLzValue*)
((GLubyte*) gc->polygon.shader.zbuf
+ gc->polygon.shader.zbufLittle);
}
if (modeFlags & (__GL_SHADE_COMPUTE_FOG | __GL_SHADE_INTERP_FOG))
{
gc->polygon.shader.frag.f += gc->polygon.shader.fLittle;
}
}
}
gc->polygon.shader.ixLeft = ixLeft;
gc->polygon.shader.ixLeftFrac = ixLeftFrac;
gc->polygon.shader.ixRight = ixRight;
gc->polygon.shader.ixRightFrac = ixRightFrac;
#ifdef NT
if (iMaxWidth > __GL_MAX_STACK_STIPPLE_BITS)
{
gcTempFree(gc, words);
}
if (iMaxWidth > (__GL_MAX_STACKED_COLORS>>1))
{
gcTempFree(gc, vColors);
gcTempFree(gc, vFbcolors);
}
#endif
}
static void SnapXLeft(__GLcontext *gc, __GLfloat xLeft, __GLfloat dxdyLeft)
{
GLint ixLeft, ixLeftFrac, lineBytes, elementSize, iLittle, iBig;
ASSERT_CHOP_ROUND();
ixLeft = __GL_VERTEX_FLOAT_TO_INT(xLeft);
/* Pre-add .5 to allow truncation in spanWidth calculation */
ixLeftFrac = __GL_VERTEX_PROMOTED_FRACTION(xLeft) + 0x40000000;
gc->polygon.shader.ixLeft = ixLeft + (((GLuint) ixLeftFrac) >> 31);
gc->polygon.shader.ixLeftFrac = ixLeftFrac & ~0x80000000;
/* Compute big and little steps */
iLittle = FTOL(dxdyLeft);
gc->polygon.shader.dxLeftFrac = FLT_FRACTION(dxdyLeft - iLittle);
if (dxdyLeft < 0) {
iBig = iLittle - 1;
} else {
iBig = iLittle + 1;
}
if (gc->polygon.shader.modeFlags & __GL_SHADE_STENCIL_TEST) {
/*
** Compute the big and little stencil buffer steps. We walk the
** memory pointers for the stencil buffer along the edge of the
** triangle as we walk the edge. This way we don't have to
** recompute the buffer address as we go.
*/
elementSize = gc->stencilBuffer.buf.elementSize;
lineBytes = elementSize * gc->stencilBuffer.buf.outerWidth;
gc->polygon.shader.sbufLittle = lineBytes + iLittle * elementSize;
gc->polygon.shader.sbufBig = lineBytes + iBig * elementSize;
}
if (gc->polygon.shader.modeFlags & __GL_SHADE_DEPTH_TEST) {
/*
** Compute the big and little depth buffer steps. We walk the
** memory pointers for the depth buffer along the edge of the
** triangle as we walk the edge. This way we don't have to
** recompute the buffer address as we go.
*/
elementSize = gc->depthBuffer.buf.elementSize;
lineBytes = elementSize * gc->depthBuffer.buf.outerWidth;
gc->polygon.shader.zbufLittle = lineBytes + iLittle * elementSize;
gc->polygon.shader.zbufBig = lineBytes + iBig * elementSize;
}
gc->polygon.shader.dxLeftLittle = iLittle;
gc->polygon.shader.dxLeftBig = iBig;
}
static void SnapXRight(__GLshade *sh, __GLfloat xRight, __GLfloat dxdyRight)
{
GLint ixRight, ixRightFrac, iLittle, iBig;
ASSERT_CHOP_ROUND();
ixRight = __GL_VERTEX_FLOAT_TO_INT(xRight);
/* Pre-add .5 to allow truncation in spanWidth calculation */
ixRightFrac = __GL_VERTEX_PROMOTED_FRACTION(xRight) + 0x40000000;
sh->ixRight = ixRight + (((GLuint) ixRightFrac) >> 31);
sh->ixRightFrac = ixRightFrac & ~0x80000000;
/* Compute big and little steps */
iLittle = FTOL(dxdyRight);
sh->dxRightFrac = FLT_FRACTION(dxdyRight - iLittle);
if (dxdyRight < 0) {
iBig = iLittle - 1;
} else {
iBig = iLittle + 1;
}
sh->dxRightLittle = iLittle;
sh->dxRightBig = iBig;
}
__GLfloat __glPolygonOffsetZ(__GLcontext *gc )
{
__GLshade *sh = &gc->polygon.shader;
__GLfloat factor;
__GLfloat maxdZ;
__GLfloat bias;
__GLfloat offsetZ;
/*
** Calculate factor and bias
*/
factor = gc->state.polygon.factor;
// For 16-bit z, bias = units,
// For 32-bit z, we only have 24 bits of resolution from the floating
// point z value. Therefore, the minimum resolvable difference in z
// values is 8-bits, and we multiply units by 2**8, or 256.
if( gc->modes.depthBits == 16 )
bias = gc->state.polygon.units;
else
bias = gc->state.polygon.units * __glVal256;
/*
** find the maximum Z slope with respect to X and Y
*/
// Note: all z values have already been scaled up from [0,1]
if(__GL_ABSF(sh->dzdxf) > __GL_ABSF(sh->dzdyf))
maxdZ = __GL_ABSF(sh->dzdxf);
else
maxdZ = __GL_ABSF(sh->dzdyf);
offsetZ = factor * maxdZ + bias;
// XXX! This value should really be clamped, but supposedly we don't
// bother in other parts of the code, so leave it for now. Clamping
// should also only be applied AFTER the addition of offsetZ to any
// base value.
return( offsetZ );
}
#ifdef NT
static void SetInitialParameters(__GLcontext *gc, const __GLvertex *a,
const __GLcolor *ac, __GLfloat aFog,
__GLfloat dx, __GLfloat dy)
{
__GLshade *sh = &gc->polygon.shader;
#else
static void SetInitialParameters(__GLshade *sh, const __GLvertex *a,
const __GLcolor *ac, __GLfloat aFog,
__GLfloat dx, __GLfloat dy)
{
#endif
__GLfloat little = sh->dxLeftLittle;
__GLfloat big = sh->dxLeftBig;
GLuint modeFlags = sh->modeFlags;
#define bPolygonOffset \
(gc->state.enables.general & __GL_POLYGON_OFFSET_FILL_ENABLE )
if (big > little) {
if (modeFlags & __GL_SHADE_RGB) {
if (modeFlags & __GL_SHADE_SMOOTH) {
sh->frag.color.r = ac->r + dx*sh->drdx + dy*sh->drdy;
sh->rLittle = sh->drdy + little * sh->drdx;
sh->rBig = sh->rLittle + sh->drdx;
sh->frag.color.g = ac->g + dx*sh->dgdx + dy*sh->dgdy;
sh->gLittle = sh->dgdy + little * sh->dgdx;
sh->gBig = sh->gLittle + sh->dgdx;
sh->frag.color.b = ac->b + dx*sh->dbdx + dy*sh->dbdy;
sh->bLittle = sh->dbdy + little * sh->dbdx;
sh->bBig = sh->bLittle + sh->dbdx;
sh->frag.color.a = ac->a + dx*sh->dadx + dy*sh->dady;
sh->aLittle = sh->dady + little * sh->dadx;
sh->aBig =sh->aLittle + sh->dadx;
}
if (modeFlags & __GL_SHADE_TEXTURE) {
__GLfloat oneOverW = a->window.w;
sh->frag.s = a->texture.x * oneOverW + dx*sh->dsdx
+ dy*sh->dsdy;
sh->sLittle = sh->dsdy + little * sh->dsdx;
sh->sBig = sh->sLittle + sh->dsdx;
sh->frag.t = a->texture.y * oneOverW + dx*sh->dtdx
+ dy*sh->dtdy;
sh->tLittle = sh->dtdy + little * sh->dtdx;
sh->tBig = sh->tLittle + sh->dtdx;
sh->frag.qw = a->texture.w * oneOverW + dx*sh->dqwdx
+ dy*sh->dqwdy;
sh->qwLittle = sh->dqwdy + little * sh->dqwdx;
sh->qwBig = sh->qwLittle + sh->dqwdx;
}
} else {
if (modeFlags & __GL_SHADE_SMOOTH) {
sh->frag.color.r = ac->r + dx*sh->drdx + dy*sh->drdy;
sh->rLittle = sh->drdy + little * sh->drdx;
sh->rBig = sh->rLittle + sh->drdx;
}
}
if (modeFlags & __GL_SHADE_DEPTH_ITER) {
__GLfloat zLittle, zOffset;
zOffset = bPolygonOffset ? __glPolygonOffsetZ(gc) : 0.0f;
if (gc->modes.depthBits == 16) {
sh->frag.z = (__GLzValue)
FLT_TO_Z16_SCALE(a->window.z + dx*sh->dzdxf + dy*sh->dzdyf
+ zOffset );
zLittle = sh->dzdyf + little * sh->dzdxf;
sh->zLittle = FLT_TO_Z16_SCALE(zLittle);
sh->zBig = FLT_TO_Z16_SCALE(zLittle + sh->dzdxf);
}
else {
sh->frag.z = (__GLzValue)
FTOL(a->window.z + dx*sh->dzdxf + dy*sh->dzdyf +
zOffset );
zLittle = sh->dzdyf + little * sh->dzdxf;
sh->zLittle = FTOL(zLittle);
sh->zBig = FTOL(zLittle + sh->dzdxf);
}
}
if (modeFlags & (__GL_SHADE_COMPUTE_FOG | __GL_SHADE_INTERP_FOG))
{
sh->frag.f = aFog + dx*sh->dfdx + dy*sh->dfdy;
sh->fLittle = sh->dfdy + little * sh->dfdx;
sh->fBig = sh->fLittle + sh->dfdx;
}
} else {
if (modeFlags & __GL_SHADE_RGB) {
if (modeFlags & __GL_SHADE_SMOOTH) {
sh->frag.color.r = ac->r + dx*sh->drdx + dy*sh->drdy;
sh->rLittle = sh->drdy + little * sh->drdx;
sh->rBig = sh->rLittle - sh->drdx;
sh->frag.color.g = ac->g + dx*sh->dgdx + dy*sh->dgdy;
sh->gLittle = sh->dgdy + little * sh->dgdx;
sh->gBig = sh->gLittle - sh->dgdx;
sh->frag.color.b = ac->b + dx*sh->dbdx + dy*sh->dbdy;
sh->bLittle = sh->dbdy + little * sh->dbdx;
sh->bBig = sh->bLittle - sh->dbdx;
sh->frag.color.a = ac->a + dx*sh->dadx + dy*sh->dady;
sh->aLittle = sh->dady + little * sh->dadx;
sh->aBig =sh->aLittle - sh->dadx;
}
if (modeFlags & __GL_SHADE_TEXTURE) {
__GLfloat oneOverW = a->window.w;
sh->frag.s = a->texture.x * oneOverW + dx*sh->dsdx
+ dy*sh->dsdy;
sh->sLittle = sh->dsdy + little * sh->dsdx;
sh->sBig = sh->sLittle - sh->dsdx;
sh->frag.t = a->texture.y * oneOverW + dx*sh->dtdx
+ dy*sh->dtdy;
sh->tLittle = sh->dtdy + little * sh->dtdx;
sh->tBig = sh->tLittle - sh->dtdx;
sh->frag.qw = a->texture.w * oneOverW + dx*sh->dqwdx
+ dy*sh->dqwdy;
sh->qwLittle = sh->dqwdy + little * sh->dqwdx;
sh->qwBig = sh->qwLittle - sh->dqwdx;
}
} else {
if (modeFlags & __GL_SHADE_SMOOTH) {
sh->frag.color.r = ac->r + dx*sh->drdx + dy*sh->drdy;
sh->rLittle = sh->drdy + little * sh->drdx;
sh->rBig = sh->rLittle - sh->drdx;
}
}
if (modeFlags & __GL_SHADE_DEPTH_ITER) {
__GLfloat zLittle, zOffset;
zOffset = bPolygonOffset ? __glPolygonOffsetZ(gc) : 0.0f;
if(( gc->modes.depthBits == 16 ) &&
( gc->depthBuffer.scale <= (GLuint)0xffff )) {
sh->frag.z = (__GLzValue)
FLT_TO_Z16_SCALE(a->window.z + dx*sh->dzdxf + dy*sh->dzdyf
+ zOffset );
zLittle = sh->dzdyf + little * sh->dzdxf;
sh->zLittle = FLT_TO_Z16_SCALE(zLittle);
sh->zBig = FLT_TO_Z16_SCALE(zLittle - sh->dzdxf);
}
else {
sh->frag.z = (__GLzValue)
FTOL( a->window.z + dx*sh->dzdxf + dy*sh->dzdyf+ zOffset );
zLittle = sh->dzdyf + little * sh->dzdxf;
sh->zLittle = FTOL(zLittle);
sh->zBig = FTOL(zLittle - sh->dzdxf);
}
}
if (modeFlags & (__GL_SHADE_COMPUTE_FOG | __GL_SHADE_INTERP_FOG))
{
sh->frag.f = aFog + dx*sh->dfdx + dy*sh->dfdy;
sh->fLittle = sh->dfdy + little * sh->dfdx;
sh->fBig = sh->fLittle - sh->dfdx;
}
}
}
void FASTCALL __glFillTriangle(__GLcontext *gc, __GLvertex *a, __GLvertex *b,
__GLvertex *c, GLboolean ccw)
{
__GLfloat oneOverArea, t1, t2, t3, t4;
__GLfloat dxAC, dxBC, dyAC, dyBC;
__GLfloat aFog, bFog;
__GLfloat dxAB, dyAB;
__GLfloat dx, dy, dxdyLeft, dxdyRight;
__GLcolor *ac, *bc;
GLint aIY, bIY, cIY;
GLuint modeFlags;
__GLfloat dxdyAC;
CHOP_ROUND_ON();
/* Pre-compute one over polygon area */
__GL_FLOAT_BEGIN_DIVIDE(__glOne, gc->polygon.shader.area, &oneOverArea);
/* Fetch some stuff we are going to reuse */
modeFlags = gc->polygon.shader.modeFlags;
dxAC = gc->polygon.shader.dxAC;
dxBC = gc->polygon.shader.dxBC;
dyAC = gc->polygon.shader.dyAC;
dyBC = gc->polygon.shader.dyBC;
ac = a->color;
bc = b->color;
/*
** Compute delta values for unit changes in x or y for each
** parameter.
*/
__GL_FLOAT_SIMPLE_END_DIVIDE(oneOverArea);
t1 = dyAC * oneOverArea;
t2 = dyBC * oneOverArea;
t3 = dxAC * oneOverArea;
t4 = dxBC * oneOverArea;
if (modeFlags & __GL_SHADE_RGB) {
if (modeFlags & __GL_SHADE_SMOOTH) {
__GLfloat drAC, dgAC, dbAC, daAC;
__GLfloat drBC, dgBC, dbBC, daBC;
__GLcolor *cc;
cc = c->color;
drAC = ac->r - cc->r;
drBC = bc->r - cc->r;
dgAC = ac->g - cc->g;
dgBC = bc->g - cc->g;
dbAC = ac->b - cc->b;
dbBC = bc->b - cc->b;
daAC = ac->a - cc->a;
daBC = bc->a - cc->a;
gc->polygon.shader.drdx = drAC * t2 - drBC * t1;
gc->polygon.shader.drdy = drBC * t3 - drAC * t4;
gc->polygon.shader.dgdx = dgAC * t2 - dgBC * t1;
gc->polygon.shader.dgdy = dgBC * t3 - dgAC * t4;
gc->polygon.shader.dbdx = dbAC * t2 - dbBC * t1;
gc->polygon.shader.dbdy = dbBC * t3 - dbAC * t4;
gc->polygon.shader.dadx = daAC * t2 - daBC * t1;
gc->polygon.shader.dady = daBC * t3 - daAC * t4;
} else {
__GLcolor *flatColor = gc->vertex.provoking->color;
gc->polygon.shader.frag.color = *flatColor;
}
if (modeFlags & __GL_SHADE_TEXTURE) {
__GLfloat awinv, bwinv, cwinv, scwinv, tcwinv, qwcwinv;
__GLfloat dsAC, dsBC, dtAC, dtBC, dqwAC, dqwBC;
awinv = a->window.w;
bwinv = b->window.w;
cwinv = c->window.w;
scwinv = c->texture.x * cwinv;
tcwinv = c->texture.y * cwinv;
qwcwinv = c->texture.w * cwinv;
dsAC = a->texture.x * awinv - scwinv;
dsBC = b->texture.x * bwinv - scwinv;
dtAC = a->texture.y * awinv - tcwinv;
dtBC = b->texture.y * bwinv - tcwinv;
dqwAC = a->texture.w * awinv - qwcwinv;
dqwBC = b->texture.w * bwinv - qwcwinv;
gc->polygon.shader.dsdx = dsAC * t2 - dsBC * t1;
gc->polygon.shader.dsdy = dsBC * t3 - dsAC * t4;
gc->polygon.shader.dtdx = dtAC * t2 - dtBC * t1;
gc->polygon.shader.dtdy = dtBC * t3 - dtAC * t4;
gc->polygon.shader.dqwdx = dqwAC * t2 - dqwBC * t1;
gc->polygon.shader.dqwdy = dqwBC * t3 - dqwAC * t4;
}
} else {
if (modeFlags & __GL_SHADE_SMOOTH) {
__GLfloat drAC;
__GLfloat drBC;
__GLcolor *cc;
cc = c->color;
drAC = ac->r - cc->r;
drBC = bc->r - cc->r;
gc->polygon.shader.drdx = drAC * t2 - drBC * t1;
gc->polygon.shader.drdy = drBC * t3 - drAC * t4;
} else {
__GLcolor *flatColor = gc->vertex.provoking->color;
gc->polygon.shader.frag.color.r = flatColor->r;
}
}
if (modeFlags & __GL_SHADE_DEPTH_ITER) {
__GLfloat dzAC, dzBC;
dzAC = a->window.z - c->window.z;
dzBC = b->window.z - c->window.z;
gc->polygon.shader.dzdxf = dzAC * t2 - dzBC * t1;
gc->polygon.shader.dzdyf = dzBC * t3 - dzAC * t4;
#ifdef NT
if(( gc->modes.depthBits == 16 ) &&
( gc->depthBuffer.scale <= (GLuint)0xffff )) {
gc->polygon.shader.dzdx =
FLT_TO_Z16_SCALE(gc->polygon.shader.dzdxf);
}
else {
gc->polygon.shader.dzdx = FTOL(gc->polygon.shader.dzdxf);
}
#else
gc->polygon.shader.dzdx = (GLint) gc->polygon.shader.dzdxf;
#endif
}
if (modeFlags & __GL_SHADE_COMPUTE_FOG)
{
__GLfloat dfAC, dfBC, cFog;
aFog = a->eyeZ;
bFog = b->eyeZ;
cFog = c->eyeZ;
dfAC = aFog - cFog;
dfBC = bFog - cFog;
gc->polygon.shader.dfdx = dfAC * t2 - dfBC * t1;
gc->polygon.shader.dfdy = dfBC * t3 - dfAC * t4;
}
else if (modeFlags & __GL_SHADE_INTERP_FOG)
{
__GLfloat dfAC, dfBC, cFog;
aFog = a->fog;
bFog = b->fog;
cFog = c->fog;
dfAC = aFog - cFog;
dfBC = bFog - cFog;
gc->polygon.shader.dfdx = dfAC * t2 - dfBC * t1;
gc->polygon.shader.dfdy = dfBC * t3 - dfAC * t4;
}
__GL_FLOAT_SIMPLE_BEGIN_DIVIDE(dxAC, dyAC, dxdyAC);
/* Snap each y coordinate to its pixel center */
aIY = __GL_VERTEX_FIXED_TO_INT(__GL_VERTEX_FLOAT_TO_FIXED(a->window.y)+
__GL_VERTEX_FRAC_HALF);
bIY = __GL_VERTEX_FIXED_TO_INT(__GL_VERTEX_FLOAT_TO_FIXED(b->window.y)+
__GL_VERTEX_FRAC_HALF);
cIY = __GL_VERTEX_FIXED_TO_INT(__GL_VERTEX_FLOAT_TO_FIXED(c->window.y)+
__GL_VERTEX_FRAC_HALF);
/*
** This algorithim always fills from bottom to top, left to right.
** Because of this, ccw triangles are inherently faster because
** the parameter values need not be recomputed.
*/
dxAB = a->window.x - b->window.x;
dyAB = a->window.y - b->window.y;
if (ccw) {
dy = (aIY + __glHalf) - a->window.y;
__GL_FLOAT_SIMPLE_END_DIVIDE(dxdyAC);
SnapXLeft(gc, a->window.x + dy*dxdyAC, dxdyAC);
dx = (gc->polygon.shader.ixLeft + __glHalf) - a->window.x;
#ifdef NT
SetInitialParameters(gc, a, ac, aFog, dx, dy);
#else
SetInitialParameters(&gc->polygon.shader, a, ac, aFog, dx, dy);
#endif
if (aIY != bIY) {
dxdyRight = dxAB / dyAB;
SnapXRight(&gc->polygon.shader, a->window.x + dy*dxdyRight,
dxdyRight);
FillSubTriangle(gc, aIY, bIY);
}
if (bIY != cIY) {
dxdyRight = dxBC / dyBC;
dy = (bIY + __glHalf) - b->window.y;
SnapXRight(&gc->polygon.shader, b->window.x + dy*dxdyRight,
dxdyRight);
FillSubTriangle(gc, bIY, cIY);
}
} else {
dy = (aIY + __glHalf) - a->window.y;
__GL_FLOAT_SIMPLE_END_DIVIDE(dxdyAC);
SnapXRight(&gc->polygon.shader, a->window.x + dy*dxdyAC, dxdyAC);
if (aIY != bIY) {
dxdyLeft = dxAB / dyAB;
SnapXLeft(gc, a->window.x + dy*dxdyLeft, dxdyLeft);
dx = (gc->polygon.shader.ixLeft + __glHalf) - a->window.x;
#ifdef NT
SetInitialParameters(gc, a, ac, aFog, dx, dy);
#else
SetInitialParameters(&gc->polygon.shader, a, ac, aFog, dx, dy);
#endif
FillSubTriangle(gc, aIY, bIY);
}
if (bIY != cIY) {
dxdyLeft = dxBC / dyBC;
dy = (bIY + __glHalf) - b->window.y;
SnapXLeft(gc, b->window.x + dy*dxdyLeft, dxdyLeft);
dx = (gc->polygon.shader.ixLeft + __glHalf) - b->window.x;
#ifdef NT
SetInitialParameters(gc, b, bc, bFog, dx, dy);
#else
SetInitialParameters(&gc->polygon.shader, b, bc, bFog, dx, dy);
#endif
FillSubTriangle(gc, bIY, cIY);
}
}
CHOP_ROUND_OFF();
}
void FASTCALL __glFillFlatFogTriangle(__GLcontext *gc, __GLvertex *a, __GLvertex *b,
__GLvertex *c, GLboolean ccw)
{
__GLcolor acol, bcol, ccol;
__GLcolor *aocp, *bocp, *cocp;
__GLvertex *pv;
pv = gc->vertex.provoking;
(*gc->procs.fogColor)(gc, &acol, pv->color, a->fog);
(*gc->procs.fogColor)(gc, &bcol, pv->color, b->fog);
(*gc->procs.fogColor)(gc, &ccol, pv->color, c->fog);
aocp = a->color;
bocp = b->color;
cocp = c->color;
a->color = &acol;
b->color = &bcol;
c->color = &ccol;
(*gc->procs.fillTriangle2)(gc, a, b, c, ccw);
a->color = aocp;
b->color = bocp;
c->color = cocp;
}
#ifdef GL_WIN_specular_fog
void FASTCALL __glFillFlatSpecFogTriangle(__GLcontext *gc, __GLvertex *a,
__GLvertex *b, __GLvertex *c,
GLboolean ccw)
{
__GLfloat af, bf, cf;
__GLvertex *pv;
pv = gc->vertex.provoking;
af = a->fog;
bf = b->fog;
cf = c->fog;
a->fog = b->fog = c->fog = pv->fog;
(*gc->procs.fillTriangle2)(gc, a, b, c, ccw);
a->fog = af;
b->fog = bf;
c->fog = cf;
}
#endif //GL_WIN_specular_fog