636 lines
20 KiB
C
636 lines
20 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 <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <nturtl.h>
|
||
|
#include <stddef.h>
|
||
|
#include <windows.h>
|
||
|
#include <winddi.h>
|
||
|
|
||
|
#include "render.h"
|
||
|
#include "context.h"
|
||
|
#include "global.h"
|
||
|
#include "gencx.h"
|
||
|
#include "..\inc\wglp.h"
|
||
|
|
||
|
#define FLT_TO_FIX(value) \
|
||
|
*((GLint *)&value) = (GLint)(*((__GLfloat *)&(value)) * (__GLfloat)65536.0)
|
||
|
|
||
|
/* This routine sets gc->polygon.shader.cfb to gc->drawBuffer */
|
||
|
|
||
|
void __fastTriangleSetup(__GLcontext *gc)
|
||
|
{
|
||
|
SPANREC deltaRec;
|
||
|
|
||
|
if (gc->polygon.shader.modeFlags & __GL_SHADE_RGB) {
|
||
|
if (gc->polygon.shader.modeFlags & __GL_SHADE_DITHER) {
|
||
|
__fastRGBSmoothSpanSetup(gc);
|
||
|
__fastRGBFlatSpanSetup(gc);
|
||
|
} else {
|
||
|
__fastRGBNDSmoothSpanSetup(gc);
|
||
|
__fastRGBNDFlatSpanSetup(gc);
|
||
|
}
|
||
|
} else {
|
||
|
if (gc->polygon.shader.modeFlags & __GL_SHADE_DITHER) {
|
||
|
__fastCISmoothSpanSetup(gc);
|
||
|
__fastCIFlatSpanSetup(gc);
|
||
|
} else {
|
||
|
__fastCINDSmoothSpanSetup(gc);
|
||
|
__fastCINDFlatSpanSetup(gc);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
deltaRec.r = 0;
|
||
|
deltaRec.g = 0;
|
||
|
deltaRec.b = 0;
|
||
|
deltaRec.a = 0;
|
||
|
deltaRec.z = 0;
|
||
|
|
||
|
__fastDeltaSpan(gc, &deltaRec); // Set up initial delta values
|
||
|
}
|
||
|
|
||
|
/*static*/ void fastFillSubTriangle(__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;
|
||
|
__GLGENcontext *gengc = (__GLGENcontext *)gc;
|
||
|
#ifdef NT
|
||
|
__GLstippleWord stackWords[__GL_MAX_STACK_STIPPLE_WORDS];
|
||
|
__GLstippleWord *words;
|
||
|
GLuint maxWidth;
|
||
|
#else
|
||
|
__GLstippleWord words[__GL_MAX_STIPPLE_WORDS];
|
||
|
#endif
|
||
|
__GLspanFunc spanFunc =
|
||
|
((FASTFUNCS *)(*((VOID **)(gengc->pPrivateArea))))->__fastSpanFuncPtr;
|
||
|
|
||
|
#ifdef NT
|
||
|
maxWidth = (gc->transform.clipX1 - gc->transform.clipX0) + 31;
|
||
|
if (maxWidth > __GL_MAX_STACK_STIPPLE_BITS)
|
||
|
{
|
||
|
words = __wglTempAlloc(gc, (maxWidth+__GL_STIPPLE_BITS-1)/8);
|
||
|
if (words == NULL)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
words = stackWords;
|
||
|
}
|
||
|
#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.stipplePat = words;
|
||
|
|
||
|
if (modeFlags & __GL_SHADE_DEPTH_TEST) {
|
||
|
gc->polygon.shader.zbuf =
|
||
|
__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),
|
||
|
ixLeft, iyBottom);
|
||
|
}
|
||
|
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;
|
||
|
|
||
|
if (gc->state.raster.drawBuffer == GL_FRONT_AND_BACK) {
|
||
|
gc->polygon.shader.cfb = &gc->frontBuffer;
|
||
|
(*spanFunc)(gc);
|
||
|
|
||
|
if (!((GLint)gc->polygon.shader.cfb->buf.other & DIB_FORMAT))
|
||
|
wglCopyBits(gengc->pdco, gengc->pwo, gengc->ColorsBitmap,
|
||
|
__GL_UNBIAS_X(gc, ixLeft) +
|
||
|
gc->drawBuffer->buf.xOrigin,
|
||
|
__GL_UNBIAS_Y(gc, iyBottom) +
|
||
|
gc->drawBuffer->buf.yOrigin,
|
||
|
spanWidth, TRUE);
|
||
|
|
||
|
|
||
|
gc->polygon.shader.cfb = &gc->backBuffer;
|
||
|
(*spanFunc)(gc);
|
||
|
} else {
|
||
|
|
||
|
(*spanFunc)(gc);
|
||
|
|
||
|
if (!((GLint)gc->drawBuffer->buf.other & DIB_FORMAT))
|
||
|
wglCopyBits(gengc->pdco, gengc->pwo, gengc->ColorsBitmap,
|
||
|
__GL_UNBIAS_X(gc, ixLeft) +
|
||
|
gc->drawBuffer->buf.xOrigin,
|
||
|
__GL_UNBIAS_Y(gc, iyBottom) +
|
||
|
gc->drawBuffer->buf.yOrigin,
|
||
|
spanWidth, TRUE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* 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) {
|
||
|
*((GLint *)&gc->polygon.shader.frag.color.r) +=
|
||
|
*((GLint *)&gc->polygon.shader.rBig);
|
||
|
*((GLint *)&gc->polygon.shader.frag.color.g) +=
|
||
|
*((GLint *)&gc->polygon.shader.gBig);
|
||
|
*((GLint *)&gc->polygon.shader.frag.color.b) +=
|
||
|
*((GLint *)&gc->polygon.shader.bBig);
|
||
|
*((GLint *)&gc->polygon.shader.frag.color.a) +=
|
||
|
*((GLint *)&gc->polygon.shader.aBig);
|
||
|
}
|
||
|
} else {
|
||
|
if (modeFlags & __GL_SHADE_SMOOTH) {
|
||
|
*((GLint *)&gc->polygon.shader.frag.color.r) +=
|
||
|
*((GLint *)&gc->polygon.shader.rBig);
|
||
|
}
|
||
|
}
|
||
|
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);
|
||
|
}
|
||
|
} else {
|
||
|
/* Use small step */
|
||
|
ixLeft += dxLeftLittle;
|
||
|
if (modeFlags & __GL_SHADE_RGB) {
|
||
|
if (modeFlags & __GL_SHADE_SMOOTH) {
|
||
|
*((GLint *)&gc->polygon.shader.frag.color.r) +=
|
||
|
*((GLint *)&gc->polygon.shader.rLittle);
|
||
|
*((GLint *)&gc->polygon.shader.frag.color.g) +=
|
||
|
*((GLint *)&gc->polygon.shader.gLittle);
|
||
|
*((GLint *)&gc->polygon.shader.frag.color.b) +=
|
||
|
*((GLint *)&gc->polygon.shader.bLittle);
|
||
|
*((GLint *)&gc->polygon.shader.frag.color.a) +=
|
||
|
*((GLint *)&gc->polygon.shader.aLittle);
|
||
|
}
|
||
|
} else {
|
||
|
if (modeFlags & __GL_SHADE_SMOOTH) {
|
||
|
*((GLint *)&gc->polygon.shader.frag.color.r) +=
|
||
|
*((GLint *)&gc->polygon.shader.rLittle);
|
||
|
}
|
||
|
}
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
gc->polygon.shader.ixLeft = ixLeft;
|
||
|
gc->polygon.shader.ixLeftFrac = ixLeftFrac;
|
||
|
gc->polygon.shader.ixRight = ixRight;
|
||
|
gc->polygon.shader.ixRightFrac = ixRightFrac;
|
||
|
|
||
|
#ifdef NT
|
||
|
if (maxWidth > __GL_MAX_STACK_STIPPLE_BITS)
|
||
|
{
|
||
|
__wglTempFree(gc, words);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#define __TWO_31 ((__GLfloat) 2147483648.0)
|
||
|
|
||
|
#define __FRACTION(result,f) \
|
||
|
result = (GLint) ((f) * __TWO_31)
|
||
|
|
||
|
static void SnapXLeft(__GLcontext *gc, __GLfloat xLeft, __GLfloat dxdyLeft)
|
||
|
{
|
||
|
__GLfloat little, dx;
|
||
|
GLint ixLeft, ixLeftFrac, frac, lineBytes, elementSize, ilittle, ibig;
|
||
|
|
||
|
ixLeft = (GLint) xLeft;
|
||
|
dx = xLeft - ixLeft;
|
||
|
__FRACTION(ixLeftFrac,dx);
|
||
|
|
||
|
/* Pre-add .5 to allow truncation in spanWidth calculation */
|
||
|
ixLeftFrac += 0x40000000;
|
||
|
gc->polygon.shader.ixLeft = ixLeft + (((GLuint) ixLeftFrac) >> 31);
|
||
|
gc->polygon.shader.ixLeftFrac = ixLeftFrac & ~0x80000000;
|
||
|
|
||
|
/* Compute big and little steps */
|
||
|
ilittle = (GLint) dxdyLeft;
|
||
|
little = (__GLfloat) ilittle;
|
||
|
if (dxdyLeft < 0) {
|
||
|
ibig = ilittle - 1;
|
||
|
dx = little - dxdyLeft;
|
||
|
__FRACTION(frac,dx);
|
||
|
gc->polygon.shader.dxLeftFrac = -frac;
|
||
|
} else {
|
||
|
ibig = ilittle + 1;
|
||
|
dx = dxdyLeft - little;
|
||
|
__FRACTION(frac,dx);
|
||
|
gc->polygon.shader.dxLeftFrac = frac;
|
||
|
}
|
||
|
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)
|
||
|
{
|
||
|
__GLfloat little, big, dx;
|
||
|
GLint ixRight, ixRightFrac, frac;
|
||
|
|
||
|
ixRight = (GLint) xRight;
|
||
|
dx = xRight - ixRight;
|
||
|
__FRACTION(ixRightFrac,dx);
|
||
|
|
||
|
/* Pre-add .5 to allow truncation in spanWidth calculation */
|
||
|
ixRightFrac += 0x40000000;
|
||
|
sh->ixRight = ixRight + (((GLuint) ixRightFrac) >> 31);
|
||
|
sh->ixRightFrac = ixRightFrac & ~0x80000000;
|
||
|
|
||
|
/* Compute big and little steps */
|
||
|
little = (__GLfloat) ((GLint) dxdyRight);
|
||
|
if (dxdyRight < 0) {
|
||
|
big = little - 1;
|
||
|
dx = little - dxdyRight;
|
||
|
__FRACTION(frac,dx);
|
||
|
sh->dxRightFrac = -frac;
|
||
|
} else {
|
||
|
big = little + 1;
|
||
|
dx = dxdyRight - little;
|
||
|
__FRACTION(frac,dx);
|
||
|
sh->dxRightFrac = frac;
|
||
|
}
|
||
|
sh->dxRightLittle = (GLint) little;
|
||
|
sh->dxRightBig = (GLint) big;
|
||
|
}
|
||
|
|
||
|
static void SetInitialParameters(__GLshade *sh, const __GLvertex *a,
|
||
|
const __GLcolor *ac, __GLfloat aFog,
|
||
|
__GLfloat dx, __GLfloat dy)
|
||
|
{
|
||
|
__GLfloat little = sh->dxLeftLittle;
|
||
|
__GLfloat big = sh->dxLeftBig;
|
||
|
GLuint modeFlags = sh->modeFlags;
|
||
|
|
||
|
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;
|
||
|
|
||
|
FLT_TO_FIX(sh->frag.color.r);
|
||
|
FLT_TO_FIX(sh->frag.color.g);
|
||
|
FLT_TO_FIX(sh->frag.color.b);
|
||
|
FLT_TO_FIX(sh->frag.color.a);
|
||
|
|
||
|
FLT_TO_FIX(sh->rLittle);
|
||
|
FLT_TO_FIX(sh->gLittle);
|
||
|
FLT_TO_FIX(sh->bLittle);
|
||
|
FLT_TO_FIX(sh->aLittle);
|
||
|
|
||
|
FLT_TO_FIX(sh->rBig);
|
||
|
FLT_TO_FIX(sh->gBig);
|
||
|
FLT_TO_FIX(sh->bBig);
|
||
|
FLT_TO_FIX(sh->aBig);
|
||
|
|
||
|
}
|
||
|
} 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;
|
||
|
|
||
|
FLT_TO_FIX(sh->frag.color.r);
|
||
|
FLT_TO_FIX(sh->rLittle);
|
||
|
FLT_TO_FIX(sh->rBig);
|
||
|
}
|
||
|
}
|
||
|
if (modeFlags & __GL_SHADE_DEPTH_ITER) {
|
||
|
__GLfloat zLittle;
|
||
|
|
||
|
sh->frag.z = (__GLzValue)
|
||
|
(a->window.z + dx*sh->dzdxf + dy*sh->dzdyf);
|
||
|
zLittle = sh->dzdyf + little * sh->dzdxf;
|
||
|
sh->zLittle = (GLint)zLittle;
|
||
|
sh->zBig = (GLint)(zLittle + sh->dzdxf);
|
||
|
}
|
||
|
if (modeFlags & __GL_SHADE_SLOW_FOG) {
|
||
|
sh->frag.f = aFog + dx*sh->dfdx + dy*sh->dfdy;
|
||
|
sh->fLittle = sh->dfdy + little * sh->dfdx;
|
||
|
sh->fBig = sh->fLittle + sh->dfdx;
|
||
|
|
||
|
FLT_TO_FIX(sh->frag.f);
|
||
|
FLT_TO_FIX(sh->fLittle);
|
||
|
FLT_TO_FIX(sh->fBig);
|
||
|
}
|
||
|
} 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;
|
||
|
|
||
|
FLT_TO_FIX(sh->frag.color.r);
|
||
|
FLT_TO_FIX(sh->frag.color.g);
|
||
|
FLT_TO_FIX(sh->frag.color.b);
|
||
|
FLT_TO_FIX(sh->frag.color.a);
|
||
|
|
||
|
FLT_TO_FIX(sh->rLittle);
|
||
|
FLT_TO_FIX(sh->gLittle);
|
||
|
FLT_TO_FIX(sh->bLittle);
|
||
|
FLT_TO_FIX(sh->aLittle);
|
||
|
|
||
|
FLT_TO_FIX(sh->rBig);
|
||
|
FLT_TO_FIX(sh->gBig);
|
||
|
FLT_TO_FIX(sh->bBig);
|
||
|
FLT_TO_FIX(sh->aBig);
|
||
|
}
|
||
|
} 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;
|
||
|
|
||
|
FLT_TO_FIX(sh->frag.color.r);
|
||
|
FLT_TO_FIX(sh->rLittle);
|
||
|
FLT_TO_FIX(sh->rBig);
|
||
|
}
|
||
|
}
|
||
|
if (modeFlags & __GL_SHADE_DEPTH_ITER) {
|
||
|
__GLfloat zLittle;
|
||
|
sh->frag.z = (__GLzValue)
|
||
|
(a->window.z + dx*sh->dzdxf + dy*sh->dzdyf);
|
||
|
zLittle = sh->dzdyf + little * sh->dzdxf;
|
||
|
sh->zLittle = (GLint)zLittle;
|
||
|
sh->zBig = (GLint)(zLittle - sh->dzdxf);
|
||
|
}
|
||
|
if (modeFlags & __GL_SHADE_SLOW_FOG) {
|
||
|
sh->frag.f = aFog + dx*sh->dfdx + dy*sh->dfdy;
|
||
|
sh->fLittle = sh->dfdy + little * sh->dfdx;
|
||
|
sh->fBig = sh->fLittle - sh->dfdx;
|
||
|
|
||
|
FLT_TO_FIX(sh->frag.f);
|
||
|
FLT_TO_FIX(sh->fLittle);
|
||
|
FLT_TO_FIX(sh->fBig);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void __fastFillTriangle(__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;
|
||
|
SPANREC deltaRec;
|
||
|
|
||
|
|
||
|
/* Pre-compute one over polygon area */
|
||
|
|
||
|
oneOverArea = __glOne / gc->polygon.shader.area;
|
||
|
|
||
|
/* 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.
|
||
|
*/
|
||
|
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;
|
||
|
gc->polygon.shader.drdx = drAC * t2 - drBC * t1;
|
||
|
gc->polygon.shader.drdy = drBC * t3 - drAC * t4;
|
||
|
dgAC = ac->g - cc->g;
|
||
|
dgBC = bc->g - cc->g;
|
||
|
gc->polygon.shader.dgdx = dgAC * t2 - dgBC * t1;
|
||
|
gc->polygon.shader.dgdy = dgBC * t3 - dgAC * t4;
|
||
|
dbAC = ac->b - cc->b;
|
||
|
dbBC = bc->b - cc->b;
|
||
|
gc->polygon.shader.dbdx = dbAC * t2 - dbBC * t1;
|
||
|
gc->polygon.shader.dbdy = dbBC * t3 - dbAC * t4;
|
||
|
daAC = ac->a - cc->a;
|
||
|
daBC = bc->a - cc->a;
|
||
|
gc->polygon.shader.dadx = daAC * t2 - daBC * t1;
|
||
|
gc->polygon.shader.dady = daBC * t3 - daAC * t4;
|
||
|
|
||
|
RtlCopyMemory(&deltaRec.r, &gc->polygon.shader.drdx,
|
||
|
4 * sizeof(__GLfloat));
|
||
|
|
||
|
FLT_TO_FIX(deltaRec.r);
|
||
|
FLT_TO_FIX(deltaRec.g);
|
||
|
FLT_TO_FIX(deltaRec.b);
|
||
|
FLT_TO_FIX(deltaRec.a);
|
||
|
} else {
|
||
|
__GLcolor *flatColor = gc->vertex.provoking->color;
|
||
|
gc->polygon.shader.frag.color.r = flatColor->r;
|
||
|
gc->polygon.shader.frag.color.g = flatColor->g;
|
||
|
gc->polygon.shader.frag.color.b = flatColor->b;
|
||
|
gc->polygon.shader.frag.color.a = flatColor->a;
|
||
|
|
||
|
FLT_TO_FIX(gc->polygon.shader.frag.color.r);
|
||
|
FLT_TO_FIX(gc->polygon.shader.frag.color.g);
|
||
|
FLT_TO_FIX(gc->polygon.shader.frag.color.b);
|
||
|
FLT_TO_FIX(gc->polygon.shader.frag.color.a);
|
||
|
}
|
||
|
} 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;
|
||
|
|
||
|
deltaRec.r = *((GLint *)&gc->polygon.shader.drdx);
|
||
|
FLT_TO_FIX(deltaRec.r);
|
||
|
} else {
|
||
|
__GLcolor *flatColor = gc->vertex.provoking->color;
|
||
|
gc->polygon.shader.frag.color.r = flatColor->r;
|
||
|
FLT_TO_FIX(gc->polygon.shader.frag.color.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;
|
||
|
deltaRec.z = gc->polygon.shader.dzdx = (GLint) gc->polygon.shader.dzdxf;
|
||
|
}
|
||
|
|
||
|
__fastDeltaSpan(gc, &deltaRec); // Set up span delta values
|
||
|
|
||
|
|
||
|
/* Snap each y coordinate to its pixel center */
|
||
|
aIY = (GLint) (a->window.y + __glHalf);
|
||
|
bIY = (GLint) (b->window.y + __glHalf);
|
||
|
cIY = (GLint) (c->window.y + __glHalf);
|
||
|
|
||
|
/*
|
||
|
** 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) {
|
||
|
dxdyLeft = dxAC / dyAC;
|
||
|
dy = (aIY + __glHalf) - a->window.y;
|
||
|
SnapXLeft(gc, a->window.x + dy*dxdyLeft, dxdyLeft);
|
||
|
dx = (gc->polygon.shader.ixLeft + __glHalf) - a->window.x;
|
||
|
SetInitialParameters(&gc->polygon.shader, a, ac, aFog, dx, dy);
|
||
|
if (aIY != bIY) {
|
||
|
dxdyRight = dxAB / dyAB;
|
||
|
SnapXRight(&gc->polygon.shader, a->window.x + dy*dxdyRight,
|
||
|
dxdyRight);
|
||
|
fastFillSubTriangle(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);
|
||
|
fastFillSubTriangle(gc, bIY, cIY);
|
||
|
}
|
||
|
} else {
|
||
|
dxdyRight = dxAC / dyAC;
|
||
|
dy = (aIY + __glHalf) - a->window.y;
|
||
|
SnapXRight(&gc->polygon.shader, a->window.x + dy*dxdyRight, dxdyRight);
|
||
|
if (aIY != bIY) {
|
||
|
dxdyLeft = dxAB / dyAB;
|
||
|
SnapXLeft(gc, a->window.x + dy*dxdyLeft, dxdyLeft);
|
||
|
dx = (gc->polygon.shader.ixLeft + __glHalf) - a->window.x;
|
||
|
SetInitialParameters(&gc->polygon.shader, a, ac, aFog, dx, dy);
|
||
|
fastFillSubTriangle(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;
|
||
|
SetInitialParameters(&gc->polygon.shader, b, bc, bFog, dx, dy);
|
||
|
fastFillSubTriangle(gc, bIY, cIY);
|
||
|
}
|
||
|
}
|
||
|
}
|