|
|
/******************************Module*Header*******************************\
* Module Name: genaline.c * * * * This module provides accelerated interpolated line support. * * * * Created: 8-Dec-1995 * * Author: Otto Berkes [ottob] * * * * 23-Jan-1996 Drew Bliss [drewb] * * Cut down antialiasing code to provide aliased versions * * Optimized line setup * * * * Copyright (c) 1995-1996 Microsoft Corporation * \**************************************************************************/
#include "precomp.h"
#pragma hdrstop
// #define DO_CHECK_PIXELS
#ifdef _X86_
#include <gli386.h>
#endif
#include "genline.h"
#ifndef NO_COMPILER_BUG
#undef __GL_FLOAT_SIMPLE_BEGIN_DIVIDE
#undef __GL_FLOAT_SIMPLE_END_DIVIDE
#define __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(a, b, c) \
__GL_FLOAT_BEGIN_DIVIDE(a, b, &(c)) #define __GL_FLOAT_SIMPLE_END_DIVIDE(r) \
__GL_FLOAT_END_DIVIDE(&(r)) #endif
// Also used by soft line code
BOOL FASTCALL __glInitLineData(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1) { GLint start, end; __GLfloat x0,y0,x1,y1; __GLfloat minorStart; __GLfloat fdx, fdy; __GLfloat offset; __GLfloat slope; __GLlineState *ls = &gc->state.line; __GLfloat halfWidth; GLint x0frac, x1frac, y0frac, y1frac, totDist; GLint ix0, ix1, iy0, iy1, idx, idy; __GLcolorBuffer *cfb = gc->drawBuffer;
ASSERT_CHOP_ROUND(); gc->line.options.v0 = v0; gc->line.options.v1 = v1; gc->line.options.width = ls->aliasedWidth;
x0 = v0->window.x; y0 = v0->window.y; x1 = v1->window.x; y1 = v1->window.y;
#ifdef DO_CHECK_PIXELS
if (x0 < gc->transform.fminx || x0 >= gc->transform.fmaxx || y0 < gc->transform.fminy || y0 >= gc->transform.fmaxy || x1 < gc->transform.fminx || x1 >= gc->transform.fmaxx || y1 < gc->transform.fminy || y1 >= gc->transform.fmaxy) { DbgPrint("Line coordinates out %.3lf,%.3lf - %.3lf,%.3lf%s\n", x0, y0, x1, y1, !gc->transform.reasonableViewport ? " (unreasonable)" : ""); } #endif
fdx = x1-x0; fdy = y1-y0;
halfWidth = (ls->aliasedWidth - 1) * __glHalf;
ix0 = __GL_VERTEX_FLOAT_TO_INT(x0); x0frac = __GL_VERTEX_FLOAT_FRACTION(x0); iy0 = __GL_VERTEX_FLOAT_TO_INT(y0); y0frac = __GL_VERTEX_FLOAT_FRACTION(y0); ix1 = __GL_VERTEX_FLOAT_TO_INT(x1); x1frac = __GL_VERTEX_FLOAT_FRACTION(x1); iy1 = __GL_VERTEX_FLOAT_TO_INT(y1); y1frac = __GL_VERTEX_FLOAT_FRACTION(y1);
#if 0
DbgPrint("Line %.3lf,%.3lf - %.3lf,%.3lf\n", x0, y0, x1, y1); DbgPrint("Line %d.%03d,%d.%03d - %d.%03d,%d.%03d\n", ix0, x0frac, iy0, y0frac, ix1, x1frac, iy1, y1frac); #endif
// An interesting property of window coordinates is that subtracting
// two of them cancels the exponent so the result is the fixed-point
// difference
idx = CASTINT(x1)-CASTINT(x0); idy = CASTINT(y1)-CASTINT(y0); if (idx > 0) { if (idy > 0) { if (idx > idy) { /* dx > dy > 0 */ gc->line.options.yBig = 1; gc->polygon.shader.sbufBig = cfb->buf.outerWidth+GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth+1;
posxmajor: /* dx > |dy| >= 0 */ gc->line.options.yLittle = 0; gc->line.options.xBig = 1; gc->line.options.xLittle = 1; gc->polygon.shader.sbufLittle = GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufLittle = 1; __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(__glOne, fdx, slope);
start = ix0; end = ix1;
y0frac -= __GL_VERTEX_FRAC_HALF; if (y0frac < 0) y0frac = -y0frac;
totDist = y0frac + x0frac - __GL_VERTEX_FRAC_ONE; if (totDist > 0) start++;
y1frac -= __GL_VERTEX_FRAC_HALF; if (y1frac < 0) y1frac = -y1frac;
totDist = y1frac + x1frac - __GL_VERTEX_FRAC_ONE; if (totDist > 0) end++;
offset = start + __glHalf - x0;
gc->line.options.length = fdx; gc->line.options.numPixels = end - start;
xmajorfinish: gc->line.options.axis = __GL_X_MAJOR; gc->line.options.xStart = start; gc->line.options.offset = offset;
__GL_FLOAT_SIMPLE_END_DIVIDE(slope); gc->line.options.oneOverLength = slope; slope *= fdy;
minorStart = y0 + offset*slope - halfWidth; gc->line.options.yStart = __GL_VERTEX_FLOAT_TO_INT(minorStart); if (gc->line.options.yStart < gc->transform.miny) { gc->line.options.yStart = gc->transform.miny; gc->line.options.fraction = 0; } else if (gc->line.options.yStart >= gc->transform.maxy) { gc->line.options.yStart = gc->transform.maxy-1; gc->line.options.fraction = __GL_VERTEX_PROMOTE_FRACTION( (1 << __GL_VERTEX_FRAC_BITS)-1); } else { gc->line.options.fraction = __GL_VERTEX_PROMOTED_FRACTION(minorStart); } gc->line.options.dfraction = FLT_FRACTION(slope); } else { /* dy >= dx > 0 */ gc->line.options.xBig = 1; gc->polygon.shader.sbufBig = cfb->buf.outerWidth+GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth+1; posymajor: /* dy >= |dx| >= 0, dy != 0 */ gc->line.options.xLittle = 0; gc->line.options.yBig = 1; gc->line.options.yLittle = 1; gc->polygon.shader.sbufLittle = cfb->buf.outerWidth; gc->polygon.shader.zbufLittle = gc->depthBuffer.buf.outerWidth; __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(__glOne, fdy, slope); start = iy0; end = iy1;
x0frac -= __GL_VERTEX_FRAC_HALF; if (x0frac < 0) x0frac = -x0frac;
totDist = y0frac + x0frac - __GL_VERTEX_FRAC_ONE; if (totDist > 0) start++;
x1frac -= __GL_VERTEX_FRAC_HALF; if (x1frac < 0) x1frac = -x1frac;
totDist = y1frac + x1frac - __GL_VERTEX_FRAC_ONE; if (totDist > 0) end++;
offset = start + __glHalf - y0;
gc->line.options.length = fdy; gc->line.options.numPixels = end - start;
ymajorfinish: gc->line.options.axis = __GL_Y_MAJOR; gc->line.options.yStart = start; gc->line.options.offset = offset;
__GL_FLOAT_SIMPLE_END_DIVIDE(slope); gc->line.options.oneOverLength = slope; slope *= fdx; minorStart = x0 + offset*slope - halfWidth; gc->line.options.xStart = __GL_VERTEX_FLOAT_TO_INT(minorStart); if (gc->line.options.xStart < gc->transform.minx) { gc->line.options.xStart = gc->transform.minx; gc->line.options.fraction = 0; } else if (gc->line.options.xStart >= gc->transform.maxx) { gc->line.options.xStart = gc->transform.maxx-1; gc->line.options.fraction = __GL_VERTEX_PROMOTE_FRACTION( (1 << __GL_VERTEX_FRAC_BITS)-1); } else { gc->line.options.fraction = __GL_VERTEX_PROMOTED_FRACTION(minorStart); } gc->line.options.dfraction = FLT_FRACTION(slope); } } else { if (idx > -idy) { /* dx > -dy >= 0 */ gc->line.options.yBig = -1; gc->polygon.shader.sbufBig = GENACCEL(gc).xMultiplier-cfb->buf.outerWidth; gc->polygon.shader.zbufBig = 1-gc->depthBuffer.buf.outerWidth; goto posxmajor; } else { /* -dy >= dx >= 0, dy != 0 */ gc->line.options.xBig = 1; gc->polygon.shader.sbufBig = GENACCEL(gc).xMultiplier-cfb->buf.outerWidth; gc->polygon.shader.zbufBig = 1-gc->depthBuffer.buf.outerWidth; negymajor: /* -dy >= |dx| >= 0, dy != 0 */ gc->line.options.xLittle = 0; gc->line.options.yBig = -1; gc->line.options.yLittle = -1; gc->polygon.shader.sbufLittle = -cfb->buf.outerWidth; gc->polygon.shader.zbufLittle = -gc->depthBuffer.buf.outerWidth;
__GL_FLOAT_BEGIN_DIVIDE(__glOne, -fdy, &slope);
start = iy0; end = iy1;
x0frac -= __GL_VERTEX_FRAC_HALF; if (x0frac < 0) x0frac = -x0frac;
totDist = x0frac - y0frac; if (totDist > 0) start--;
x1frac -= __GL_VERTEX_FRAC_HALF; if (x1frac < 0) x1frac = -x1frac;
totDist = x1frac - y1frac; if (totDist > 0) end--;
offset = y0 - (start + __glHalf);
gc->line.options.length = -fdy; gc->line.options.numPixels = start - end; goto ymajorfinish; } } } else { if (idy > 0) { if (-idx > idy) { /* -dx > dy > 0 */ gc->line.options.yBig = 1; gc->polygon.shader.sbufBig = cfb->buf.outerWidth-GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth-1; negxmajor: /* -dx > |dy| >= 0 */ gc->line.options.yLittle = 0; gc->line.options.xBig = -1; gc->line.options.xLittle = -1; gc->polygon.shader.sbufLittle = -GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufLittle = -1;
__GL_FLOAT_BEGIN_DIVIDE(__glOne, -fdx, &slope);
start = ix0; end = ix1;
y0frac -= __GL_VERTEX_FRAC_HALF; if (y0frac < 0) y0frac = -y0frac;
totDist = y0frac - x0frac; if (totDist > 0) start--;
y1frac -= __GL_VERTEX_FRAC_HALF; if (y1frac < 0) y1frac = -y1frac;
totDist = y1frac - x1frac; if (totDist > 0) end--;
offset = x0 - (start + __glHalf);
gc->line.options.length = -fdx; gc->line.options.numPixels = start - end;
goto xmajorfinish; } else { /* dy >= -dx >= 0, dy != 0 */ gc->line.options.xBig = -1; gc->polygon.shader.sbufBig = cfb->buf.outerWidth-GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth-1; goto posymajor; } } else { if (idx < idy) { /* -dx > -dy >= 0 */ gc->line.options.yBig = -1; gc->polygon.shader.sbufBig = -GENACCEL(gc).xMultiplier-cfb->buf.outerWidth; gc->polygon.shader.zbufBig = -1-gc->depthBuffer.buf.outerWidth; goto negxmajor; } else { /* -dy >= -dx >= 0 */ if ((idx | idy) == 0) { gc->line.options.numPixels = 0; return FALSE; } gc->line.options.xBig = -1; gc->polygon.shader.sbufBig = -GENACCEL(gc).xMultiplier-cfb->buf.outerWidth; gc->polygon.shader.zbufBig = -1-gc->depthBuffer.buf.outerWidth; goto negymajor; } } }
#ifdef DO_CHECK_PIXELS
if (gc->line.options.numPixels > 0) { ix0 = gc->line.options.xStart; iy0 = gc->line.options.yStart; if (ix0 < gc->transform.minx || ix0 >= gc->transform.maxx || iy0 < gc->transform.miny || iy0 >= gc->transform.maxy) { DbgPrint("Start out of bounds %d,%d (%d,%d - %d,%d) for %d,%d\n", ix0, iy0, gc->transform.minx, gc->transform.miny, gc->transform.maxx, gc->transform.maxy, idx, idy); DbgPrint(" Line %.3lf,%.3lf - %.3lf,%.3lf\n", x0, y0, x1, y1); DbgPrint(" Viewport %.3lf,%.3lf - %.3lf,%.3lf%s\n", gc->state.viewport.xCenter, gc->state.viewport.yCenter, gc->state.viewport.xScale, gc->state.viewport.yScale, !gc->transform.reasonableViewport ? " (unreasonable)" : ""); } } #endif
return gc->line.options.numPixels > 0; }
// Only used by fast single-pixel line code
// It differs from glInitLineData only in the removal of halfWidth
BOOL FASTCALL __glInitThinLineData(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1) { GLint start, end; __GLfloat x0,y0,x1,y1; __GLfloat minorStart; __GLfloat fdx, fdy; __GLfloat offset; __GLfloat slope; GLint x0frac, x1frac, y0frac, y1frac, totDist; GLint ix0, ix1, iy0, iy1, idx, idy; __GLcolorBuffer *cfb = gc->drawBuffer;
ASSERT_CHOP_ROUND();
ASSERTOPENGL(gc->state.line.aliasedWidth == __glOne, "ThinAlias setup for wrong line state\n");
x0 = v0->window.x; y0 = v0->window.y; x1 = v1->window.x; y1 = v1->window.y;
#ifdef DO_CHECK_PIXELS
gc->line.options.v0 = v0; gc->line.options.v1 = v1;
if (x0 < gc->transform.fminx || x0 >= gc->transform.fmaxx || y0 < gc->transform.fminy || y0 >= gc->transform.fmaxy || x1 < gc->transform.fminx || x1 >= gc->transform.fmaxx || y1 < gc->transform.fminy || y1 >= gc->transform.fmaxy) { DbgPrint("Line coordinates out %.3lf,%.3lf - %.3lf,%.3lf%s\n", x0, y0, x1, y1, !gc->transform.reasonableViewport ? " (unreasonable)" : ""); } #endif
fdx = x1-x0; fdy = y1-y0;
ix0 = __GL_VERTEX_FLOAT_TO_INT(x0); x0frac = __GL_VERTEX_FLOAT_FRACTION(x0); iy0 = __GL_VERTEX_FLOAT_TO_INT(y0); y0frac = __GL_VERTEX_FLOAT_FRACTION(y0); ix1 = __GL_VERTEX_FLOAT_TO_INT(x1); x1frac = __GL_VERTEX_FLOAT_FRACTION(x1); iy1 = __GL_VERTEX_FLOAT_TO_INT(y1); y1frac = __GL_VERTEX_FLOAT_FRACTION(y1);
#if 0
DbgPrint("Line %.3lf,%.3lf - %.3lf,%.3lf\n", x0, y0, x1, y1); DbgPrint("Line %d.%03d,%d.%03d - %d.%03d,%d.%03d\n", ix0, x0frac, iy0, y0frac, ix1, x1frac, iy1, y1frac); #endif
// An interesting property of window coordinates is that subtracting
// two of them cancels the exponent so the result is the fixed-point
// difference
idx = CASTINT(x1)-CASTINT(x0); idy = CASTINT(y1)-CASTINT(y0); if (idx > 0) { if (idy > 0) { if (idx > idy) { /* dx > dy > 0 */ gc->line.options.yBig = 1; gc->polygon.shader.sbufBig = cfb->buf.outerWidth+GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth+1;
posxmajor: /* dx > |dy| >= 0 */ gc->line.options.yLittle = 0; gc->line.options.xBig = 1; gc->line.options.xLittle = 1; gc->polygon.shader.sbufLittle = GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufLittle = 1; __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(__glOne, fdx, slope);
start = ix0; end = ix1;
y0frac -= __GL_VERTEX_FRAC_HALF; if (y0frac < 0) y0frac = -y0frac;
totDist = y0frac + x0frac - __GL_VERTEX_FRAC_ONE; if (totDist > 0) start++;
y1frac -= __GL_VERTEX_FRAC_HALF; if (y1frac < 0) y1frac = -y1frac;
totDist = y1frac + x1frac - __GL_VERTEX_FRAC_ONE; if (totDist > 0) end++;
offset = start + __glHalf - x0;
gc->line.options.length = fdx; gc->line.options.numPixels = end - start;
xmajorfinish: gc->line.options.axis = __GL_X_MAJOR; gc->line.options.xStart = start; gc->line.options.offset = offset;
__GL_FLOAT_SIMPLE_END_DIVIDE(slope); gc->line.options.oneOverLength = slope; slope *= fdy;
minorStart = y0 + offset*slope; gc->line.options.yStart = __GL_VERTEX_FLOAT_TO_INT(minorStart); if (gc->line.options.yStart < gc->transform.miny) { gc->line.options.yStart = gc->transform.miny; gc->line.options.fraction = 0; } else if (gc->line.options.yStart >= gc->transform.maxy) { gc->line.options.yStart = gc->transform.maxy-1; gc->line.options.fraction = __GL_VERTEX_PROMOTE_FRACTION( (1 << __GL_VERTEX_FRAC_BITS)-1); } else { gc->line.options.fraction = __GL_VERTEX_PROMOTED_FRACTION(minorStart); }
gc->line.options.dfraction = FLT_FRACTION(slope); } else { /* dy >= dx > 0 */ gc->line.options.xBig = 1; gc->polygon.shader.sbufBig = cfb->buf.outerWidth+GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth+1; posymajor: /* dy >= |dx| >= 0, dy != 0 */ gc->line.options.xLittle = 0; gc->line.options.yBig = 1; gc->line.options.yLittle = 1; gc->polygon.shader.sbufLittle = cfb->buf.outerWidth; gc->polygon.shader.zbufLittle = gc->depthBuffer.buf.outerWidth; __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(__glOne, fdy, slope); start = iy0; end = iy1;
x0frac -= __GL_VERTEX_FRAC_HALF; if (x0frac < 0) x0frac = -x0frac;
totDist = y0frac + x0frac - __GL_VERTEX_FRAC_ONE; if (totDist > 0) start++;
x1frac -= __GL_VERTEX_FRAC_HALF; if (x1frac < 0) x1frac = -x1frac;
totDist = y1frac + x1frac - __GL_VERTEX_FRAC_ONE; if (totDist > 0) end++;
offset = start + __glHalf - y0;
gc->line.options.length = fdy; gc->line.options.numPixels = end - start;
ymajorfinish: gc->line.options.axis = __GL_Y_MAJOR; gc->line.options.yStart = start; gc->line.options.offset = offset;
__GL_FLOAT_SIMPLE_END_DIVIDE(slope); gc->line.options.oneOverLength = slope; slope *= fdx; minorStart = x0 + offset*slope; gc->line.options.xStart = __GL_VERTEX_FLOAT_TO_INT(minorStart); if (gc->line.options.xStart < gc->transform.minx) { gc->line.options.xStart = gc->transform.minx; gc->line.options.fraction = 0; } else if (gc->line.options.xStart >= gc->transform.maxx) { gc->line.options.xStart = gc->transform.maxx-1; gc->line.options.fraction = __GL_VERTEX_PROMOTE_FRACTION( (1 << __GL_VERTEX_FRAC_BITS)-1); } else { gc->line.options.fraction = __GL_VERTEX_PROMOTED_FRACTION(minorStart); } gc->line.options.dfraction = FLT_FRACTION(slope); } } else { if (idx > -idy) { /* dx > -dy >= 0 */ gc->line.options.yBig = -1; gc->polygon.shader.sbufBig = GENACCEL(gc).xMultiplier-cfb->buf.outerWidth; gc->polygon.shader.zbufBig = 1-gc->depthBuffer.buf.outerWidth; goto posxmajor; } else { /* -dy >= dx >= 0, dy != 0 */ gc->line.options.xBig = 1; gc->polygon.shader.sbufBig = GENACCEL(gc).xMultiplier-cfb->buf.outerWidth; gc->polygon.shader.zbufBig = 1-gc->depthBuffer.buf.outerWidth; negymajor: /* -dy >= |dx| >= 0, dy != 0 */ gc->line.options.xLittle = 0; gc->line.options.yBig = -1; gc->line.options.yLittle = -1; gc->polygon.shader.sbufLittle = -cfb->buf.outerWidth; gc->polygon.shader.zbufLittle = -gc->depthBuffer.buf.outerWidth;
__GL_FLOAT_BEGIN_DIVIDE(__glOne, -fdy, &slope);
start = iy0; end = iy1;
x0frac -= __GL_VERTEX_FRAC_HALF; if (x0frac < 0) x0frac = -x0frac;
totDist = x0frac - y0frac; if (totDist > 0) start--;
x1frac -= __GL_VERTEX_FRAC_HALF; if (x1frac < 0) x1frac = -x1frac;
totDist = x1frac - y1frac; if (totDist > 0) end--;
offset = y0 - (start + __glHalf);
gc->line.options.length = -fdy; gc->line.options.numPixels = start - end; goto ymajorfinish; } } } else { if (idy > 0) { if (-idx > idy) { /* -dx > dy > 0 */ gc->line.options.yBig = 1; gc->polygon.shader.sbufBig = cfb->buf.outerWidth-GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth-1; negxmajor: /* -dx > |dy| >= 0 */ gc->line.options.yLittle = 0; gc->line.options.xBig = -1; gc->line.options.xLittle = -1; gc->polygon.shader.sbufLittle = -GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufLittle = -1;
__GL_FLOAT_BEGIN_DIVIDE(__glOne, -fdx, &slope);
start = ix0; end = ix1;
y0frac -= __GL_VERTEX_FRAC_HALF; if (y0frac < 0) y0frac = -y0frac;
totDist = y0frac - x0frac; if (totDist > 0) start--;
y1frac -= __GL_VERTEX_FRAC_HALF; if (y1frac < 0) y1frac = -y1frac;
totDist = y1frac - x1frac; if (totDist > 0) end--;
offset = x0 - (start + __glHalf);
gc->line.options.length = -fdx; gc->line.options.numPixels = start - end;
goto xmajorfinish; } else { /* dy >= -dx >= 0, dy != 0 */ gc->line.options.xBig = -1; gc->polygon.shader.sbufBig = cfb->buf.outerWidth-GENACCEL(gc).xMultiplier; gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth-1; goto posymajor; } } else { if (idx < idy) { /* -dx > -dy >= 0 */ gc->line.options.yBig = -1; gc->polygon.shader.sbufBig = -GENACCEL(gc).xMultiplier-cfb->buf.outerWidth; gc->polygon.shader.zbufBig = -1-gc->depthBuffer.buf.outerWidth; goto negxmajor; } else { /* -dy >= -dx >= 0 */ if ((idx | idy) == 0) { gc->line.options.numPixels = 0; return FALSE; } gc->line.options.xBig = -1; gc->polygon.shader.sbufBig = -GENACCEL(gc).xMultiplier-cfb->buf.outerWidth; gc->polygon.shader.zbufBig = -1-gc->depthBuffer.buf.outerWidth; goto negymajor; } } }
#ifdef DO_CHECK_PIXELS
if (gc->line.options.numPixels > 0) { ix0 = gc->line.options.xStart; iy0 = gc->line.options.yStart; if (ix0 < gc->transform.minx || ix0 >= gc->transform.maxx || iy0 < gc->transform.miny || iy0 >= gc->transform.maxy) { DbgPrint("Start out of bounds %d,%d (%d,%d - %d,%d) for %d,%d\n", ix0, iy0, gc->transform.minx, gc->transform.miny, gc->transform.maxx, gc->transform.maxy, idx, idy); DbgPrint(" Line %.3lf,%.3lf - %.3lf,%.3lf\n", x0, y0, x1, y1); DbgPrint(" Viewport %.3lf,%.3lf - %.3lf,%.3lf%s\n", gc->state.viewport.xCenter, gc->state.viewport.yCenter, gc->state.viewport.xScale, gc->state.viewport.yScale, !gc->transform.reasonableViewport ? " (unreasonable)" : ""); } } #endif
return gc->line.options.numPixels > 0; }
// Called to render both anti-aliased and aliased lines
void FASTCALL __glGenRenderEitherLine(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1, GLuint flags) { __GLfloat invDelta; GLuint modeFlags = gc->polygon.shader.modeFlags;
CHOP_ROUND_ON();
if (!(*GENACCEL(gc).__fastGenInitLineData)(gc, v0, v1)) { CHOP_ROUND_OFF(); return; }
ASSERTOPENGL(GENACCEL(gc).rAccelScale == FIX_SCALEFACT, "rAccelScale != FIX_SCALEFACT\n"); ASSERTOPENGL(GENACCEL(gc).gAccelScale == FIX_SCALEFACT, "gAccelScale != FIX_SCALEFACT\n"); ASSERTOPENGL(GENACCEL(gc).bAccelScale == FIX_SCALEFACT, "bAccelScale != FIX_SCALEFACT\n"); // Alpha is always scaled between 0 and 255
invDelta = gc->line.options.oneOverLength; /*
** Set up increments for any enabled line options. */
if ((gc->drawBuffer->buf.flags & DIB_FORMAT) == 0) { // For non-DIBs we pick up the bytes from ColorsBits so
// the pixel pointer doesn't move
gc->polygon.shader.sbufLittle = 0; gc->polygon.shader.sbufBig = 0; }
if (modeFlags & __GL_SHADE_SMOOTH) { __GLcolor *c0 = v0->color; __GLcolor *c1 = v1->color;
/*
** Calculate red, green, blue and alpha value increments. */
if (gc->modes.rgbMode) { __GLfloat dr, dg, db; #ifdef _X86_
__asm { ; Compute dr, dg and db mov eax, c0 mov edx, c1 fld DWORD PTR [eax+COLOR_r] fld DWORD PTR [eax+COLOR_g] fld DWORD PTR [eax+COLOR_b] fld DWORD PTR [edx+COLOR_r] fsub st(0), st(3) fld DWORD PTR [edx+COLOR_g] fsub st(0), st(3) fld DWORD PTR [edx+COLOR_b] fsub st(0), st(3) mov edx, gc fstp db fstp dg fstp dr FLT_STACK_RGB_TO_GC_FIXED(GC_SHADER_R, GC_SHADER_G, GC_SHADER_B) } #else
dr = c1->r - c0->r; CASTFIX(gc->polygon.shader.frag.color.r) = UNSAFE_FLT_TO_FIX(c0->r); dg = c1->g - c0->g; CASTFIX(gc->polygon.shader.frag.color.g) = UNSAFE_FLT_TO_FIX(c0->g); db = c1->b - c0->b; CASTFIX(gc->polygon.shader.frag.color.b) = UNSAFE_FLT_TO_FIX(c0->b); #endif
if ((CASTINT(dr) | CASTINT(dg) | CASTINT(db)) == 0) { CASTINT(gc->polygon.shader.drdx) = 0; CASTINT(gc->polygon.shader.dgdx) = 0; CASTINT(gc->polygon.shader.dbdx) = 0; } else { #ifdef _X86_
__asm { fld dr fld dg fld db fld invDelta fmul __glVal65536 mov edx, gc fmul st(3), st(0) fmul st(2), st(0) fmulp st(1), st(0) fistp DWORD PTR [edx+GC_SHADE_dbdx] fistp DWORD PTR [edx+GC_SHADE_dgdx] fistp DWORD PTR [edx+GC_SHADE_drdx] } #else
CASTFIX(gc->polygon.shader.drdx) = UNSAFE_FLT_TO_FIX(dr * invDelta); CASTFIX(gc->polygon.shader.dgdx) = UNSAFE_FLT_TO_FIX(dg * invDelta); CASTFIX(gc->polygon.shader.dbdx) = UNSAFE_FLT_TO_FIX(db * invDelta); #endif
}
if (gc->state.enables.general & __GL_BLEND_ENABLE) { __GLfloat da; da = c1->a - c0->a; CASTFIX(gc->polygon.shader.frag.color.a) = UNSAFE_FTOL(c0->a * GENACCEL(gc).aAccelScale); if (__GL_FLOAT_EQZ(da)) { CASTINT(gc->polygon.shader.dadx) = 0; } else { CASTFIX(gc->polygon.shader.dadx) = UNSAFE_FTOL(da * invDelta * GENACCEL(gc).aAccelScale); } } } else { __GLfloat dr; dr = c1->r - c0->r; CASTFIX(gc->polygon.shader.frag.color.r) = UNSAFE_FLT_TO_FIX(c0->r);
if (__GL_FLOAT_EQZ(dr)) { CASTINT(gc->polygon.shader.drdx) = 0; } else { CASTFIX(gc->polygon.shader.drdx) = UNSAFE_FLT_TO_FIX(dr * invDelta); } } } else { __GLcolor *c1 = v0->color;
if (gc->modes.rgbMode) { #ifdef _X86_
__asm { mov eax, c1 fld DWORD PTR [eax+COLOR_r] fld DWORD PTR [eax+COLOR_g] fld DWORD PTR [eax+COLOR_b] mov edx, gc FLT_STACK_RGB_TO_GC_FIXED(GC_SHADER_R, GC_SHADER_G, GC_SHADER_B) } #else
CASTFIX(gc->polygon.shader.frag.color.r) = UNSAFE_FLT_TO_FIX(c1->r); CASTFIX(gc->polygon.shader.frag.color.g) = UNSAFE_FLT_TO_FIX(c1->g); CASTFIX(gc->polygon.shader.frag.color.b) = UNSAFE_FLT_TO_FIX(c1->b); #endif
if (gc->state.enables.general & __GL_BLEND_ENABLE) { CASTFIX(gc->polygon.shader.frag.color.a) = UNSAFE_FTOL(c1->a * GENACCEL(gc).aAccelScale); } } else { CASTFIX(gc->polygon.shader.frag.color.r) = UNSAFE_FLT_TO_FIX(c1->r); } } if (modeFlags & __GL_SHADE_DEPTH_ITER) { // The increment is in USHORT units so it only needs to be
// scaled in the 32-bit Z buffer case
if (gc->depthBuffer.buf.elementSize == 4) { gc->polygon.shader.zbufLittle <<= 1; gc->polygon.shader.zbufBig <<= 1; }
/*
** Calculate window z coordinate increment and starting position. */ if(( gc->modes.depthBits == 16 ) && ( gc->depthBuffer.scale <= (GLuint)0xffff )) { ASSERTOPENGL(Z16_SCALE == FIX_SCALEFACT, "Z16 scaling different from fixed\n"); gc->polygon.shader.dzdx = FLT_TO_Z16_SCALE((v1->window.z - v0->window.z) * invDelta); gc->polygon.shader.frag.z = FTOL(v0->window.z*Z16_SCALE + gc->polygon.shader.dzdx * gc->line.options.offset); } else { gc->polygon.shader.dzdx = FTOL((v1->window.z - v0->window.z) * invDelta); gc->polygon.shader.frag.z = FTOL(v0->window.z + gc->polygon.shader.dzdx * gc->line.options.offset); } }
(*GENACCEL(gc).__fastGenLineProc)(gc);
CHOP_ROUND_OFF(); }
#define DITHER_PIXEL(pPix, x, y)\
{\ ULONG r, g, b;\ DWORD ditherVal;\ \ ditherVal = ditherShade[((x) & 0x3) + \ (((y) & 0x3) << 3)];\ \ r = ((rAccum + ditherVal) >> (16-RSHIFT)) & RMASK;\ g = ((gAccum + ditherVal) >> (16-GSHIFT)) & GMASK;\ b = ((bAccum + ditherVal) >> (16-BSHIFT)) & BMASK;\ \ WRITE_PIX(pPix);\ }
#define BLEND_PIXEL(pPix, alpha, x, y)\
{\ ULONG pix;\ ULONG rDisplay, gDisplay, bDisplay, aDisplay;\ ULONG r, g, b;\ ULONG invAlpha;\ DWORD ditherVal;\ \ ditherVal = ditherShade[((x) & 0x3) + \ (((y) & 0x3) << 3)];\ \ aDisplay = (gbMulTable[((aAccum >> 16) & 0xff) | (alpha)]) << 8;\ \ pix = READ_PIX(pPix);\ \ rDisplay = ((pix & RMASK) >> RSHIFT) << (8 - RBITS);\ gDisplay = ((pix & GMASK) >> GSHIFT) << (8 - GBITS);\ bDisplay = ((pix & BMASK) >> BSHIFT) << (8 - BBITS);\ \ if (gc->state.raster.blendDst == GL_ONE) { \ \ r = (gbMulTable[((rAccum >> (RBITS+8)) & 0xff) | aDisplay] + rDisplay)\ + (ditherVal >> (RBITS + 8));\ g = (gbMulTable[((gAccum >> (GBITS+8)) & 0xff) | aDisplay] + gDisplay)\ + (ditherVal >> (GBITS + 8));\ b = (gbMulTable[((bAccum >> (BBITS+8)) & 0xff) | aDisplay] + bDisplay)\ + (ditherVal >> (BBITS + 8));\ r = ((gbSatTable[r] << (RBITS+8)) \ >> (16 - RSHIFT)) & RMASK;\ g = ((gbSatTable[g] << (GBITS+8)) \ >> (16 - GSHIFT)) & GMASK;\ b = ((gbSatTable[b] << (BBITS+8)) \ >> (16 - BSHIFT)) & BMASK;\ \ } else { \ \ invAlpha = 0xff00 - (ULONG)aDisplay;\ \ rDisplay = gbMulTable[rDisplay | invAlpha];\ gDisplay = gbMulTable[gDisplay | invAlpha];\ bDisplay = gbMulTable[bDisplay | invAlpha];\ \ r = ((((gbMulTable[((rAccum >> (RBITS+8)) & 0xff) | aDisplay] + rDisplay)\ << (RBITS+8)) + ditherVal) >> (16 - RSHIFT)) & RMASK;\ \ g = ((((gbMulTable[((gAccum >> (GBITS+8)) & 0xff) | aDisplay] + gDisplay)\ << (GBITS+8)) + ditherVal) >> (16 - GSHIFT)) & GMASK;\ \ b = ((((gbMulTable[((bAccum >> (BBITS+8)) & 0xff) | aDisplay] + bDisplay)\ << (BBITS+8)) + ditherVal) >> (16 - BSHIFT)) & BMASK;\ } \ \ WRITE_PIX(pPix);\ }
#define WRITE_PIXEL_GEN(pPix, alpha, x, y)\
if (gc->state.enables.general & __GL_BLEND_ENABLE) {\ ULONG pix;\ ULONG rDisplay, gDisplay, bDisplay, aDisplay;\ ULONG r, g, b;\ ULONG invAlpha;\ DWORD ditherVal;\ \ if (modeFlags & __GL_SHADE_DITHER) {\ ditherVal = ditherShade[((x) & 0x3) + \ (((y) & 0x3) << 3)];\ } else\ ditherVal = 0;\ \ aDisplay = (gbMulTable[((aAccum >> 16) & 0xff) | (alpha)]) << 8;\ \ switch (bytesPerPixel) {\ case 1:\ pix = ((__GLGENcontext *)gc)->pajInvTranslateVector[*((BYTE *)(pPix))];\ rDisplay = ((pix & rMask) >> rShift) << (8 - rBits);\ gDisplay = ((pix & gMask) >> gShift) << (8 - gBits);\ bDisplay = ((pix & bMask) >> bShift) << (8 - bBits);\ break;\ case 2:\ pix = *((USHORT *)(pPix));\ rDisplay = ((pix & rMask) >> rShift) << (8 - rBits);\ gDisplay = ((pix & gMask) >> gShift) << (8 - gBits);\ bDisplay = ((pix & bMask) >> bShift) << (8 - bBits);\ break;\ case 3:\ default:\ if (rShift > bShift) {\ rDisplay = pPix[2];\ gDisplay = pPix[1];\ bDisplay = pPix[0];\ } else {\ rDisplay = pPix[0];\ gDisplay = pPix[1];\ bDisplay = pPix[2];\ }\ break;\ }\ \ if (gc->state.raster.blendDst == GL_ONE) { \ \ r = (gbMulTable[((rAccum >> (rBits+8)) & 0xff) | aDisplay] + rDisplay)\ + (ditherVal >> (rBits + 8));\ g = (gbMulTable[((gAccum >> (gBits+8)) & 0xff) | aDisplay] + gDisplay)\ + (ditherVal >> (gBits + 8));\ b = (gbMulTable[((bAccum >> (bBits+8)) & 0xff) | aDisplay] + bDisplay)\ + (ditherVal >> (bBits + 8));\ r = ((gbSatTable[r] << (rBits+8)) \ >> (16 - rShift)) & rMask;\ g = ((gbSatTable[g] << (gBits+8)) \ >> (16 - gShift)) & gMask;\ b = ((gbSatTable[b] << (bBits+8)) \ >> (16 - bShift)) & bMask;\ \ } else { \ \ invAlpha = 0xff00 - (ULONG)aDisplay;\ \ rDisplay = gbMulTable[rDisplay | invAlpha];\ gDisplay = gbMulTable[gDisplay | invAlpha];\ bDisplay = gbMulTable[bDisplay | invAlpha];\ \ r = ((((gbMulTable[((rAccum >> (rBits+8)) & 0xff) | aDisplay] + rDisplay)\ << (rBits+8)) + ditherVal) >> (16 - rShift)) & rMask;\ \ g = ((((gbMulTable[((gAccum >> (gBits+8)) & 0xff) | aDisplay] + gDisplay)\ << (gBits+8)) + ditherVal) >> (16 - gShift)) & gMask;\ \ b = ((((gbMulTable[((bAccum >> (bBits+8)) & 0xff) | aDisplay] + bDisplay)\ << (bBits+8)) + ditherVal) >> (16 - bShift)) & bMask;\ } \ \ switch (bytesPerPixel) {\ case 1:\ pPix[0] = ((__GLGENcontext *)gc)->xlatPalette[r | g | b];\ break;\ case 2:\ *((USHORT *)pPix) = (USHORT)(r | g | b);\ break;\ case 3:\ pix = r | g | b;\ *((USHORT UNALIGNED *)pPix) = (USHORT)pix;\ pPix[2] = (BYTE)(pix >> 16);\ break;\ default:\ *((DWORD *)pPix) = (DWORD)(r | g | b);\ break;\ }\ } else {\ ULONG r, g, b;\ DWORD ditherVal;\ ULONG pix;\ \ if (modeFlags & __GL_SHADE_DITHER) {\ ditherVal = ditherShade[((x) & 0x3) + (((y) & 0x3) << 3)];\ } else\ ditherVal = 0;\ \ r = ((rAccum + ditherVal) >> (16-rShift)) & rMask;\ g = ((gAccum + ditherVal) >> (16-gShift)) & gMask;\ b = ((bAccum + ditherVal) >> (16-bShift)) & bMask;\ \ switch (bytesPerPixel) {\ case 1:\ pPix[0] = ((__GLGENcontext *)gc)->xlatPalette[r | g | b];\ break;\ case 2:\ *((USHORT *)pPix) = (USHORT)(r | g | b);\ break;\ case 3:\ pix = r | g | b;\ *((USHORT UNALIGNED *)pPix) = (USHORT)pix;\ pPix[2] = (BYTE)(pix >> 16);\ break;\ default:\ *((DWORD *)pPix) = (DWORD)(r | g | b);\ break;\ }\ }
#ifdef DO_CHECK_PIXELS
#define CHECK_PIXEL(gc, cfb, count, bx, by) \
{\ GLint fbX, fbY;\ \ fbX = __GL_UNBIAS_X(gc, bx);\ fbY = __GL_UNBIAS_Y(gc, by);\ if (!(fbX >= 0 && fbX < (cfb)->buf.width &&\ fbY >= 0 && fbY < (cfb)->buf.height))\ {\ DbgPrint("Pixel out of bounds at %c %d of %d: %d,%d (%d,%d)\n",\ (gc)->line.options.axis == __GL_Y_MAJOR ? 'Y' : 'X',\ (gc)->line.options.numPixels-(count),\ (gc)->line.options.numPixels,\ fbX, fbY, (cfb)->buf.width, (cfb)->buf.height);\ DbgPrint(" Line %.3lf,%.3lf - %.3lf,%.3lf\n",\ (gc)->line.options.v0->window.x,\ (gc)->line.options.v0->window.y,\ (gc)->line.options.v1->window.x,\ (gc)->line.options.v1->window.y);\ }\ } #else
#define CHECK_PIXEL(gc, cfb, w, x, y)
#endif
#define FAST_AA_LINE \
{\ GLint xLittle, xBig, yLittle, yBig;\ GLint fragX2, fragY2;\ BYTE *pPix;\ BYTE *pPix2;\ USHORT *pZ;\ USHORT *pZ2;\ __GLfragment frag;\ __GLcolorBuffer *cfb = gc->drawBuffer;\ LONG rAccum, gAccum, bAccum, aAccum;\ LONG pixAdjStep;\ ULONG zAdjStep;\ ULONG coverage, invCoverage;\ LONG fragXinc;\ LONG fragYinc;\ LONG bytesPerPixel;\ __GLzValue zAccum;\ GLint clipX1 = gc->transform.clipX1;\ GLint clipY1 = gc->transform.clipY1;\ \ GLint fraction, dfraction;\ GLint w;\ GLuint modeFlags = gc->polygon.shader.modeFlags;\ \ ASSERTOPENGL((cfb->buf.flags &\ (DIB_FORMAT | NO_CLIP)) == (DIB_FORMAT | NO_CLIP),\ "FAST_AA_LINE on clipping surface\n");\ \ fraction = gc->line.options.fraction;\ dfraction = gc->line.options.dfraction;\ \ xBig = gc->line.options.xBig;\ yBig = gc->line.options.yBig;\ xLittle = gc->line.options.xLittle;\ yLittle = gc->line.options.yLittle;\ \ frag.x = gc->line.options.xStart;\ frag.y = gc->line.options.yStart;\ \ bytesPerPixel = GENACCEL(gc).xMultiplier;\ \ if (gc->line.options.axis == __GL_Y_MAJOR) {\ pixAdjStep = bytesPerPixel;\ zAdjStep = 1;\ fragXinc = 1;\ fragYinc = 0;\ } else {\ pixAdjStep = cfb->buf.outerWidth;\ zAdjStep = gc->depthBuffer.buf.outerWidth;\ fragXinc = 0;\ fragYinc = 1;\ }\ \ pPix = (BYTE *)((ULONG_PTR)cfb->buf.base +\ (__GL_UNBIAS_Y(gc, frag.y) + cfb->buf.yOrigin) * cfb->buf.outerWidth +\ (__GL_UNBIAS_X(gc, frag.x) + cfb->buf.xOrigin) * bytesPerPixel);\ \ if (modeFlags & __GL_SHADE_DEPTH_TEST) {\ zAccum = gc->polygon.shader.frag.z;\ \ if( gc->modes.depthBits == 32 ) {\ pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),\ frag.x, frag.y);\ \ zAdjStep *= 2;\ } else {\ pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer,\ (__GLz16Value*),\ frag.x, frag.y);\ }\ \ }\ \ rAccum = CASTFIX(gc->polygon.shader.frag.color.r);\ gAccum = CASTFIX(gc->polygon.shader.frag.color.g);\ bAccum = CASTFIX(gc->polygon.shader.frag.color.b);\ aAccum = CASTFIX(gc->polygon.shader.frag.color.a);\ \ w = gc->line.options.numPixels;\ for (;;)\ {\ CHECK_PIXEL(gc, cfb, w, frag.x, frag.y);\ \ invCoverage = ((fraction << 1) & 0xff000000) >> 16;\ coverage = 0xff00 - invCoverage;\ \ if (modeFlags & __GL_SHADE_DEPTH_TEST) {\ if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ ))\ goto noWrite1;\ }\ \ BLEND_PIXEL(pPix, coverage, frag.x, frag.y);\ noWrite1:\ \ fragX2 = frag.x + fragXinc;\ fragY2 = frag.y + fragYinc;\ if ((fragX2 >= clipX1) || (fragY2 >= clipY1)) {\ goto noWrite2;\ }\ \ pZ2 = pZ+zAdjStep;\ if (modeFlags & __GL_SHADE_DEPTH_TEST) {\ if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ2 ))\ goto noWrite2;\ }\ \ pPix2 = pPix + pixAdjStep;\ BLEND_PIXEL(pPix2, invCoverage, fragX2, fragY2);\ noWrite2:\ \ if (--w <= 0)\ return GL_TRUE;\ \ fraction += dfraction;\ if (fraction < 0) {\ fraction &= ~0x80000000;\ frag.x += xBig;\ frag.y += yBig;\ pPix += gc->polygon.shader.sbufBig;\ pZ += gc->polygon.shader.zbufBig;\ } else {\ frag.x += xLittle;\ frag.y += yLittle;\ pPix += gc->polygon.shader.sbufLittle;\ pZ += gc->polygon.shader.zbufLittle;\ }\ \ if (modeFlags & __GL_SHADE_SMOOTH) {\ rAccum += CASTFIX(gc->polygon.shader.drdx);\ gAccum += CASTFIX(gc->polygon.shader.dgdx);\ bAccum += CASTFIX(gc->polygon.shader.dbdx);\ aAccum += CASTFIX(gc->polygon.shader.dadx);\ }\ \ if (modeFlags & __GL_SHADE_DEPTH_ITER) {\ zAccum += gc->polygon.shader.dzdx;\ }\ }\ \ return GL_TRUE;\ }
/************************************************************************/
#undef BPP
#undef RSHIFT
#undef GSHIFT
#undef BSHIFT
#undef RBITS
#undef GBITS
#undef BBITS
#undef RMASK
#undef GMASK
#undef BMASK
#undef READ_PIX
#undef WRITE_PIX
#define RSHIFT 0
#define GSHIFT 3
#define BSHIFT 6
#define RBITS 3
#define GBITS 3
#define BBITS 2
#define RMASK (((1 << RBITS) - 1) << RSHIFT)
#define GMASK (((1 << GBITS) - 1) << GSHIFT)
#define BMASK (((1 << BBITS) - 1) << BSHIFT)
#define BPP 8
#define READ_PIX(pPix) \
((__GLGENcontext *)gc)->pajInvTranslateVector[*((BYTE *)(pPix))] #define WRITE_PIX(pPix) \
pPix[0] = ((__GLGENcontext *)gc)->xlatPalette[r | g | b]
GLboolean FASTCALL __fastGenAntiAliasLine332(__GLcontext *gc) FAST_AA_LINE
#undef BPP
#undef RSHIFT
#undef GSHIFT
#undef BSHIFT
#undef RBITS
#undef GBITS
#undef BBITS
#undef RMASK
#undef GMASK
#undef BMASK
#undef READ_PIX
#undef WRITE_PIX
#define RSHIFT 10
#define GSHIFT 5
#define BSHIFT 0
#define RBITS 5
#define GBITS 5
#define BBITS 5
#define RMASK (((1 << RBITS) - 1) << RSHIFT)
#define GMASK (((1 << GBITS) - 1) << GSHIFT)
#define BMASK (((1 << BBITS) - 1) << BSHIFT)
#define BPP 16
#define READ_PIX(pPix) \
*((USHORT *)(pPix)) #define WRITE_PIX(pPix) \
*((USHORT *)pPix) = (USHORT)(r | g | b)
GLboolean FASTCALL __fastGenAntiAliasLine555(__GLcontext *gc) FAST_AA_LINE
#undef BPP
#undef RSHIFT
#undef GSHIFT
#undef BSHIFT
#undef RBITS
#undef GBITS
#undef BBITS
#undef RMASK
#undef GMASK
#undef BMASK
#undef READ_PIX
#undef WRITE_PIX
#define RSHIFT 11
#define GSHIFT 5
#define BSHIFT 0
#define RBITS 5
#define GBITS 6
#define BBITS 5
#define RMASK (((1 << RBITS) - 1) << RSHIFT)
#define GMASK (((1 << GBITS) - 1) << GSHIFT)
#define BMASK (((1 << BBITS) - 1) << BSHIFT)
#define BPP 16
#define READ_PIX(pPix) \
*((USHORT *)(pPix)) #define WRITE_PIX(pPix) \
*((USHORT *)pPix) = (USHORT)(r | g | b)
GLboolean FASTCALL __fastGenAntiAliasLine565(__GLcontext *gc) FAST_AA_LINE
GLboolean FASTCALL __fastGenAntiAliasLine(__GLcontext *gc) { GLint xLittle, xBig, yLittle, yBig; GLint fragX2, fragY2; BYTE *pPix; BYTE *pPix2; USHORT *pZ; USHORT *pZ2; __GLfragment frag; __GLcolorBuffer *cfb = gc->drawBuffer; LONG rAccum, gAccum, bAccum, aAccum; ULONG rMask, gMask, bMask; ULONG rShift, gShift, bShift; ULONG rBits, gBits, bBits; LONG bytesPerPixel; LONG pixAdjStep; ULONG zAdjStep; ULONG coverage, invCoverage; LONG fragXinc; LONG fragYinc; GLint cfbX, cfbY; int copyPix; __GLGENcontext *gengc = (__GLGENcontext *)gc; __GLzValue zAccum; GLint clipX1 = gc->transform.clipX1; GLint clipY1 = gc->transform.clipY1;
GLint fraction, dfraction; GLint w; GLuint modeFlags = gc->polygon.shader.modeFlags;
w = gc->line.options.numPixels;
fraction = gc->line.options.fraction; dfraction = gc->line.options.dfraction;
xBig = gc->line.options.xBig; yBig = gc->line.options.yBig; xLittle = gc->line.options.xLittle; yLittle = gc->line.options.yLittle;
frag.x = gc->line.options.xStart; frag.y = gc->line.options.yStart;
bytesPerPixel = GENACCEL(gc).xMultiplier;
if (gc->line.options.axis == __GL_Y_MAJOR) { pixAdjStep = bytesPerPixel; zAdjStep = 1; fragXinc = 1; fragYinc = 0; // For Y-major non-DIB lines we can copy both affected pixels
// at once since they are adjacent in memory
copyPix = 2; } else { if ((cfb->buf.flags & DIB_FORMAT) != 0) { pixAdjStep = cfb->buf.outerWidth; } else { pixAdjStep = 0; } zAdjStep = gc->depthBuffer.buf.outerWidth; fragXinc = 0; fragYinc = 1; copyPix = 1; }
if ((cfb->buf.flags & DIB_FORMAT) != 0) { pPix = (BYTE *)((ULONG_PTR)cfb->buf.base + (__GL_UNBIAS_Y(gc, frag.y) + cfb->buf.yOrigin) * cfb->buf.outerWidth + (__GL_UNBIAS_X(gc, frag.x) + cfb->buf.xOrigin) * bytesPerPixel); } else { pPix = gengc->ColorsBits; }
if (modeFlags & __GL_SHADE_DEPTH_TEST) { zAccum = gc->polygon.shader.frag.z;
if( gc->modes.depthBits == 32 ) { pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*), frag.x, frag.y); // Adjust for pZ being a USHORT * but traversing a 32-bit
// depth buffer
zAdjStep *= 2; } else { pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLz16Value*), frag.x, frag.y); } }
rShift = cfb->redShift; gShift = cfb->greenShift; bShift = cfb->blueShift;
rMask = gc->modes.redMask; gMask = gc->modes.greenMask; bMask = gc->modes.blueMask;
rBits = gc->modes.redBits; gBits = gc->modes.greenBits; bBits = gc->modes.blueBits;
rAccum = CASTFIX(gc->polygon.shader.frag.color.r); gAccum = CASTFIX(gc->polygon.shader.frag.color.g); bAccum = CASTFIX(gc->polygon.shader.frag.color.b); aAccum = CASTFIX(gc->polygon.shader.frag.color.a);
for (;;) { CHECK_PIXEL(gc, cfb, w, frag.x, frag.y);
invCoverage = ((fraction << 1) & 0xff000000) >> 16; coverage = 0xff00 - invCoverage;
if ((cfb->buf.flags & DIB_FORMAT) == 0) { cfbX = __GL_UNBIAS_X(gc, frag.x)+cfb->buf.xOrigin; cfbY = __GL_UNBIAS_Y(gc, frag.y)+cfb->buf.yOrigin; gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, copyPix, FALSE); }
if (modeFlags & __GL_SHADE_DEPTH_TEST) { if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ )) goto noWrite1; }
if ((cfb->buf.flags & (NO_CLIP | DIB_FORMAT)) == DIB_FORMAT) { cfbX = __GL_UNBIAS_X(gc, frag.x)+cfb->buf.xOrigin; cfbY = __GL_UNBIAS_Y(gc, frag.y)+cfb->buf.yOrigin; if (!wglPixelVisible(cfbX, cfbY)) { goto noWrite1; } } WRITE_PIXEL_GEN(pPix, coverage, frag.x, frag.y); if ((cfb->buf.flags & DIB_FORMAT) == 0 && copyPix == 1) { gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, copyPix, TRUE); } noWrite1:
fragX2 = frag.x + fragXinc; fragY2 = frag.y + fragYinc; if ((fragX2 >= clipX1) || (fragY2 >= clipY1)) { goto noWrite2; }
pZ2 = pZ+zAdjStep; if (modeFlags & __GL_SHADE_DEPTH_TEST) { if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ2 )) goto noWrite2; }
if ((cfb->buf.flags & (NO_CLIP | DIB_FORMAT)) == DIB_FORMAT) { cfbX = __GL_UNBIAS_X(gc, fragX2)+cfb->buf.xOrigin; cfbY = __GL_UNBIAS_Y(gc, fragY2)+cfb->buf.yOrigin; if (!wglPixelVisible(cfbX, cfbY)) { goto noWrite2; } } pPix2 = pPix + pixAdjStep;
if ((cfb->buf.flags & DIB_FORMAT) == 0 && copyPix == 1) { cfbX += fragXinc; cfbY += fragYinc; gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, copyPix, FALSE); }
WRITE_PIXEL_GEN(pPix2, invCoverage, fragX2, fragY2); noWrite2:
if ((cfb->buf.flags & DIB_FORMAT) == 0) { gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, copyPix, TRUE); } if (--w <= 0) return GL_TRUE;
fraction += dfraction; if (fraction < 0) { fraction &= ~0x80000000; frag.x += xBig; frag.y += yBig; pPix += gc->polygon.shader.sbufBig; pZ += gc->polygon.shader.zbufBig; } else { frag.x += xLittle; frag.y += yLittle; pPix += gc->polygon.shader.sbufLittle; pZ += gc->polygon.shader.zbufLittle; }
if (modeFlags & __GL_SHADE_SMOOTH) { rAccum += CASTFIX(gc->polygon.shader.drdx); gAccum += CASTFIX(gc->polygon.shader.dgdx); bAccum += CASTFIX(gc->polygon.shader.dbdx); aAccum += CASTFIX(gc->polygon.shader.dadx); }
if (modeFlags & __GL_SHADE_DEPTH_ITER) { zAccum += gc->polygon.shader.dzdx; } }
return GL_TRUE; }
/************************************************************************/
#define FAST_A_LINE_BLEND \
{\ GLint xLittle, xBig, yLittle, yBig;\ BYTE *pPix;\ USHORT *pZ;\ __GLfragment frag;\ __GLcolorBuffer *cfb = gc->drawBuffer;\ LONG rAccum, gAccum, bAccum, aAccum;\ LONG bytesPerPixel;\ __GLzValue zAccum;\ GLint fraction, dfraction;\ GLint w;\ GLuint modeFlags = gc->polygon.shader.modeFlags;\ ULONG coverage = 0xff00;\ \ ASSERTOPENGL((cfb->buf.flags &\ (DIB_FORMAT | NO_CLIP)) == (DIB_FORMAT | NO_CLIP),\ "FAST_A_LINE_BLEND on clipping surface\n");\ \ fraction = gc->line.options.fraction;\ dfraction = gc->line.options.dfraction;\ \ xBig = gc->line.options.xBig;\ yBig = gc->line.options.yBig;\ xLittle = gc->line.options.xLittle;\ yLittle = gc->line.options.yLittle;\ \ frag.x = gc->line.options.xStart;\ frag.y = gc->line.options.yStart;\ \ bytesPerPixel = GENACCEL(gc).xMultiplier;\ \ pPix = (BYTE *)((ULONG_PTR)cfb->buf.base +\ (__GL_UNBIAS_Y(gc, frag.y) + cfb->buf.yOrigin) * cfb->buf.outerWidth +\ (__GL_UNBIAS_X(gc, frag.x) + cfb->buf.xOrigin) * bytesPerPixel);\ \ if (modeFlags & __GL_SHADE_DEPTH_TEST) {\ zAccum = gc->polygon.shader.frag.z;\ \ if( gc->modes.depthBits == 32 ) {\ pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),\ frag.x, frag.y);\ \ } else {\ pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer,\ (__GLz16Value*),\ frag.x, frag.y);\ }\ \ }\ \ rAccum = CASTFIX(gc->polygon.shader.frag.color.r);\ gAccum = CASTFIX(gc->polygon.shader.frag.color.g);\ bAccum = CASTFIX(gc->polygon.shader.frag.color.b);\ aAccum = CASTFIX(gc->polygon.shader.frag.color.a);\ \ w = gc->line.options.numPixels;\ for (;;)\ {\ CHECK_PIXEL(gc, cfb, w, frag.x, frag.y);\ \ if (modeFlags & __GL_SHADE_DEPTH_TEST) {\ if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ))\ goto NoWrite;\ }\ \ BLEND_PIXEL(pPix, coverage, frag.x, frag.y);\ NoWrite:\ \ if (--w <= 0)\ return GL_TRUE;\ \ fraction += dfraction;\ if (fraction < 0) {\ fraction &= ~0x80000000;\ frag.x += xBig;\ frag.y += yBig;\ pPix += gc->polygon.shader.sbufBig;\ pZ += gc->polygon.shader.zbufBig;\ } else {\ frag.x += xLittle;\ frag.y += yLittle;\ pPix += gc->polygon.shader.sbufLittle;\ pZ += gc->polygon.shader.zbufLittle;\ }\ \ if (modeFlags & __GL_SHADE_SMOOTH) {\ rAccum += CASTFIX(gc->polygon.shader.drdx);\ gAccum += CASTFIX(gc->polygon.shader.dgdx);\ bAccum += CASTFIX(gc->polygon.shader.dbdx);\ aAccum += CASTFIX(gc->polygon.shader.dadx);\ }\ \ if (modeFlags & __GL_SHADE_DEPTH_ITER) {\ zAccum += gc->polygon.shader.dzdx;\ }\ }\ \ return GL_TRUE;\ }
#undef BPP
#undef RSHIFT
#undef GSHIFT
#undef BSHIFT
#undef RBITS
#undef GBITS
#undef BBITS
#undef RMASK
#undef GMASK
#undef BMASK
#undef READ_PIX
#undef WRITE_PIX
#define RSHIFT 0
#define GSHIFT 3
#define BSHIFT 6
#define RBITS 3
#define GBITS 3
#define BBITS 2
#define RMASK (((1 << RBITS) - 1) << RSHIFT)
#define GMASK (((1 << GBITS) - 1) << GSHIFT)
#define BMASK (((1 << BBITS) - 1) << BSHIFT)
#define BPP 8
#define READ_PIX(pPix) \
((__GLGENcontext *)gc)->pajInvTranslateVector[*((BYTE *)(pPix))] #define WRITE_PIX(pPix) \
pPix[0] = ((__GLGENcontext *)gc)->xlatPalette[r | g | b]
GLboolean FASTCALL __fastGenBlendAliasLine332(__GLcontext *gc) FAST_A_LINE_BLEND
#undef BPP
#undef RSHIFT
#undef GSHIFT
#undef BSHIFT
#undef RBITS
#undef GBITS
#undef BBITS
#undef RMASK
#undef GMASK
#undef BMASK
#undef READ_PIX
#undef WRITE_PIX
#define RSHIFT 10
#define GSHIFT 5
#define BSHIFT 0
#define RBITS 5
#define GBITS 5
#define BBITS 5
#define RMASK (((1 << RBITS) - 1) << RSHIFT)
#define GMASK (((1 << GBITS) - 1) << GSHIFT)
#define BMASK (((1 << BBITS) - 1) << BSHIFT)
#define BPP 16
#define READ_PIX(pPix) \
*((USHORT *)(pPix)) #define WRITE_PIX(pPix) \
*((USHORT *)pPix) = (USHORT)(r | g | b)
GLboolean FASTCALL __fastGenBlendAliasLine555(__GLcontext *gc) FAST_A_LINE_BLEND
#undef BPP
#undef RSHIFT
#undef GSHIFT
#undef BSHIFT
#undef RBITS
#undef GBITS
#undef BBITS
#undef RMASK
#undef GMASK
#undef BMASK
#undef READ_PIX
#undef WRITE_PIX
#define RSHIFT 11
#define GSHIFT 5
#define BSHIFT 0
#define RBITS 5
#define GBITS 6
#define BBITS 5
#define RMASK (((1 << RBITS) - 1) << RSHIFT)
#define GMASK (((1 << GBITS) - 1) << GSHIFT)
#define BMASK (((1 << BBITS) - 1) << BSHIFT)
#define BPP 16
#define READ_PIX(pPix) \
*((USHORT *)(pPix)) #define WRITE_PIX(pPix) \
*((USHORT *)pPix) = (USHORT)(r | g | b)
GLboolean FASTCALL __fastGenBlendAliasLine565(__GLcontext *gc) FAST_A_LINE_BLEND
/************************************************************************/
#define FAST_A_LINE_NO_BLEND \
{\ GLint xLittle, xBig, yLittle, yBig;\ BYTE *pPix;\ USHORT *pZ;\ __GLfragment frag;\ __GLcolorBuffer *cfb = gc->drawBuffer;\ LONG rAccum, gAccum, bAccum;\ LONG bytesPerPixel;\ __GLzValue zAccum;\ GLint fraction, dfraction;\ GLint w;\ GLuint modeFlags = gc->polygon.shader.modeFlags;\ \ ASSERTOPENGL((cfb->buf.flags &\ (DIB_FORMAT | NO_CLIP)) == (DIB_FORMAT | NO_CLIP),\ "FAST_A_LINE_NO_BLEND on clipping surface\n");\ \ fraction = gc->line.options.fraction;\ dfraction = gc->line.options.dfraction;\ \ xBig = gc->line.options.xBig;\ yBig = gc->line.options.yBig;\ xLittle = gc->line.options.xLittle;\ yLittle = gc->line.options.yLittle;\ \ frag.x = gc->line.options.xStart;\ frag.y = gc->line.options.yStart;\ \ bytesPerPixel = GENACCEL(gc).xMultiplier;\ \ pPix = (BYTE *)((ULONG_PTR)cfb->buf.base +\ (__GL_UNBIAS_Y(gc, frag.y) + cfb->buf.yOrigin) * cfb->buf.outerWidth +\ (__GL_UNBIAS_X(gc, frag.x) + cfb->buf.xOrigin) * bytesPerPixel);\ \ if (modeFlags & __GL_SHADE_DEPTH_TEST) {\ zAccum = gc->polygon.shader.frag.z;\ \ if( gc->modes.depthBits == 32 ) {\ pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),\ frag.x, frag.y);\ \ } else {\ pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer,\ (__GLz16Value*),\ frag.x, frag.y);\ }\ \ }\ \ rAccum = CASTFIX(gc->polygon.shader.frag.color.r);\ gAccum = CASTFIX(gc->polygon.shader.frag.color.g);\ bAccum = CASTFIX(gc->polygon.shader.frag.color.b);\ \ w = gc->line.options.numPixels;\ for (;;)\ {\ CHECK_PIXEL(gc, cfb, w, frag.x, frag.y);\ \ if (modeFlags & __GL_SHADE_DEPTH_TEST) {\ if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ))\ goto NoWrite;\ }\ \ DITHER_PIXEL(pPix, frag.x, frag.y);\ NoWrite:\ \ if (--w <= 0)\ return GL_TRUE;\ \ fraction += dfraction;\ if (fraction < 0) {\ fraction &= ~0x80000000;\ frag.x += xBig;\ frag.y += yBig;\ pPix += gc->polygon.shader.sbufBig;\ pZ += gc->polygon.shader.zbufBig;\ } else {\ frag.x += xLittle;\ frag.y += yLittle;\ pPix += gc->polygon.shader.sbufLittle;\ pZ += gc->polygon.shader.zbufLittle;\ }\ \ if (modeFlags & __GL_SHADE_SMOOTH) {\ rAccum += CASTFIX(gc->polygon.shader.drdx);\ gAccum += CASTFIX(gc->polygon.shader.dgdx);\ bAccum += CASTFIX(gc->polygon.shader.dbdx);\ }\ \ if (modeFlags & __GL_SHADE_DEPTH_ITER) {\ zAccum += gc->polygon.shader.dzdx;\ }\ }\ \ return GL_TRUE;\ }
#undef BPP
#undef RSHIFT
#undef GSHIFT
#undef BSHIFT
#undef RBITS
#undef GBITS
#undef BBITS
#undef RMASK
#undef GMASK
#undef BMASK
#undef READ_PIX
#undef WRITE_PIX
#define RSHIFT 0
#define GSHIFT 3
#define BSHIFT 6
#define RBITS 3
#define GBITS 3
#define BBITS 2
#define RMASK (((1 << RBITS) - 1) << RSHIFT)
#define GMASK (((1 << GBITS) - 1) << GSHIFT)
#define BMASK (((1 << BBITS) - 1) << BSHIFT)
#define BPP 8
#define WRITE_PIX(pPix) \
pPix[0] = ((__GLGENcontext *)gc)->xlatPalette[r | g | b]
GLboolean FASTCALL __fastGenNoBlendAliasLine332(__GLcontext *gc) FAST_A_LINE_NO_BLEND
#undef BPP
#undef RSHIFT
#undef GSHIFT
#undef BSHIFT
#undef RBITS
#undef GBITS
#undef BBITS
#undef RMASK
#undef GMASK
#undef BMASK
#undef READ_PIX
#undef WRITE_PIX
#define RSHIFT 10
#define GSHIFT 5
#define BSHIFT 0
#define RBITS 5
#define GBITS 5
#define BBITS 5
#define RMASK (((1 << RBITS) - 1) << RSHIFT)
#define GMASK (((1 << GBITS) - 1) << GSHIFT)
#define BMASK (((1 << BBITS) - 1) << BSHIFT)
#define BPP 16
#define WRITE_PIX(pPix) \
*((USHORT *)pPix) = (USHORT)(r | g | b)
GLboolean FASTCALL __fastGenNoBlendAliasLine555(__GLcontext *gc) FAST_A_LINE_NO_BLEND
#undef BPP
#undef RSHIFT
#undef GSHIFT
#undef BSHIFT
#undef RBITS
#undef GBITS
#undef BBITS
#undef RMASK
#undef GMASK
#undef BMASK
#undef READ_PIX
#undef WRITE_PIX
#define RSHIFT 11
#define GSHIFT 5
#define BSHIFT 0
#define RBITS 5
#define GBITS 6
#define BBITS 5
#define RMASK (((1 << RBITS) - 1) << RSHIFT)
#define GMASK (((1 << GBITS) - 1) << GSHIFT)
#define BMASK (((1 << BBITS) - 1) << BSHIFT)
#define BPP 16
#define WRITE_PIX(pPix) \
*((USHORT *)pPix) = (USHORT)(r | g | b)
GLboolean FASTCALL __fastGenNoBlendAliasLine565(__GLcontext *gc) FAST_A_LINE_NO_BLEND
// WRITE_PIXEL_GEN handles both blending and no blending so this
// generic routine works for both of those cases
GLboolean FASTCALL __fastGenAliasLine(__GLcontext *gc) { GLint xLittle, xBig, yLittle, yBig; BYTE *pPix; USHORT *pZ; __GLfragment frag; __GLcolorBuffer *cfb = gc->drawBuffer; LONG rAccum, gAccum, bAccum, aAccum; ULONG rMask, gMask, bMask; ULONG rShift, gShift, bShift; ULONG rBits, gBits, bBits; LONG bytesPerPixel; GLint cfbX, cfbY; __GLGENcontext *gengc = (__GLGENcontext *)gc; __GLzValue zAccum; GLint fraction, dfraction; GLint w; GLuint modeFlags = gc->polygon.shader.modeFlags; // Only present for placeholder in WRITE_PIXEL_GEN macro
ULONG coverage = 0xff00;
w = gc->line.options.numPixels;
fraction = gc->line.options.fraction; dfraction = gc->line.options.dfraction;
xBig = gc->line.options.xBig; yBig = gc->line.options.yBig; xLittle = gc->line.options.xLittle; yLittle = gc->line.options.yLittle;
frag.x = gc->line.options.xStart; frag.y = gc->line.options.yStart;
bytesPerPixel = GENACCEL(gc).xMultiplier;
if ((cfb->buf.flags & DIB_FORMAT) != 0) { pPix = (BYTE *)((ULONG_PTR)cfb->buf.base + (__GL_UNBIAS_Y(gc, frag.y) + cfb->buf.yOrigin) * cfb->buf.outerWidth + (__GL_UNBIAS_X(gc, frag.x) + cfb->buf.xOrigin) * bytesPerPixel); } else { pPix = gengc->ColorsBits; }
if (modeFlags & __GL_SHADE_DEPTH_TEST) { zAccum = gc->polygon.shader.frag.z;
if( gc->modes.depthBits == 32 ) { pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*), frag.x, frag.y); } else { pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLz16Value*), frag.x, frag.y); } }
rShift = cfb->redShift; gShift = cfb->greenShift; bShift = cfb->blueShift;
rMask = gc->modes.redMask; gMask = gc->modes.greenMask; bMask = gc->modes.blueMask;
rBits = gc->modes.redBits; gBits = gc->modes.greenBits; bBits = gc->modes.blueBits;
rAccum = CASTFIX(gc->polygon.shader.frag.color.r); gAccum = CASTFIX(gc->polygon.shader.frag.color.g); bAccum = CASTFIX(gc->polygon.shader.frag.color.b); aAccum = CASTFIX(gc->polygon.shader.frag.color.a);
for (;;) { CHECK_PIXEL(gc, cfb, w, frag.x, frag.y); if (modeFlags & __GL_SHADE_DEPTH_TEST) { if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ)) goto NoWrite; }
if ((cfb->buf.flags & (NO_CLIP | DIB_FORMAT)) == DIB_FORMAT) { cfbX = __GL_UNBIAS_X(gc, frag.x)+cfb->buf.xOrigin; cfbY = __GL_UNBIAS_Y(gc, frag.y)+cfb->buf.yOrigin; if (!wglPixelVisible(cfbX, cfbY)) { goto NoWrite; } } if ((cfb->buf.flags & DIB_FORMAT) == 0) { cfbX = __GL_UNBIAS_X(gc, frag.x)+cfb->buf.xOrigin; cfbY = __GL_UNBIAS_Y(gc, frag.y)+cfb->buf.yOrigin; gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, 1, FALSE); }
WRITE_PIXEL_GEN(pPix, coverage, frag.x, frag.y);
if ((cfb->buf.flags & DIB_FORMAT) == 0) { gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, 1, TRUE); }
NoWrite: if (--w <= 0) return GL_TRUE; fraction += dfraction; if (fraction < 0) { fraction &= ~0x80000000; frag.x += xBig; frag.y += yBig; pPix += gc->polygon.shader.sbufBig; pZ += gc->polygon.shader.zbufBig; } else { frag.x += xLittle; frag.y += yLittle; pPix += gc->polygon.shader.sbufLittle; pZ += gc->polygon.shader.zbufLittle; }
if (modeFlags & __GL_SHADE_SMOOTH) { rAccum += CASTFIX(gc->polygon.shader.drdx); gAccum += CASTFIX(gc->polygon.shader.dgdx); bAccum += CASTFIX(gc->polygon.shader.dbdx); aAccum += CASTFIX(gc->polygon.shader.dadx); }
if (modeFlags & __GL_SHADE_DEPTH_ITER) { zAccum += gc->polygon.shader.dzdx; } }
return GL_TRUE; }
/************************************************************************/
// Bits 0-1 are for pixel format
// Bit 2 is for GL_BLEND enable
// Bit 3 is for GL_LINE_SMOOTH_ENABLE
fastGenLineProc pfnFastGenLineProcs[] = { __fastGenAliasLine, __fastGenNoBlendAliasLine332, __fastGenNoBlendAliasLine555, __fastGenNoBlendAliasLine565, __fastGenAliasLine, __fastGenBlendAliasLine332, __fastGenBlendAliasLine555, __fastGenBlendAliasLine565, __fastGenAntiAliasLine, __fastGenAntiAliasLine, __fastGenAntiAliasLine, __fastGenAntiAliasLine, __fastGenAntiAliasLine, __fastGenAntiAliasLine332, __fastGenAntiAliasLine555, __fastGenAntiAliasLine565 };
//
// Assumptions for accelerated lines:
//
// no blending, or (SRC, 1-SRC), or (SRC, 1)
// not both buffers
// not stippled
// not stenciled
// not textured
// not alpha-tested
// not masked, zmasked
// no logicOp
// not slow fog
// not color-indexed
// not wide
#define __SLOW_LINE_MODE_FLAGS \
(__GL_SHADE_TEXTURE | __GL_SHADE_LINE_STIPPLE | \ __GL_SHADE_STENCIL_TEST | __GL_SHADE_LOGICOP | \ __GL_SHADE_ALPHA_TEST | __GL_SHADE_MASK | \ __GL_SHADE_SLOW_FOG)
BOOL FASTCALL __glGenSetupEitherLines(__GLcontext *gc) { #ifdef _MCD_
GENMCDSTATE *pMcdState = ((__GLGENcontext *) gc)->pMcdState; #endif
GLuint modeFlags = gc->polygon.shader.modeFlags; LONG bytesPerPixel; int fmt; BOOL bAccelerate = (((__GLGENcontext *)gc)->gsurf.pfd.cColorBits >= 8) && (gc->state.raster.drawBuffer != GL_FRONT_AND_BACK) && (gc->state.raster.drawBuffer != GL_NONE) && ( ! ALPHA_WRITE_ENABLED( gc->drawBuffer ) ) && ( ((gc->polygon.shader.modeFlags & __GL_SHADE_DEPTH_TEST) && (gc->polygon.shader.modeFlags & __GL_SHADE_DEPTH_ITER) && (gc->state.depth.writeEnable)) || (!(gc->polygon.shader.modeFlags & __GL_SHADE_DEPTH_TEST) && !(gc->polygon.shader.modeFlags & __GL_SHADE_DEPTH_ITER)) ) && (gc->transform.reasonableViewport) && (gc->state.line.aliasedWidth == 1) && (modeFlags & __GL_SHADE_RGB) && #ifdef GL_WIN_phong_shading
!(modeFlags & __GL_SHADE_PHONG) && #endif //GL_WIN_phong_shading
#ifdef GL_WIN_specular_fog
!(modeFlags & __GL_SHADE_SPEC_FOG) && #endif //GL_WIN_specular_fog
(!(modeFlags & __SLOW_LINE_MODE_FLAGS)) && (!(gc->state.enables.general & __GL_BLEND_ENABLE) || ((gc->state.raster.blendSrc == GL_SRC_ALPHA) && ((gc->state.raster.blendDst == GL_ONE_MINUS_SRC_ALPHA) || (gc->state.raster.blendDst == GL_ONE))) );
#ifdef _MCD_
bAccelerate &= (!pMcdState || (pMcdState->McdBuffers.mcdDepthBuf.bufFlags & MCDBUF_ENABLED)); #endif
// Resort to soft code if we can't handle the line:
if (!bAccelerate) { return FALSE; } else if (gc->state.enables.general & __GL_LINE_SMOOTH_ENABLE) { if (gc->state.hints.lineSmooth == GL_NICEST) { return FALSE; } } else if ((modeFlags & __GL_SHADE_CHEAP_FOG) && (modeFlags & __GL_SHADE_SMOOTH_LIGHT) == 0) { // We only support cheap fog done by the front end, not
// flat cheap fog done by the render procs
return FALSE; }
GENACCEL(gc).xMultiplier = bytesPerPixel = (((__GLGENcontext *)gc)->gsurf.pfd.cColorBits + 7) >> 3;
// Set up our local z-buffer procs:
if (modeFlags & __GL_SHADE_DEPTH_ITER) __fastGenPickZStoreProc(gc); gc->procs.renderLine = __glGenRenderEitherLine;
// Assume generic format
fmt = 0;
// For deep-color modes, we don't support most-significant-byte
// formats...
// For non-MSB deep-color modes, we only support generic rendering
if (bytesPerPixel > 2) { if (((gc->drawBuffer->redShift > 16) || (gc->drawBuffer->greenShift > 16) || (gc->drawBuffer->blueShift > 16))) { return FALSE; } else { goto PickProc; } }
// Just use generic acceleration if we're not
// dithering, since these are hardwired into the fastest routines...
// We also only support unclipped surfaces in the fastest routines
if (!(modeFlags & __GL_SHADE_DITHER) || (gc->drawBuffer->buf.flags & (DIB_FORMAT | NO_CLIP)) != (DIB_FORMAT | NO_CLIP)) { goto PickProc; }
// Now, check for supported color formats for fastest modes:
if ((bytesPerPixel == 1) && (gc->drawBuffer->redShift == 0) && (gc->drawBuffer->greenShift == 3) && (gc->drawBuffer->blueShift == 6)) { fmt = 1; } else if (bytesPerPixel == 2) { if ((gc->drawBuffer->greenShift == 5) && (gc->drawBuffer->blueShift == 0)) { if (gc->drawBuffer->redShift == 10) { fmt = 2; } else if (gc->drawBuffer->redShift == 11) { fmt = 3; } } }
PickProc: if (gc->state.enables.general & __GL_BLEND_ENABLE) { fmt += 4; } if (gc->state.enables.general & __GL_LINE_SMOOTH_ENABLE) { fmt += 8; } GENACCEL(gc).__fastGenLineProc = pfnFastGenLineProcs[fmt];
if (gc->state.line.aliasedWidth != 1) { GENACCEL(gc).__fastGenInitLineData = __glInitLineData; } else { GENACCEL(gc).__fastGenInitLineData = __glInitThinLineData; } return TRUE; }
|