mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1580 lines
49 KiB
1580 lines
49 KiB
/*
|
|
** Copyright 1991,1992,1993, Silicon Graphics, Inc.
|
|
** All Rights Reserved.
|
|
**
|
|
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
|
|
** the contents of this file may not be disclosed to third parties, copied or
|
|
** duplicated in any form, in whole or in part, without the prior written
|
|
** permission of Silicon Graphics, Inc.
|
|
**
|
|
** RESTRICTED RIGHTS LEGEND:
|
|
** Use, duplication or disclosure by the Government is subject to restrictions
|
|
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
|
|
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
|
|
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
|
|
** rights reserved under the Copyright Laws of the United States.
|
|
*/
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#include "genline.h"
|
|
#include "devlock.h"
|
|
|
|
/******************************Public*Routine******************************\
|
|
* __fastGenLineSetupDisplay
|
|
*
|
|
* Initializes the accelerated line-rendering state machine for display surfaces.
|
|
* There are basically 4 levels in the state machine:
|
|
* 1. lineBegin
|
|
* This function initializes the initial states of the lower levels.
|
|
*
|
|
* 2. lineVertex
|
|
* This function adds vertices to the path
|
|
*
|
|
* 3. lineEnd
|
|
* This function calls the routine to stroke the path.
|
|
*
|
|
* History:
|
|
* 09-Jan-1996 -by- Drew Bliss [drewb]
|
|
* Totally rewrote fast line support
|
|
* 29-Mar-1994 [v-eddier]
|
|
* Changed name when __fastGenLineSetupDIB was added.
|
|
* 22-Mar-1994 -by- Eddie Robinson [v-eddier]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL FASTCALL __fastGenLineSetupDisplay(__GLcontext *gc)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *) gc;
|
|
GENACCEL *genAccel = (GENACCEL *) gengc->pPrivateArea;
|
|
GLuint modeFlags = gc->polygon.shader.modeFlags;
|
|
|
|
// allocate line buffer
|
|
|
|
if (!genAccel->pFastLineBuffer) {
|
|
if (!(genAccel->pFastLineBuffer =
|
|
(BYTE *) GCALLOC(gc, __FAST_LINE_BUFFER_SIZE)))
|
|
return FALSE;
|
|
}
|
|
|
|
// Set the line rasterization function pointers
|
|
gc->procs.lineBegin = __fastGenLineBegin;
|
|
gc->procs.lineEnd = __fastGenLineEnd;
|
|
|
|
if (gc->state.line.aliasedWidth > 1)
|
|
{
|
|
gc->procs.renderLine = __fastGenLineWide;
|
|
}
|
|
else
|
|
{
|
|
gc->procs.renderLine = __fastGenLine;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* __fastLineComputeOffsets
|
|
*
|
|
* Precomputes static offsets for fast line drawing
|
|
*
|
|
* History:
|
|
* Tue Aug 15 18:10:29 1995 -by- Drew Bliss [drewb]
|
|
* Created
|
|
*
|
|
\**************************************************************************/
|
|
|
|
void FASTCALL __fastLineComputeOffsets(__GLGENcontext *gengc)
|
|
{
|
|
GENACCEL *genAccel;
|
|
|
|
genAccel = (GENACCEL *)gengc->pPrivateArea;
|
|
ASSERTOPENGL(genAccel != NULL,
|
|
"ComputeFastLineOffsets with no genaccel\n");
|
|
|
|
// If acceleration is wired-in, set the offsets for line drawing.
|
|
// These offsets include the following:
|
|
// subtraction of the viewport bias
|
|
// addition of the client window origin
|
|
// subtraction of .5 to align GL pixel centers with GDI's pixel centers
|
|
// addition of 1/32 to round the value which will be converted to
|
|
// 28.4 fixed point
|
|
|
|
#ifdef _CLIENTSIDE_
|
|
// Window-relative coordinates
|
|
genAccel->fastLineOffsetX = 0 -
|
|
gengc->gc.constants.viewportXAdjust - (__GLfloat) (0.5 - 0.03125);
|
|
|
|
genAccel->fastLineOffsetY = 0 -
|
|
gengc->gc.constants.viewportYAdjust - (__GLfloat) (0.5 - 0.03125);
|
|
#else
|
|
// Screen-relative coordinates
|
|
genAccel->fastLineOffsetX = gengc->gc.drawBuffer->buf.xOrigin -
|
|
gengc->gc.constants.viewportXAdjust - (__GLfloat) (0.5 - 0.03125);
|
|
|
|
genAccel->fastLineOffsetY = gengc->gc.drawBuffer->buf.yOrigin -
|
|
gengc->gc.constants.viewportYAdjust - (__GLfloat) (0.5 - 0.03125);
|
|
#endif
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* __fastLineComputeColor*
|
|
*
|
|
* Computes the color index to use for line drawing. These functions are
|
|
* called through a function pointer whenever the vertex color changes.
|
|
*
|
|
* History:
|
|
* 22-Mar-1994 -by- Eddie Robinson [v-eddier]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
GLubyte vujRGBtoVGA[8] = {
|
|
0x0, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
|
|
};
|
|
|
|
ULONG FASTCALL __fastLineComputeColorRGB4(__GLcontext *gc, __GLcolor *color)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *) gc;
|
|
PIXELFORMATDESCRIPTOR *pfmt = &gengc->gsurf.pfd;
|
|
int ir, ig, ib;
|
|
|
|
ir = (int) color->r;
|
|
ig = (int) color->g;
|
|
ib = (int) color->b;
|
|
return (ULONG) vujRGBtoVGA[(ir << pfmt->cRedShift) |
|
|
(ig << pfmt->cGreenShift) |
|
|
(ib << pfmt->cBlueShift)];
|
|
}
|
|
|
|
ULONG FASTCALL __fastLineComputeColorRGB8(__GLcontext *gc, __GLcolor *color)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *) gc;
|
|
PIXELFORMATDESCRIPTOR *pfmt = &gengc->gsurf.pfd;
|
|
int ir, ig, ib;
|
|
|
|
ir = (int) color->r;
|
|
ig = (int) color->g;
|
|
ib = (int) color->b;
|
|
return (ULONG) gengc->pajTranslateVector[(ir << pfmt->cRedShift) |
|
|
(ig << pfmt->cGreenShift) |
|
|
(ib << pfmt->cBlueShift)];
|
|
}
|
|
|
|
ULONG FASTCALL __fastLineComputeColorRGB(__GLcontext *gc, __GLcolor *color)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *) gc;
|
|
PIXELFORMATDESCRIPTOR *pfmt = &gengc->gsurf.pfd;
|
|
int ir, ig, ib;
|
|
|
|
ir = (int) color->r;
|
|
ig = (int) color->g;
|
|
ib = (int) color->b;
|
|
return (ULONG) ((ir << pfmt->cRedShift) |
|
|
(ig << pfmt->cGreenShift) |
|
|
(ib << pfmt->cBlueShift));
|
|
}
|
|
|
|
ULONG FASTCALL __fastLineComputeColorCI4and8(__GLcontext *gc, __GLcolor *color)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *) gc;
|
|
|
|
return (ULONG) gengc->pajTranslateVector[(int)color->r];
|
|
}
|
|
|
|
ULONG FASTCALL __fastLineComputeColorCI(__GLcontext *gc, __GLcolor *color)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *) gc;
|
|
GLuint *pTrans = (GLuint *) gengc->pajTranslateVector;
|
|
|
|
return (ULONG) pTrans[(int)(color->r)+1];
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* __glQueryLineAcceleration
|
|
*
|
|
* Determines if lines are accelerated through the DDI and performs some
|
|
* initialization. Currently, this routine only checks for acceleration via
|
|
* the standard DDI. Eventually, it could support checking for acceleration
|
|
* via the extended DDI.
|
|
*
|
|
* History:
|
|
* 22-Mar-1994 -by- Eddie Robinson [v-eddier]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
void FASTCALL __glQueryLineAcceleration(__GLcontext *gc)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *) gc;
|
|
GENACCEL *genAccel = (GENACCEL *) gengc->pPrivateArea;
|
|
PIXELFORMATDESCRIPTOR *pfmt;
|
|
|
|
pfmt = &gengc->gsurf.pfd;
|
|
|
|
// On the client side we can draw into any surface with GDI
|
|
// and (presumably) get the best possible plain 2D line drawing
|
|
// performance
|
|
genAccel->bFastLineDIBAccel = TRUE;
|
|
|
|
//XXX eventually, check rxcaps and set appropriate mode bits
|
|
|
|
genAccel->bFastLineDispAccel = TRUE;
|
|
|
|
// set modes supported by hardware. These are equivalent to the
|
|
// gc->polygon.shader.modeFlags checked in the pick function
|
|
|
|
genAccel->flLineAccelModes = 0;
|
|
|
|
// Set the color computation function
|
|
|
|
if (pfmt->iPixelType == PFD_TYPE_RGBA) {
|
|
switch (pfmt->cColorBits) {
|
|
case 4:
|
|
genAccel->fastLineComputeColor = __fastLineComputeColorRGB4;
|
|
break;
|
|
case 8:
|
|
genAccel->fastLineComputeColor = __fastLineComputeColorRGB8;
|
|
break;
|
|
case 16:
|
|
case 24:
|
|
case 32:
|
|
genAccel->fastLineComputeColor = __fastLineComputeColorRGB;
|
|
break;
|
|
default:
|
|
genAccel->bFastLineDispAccel = FALSE;
|
|
return;
|
|
}
|
|
} else {
|
|
switch (pfmt->cColorBits) {
|
|
case 4:
|
|
case 8:
|
|
genAccel->fastLineComputeColor = __fastLineComputeColorCI4and8;
|
|
break;
|
|
case 16:
|
|
case 24:
|
|
case 32:
|
|
genAccel->fastLineComputeColor = __fastLineComputeColorCI;
|
|
break;
|
|
default:
|
|
genAccel->bFastLineDispAccel = FALSE;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
|
|
// Macros to hide how the single pFastLineBuffer is divided into two
|
|
// sections, one for points and one for counts
|
|
#define FAST_LINE_FIRST_POINT(genAccel) \
|
|
((POINT *)(genAccel)->pFastLineBuffer)
|
|
|
|
#define FAST_LINE_FIRST_COUNT(genAccel) \
|
|
((DWORD *)((genAccel)->pFastLineBuffer+__FAST_LINE_BUFFER_SIZE)- \
|
|
__FAST_LINE_BUFFER_COUNTS)
|
|
|
|
#define FAST_LINE_LAST_POINT(genAccel) \
|
|
((POINT *)FAST_LINE_FIRST_COUNT(genAccel)-1)
|
|
|
|
#define FAST_LINE_LAST_COUNT(genAccel) \
|
|
((DWORD *)((genAccel)->pFastLineBuffer+__FAST_LINE_BUFFER_SIZE)-1)
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* __fastGenLineBegin
|
|
*
|
|
* Initializes fast line state
|
|
*
|
|
* History:
|
|
* Mon Jan 08 19:22:32 1996 -by- Drew Bliss [drewb]
|
|
* Created
|
|
*
|
|
\**************************************************************************/
|
|
|
|
void FASTCALL __fastGenLineBegin(__GLcontext *gc)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *)gc;
|
|
GENACCEL *genAccel = &gengc->genAccel;
|
|
|
|
genAccel->pFastLinePoint = FAST_LINE_FIRST_POINT(genAccel)-1;
|
|
genAccel->pFastLineCount = FAST_LINE_FIRST_COUNT(genAccel)-1;
|
|
genAccel->fastLineCounts = 0;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* __fastGenLineEnd
|
|
*
|
|
* Renders any current lines in the fast line buffer and
|
|
* then resets the fast line state
|
|
*
|
|
* History:
|
|
* Mon Jan 08 19:22:52 1996 -by- Drew Bliss [drewb]
|
|
* Created
|
|
*
|
|
\**************************************************************************/
|
|
|
|
void FASTCALL __fastGenLineEnd(__GLcontext *gc)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *)gc;
|
|
GENACCEL *genAccel = &gengc->genAccel;
|
|
ULONG ulSolidColor;
|
|
HDC hdc;
|
|
HPEN hpen;
|
|
|
|
if (genAccel->fastLineCounts == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// If there is no lock, we must have failed to reacquire the lock
|
|
// from the previous call to wglStrokePath. This is an error condition
|
|
// and we should not continue.
|
|
|
|
if (gengc->fsLocks == 0)
|
|
{
|
|
WARNING("fastGenLineEnd: no lock\n");
|
|
return;
|
|
}
|
|
|
|
// We need to sychronize with GDI before making GDI calls
|
|
glsrvSynchronizeWithGdi(gengc, gengc->pwndLocked,
|
|
COLOR_LOCK_FLAGS | DEPTH_LOCK_FLAGS);
|
|
|
|
// If this color is the same as the one we've cached, use the
|
|
// cached information
|
|
hdc = CURRENT_DC_GC(gc);
|
|
if (!gengc->fStrokeInvalid && hdc == gengc->hdcStroke)
|
|
{
|
|
hpen = gengc->hpenStroke;
|
|
ASSERTOPENGL(hpen != NULL, "Cached stroke pen is null\n");
|
|
}
|
|
else
|
|
{
|
|
if (gengc->hpenStroke != NULL)
|
|
{
|
|
// Deselect the object before deletion
|
|
if (gengc->hdcStroke != NULL)
|
|
{
|
|
SelectObject(gengc->hdcStroke, GetStockObject(BLACK_PEN));
|
|
gengc->hdcStroke = NULL;
|
|
}
|
|
|
|
DeleteObject(gengc->hpenStroke);
|
|
}
|
|
|
|
ulSolidColor = wglTranslateColor(gengc->crStroke, hdc,
|
|
gengc, &gengc->gsurf.pfd);
|
|
hpen = CreatePen(PS_SOLID, 0, ulSolidColor);
|
|
gengc->hpenStroke = hpen;
|
|
|
|
if (hpen == NULL ||
|
|
SelectObject(hdc, hpen) == NULL)
|
|
{
|
|
if (hpen != NULL)
|
|
{
|
|
DeleteObject(hpen);
|
|
gengc->hpenStroke = NULL;
|
|
}
|
|
|
|
gengc->cStroke.r = -1.0f;
|
|
gengc->fStrokeInvalid = TRUE;
|
|
goto Exit;
|
|
}
|
|
|
|
gengc->hdcStroke = hdc;
|
|
gengc->fStrokeInvalid = FALSE;
|
|
}
|
|
|
|
#ifdef DBG_VERBOSE
|
|
{
|
|
DWORD i;
|
|
DWORD *count;
|
|
POINT *pt;
|
|
|
|
count = FAST_LINE_FIRST_COUNT(genAccel);
|
|
pt = FAST_LINE_FIRST_POINT(genAccel);
|
|
for (i = 0; i < genAccel->fastLineCounts; i++)
|
|
{
|
|
DbgPrint("Polyline with %d points at %d\n",
|
|
*count, pt-FAST_LINE_FIRST_POINT(genAccel));
|
|
pt += *count;
|
|
count++;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
PolyPolyline(hdc,
|
|
FAST_LINE_FIRST_POINT(genAccel),
|
|
FAST_LINE_FIRST_COUNT(genAccel),
|
|
genAccel->fastLineCounts);
|
|
|
|
Exit:
|
|
// No more need for GDI operations
|
|
glsrvDecoupleFromGdi(gengc, gengc->pwndLocked,
|
|
COLOR_LOCK_FLAGS | DEPTH_LOCK_FLAGS);
|
|
|
|
// Reset
|
|
__fastGenLineBegin(gc);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* __fastGenLineSetStrokeColor
|
|
*
|
|
* Updates cached pen with current color if necessary
|
|
*
|
|
* History:
|
|
* Wed Jan 17 20:37:15 1996 -by- Drew Bliss [drewb]
|
|
* Created
|
|
*
|
|
\**************************************************************************/
|
|
|
|
BOOL __fastGenLineSetStrokeColor(__GLGENcontext *gengc, __GLcolor *color)
|
|
{
|
|
if (__GL_FLOAT_NE(color->r, gengc->cStroke.r) ||
|
|
(gengc->gsurf.pfd.iPixelType == PFD_TYPE_RGBA
|
|
&& (__GL_FLOAT_NE(color->g, gengc->cStroke.g) ||
|
|
__GL_FLOAT_NE(color->b, gengc->cStroke.b))))
|
|
{
|
|
ASSERTOPENGL(color->r >= 0.0f, "Invalid color\n");
|
|
|
|
#ifdef DBG_VERBOSE
|
|
if (gengc->cStroke.r >= 0.0f)
|
|
{
|
|
DbgPrint("Color change\n");
|
|
}
|
|
#endif
|
|
|
|
// Flush whatever we have so far
|
|
__fastGenLineEnd(&gengc->gc);
|
|
|
|
// Set current color
|
|
if (gengc->gsurf.pfd.iPixelType == PFD_TYPE_RGBA)
|
|
gengc->cStroke = *color;
|
|
else
|
|
gengc->cStroke.r = color->r;
|
|
gengc->crStroke =
|
|
gengc->genAccel.fastLineComputeColor((__GLcontext *)gengc,
|
|
&gengc->cStroke);
|
|
// Invalidate cached pen
|
|
gengc->fStrokeInvalid = TRUE;
|
|
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* __fastGenLine
|
|
*
|
|
* Accumulates incoming vertices in the fast line buffer
|
|
* Thin line version
|
|
*
|
|
* History:
|
|
* Mon Jan 08 19:23:19 1996 -by- Drew Bliss [drewb]
|
|
* Created
|
|
*
|
|
\**************************************************************************/
|
|
|
|
void FASTCALL __fastGenLine(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1,
|
|
GLuint flags)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *)gc;
|
|
GENACCEL *genAccel = &gengc->genAccel;
|
|
POINT pt;
|
|
|
|
#ifdef DBG_VERBOSE
|
|
DbgPrint("Counts %d, count %d, flags %X\n",
|
|
genAccel->fastLineCounts,
|
|
genAccel->pFastLineCount >= FAST_LINE_FIRST_COUNT(genAccel) ?
|
|
*genAccel->pFastLineCount : -1,
|
|
flags);
|
|
#endif
|
|
|
|
// Check for flushing conditions. We flush if:
|
|
// The provoking vertex's color is different from the current color
|
|
// This is the first vertex of a line and we don't have space for
|
|
// a new count and two vertices
|
|
// This is not the first vertex of a line and we don't have space for
|
|
// a new vertex
|
|
//
|
|
// According to spec we have to use color form a second vertex for flat
|
|
// shaded case
|
|
//
|
|
if (__fastGenLineSetStrokeColor(gengc, v1->color))
|
|
{
|
|
// Since we flushed, the current vertex is now the beginning
|
|
// of a polyline
|
|
flags |= __GL_LVERT_FIRST;
|
|
}
|
|
|
|
if (((flags & __GL_LVERT_FIRST) != 0 &&
|
|
(genAccel->pFastLinePoint+1 >= FAST_LINE_LAST_POINT(genAccel) ||
|
|
genAccel->pFastLineCount >= FAST_LINE_LAST_COUNT(genAccel))) ||
|
|
((flags & __GL_LVERT_FIRST) == 0 &&
|
|
genAccel->pFastLinePoint >= FAST_LINE_LAST_POINT(genAccel)))
|
|
{
|
|
#ifdef DBG_VERBOSE
|
|
DbgPrint("Overflow\n");
|
|
#endif
|
|
|
|
__fastGenLineEnd(gc);
|
|
|
|
// Since we flushed, the current vertex is now the beginning
|
|
// of a polyline
|
|
flags |= __GL_LVERT_FIRST;
|
|
}
|
|
|
|
// If we're starting a polyline, update the counts and add
|
|
// the vertex data
|
|
if (flags & __GL_LVERT_FIRST)
|
|
{
|
|
#ifdef DBG_VERBOSE
|
|
if (genAccel->pFastLineCount >= FAST_LINE_FIRST_COUNT(genAccel))
|
|
{
|
|
DbgPrint("First ended polyline with %d points\n",
|
|
*genAccel->pFastLineCount);
|
|
}
|
|
#endif
|
|
// Check to make sure we don't ever create segments with only
|
|
// one vertex
|
|
ASSERTOPENGL(genAccel->pFastLineCount <
|
|
FAST_LINE_FIRST_COUNT(genAccel) ||
|
|
*genAccel->pFastLineCount > 1,
|
|
"Line segment with only one vertex\n");
|
|
|
|
genAccel->fastLineCounts++;
|
|
genAccel->pFastLineCount++;
|
|
*genAccel->pFastLineCount = 1;
|
|
|
|
// Compute device coordinates
|
|
pt.x = __FAST_LINE_FLTTODEV(v0->window.x + genAccel->fastLineOffsetX);
|
|
pt.y = __FAST_LINE_FLTTODEV(v0->window.y + genAccel->fastLineOffsetY);
|
|
*(++genAccel->pFastLinePoint) = pt;
|
|
}
|
|
|
|
ASSERTOPENGL(genAccel->pFastLineCount >=
|
|
FAST_LINE_FIRST_COUNT(genAccel) &&
|
|
*genAccel->pFastLineCount > 0,
|
|
"Added fast point without count\n");
|
|
|
|
// Compute device coordinates
|
|
pt.x = __FAST_LINE_FLTTODEV(v1->window.x + genAccel->fastLineOffsetX);
|
|
pt.y = __FAST_LINE_FLTTODEV(v1->window.y + genAccel->fastLineOffsetY);
|
|
(*genAccel->pFastLineCount)++;
|
|
*(++genAccel->pFastLinePoint) = pt;
|
|
|
|
// Check on counts also
|
|
ASSERTOPENGL(genAccel->pFastLineCount <= FAST_LINE_LAST_COUNT(genAccel),
|
|
"Fast line count buffer overflow\n");
|
|
ASSERTOPENGL(genAccel->pFastLinePoint <= FAST_LINE_LAST_POINT(genAccel),
|
|
"Fast line point buffer overflow\n");
|
|
|
|
// Make sure the current color is being maintained properly
|
|
ASSERTOPENGL((v1->color->r == gengc->cStroke.r) &&
|
|
(gengc->gsurf.pfd.iPixelType == PFD_TYPE_COLORINDEX ||
|
|
(v1->color->g == gengc->cStroke.g &&
|
|
v1->color->b == gengc->cStroke.b)),
|
|
"Fast line color mismatch\n");
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
*
|
|
* __fastGenLineWide
|
|
*
|
|
* Accumulates incoming vertices in the fast line buffer
|
|
* Wide line version
|
|
* For wide lines we can't maintain connectivity because of the
|
|
* way OpenGL wide lines are defined. Instead, each segment
|
|
* of a wide line is decomposed into aliasedWidth unconnected
|
|
* line segments
|
|
*
|
|
* History:
|
|
* Tue Jan 09 11:32:10 1996 -by- Drew Bliss [drewb]
|
|
* Created
|
|
*
|
|
\**************************************************************************/
|
|
|
|
void FASTCALL __fastGenLineWide(__GLcontext *gc, __GLvertex *v0,
|
|
__GLvertex *v1, GLuint flags)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *)gc;
|
|
GENACCEL *genAccel = &gengc->genAccel;
|
|
POINT pt1, pt2;
|
|
GLint width;
|
|
long adjust;
|
|
GLfloat dx, dy;
|
|
|
|
// Set the current pen color
|
|
// According to spec we have to use color form a second vertex for flat
|
|
// shaded case
|
|
//
|
|
__fastGenLineSetStrokeColor(gengc, v1->color);
|
|
|
|
// We have a wide line segment from v0 to v1
|
|
// Compute its width and add an appropriate number of
|
|
// side-by-side thin segments to create the wide form
|
|
|
|
// Compute device coordinates
|
|
pt1.x = __FAST_LINE_FLTTODEV(v0->window.x +
|
|
genAccel->fastLineOffsetX);
|
|
pt1.y = __FAST_LINE_FLTTODEV(v0->window.y +
|
|
genAccel->fastLineOffsetY);
|
|
pt2.x = __FAST_LINE_FLTTODEV(v1->window.x +
|
|
genAccel->fastLineOffsetX);
|
|
pt2.y = __FAST_LINE_FLTTODEV(v1->window.y +
|
|
genAccel->fastLineOffsetY);
|
|
|
|
width = gc->state.line.aliasedWidth;
|
|
|
|
/*
|
|
** Compute the minor-axis adjustment for the first line segment
|
|
** this can be a fixed point value with 4 fractional bits
|
|
*/
|
|
adjust = ((width - 1) * __FAST_LINE_UNIT_VALUE) / 2;
|
|
|
|
// Determine the major axis
|
|
dx = v0->window.x - v1->window.x;
|
|
if (dx < 0.0)
|
|
{
|
|
dx = -dx;
|
|
}
|
|
dy = v0->window.y - v1->window.y;
|
|
if (dy < 0.0)
|
|
{
|
|
dy = -dy;
|
|
}
|
|
|
|
if (dx > dy)
|
|
{
|
|
pt1.y -= adjust;
|
|
pt2.y -= adjust;
|
|
|
|
while (width-- > 0)
|
|
{
|
|
// Make sure we have room for another count and two more
|
|
// vertices
|
|
if (genAccel->pFastLinePoint+1 >= FAST_LINE_LAST_POINT(genAccel) ||
|
|
genAccel->pFastLineCount >= FAST_LINE_LAST_COUNT(genAccel))
|
|
{
|
|
__fastGenLineEnd(gc);
|
|
}
|
|
|
|
genAccel->fastLineCounts++;
|
|
genAccel->pFastLineCount++;
|
|
*genAccel->pFastLineCount = 2;
|
|
*(++genAccel->pFastLinePoint) = pt1;
|
|
*(++genAccel->pFastLinePoint) = pt2;
|
|
|
|
pt1.y++;
|
|
pt2.y++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pt1.x -= adjust;
|
|
pt2.x -= adjust;
|
|
|
|
while (width-- > 0)
|
|
{
|
|
// Make sure we have room for another count and two more
|
|
// vertices
|
|
if (genAccel->pFastLinePoint+1 >= FAST_LINE_LAST_POINT(genAccel) ||
|
|
genAccel->pFastLineCount >= FAST_LINE_LAST_COUNT(genAccel))
|
|
{
|
|
__fastGenLineEnd(gc);
|
|
}
|
|
|
|
genAccel->fastLineCounts++;
|
|
genAccel->pFastLineCount++;
|
|
*genAccel->pFastLineCount = 2;
|
|
*(++genAccel->pFastLinePoint) = pt1;
|
|
*(++genAccel->pFastLinePoint) = pt2;
|
|
|
|
pt1.x++;
|
|
pt2.x++;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if NT_NO_BUFFER_INVARIANCE
|
|
|
|
PFN_RENDER_LINE __fastGenRenderLineDIBFuncs[32] = {
|
|
__fastGenRenderLineDIBCI8,
|
|
__fastGenRenderLineDIBCI16,
|
|
__fastGenRenderLineDIBCIRGB,
|
|
__fastGenRenderLineDIBCIBGR,
|
|
__fastGenRenderLineDIBCI32,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
__fastGenRenderLineDIBRGB8,
|
|
__fastGenRenderLineDIBRGB16,
|
|
__fastGenRenderLineDIBRGB,
|
|
__fastGenRenderLineDIBBGR,
|
|
__fastGenRenderLineDIBRGB32,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
__fastGenRenderLineWideDIBCI8,
|
|
__fastGenRenderLineWideDIBCI16,
|
|
__fastGenRenderLineWideDIBCIRGB,
|
|
__fastGenRenderLineWideDIBCIBGR,
|
|
__fastGenRenderLineWideDIBCI32,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
__fastGenRenderLineWideDIBRGB8,
|
|
__fastGenRenderLineWideDIBRGB16,
|
|
__fastGenRenderLineWideDIBRGB,
|
|
__fastGenRenderLineWideDIBBGR,
|
|
__fastGenRenderLineWideDIBRGB32,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
/******************************Public*Routine******************************\
|
|
* __fastGenLineSetupDIB
|
|
*
|
|
* Initializes the accelerated line-rendering function pointer for bitmap
|
|
* surfaces. All accelerated lines drawn to bitmaps are drawn by the
|
|
* gc->procs.renderLine funtion pointer.
|
|
*
|
|
* History:
|
|
* 29-Mar-1994 -by- Eddie Robinson [v-eddier]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL FASTCALL __fastGenLineSetupDIB(__GLcontext *gc)
|
|
{
|
|
__GLGENcontext *gengc = (__GLGENcontext *) gc;
|
|
PIXELFORMATDESCRIPTOR *pfmt = &gengc->gsurf.pfd;
|
|
GLint index;
|
|
|
|
switch (pfmt->cColorBits) {
|
|
case 8:
|
|
index = 0;
|
|
break;
|
|
case 16:
|
|
index = 1;
|
|
break;
|
|
case 24:
|
|
if (pfmt->cRedShift == 0)
|
|
index = 2;
|
|
else
|
|
index = 3;
|
|
break;
|
|
case 32:
|
|
index = 4;
|
|
break;
|
|
}
|
|
if (gc->polygon.shader.modeFlags & __GL_SHADE_RGB)
|
|
index |= 0x08;
|
|
|
|
if (gc->state.line.aliasedWidth > 1)
|
|
index |= 0x10;
|
|
|
|
gc->procs.renderLine = __fastGenRenderLineDIBFuncs[index];
|
|
return TRUE;
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineDIBRGB8(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle;
|
|
unsigned char *addr, pixel;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = (unsigned char) __fastLineComputeColorRGB8(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + x +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
|
|
__FAST_LINE_STROKE_DIB
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineDIBRGB16(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle;
|
|
unsigned short *addr, pixel;
|
|
GLint x, y, outerWidth_2;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = (unsigned short) __fastLineComputeColorRGB(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned short *) ((GLint)cfb->buf.base + (x << 1) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
outerWidth_2 = cfb->buf.outerWidth >> 1;
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
(gc->line.options.yLittle * outerWidth_2);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
(gc->line.options.yBig * outerWidth_2);
|
|
|
|
__FAST_LINE_STROKE_DIB
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineDIBRGB(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction;
|
|
__GLcolor *cp;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle;
|
|
unsigned char *addr, ir, ig, ib;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
cp = v1->color;
|
|
ir = (unsigned char) cp->r;
|
|
ig = (unsigned char) cp->g;
|
|
ib = (unsigned char) cp->b;
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
addrLittle = (gc->line.options.xLittle * 3) +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = (gc->line.options.xBig * 3) +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
|
|
__FAST_LINE_STROKE_DIB24
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineDIBBGR(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction;
|
|
__GLcolor *cp;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle;
|
|
unsigned char *addr, ir, ig, ib;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
cp = v1->color;
|
|
ir = (unsigned char) cp->b;
|
|
ig = (unsigned char) cp->g;
|
|
ib = (unsigned char) cp->r;
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
addrLittle = (gc->line.options.xLittle * 3) +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = (gc->line.options.xBig * 3) +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
|
|
__FAST_LINE_STROKE_DIB24
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineDIBRGB32(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle;
|
|
unsigned long *addr, pixel;
|
|
GLint x, y, outerWidth_4;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = __fastLineComputeColorRGB(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned long *) ((GLint)cfb->buf.base + (x << 2) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
outerWidth_4 = cfb->buf.outerWidth >> 2;
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
(gc->line.options.yLittle * outerWidth_4);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
(gc->line.options.yBig * outerWidth_4);
|
|
|
|
__FAST_LINE_STROKE_DIB
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineDIBCI8(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle;
|
|
unsigned char *addr, pixel;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = (unsigned char) __fastLineComputeColorCI4and8(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + x +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
|
|
__FAST_LINE_STROKE_DIB
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineDIBCI16(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle;
|
|
unsigned short *addr, pixel;
|
|
GLint x, y, outerWidth_2;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = (unsigned short) __fastLineComputeColorCI(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned short *) ((GLint)cfb->buf.base + (x << 1) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
outerWidth_2 = cfb->buf.outerWidth >> 1;
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
(gc->line.options.yLittle * outerWidth_2);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
(gc->line.options.yBig * outerWidth_2);
|
|
|
|
__FAST_LINE_STROKE_DIB
|
|
}
|
|
|
|
/*
|
|
** XXX GRE swabs bytes in palette, DIBCIRGB & DIBCIBGR are identical now
|
|
*/
|
|
void FASTCALL __fastGenRenderLineDIBCIRGB(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle;
|
|
unsigned char *addr, ir, ig, ib;
|
|
unsigned long pixel;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
// Red is lsb of pixel
|
|
pixel = __fastLineComputeColorCI(gc, v1->color);
|
|
ir = (unsigned char) (pixel & 0xff);
|
|
ig = (unsigned char) ((pixel >> 8) & 0xff);
|
|
ib = (unsigned char) ((pixel >> 16) & 0xff);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
addrLittle = (gc->line.options.xLittle * 3) +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = (gc->line.options.xBig * 3) +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
|
|
__FAST_LINE_STROKE_DIB24
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineDIBCIBGR(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle;
|
|
unsigned char *addr, ir, ig, ib;
|
|
unsigned long pixel;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
// Blue is lsb of pixel
|
|
pixel = __fastLineComputeColorCI(gc, v1->color);
|
|
// Swap blue and red
|
|
ir = (unsigned char) (pixel & 0xff);
|
|
ig = (unsigned char) ((pixel >> 8) & 0xff);
|
|
ib = (unsigned char) ((pixel >> 16) & 0xff);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
addrLittle = (gc->line.options.xLittle * 3) +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = (gc->line.options.xBig * 3) +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
|
|
__FAST_LINE_STROKE_DIB24
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineDIBCI32(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle;
|
|
unsigned long *addr, pixel;
|
|
GLint x, y, outerWidth_4;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = __fastLineComputeColorCI(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned long *) ((GLint)cfb->buf.base + (x << 2) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
outerWidth_4 = cfb->buf.outerWidth >> 2;
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
(gc->line.options.yLittle * outerWidth_4);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
(gc->line.options.yBig * outerWidth_4);
|
|
|
|
__FAST_LINE_STROKE_DIB
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineWideDIBRGB8(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction, width, w;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle, addrMinor;
|
|
unsigned char *addr, pixel;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = (unsigned char) __fastLineComputeColorRGB8(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + x +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
width = gc->line.options.width;
|
|
if (gc->line.options.axis == __GL_X_MAJOR) {
|
|
addrMinor = cfb->buf.outerWidth;
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
((gc->line.options.yBig - width) * cfb->buf.outerWidth);
|
|
} else {
|
|
addrMinor = 1;
|
|
|
|
addrLittle = gc->line.options.xLittle - width +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = gc->line.options.xBig - width +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
}
|
|
__FAST_LINE_STROKE_DIB_WIDE
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineWideDIBRGB16(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction, width, w;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle, addrMinor;
|
|
unsigned short *addr, pixel;
|
|
GLint x, y, outerWidth_2;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = (unsigned short) __fastLineComputeColorRGB(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned short *) ((GLint)cfb->buf.base + (x << 1) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
width = gc->line.options.width;
|
|
outerWidth_2 = cfb->buf.outerWidth >> 1;
|
|
|
|
if (gc->line.options.axis == __GL_X_MAJOR) {
|
|
addrMinor = outerWidth_2;
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
((gc->line.options.yLittle - width) * outerWidth_2);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
((gc->line.options.yBig - width) * outerWidth_2);
|
|
} else {
|
|
addrMinor = 1;
|
|
|
|
addrLittle = gc->line.options.xLittle - width +
|
|
(gc->line.options.yLittle * outerWidth_2);
|
|
|
|
addrBig = gc->line.options.xBig - width +
|
|
(gc->line.options.yBig * outerWidth_2);
|
|
}
|
|
__FAST_LINE_STROKE_DIB_WIDE
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineWideDIBRGB(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction, width, w;
|
|
__GLcolor *cp;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle, addrMinor;
|
|
unsigned char *addr, ir, ig, ib;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
cp = v1->color;
|
|
ir = (unsigned char) cp->r;
|
|
ig = (unsigned char) cp->g;
|
|
ib = (unsigned char) cp->b;
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
width = gc->line.options.width;
|
|
if (gc->line.options.axis == __GL_X_MAJOR) {
|
|
addrMinor = cfb->buf.outerWidth;
|
|
|
|
addrLittle = (gc->line.options.xLittle * 3) +
|
|
((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
|
|
|
|
addrBig = (gc->line.options.xBig * 3) +
|
|
((gc->line.options.yBig - width) * cfb->buf.outerWidth);
|
|
} else {
|
|
addrMinor = 3;
|
|
|
|
addrLittle = ((gc->line.options.xLittle - width) * 3) +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = ((gc->line.options.xBig - width) * 3) +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
}
|
|
__FAST_LINE_STROKE_DIB24_WIDE
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineWideDIBBGR(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction, width, w;
|
|
__GLcolor *cp;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle, addrMinor;
|
|
unsigned char *addr, ir, ig, ib;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
cp = v1->color;
|
|
ir = (unsigned char) cp->b;
|
|
ig = (unsigned char) cp->g;
|
|
ib = (unsigned char) cp->r;
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
width = gc->line.options.width;
|
|
if (gc->line.options.axis == __GL_X_MAJOR) {
|
|
addrMinor = cfb->buf.outerWidth;
|
|
|
|
addrLittle = (gc->line.options.xLittle * 3) +
|
|
((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
|
|
|
|
addrBig = (gc->line.options.xBig * 3) +
|
|
((gc->line.options.yBig - width) * cfb->buf.outerWidth);
|
|
} else {
|
|
addrMinor = 3;
|
|
|
|
addrLittle = ((gc->line.options.xLittle - width) * 3) +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = ((gc->line.options.xBig - width) * 3) +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
}
|
|
__FAST_LINE_STROKE_DIB24_WIDE
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineWideDIBRGB32(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction, width, w;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle, addrMinor;
|
|
unsigned long *addr, pixel;
|
|
GLint x, y, outerWidth_4;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = __fastLineComputeColorRGB(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned long *) ((GLint)cfb->buf.base + (x << 2) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
width = gc->line.options.width;
|
|
outerWidth_4 = cfb->buf.outerWidth >> 2;
|
|
|
|
if (gc->line.options.axis == __GL_X_MAJOR) {
|
|
addrMinor = outerWidth_4;
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
((gc->line.options.yLittle - width) * outerWidth_4);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
((gc->line.options.yBig - width) * outerWidth_4);
|
|
} else {
|
|
addrMinor = 1;
|
|
|
|
addrLittle = gc->line.options.xLittle - width +
|
|
(gc->line.options.yLittle * outerWidth_4);
|
|
|
|
addrBig = gc->line.options.xBig - width +
|
|
(gc->line.options.yBig * outerWidth_4);
|
|
}
|
|
__FAST_LINE_STROKE_DIB_WIDE
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineWideDIBCI8(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction, width, w;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle, addrMinor;
|
|
unsigned char *addr, pixel;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = (unsigned char) __fastLineComputeColorCI4and8(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + x +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
width = gc->line.options.width;
|
|
if (gc->line.options.axis == __GL_X_MAJOR) {
|
|
addrMinor = cfb->buf.outerWidth;
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
((gc->line.options.yBig - width) * cfb->buf.outerWidth);
|
|
} else {
|
|
addrMinor = 1;
|
|
|
|
addrLittle = gc->line.options.xLittle - width +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = gc->line.options.xBig - width +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
}
|
|
__FAST_LINE_STROKE_DIB_WIDE
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineWideDIBCI16(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction, width, w;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle, addrMinor;
|
|
unsigned short *addr, pixel;
|
|
GLint x, y, outerWidth_2;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = (unsigned short) __fastLineComputeColorCI(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned short *) ((GLint)cfb->buf.base + (x << 1) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
width = gc->line.options.width;
|
|
outerWidth_2 = cfb->buf.outerWidth >> 1;
|
|
|
|
if (gc->line.options.axis == __GL_X_MAJOR) {
|
|
addrMinor = outerWidth_2;
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
((gc->line.options.yLittle - width) * outerWidth_2);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
((gc->line.options.yBig - width) * outerWidth_2);
|
|
} else {
|
|
addrMinor = 1;
|
|
|
|
addrLittle = gc->line.options.xLittle - width +
|
|
(gc->line.options.yLittle * outerWidth_2);
|
|
|
|
addrBig = gc->line.options.xBig - width +
|
|
(gc->line.options.yBig * outerWidth_2);
|
|
}
|
|
__FAST_LINE_STROKE_DIB_WIDE
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineWideDIBCIRGB(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction, width, w;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle, addrMinor;
|
|
unsigned char *addr, ir, ig, ib;
|
|
unsigned long pixel;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
// Red is lsb of pixel
|
|
pixel = __fastLineComputeColorCI(gc, v1->color);
|
|
ir = (unsigned char) (pixel & 0xff);
|
|
ig = (unsigned char) ((pixel >> 8) & 0xff);
|
|
ib = (unsigned char) ((pixel >> 16) & 0xff);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
width = gc->line.options.width;
|
|
if (gc->line.options.axis == __GL_X_MAJOR) {
|
|
addrMinor = cfb->buf.outerWidth;
|
|
|
|
addrLittle = (gc->line.options.xLittle * 3) +
|
|
((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
|
|
|
|
addrBig = (gc->line.options.xBig * 3) +
|
|
((gc->line.options.yBig - width) * cfb->buf.outerWidth);
|
|
} else {
|
|
addrMinor = 3;
|
|
|
|
addrLittle = ((gc->line.options.xLittle - width) * 3) +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = ((gc->line.options.xBig - width) * 3) +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
}
|
|
__FAST_LINE_STROKE_DIB24_WIDE
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineWideDIBCIBGR(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction, width, w;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle, addrMinor;
|
|
unsigned char *addr, ir, ig, ib;
|
|
unsigned long pixel;
|
|
GLint x, y;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
// Blue is lsb of pixel
|
|
pixel = __fastLineComputeColorCI(gc, v1->color);
|
|
// Swap blue and red
|
|
ir = (unsigned char) (pixel & 0xff);
|
|
ig = (unsigned char) ((pixel >> 8) & 0xff);
|
|
ib = (unsigned char) ((pixel >> 16) & 0xff);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
width = gc->line.options.width;
|
|
if (gc->line.options.axis == __GL_X_MAJOR) {
|
|
addrMinor = cfb->buf.outerWidth;
|
|
|
|
addrLittle = (gc->line.options.xLittle * 3) +
|
|
((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
|
|
|
|
addrBig = (gc->line.options.xBig * 3) +
|
|
((gc->line.options.yBig - width) * cfb->buf.outerWidth);
|
|
} else {
|
|
addrMinor = 3;
|
|
|
|
addrLittle = ((gc->line.options.xLittle - width) * 3) +
|
|
(gc->line.options.yLittle * cfb->buf.outerWidth);
|
|
|
|
addrBig = ((gc->line.options.xBig - width) * 3) +
|
|
(gc->line.options.yBig * cfb->buf.outerWidth);
|
|
}
|
|
__FAST_LINE_STROKE_DIB24_WIDE
|
|
}
|
|
|
|
void FASTCALL __fastGenRenderLineWideDIBCI32(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
|
|
{
|
|
GLint len, fraction, dfraction, width, w;
|
|
__GLcolorBuffer *cfb;
|
|
GLint addrBig, addrLittle, addrMinor;
|
|
unsigned long *addr, pixel;
|
|
GLint x, y, outerWidth_4;
|
|
|
|
GLboolean init;
|
|
CHOP_ROUND_ON();
|
|
init = __glInitLineData(gc, v0, v1);
|
|
CHOP_ROUND_OFF();
|
|
if (!init) return;
|
|
|
|
pixel = __fastLineComputeColorCI(gc, v1->color);
|
|
|
|
cfb = gc->drawBuffer;
|
|
x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
|
|
y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
|
|
addr = (unsigned long *) ((GLint)cfb->buf.base + (x << 2) +
|
|
(y * cfb->buf.outerWidth));
|
|
|
|
width = gc->line.options.width;
|
|
outerWidth_4 = cfb->buf.outerWidth >> 2;
|
|
|
|
if (gc->line.options.axis == __GL_X_MAJOR) {
|
|
addrMinor = outerWidth_4;
|
|
|
|
addrLittle = gc->line.options.xLittle +
|
|
((gc->line.options.yLittle - width) * outerWidth_4);
|
|
|
|
addrBig = gc->line.options.xBig +
|
|
((gc->line.options.yBig - width) * outerWidth_4);
|
|
} else {
|
|
addrMinor = 1;
|
|
|
|
addrLittle = gc->line.options.xLittle - width +
|
|
(gc->line.options.yLittle * outerWidth_4);
|
|
|
|
addrBig = gc->line.options.xBig - width +
|
|
(gc->line.options.yBig * outerWidth_4);
|
|
}
|
|
__FAST_LINE_STROKE_DIB_WIDE
|
|
}
|
|
|
|
#endif //NT_NO_BUFFER_INVARIANCE
|