2342 lines
70 KiB
C
2342 lines
70 KiB
C
|
/******************************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;
|
||
|
}
|