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

4451 lines
134 KiB
C

/*
** Copyright 1991, 1992, 1993, Silicon Graphics, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of Silicon Graphics, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
*/
#include "precomp.h"
#pragma hdrstop
#include "genrgb.h"
#include "genclear.h"
#define STATIC
__GLfloat fDitherIncTable[16] = {
DITHER_INC(0), DITHER_INC(8), DITHER_INC(2), DITHER_INC(10),
DITHER_INC(12), DITHER_INC(4), DITHER_INC(14), DITHER_INC(6),
DITHER_INC(3), DITHER_INC(11), DITHER_INC(1), DITHER_INC(9),
DITHER_INC(15), DITHER_INC(7), DITHER_INC(13), DITHER_INC(5)
};
/* No Dither, No blend, No Write, No Nothing */
STATIC void FASTCALL Store_NOT(__GLcolorBuffer *cfb, const __GLfragment *frag)
{
}
STATIC GLboolean FASTCALL StoreSpanNone(__GLcontext *gc)
{
return GL_FALSE;
}
//
// Special case normal alpha blending (source alpha*src + dst*(1-sa))
// This case is used in antialiasing and actually jumping through
// the fetch and blend procs takes up a large amount of time. Moving
// the code into the store proc removes this overhead
//
// The macro requires a standard store proc setup, with gc, cfb, frag,
// blendColor and so on. It requires a dst_pix variable which
// will hold a pixel in the destination format.
// It also takes as an argument a statement which will set dst_pix.
// The reason it doesn't take the pixel itself is because only the special case
// actually needs the value. In all the flags cases the pixel
// retrieval would be wasted.
//
extern void __glDoBlend_SA_MSA(__GLcontext *gc, const __GLcolor *source,
const __GLcolor *dest, __GLcolor *result);
#define SPECIAL_ALPHA_BLEND(dst_pix_gen) \
color = &blendColor; \
if( (gc->procs.blendColor == __glDoBlend_SA_MSA) && \
!( ALPHA_WRITE_ENABLED( cfb )) ) \
{ \
__GLfloat a, msa; \
\
a = frag->color.a * gc->frontBuffer.oneOverAlphaScale; \
msa = __glOne - a; \
\
dst_pix_gen; \
blendColor.r = frag->color.r*a + msa*(__GLfloat) \
((dst_pix & gc->modes.redMask) >> cfb->redShift); \
blendColor.g = frag->color.g*a + msa*(__GLfloat) \
((dst_pix & gc->modes.greenMask) >> cfb->greenShift); \
blendColor.b = frag->color.b*a + msa*(__GLfloat) \
((dst_pix & gc->modes.blueMask) >> cfb->blueShift); \
} \
else \
{ \
(*gc->procs.blend)( gc, cfb, frag, &blendColor ); \
}
#define SPECIAL_ALPHA_BLEND_SPAN(dst_pix_gen) \
if( (gc->procs.blendColor == __glDoBlend_SA_MSA) && \
!( ALPHA_WRITE_ENABLED( cfb )) ) \
{ \
__GLcolor *color = gc->polygon.shader.colors; \
\
for ( i = 0; i < w; i++, color++ ) \
{ \
__GLfloat a, msa; \
\
a = color->a * gc->frontBuffer.oneOverAlphaScale; \
msa = __glOne - a; \
\
dst_pix_gen; \
color->r = color->r*a + msa*(__GLfloat) \
((dst_pix & gc->modes.redMask) >> cfb->redShift); \
color->g = color->g*a + msa*(__GLfloat) \
((dst_pix & gc->modes.greenMask) >> cfb->greenShift); \
color->b = color->b*a + msa*(__GLfloat) \
((dst_pix & gc->modes.blueMask) >> cfb->blueShift); \
} \
} \
else \
{ \
(*gc->procs.blendSpan)( gc ); \
}
#define DitheredRGBColorToBuffer(col, incr, cfb, dest, type) \
((dest) = (type)(( FTOL((col)->r+(incr)) << (cfb)->redShift) | \
( FTOL((col)->g+(incr)) << (cfb)->greenShift) | \
( FTOL((col)->b+(incr)) << (cfb)->blueShift)))
#define UnditheredRGBColorToBuffer(col, cfb, dest, type) \
((dest) = (type)(( FTOL((col)->r) << (cfb)->redShift) | \
( FTOL((col)->g) << (cfb)->greenShift) | \
( FTOL((col)->b) << (cfb)->blueShift)))
#define DitheredRGBAColorToBuffer(col, incr, cfb, dest, type) \
((dest) = (type)(( FTOL((col)->r+(incr)) << (cfb)->redShift) | \
( FTOL((col)->g+(incr)) << (cfb)->greenShift) | \
( FTOL((col)->b+(incr)) << (cfb)->blueShift) | \
( FTOL((col)->a+(incr)) << (cfb)->alphaShift)))
#define UnditheredRGBAColorToBuffer(col, cfb, dest, type) \
((dest) = (type)(( FTOL((col)->r) << (cfb)->redShift) | \
( FTOL((col)->g) << (cfb)->greenShift) | \
( FTOL((col)->b) << (cfb)->blueShift) | \
( FTOL((col)->a) << (cfb)->alphaShift)))
#define DitheredColorToBuffer(col, incr, cfb, dest, type) \
if( ALPHA_PIXEL_WRITE( cfb ) ) \
DitheredRGBAColorToBuffer(col, incr, cfb, dest, type); \
else \
DitheredRGBColorToBuffer(col, incr, cfb, dest, type);
#define UnditheredColorToBuffer(col, cfb, dest, type) \
if( ALPHA_PIXEL_WRITE( cfb ) ) \
UnditheredRGBAColorToBuffer(col, cfb, dest, type); \
else \
UnditheredRGBColorToBuffer(col, cfb, dest, type);
#define StoreColorAsRGB(col, dst) \
(*(dst)++ = (BYTE) FTOL((col)->r), \
*(dst)++ = (BYTE) FTOL((col)->g), \
*(dst)++ = (BYTE) FTOL((col)->b) )
#define StoreColorAsBGR(col, dst) \
(*(dst)++ = (BYTE) FTOL((col)->b), \
*(dst)++ = (BYTE) FTOL((col)->g), \
*(dst)++ = (BYTE) FTOL((col)->r) )
// Macro to read RGBA bitfield span, where alpha component has 3 possibilities:
// 1) No alpha buffer, so use constant alpha
// 2) Alpha is part of the pixel
// 3) Alpha is in the software alpha buffer
// Note, currently this is only used for 16 and 32bpp.
#define READ_RGBA_BITFIELD_SPAN(src_pix_gen) \
if( !gc->modes.alphaBits ) { \
for( ; w; w--, pResults++ ) \
{ \
src_pix_gen; \
pResults->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift); \
pResults->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift); \
pResults->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift); \
pResults->a = cfb->alphaScale; \
} \
} \
else if( ALPHA_IN_PIXEL( cfb ) ) { \
for( ; w; w--, pResults++ ) \
{ \
src_pix_gen; \
pResults->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift); \
pResults->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift); \
pResults->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift); \
pResults->a = (__GLfloat) ((pixel & gc->modes.alphaMask) >> cfb->alphaShift); \
} \
} else { \
(*cfb->alphaBuf.readSpan)(&cfb->alphaBuf, x, y, w, pResults); \
for( ; w; w--, pResults++ ) \
{ \
src_pix_gen; \
pResults->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift); \
pResults->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift); \
pResults->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift); \
} \
}
/*
* write all
*/
STATIC void FASTCALL DIBIndex4Store(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLubyte result, *puj;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
__GLfloat incr;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLubyte dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
if ( (cfb->buf.flags & NO_CLIP) ||
(*gengc->pfnPixelVisible)(x, y) )
{
incr = (enables & __GL_DITHER_ENABLE) ?
fDitherIncTable[__GL_DITHER_INDEX(frag->x, frag->y)] : __glHalf;
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x >> 1));
if( enables & __GL_BLEND_ENABLE )
{
SPECIAL_ALPHA_BLEND((dst_pix = gengc->pajInvTranslateVector
[(x & 1) ? (*puj & 0xf) : (*puj >> 4)]));
}
else
{
color = &(frag->color);
}
DitheredRGBColorToBuffer(color, incr, cfb, result, GLubyte);
if (cfb->buf.flags & NEED_FETCH)
{
if( x & 1 )
{
dst_pix = (*puj & 0x0f);
}
else
{
dst_pix = (*puj & 0xf0) >> 4;
}
dst_pix = gengc->pajInvTranslateVector[dst_pix];
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = (GLubyte)
(DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask);
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (GLubyte)
((dst_pix & cfb->destMask) | (result & cfb->sourceMask));
}
}
// now put it in
result = gengc->pajTranslateVector[result];
if (x & 1)
{
*puj = (*puj & 0xf0) | result;
}
else
{
result <<= 4;
*puj = (*puj & 0x0f) | result;
}
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
}
STATIC void FASTCALL DIBIndex8Store(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLubyte result, *puj;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
__GLfloat incr;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLubyte dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
if ( (cfb->buf.flags & NO_CLIP) ||
(*gengc->pfnPixelVisible)(x, y) )
{
incr = (enables & __GL_DITHER_ENABLE) ?
fDitherIncTable[__GL_DITHER_INDEX(frag->x, frag->y)] : __glHalf;
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + x);
if( enables & __GL_BLEND_ENABLE )
{
SPECIAL_ALPHA_BLEND((dst_pix =
gengc->pajInvTranslateVector[*puj]));
}
else
{
color = &(frag->color);
}
DitheredRGBColorToBuffer(color, incr, cfb, result, GLubyte);
if (cfb->buf.flags & NEED_FETCH)
{
dst_pix = gengc->pajInvTranslateVector[*puj];
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = (GLubyte)
(DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask);
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (GLubyte)
((dst_pix & cfb->destMask) | (result & cfb->sourceMask));
}
}
*puj = gengc->pajTranslateVector[result];
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
}
// BMF_24BPP in BGR format
STATIC void FASTCALL DIBBGRStore(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLubyte *puj;
GLuint result;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLuint dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
if ( (cfb->buf.flags & NO_CLIP) ||
(*gengc->pfnPixelVisible)(x, y) )
{
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x * 3));
if( enables & __GL_BLEND_ENABLE )
{
SPECIAL_ALPHA_BLEND(Copy3Bytes(&dst_pix, puj));
}
else
{
color = &(frag->color);
}
if (cfb->buf.flags & NEED_FETCH)
{
Copy3Bytes( &dst_pix, puj );
UnditheredRGBColorToBuffer(color, cfb, result, GLuint);
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if (cfb->buf.flags & COLORMASK_ON)
{
result =
(result & cfb->sourceMask) | (dst_pix & cfb->destMask);
}
Copy3Bytes( puj, &result );
}
else
{
StoreColorAsBGR(color, puj);
}
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
}
// BMF_24BPP in RGB format
STATIC void FASTCALL DIBRGBAStore(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLubyte *puj;
GLuint result;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLuint dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
if ( (cfb->buf.flags & NO_CLIP) ||
(*gengc->pfnPixelVisible)(x, y) )
{
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x * 3));
if( enables & __GL_BLEND_ENABLE )
{
SPECIAL_ALPHA_BLEND(Copy3Bytes(&dst_pix, puj));
}
else
{
color = &(frag->color);
}
if (cfb->buf.flags & NEED_FETCH)
{
Copy3Bytes( &dst_pix, puj );
UnditheredRGBColorToBuffer(color, cfb, result, GLuint);
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if (cfb->buf.flags & COLORMASK_ON)
{
result =
(result & cfb->sourceMask) | (dst_pix & cfb->destMask);
}
Copy3Bytes( puj, &result );
}
else
{
StoreColorAsRGB(color, puj);
}
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
}
// BMF_16BPP
STATIC void FASTCALL DIBBitfield16Store(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLushort result, *pus;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
__GLfloat incr;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLushort dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
if ( (cfb->buf.flags & NO_CLIP) ||
(*gengc->pfnPixelVisible)(x, y) )
{
incr = (enables & __GL_DITHER_ENABLE) ?
fDitherIncTable[__GL_DITHER_INDEX(frag->x, frag->y)] : __glHalf;
pus = (GLushort *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x << 1));
if( enables & __GL_BLEND_ENABLE )
{
SPECIAL_ALPHA_BLEND((dst_pix = *pus));
}
else
{
color = &(frag->color);
}
DitheredColorToBuffer(color, incr, cfb, result, GLushort);
if (cfb->buf.flags & NEED_FETCH)
{
dst_pix = *pus;
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = (GLushort)
(DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask);
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (GLushort)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
}
*pus = result;
if( ALPHA_BUFFER_WRITE( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
}
// BMF_32BPP store
// each component is 8 bits or less
// XXX could special case if shifting by 8 or use the 24 bit RGB code
STATIC void FASTCALL DIBBitfield32Store(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLuint result, *pul;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLuint dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
if ( (cfb->buf.flags & NO_CLIP) ||
(*gengc->pfnPixelVisible)(x, y) )
{
pul = (GLuint *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x << 2));
if( enables & __GL_BLEND_ENABLE )
{
SPECIAL_ALPHA_BLEND((dst_pix = *pul));
}
else
{
color = &(frag->color);
}
UnditheredColorToBuffer(color, cfb, result, GLuint);
if (cfb->buf.flags & NEED_FETCH)
{
dst_pix = *pul;
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result =
DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (dst_pix & cfb->destMask) | (result & cfb->sourceMask);
}
}
*pul = result;
if( ALPHA_BUFFER_WRITE( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
}
static GLubyte vubRGBtoVGA[8] = {
0x00,
0x90,
0xa0,
0xb0,
0xc0,
0xd0,
0xe0,
0xf0
};
STATIC void FASTCALL DisplayIndex4Store(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLubyte result, *puj;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
__GLfloat incr;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLubyte dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
incr = (enables & __GL_DITHER_ENABLE) ?
fDitherIncTable[__GL_DITHER_INDEX(frag->x, frag->y)] : __glHalf;
puj = gengc->ColorsBits;
if( enables & __GL_BLEND_ENABLE )
{
color = &blendColor;
(*gc->procs.blend)( gc, cfb, frag, &blendColor );
}
else
{
color = &(frag->color);
}
DitheredRGBColorToBuffer(color, incr, cfb, result, GLubyte);
if (cfb->buf.flags & NEED_FETCH)
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
dst_pix = *puj >> 4;
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = (GLubyte)
(DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask);
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (GLubyte)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
}
*puj = vubRGBtoVGA[result];
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, TRUE);
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
// Put fragment into created DIB and call copybits for one pixel
STATIC void FASTCALL DisplayIndex8Store(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLubyte result, *puj;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
__GLfloat incr;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLubyte dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
incr = (enables & __GL_DITHER_ENABLE) ?
fDitherIncTable[__GL_DITHER_INDEX(frag->x, frag->y)] : __glHalf;
puj = gengc->ColorsBits;
if( enables & __GL_BLEND_ENABLE )
{
color = &blendColor;
(*gc->procs.blend)( gc, cfb, frag, &blendColor );
}
else
{
color = &(frag->color);
}
DitheredRGBColorToBuffer(color, incr, cfb, result, GLubyte);
if (cfb->buf.flags & NEED_FETCH)
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
dst_pix = gengc->pajInvTranslateVector[*puj];
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = (GLubyte)
(DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask);
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (GLubyte)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
}
*puj = gengc->pajTranslateVector[result];
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, TRUE);
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
STATIC void FASTCALL DisplayBGRStore(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLubyte *puj;
GLuint result;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLuint dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
puj = gengc->ColorsBits;
if( enables & __GL_BLEND_ENABLE )
{
color = &blendColor;
(*gc->procs.blend)( gc, cfb, frag, &blendColor );
}
else
{
color = &(frag->color);
}
if (cfb->buf.flags & NEED_FETCH)
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
dst_pix = *(GLuint *)puj;
UnditheredRGBColorToBuffer(color, cfb, result, GLuint);
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result =
DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (dst_pix & cfb->destMask) |
(result & cfb->sourceMask);
}
Copy3Bytes( puj, &result );
}
else
{
StoreColorAsBGR(color, puj);
}
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, TRUE);
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
STATIC void FASTCALL DisplayRGBStore(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLubyte *puj;
GLuint result;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLuint dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
puj = gengc->ColorsBits;
if( enables & __GL_BLEND_ENABLE )
{
color = &blendColor;
(*gc->procs.blend)( gc, cfb, frag, &blendColor );
}
else
{
color = &(frag->color);
}
if (cfb->buf.flags & NEED_FETCH)
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
dst_pix = *(GLuint *)puj;
UnditheredRGBColorToBuffer(color, cfb, result, GLuint);
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result =
DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (dst_pix & cfb->destMask) |
(result & cfb->sourceMask);
}
Copy3Bytes( puj, &result );
}
else
{
StoreColorAsRGB(color, puj);
}
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, TRUE);
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
STATIC void FASTCALL DisplayBitfield16Store(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLushort result, *pus;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
__GLfloat incr;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLushort dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
incr = (enables & __GL_DITHER_ENABLE) ?
fDitherIncTable[__GL_DITHER_INDEX(frag->x, frag->y)] : __glHalf;
pus = gengc->ColorsBits;
if( enables & __GL_BLEND_ENABLE )
{
color = &blendColor;
(*gc->procs.blend)( gc, cfb, frag, &blendColor );
}
else
{
color = &(frag->color);
}
DitheredColorToBuffer(color, incr, cfb, result, GLushort);
if (cfb->buf.flags & NEED_FETCH)
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
dst_pix = *pus;
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = (GLushort)
(DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask);
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (GLushort)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
}
*pus = result;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, TRUE);
if( ALPHA_BUFFER_WRITE( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
STATIC void FASTCALL DisplayBitfield32Store(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
GLint x, y;
GLuint result, *pul;
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint enables = gc->state.enables.general;
__GLcolor blendColor;
const __GLcolor *color;
GLuint dst_pix;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, frag->x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, frag->y) + cfb->buf.yOrigin;
// x & y are screen coords now
pul = gengc->ColorsBits;
if( enables & __GL_BLEND_ENABLE )
{
color = &blendColor;
(*gc->procs.blend)( gc, cfb, frag, &blendColor );
}
else
{
color = &(frag->color);
}
UnditheredColorToBuffer(color, cfb, result, GLuint);
if (cfb->buf.flags & NEED_FETCH)
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
dst_pix = *pul;
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result =
DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (dst_pix & cfb->destMask) |
(result & cfb->sourceMask);
}
}
*pul = result;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, TRUE);
if( ALPHA_BUFFER_WRITE( cfb ) )
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, color);
}
STATIC void FASTCALL AlphaStore(__GLcolorBuffer *cfb,
const __GLfragment *frag)
{
(*cfb->alphaBuf.store)(&cfb->alphaBuf, frag->x, frag->y, &(frag->color) );
}
/******************************Public*Routine******************************\
* Index8StoreSpan
*
* Copies the current span in the renderer into a bitmap. If bDIB is TRUE,
* then the bitmap is the display in DIB format (or a memory DC). If bDIB
* is FALSE, then the bitmap is an offscreen scanline buffer and it will be
* output to the buffer by (*gengc->pfnCopyPixels)().
*
* This handles 8-bit CI mode. Blending and dithering are supported.
*
* Returns:
* GL_FALSE always. Soft code ignores return value.
*
* History:
* 15-Nov-1993 -by- Gilman Wong [gilmanw]
* Wrote it.
\**************************************************************************/
//XXX The returnSpan routine follows this routine very closely. Any changes
//XXX to this routine should also be reflected in the returnSpan routine
STATIC GLboolean FASTCALL Index8StoreSpan( __GLcontext *gc )
{
GLint xFrag, yFrag; // current fragment coordinates
__GLcolor *cp; // current fragment color
__GLcolorBuffer *cfb; // color frame buffer
GLint xScr, yScr; // current screen (pixel) coordinates
GLubyte result, *puj; // current pixel color, current pixel ptr
GLubyte *pujEnd; // end of scan line
__GLfloat incr; // current dither adj.
GLint w; // span width
ULONG ulSpanVisibility; // span visibility mode
GLint cWalls;
GLint *Walls;
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLuint flags;
GLboolean bDIB;
GLubyte dst_pix;
ASSERT_CHOP_ROUND();
// Get span position and length.
w = gc->polygon.shader.length;
xFrag = gc->polygon.shader.frag.x;
yFrag = gc->polygon.shader.frag.y;
gengc = (__GLGENcontext *)gc;
cfb = gc->drawBuffer;
xScr = __GL_UNBIAS_X(gc, xFrag) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, yFrag) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
flags = cfb->buf.flags;
bDIB = flags & DIB_FORMAT;
if( !bDIB || (flags & NO_CLIP) )
{
// Device managed or unclipped surface
ulSpanVisibility = WGL_SPAN_ALL;
}
else
{
// Device in BITMAP format
ulSpanVisibility = wglSpanVisible(xScr, yScr, w, &cWalls, &Walls);
}
// Proceed as long as the span is (partially or fully) visible.
if (ulSpanVisibility != WGL_SPAN_NONE)
{
GLboolean bCheckWalls = GL_FALSE;
GLboolean bDraw;
GLint NextWall;
if (ulSpanVisibility == WGL_SPAN_PARTIAL)
{
bCheckWalls = GL_TRUE;
if (cWalls & 0x01)
{
bDraw = GL_TRUE;
}
else
{
bDraw = GL_FALSE;
}
NextWall = *Walls++;
cWalls--;
}
// Get pointers to fragment colors array and frame buffer.
cp = gc->polygon.shader.colors;
cfb = gc->polygon.shader.cfb;
// Get pointer to bitmap.
puj = bDIB ? (GLubyte *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + xScr)
: gengc->ColorsBits;
pujEnd = puj + w;
// Case: no dithering, no masking, no blending
//
// Check for the common case (which we'll do the fastest).
if ( !(enables & (__GL_DITHER_ENABLE)) &&
!(cfb->buf.flags & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE ) )
{
//!!!XXX -- we can also opt. by unrolling the loops
incr = __glHalf;
for (; puj < pujEnd; puj++, cp++)
{
if (bCheckWalls)
{
if (xScr++ >= NextWall)
{
if (bDraw)
bDraw = GL_FALSE;
else
bDraw = GL_TRUE;
if (cWalls <= 0)
{
NextWall = gc->constants.maxViewportWidth;
}
else
{
NextWall = *Walls++;
cWalls--;
}
}
if (bDraw == GL_FALSE)
continue;
}
DitheredRGBColorToBuffer(cp, incr, cfb, result, GLubyte);
*puj = gengc->pajTranslateVector[result];
}
}
// Case: dithering, no masking, no blending
//
// Dithering is pretty common for 8-bit displays, so its probably
// worth special case also.
else if ( !(cfb->buf.flags & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
for (; puj < pujEnd; puj++, cp++, xFrag++)
{
if (bCheckWalls)
{
if (xScr++ >= NextWall)
{
if (bDraw)
bDraw = GL_FALSE;
else
bDraw = GL_TRUE;
if (cWalls <= 0)
{
NextWall = gc->constants.maxViewportWidth;
}
else
{
NextWall = *Walls++;
cWalls--;
}
}
if (bDraw == GL_FALSE)
continue;
}
incr = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
DitheredRGBColorToBuffer(cp, incr, cfb, result, GLubyte);
*puj = gengc->pajTranslateVector[result];
}
}
// Case: general
//
// Otherwise, we'll do it slower.
else
{
// Fetch pixels we will modify:
if( (!bDIB) && (cfb->buf.flags & NEED_FETCH) )
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE );
// Blend.
if (enables & __GL_BLEND_ENABLE)
{
int i;
// this overwrites fragment colors array with blended values
SPECIAL_ALPHA_BLEND_SPAN(
(dst_pix =
gengc->pajInvTranslateVector[*(puj+i)]));
}
for (; puj < pujEnd; puj++, cp++)
{
if (bCheckWalls)
{
if (xScr++ >= NextWall)
{
if (bDraw)
bDraw = GL_FALSE;
else
bDraw = GL_TRUE;
if (cWalls <= 0)
{
NextWall = gc->constants.maxViewportWidth;
}
else
{
NextWall = *Walls++;
cWalls--;
}
}
if (bDraw == GL_FALSE)
continue;
}
// Dither.
if (enables & __GL_DITHER_ENABLE)
{
incr = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
xFrag++;
}
else
{
incr = __glHalf;
}
// Convert the RGB color to color index.
DitheredRGBColorToBuffer(cp, incr, cfb, result, GLubyte);
// Color mask
if (cfb->buf.flags & NEED_FETCH)
{
dst_pix = gengc->pajInvTranslateVector[*puj];
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = (GLubyte)
(DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask);
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (GLubyte)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
}
*puj = gengc->pajTranslateVector[result];
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
// Note that we ignore walls here for simplicity...
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.storeSpan)( &cfb->alphaBuf );
}
return GL_FALSE;
}
/******************************Public*Routine******************************\
* Bitfield16StoreSpan
*
* Copies the current span in the renderer into a bitmap. If bDIB is TRUE,
* then the bitmap is the display in DIB format (or a memory DC). If bDIB
* is FALSE, then the bitmap is an offscreen scanline buffer and it will be
* output to the buffer by (*gengc->pfnCopyPixels)().
*
* This handles general 16-bit BITFIELDS mode. Blending is supported. There
* is dithering.
*
* Returns:
* GL_FALSE always. Soft code ignores return value.
*
* History:
* 08-Dec-1993 -by- Gilman Wong [gilmanw]
* Wrote it.
\**************************************************************************/
//XXX The returnSpan routine follows this routine very closely. Any changes
//XXX to this routine should also be reflected in the returnSpan routine
STATIC GLboolean FASTCALL
Bitfield16StoreSpanPartial(__GLcontext *gc, GLboolean bDIB, GLint cWalls, GLint *Walls )
{
GLint xFrag, yFrag; // current fragment coordinates
__GLcolor *cp; // current fragment color
__GLcolorBuffer *cfb; // color frame buffer
GLint xScr, yScr; // current screen (pixel) coordinates
GLushort result, *pus; // current pixel color, current pixel ptr
GLushort *pusEnd; // end of scan line
__GLfloat incr; // current dither adj.
GLint w; // span width
GLboolean bDraw;
GLint NextWall;
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLuint flags;
GLushort dst_pix;
// Get span position and length.
w = gc->polygon.shader.length;
xFrag = gc->polygon.shader.frag.x;
yFrag = gc->polygon.shader.frag.y;
gengc = (__GLGENcontext *)gc;
cfb = gc->drawBuffer;
xScr = __GL_UNBIAS_X(gc, xFrag) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, yFrag) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
flags = cfb->buf.flags;
if (cWalls & 0x01)
{
bDraw = GL_TRUE;
}
else
{
bDraw = GL_FALSE;
}
NextWall = *Walls++;
cWalls--;
// Get pointers to fragment colors array and frame buffer.
cp = gc->polygon.shader.colors;
cfb = gc->polygon.shader.cfb;
// Get pointer to bitmap.
pus = bDIB ? (GLushort *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr<<1))
: gengc->ColorsBits;
pusEnd = pus + w;
// Case: no masking, no dithering, no blending
if ( !(enables & (__GL_DITHER_ENABLE)) &&
!(cfb->buf.flags & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
incr = __glHalf;
for (; pus < pusEnd; pus++, cp++)
{
if (xScr++ >= NextWall)
{
if (bDraw)
bDraw = GL_FALSE;
else
bDraw = GL_TRUE;
if (cWalls <= 0)
{
NextWall = gc->constants.maxViewportWidth;
}
else
{
NextWall = *Walls++;
cWalls--;
}
}
if (bDraw == GL_FALSE)
continue;
DitheredColorToBuffer(cp, incr, cfb, result, GLushort);
*pus = result;
}
}
// Case: dithering, no masking, no blending
else if ( !(cfb->buf.flags & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
for (; pus < pusEnd; pus++, cp++, xFrag++)
{
if (xScr++ >= NextWall)
{
if (bDraw)
bDraw = GL_FALSE;
else
bDraw = GL_TRUE;
if (cWalls <= 0)
{
NextWall = gc->constants.maxViewportWidth;
}
else
{
NextWall = *Walls++;
cWalls--;
}
}
if (bDraw == GL_FALSE)
continue;
incr = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
DitheredColorToBuffer(cp, incr, cfb, result, GLushort);
*pus = result;
}
}
// All other cases
else
{
if( (!bDIB) && (cfb->buf.flags & NEED_FETCH) )
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
if ( enables & __GL_BLEND_ENABLE )
{
int i;
// this overwrites fragment colors array with blended values
// XXX is the +i handled properly by the optimizer ?
SPECIAL_ALPHA_BLEND_SPAN((dst_pix = *(pus+i)));
}
for (; pus < pusEnd; pus++, cp++)
{
if (xScr++ >= NextWall)
{
if (bDraw)
bDraw = GL_FALSE;
else
bDraw = GL_TRUE;
if (cWalls <= 0)
{
NextWall = gc->constants.maxViewportWidth;
}
else
{
NextWall = *Walls++;
cWalls--;
}
}
if (bDraw == GL_FALSE)
continue;
// Dither.
if ( enables & __GL_DITHER_ENABLE )
{
incr = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
xFrag++;
}
else
{
incr = __glHalf;
}
// Convert color to 16BPP format.
DitheredColorToBuffer(cp, incr, cfb, result, GLushort);
// Store result with optional masking.
if (cfb->buf.flags & NEED_FETCH)
{
dst_pix = *pus;
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = (GLushort)
(DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask);
}
if ( cfb->buf.flags & COLORMASK_ON )
{
result = (GLushort)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
}
*pus = result;
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
if( ALPHA_BUFFER_WRITE( cfb ) )
(*cfb->alphaBuf.storeSpan)( &cfb->alphaBuf );
return GL_FALSE;
}
STATIC GLboolean FASTCALL Bitfield16StoreSpan(__GLcontext *gc)
{
GLint xFrag, yFrag; // current fragment coordinates
__GLcolor *cp; // current fragment color
__GLcolorBuffer *cfb; // color frame buffer
GLboolean bDIB;
GLint xScr, yScr; // current screen (pixel) coordinates
GLushort result, *pus; // current pixel color, current pixel ptr
GLushort *pusEnd; // end of scan line
__GLfloat incr; // current dither adj.
GLint w; // span width
GLint cWalls;
GLint *Walls;
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLuint flags;
GLushort dst_pix;
ASSERT_CHOP_ROUND();
// Get span position and length.
w = gc->polygon.shader.length;
xFrag = gc->polygon.shader.frag.x;
yFrag = gc->polygon.shader.frag.y;
gengc = (__GLGENcontext *)gc;
cfb = gc->drawBuffer;
xScr = __GL_UNBIAS_X(gc, xFrag) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, yFrag) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
flags = cfb->buf.flags;
bDIB = flags & DIB_FORMAT;
// Check span visibility
if( bDIB && !(flags & NO_CLIP) )
{
// Device in BITMAP format
ULONG ulSpanVisibility; // span visibility mode
ulSpanVisibility = wglSpanVisible(xScr, yScr, w, &cWalls, &Walls);
if (ulSpanVisibility == WGL_SPAN_NONE)
return GL_FALSE;
else if (ulSpanVisibility == WGL_SPAN_PARTIAL)
return Bitfield16StoreSpanPartial( gc, bDIB, cWalls, Walls );
// else span fully visible
}
// Get pointers to fragment colors array and frame buffer.
cp = gc->polygon.shader.colors;
cfb = gc->polygon.shader.cfb;
// Get pointer to bitmap.
pus = bDIB ? (GLushort *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr<<1))
: gengc->ColorsBits;
pusEnd = pus + w;
// Case: no masking, no dithering, no blending
if ( !(enables & (__GL_DITHER_ENABLE)) &&
!(cfb->buf.flags & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
incr = __glHalf;
if( ALPHA_PIXEL_WRITE( cfb ) ) {
for (; pus < pusEnd; pus++, cp++)
DitheredRGBAColorToBuffer(cp, incr, cfb, *pus, GLushort);
} else {
for (; pus < pusEnd; pus++, cp++)
DitheredRGBColorToBuffer(cp, incr, cfb, *pus, GLushort);
}
}
// Case: dithering, no masking, no blending
else if ( !(cfb->buf.flags & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
if( ALPHA_PIXEL_WRITE( cfb ) ) {
for (; pus < pusEnd; pus++, cp++, xFrag++)
{
incr = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
DitheredRGBAColorToBuffer(cp, incr, cfb, *pus, GLushort);
}
} else {
for (; pus < pusEnd; pus++, cp++, xFrag++)
{
incr = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
DitheredRGBColorToBuffer(cp, incr, cfb, *pus, GLushort);
}
}
}
// All other cases
else
{
if( (!bDIB) && (cfb->buf.flags & NEED_FETCH) )
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
if ( enables & __GL_BLEND_ENABLE )
{
int i;
// this overwrites fragment colors array with blended values
SPECIAL_ALPHA_BLEND_SPAN((dst_pix = *(pus+i)));
}
for (; pus < pusEnd; pus++, cp++)
{
// Dither.
if ( enables & __GL_DITHER_ENABLE )
{
incr = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
xFrag++;
}
else
{
incr = __glHalf;
}
// Convert color to 16BPP format.
DitheredColorToBuffer(cp, incr, cfb, result, GLushort);
// Store result with optional masking.
if (cfb->buf.flags & NEED_FETCH)
{
dst_pix = *pus;
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = (GLushort)
(DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask);
}
if ( cfb->buf.flags & COLORMASK_ON )
{
result = (GLushort)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
}
*pus = result;
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
if( ALPHA_BUFFER_WRITE( cfb ) )
(*cfb->alphaBuf.storeSpan)( &cfb->alphaBuf );
return GL_FALSE;
}
/******************************Public*Routine******************************\
* BGRStoreSpan
*
* Copies the current span in the renderer into a bitmap. If bDIB is TRUE,
* then the bitmap is the display in DIB format (or a memory DC). If bDIB
* is FALSE, then the bitmap is an offscreen scanline buffer and it will be
* output to the buffer by (*gengc->pfnCopyPixels)().
*
* This handles GBR 24-bit mode. Blending is supported. There
* is no dithering.
*
* Returns:
* GL_FALSE always. Soft code ignores return value.
*
* History:
* 10-Jan-1994 -by- Marc Fortier [v-marcf]
* Wrote it.
\**************************************************************************/
//XXX The returnSpan routine follows this routine very closely. Any changes
//XXX to this routine should also be reflected in the returnSpan routine
STATIC GLboolean FASTCALL BGRStoreSpan(__GLcontext *gc )
{
__GLcolor *cp; // current fragment color
__GLcolorBuffer *cfb; // color frame buffer
GLint xScr, yScr; // current screen (pixel) coordinates
GLubyte *puj; // current pixel ptr
GLuint *pul; // current pixel ptr
GLuint result; // current pixel color
GLubyte *pujEnd; // end of scan line
GLint w; // span width
ULONG ulSpanVisibility; // span visibility mode
GLint cWalls;
GLint *Walls;
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLuint flags;
GLboolean bDIB;
GLuint dst_pix;
ASSERT_CHOP_ROUND();
// Get span position and length.
w = gc->polygon.shader.length;
gengc = (__GLGENcontext *)gc;
cfb = gc->drawBuffer;
xScr = __GL_UNBIAS_X(gc, gc->polygon.shader.frag.x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, gc->polygon.shader.frag.y) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
flags = cfb->buf.flags;
bDIB = flags & DIB_FORMAT;
if( !bDIB || (flags & NO_CLIP) )
{
// Device managed or unclipped surface
ulSpanVisibility = WGL_SPAN_ALL;
}
else
{
// Device in BITMAP format
ulSpanVisibility = wglSpanVisible(xScr, yScr, w, &cWalls, &Walls);
}
// Proceed as long as the span is (partially or fully) visible.
if (ulSpanVisibility != WGL_SPAN_NONE)
{
GLboolean bCheckWalls = GL_FALSE;
GLboolean bDraw;
GLint NextWall;
if (ulSpanVisibility == WGL_SPAN_PARTIAL)
{
bCheckWalls = GL_TRUE;
if (cWalls & 0x01)
{
bDraw = GL_TRUE;
}
else
{
bDraw = GL_FALSE;
}
NextWall = *Walls++;
cWalls--;
}
// Get pointers to fragment colors array and frame buffer.
cp = gc->polygon.shader.colors;
cfb = gc->polygon.shader.cfb;
// Get pointer to bitmap.
puj = bDIB ? (GLubyte *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr*3))
: gengc->ColorsBits;
pujEnd = puj + 3*w;
// Case: no masking, no blending
//!!!XXX -- do extra opt. for RGB and BGR cases
//!!!XXX -- we can also opt. by unrolling the loops
if ( !(cfb->buf.flags & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
for (; puj < pujEnd; cp++)
{
if (bCheckWalls)
{
if (xScr++ >= NextWall)
{
if (bDraw)
bDraw = GL_FALSE;
else
bDraw = GL_TRUE;
if (cWalls <= 0)
{
NextWall = gc->constants.maxViewportWidth;
}
else
{
NextWall = *Walls++;
cWalls--;
}
}
if (bDraw == GL_FALSE) {
puj += 3;
continue;
}
}
StoreColorAsBGR(cp, puj);
}
}
// All other cases
else
{
if( (!bDIB) && (cfb->buf.flags & NEED_FETCH) )
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
if (enables & __GL_BLEND_ENABLE)
{
// this overwrites fragment colors array with blended values
(*gc->procs.blendSpan)( gc );
}
for (; puj < pujEnd; cp++)
{
if (bCheckWalls)
{
if (xScr++ >= NextWall)
{
if (bDraw)
bDraw = GL_FALSE;
else
bDraw = GL_TRUE;
if (cWalls <= 0)
{
NextWall = gc->constants.maxViewportWidth;
}
else
{
NextWall = *Walls++;
cWalls--;
}
}
if (bDraw == GL_FALSE) {
puj += 3;
continue;
}
}
if (cfb->buf.flags & NEED_FETCH)
{
Copy3Bytes(&dst_pix, puj);
UnditheredRGBColorToBuffer(cp, cfb, result, GLuint);
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result =
DoLogicOp(gc->state.raster.logicOp, result,
dst_pix) & gc->modes.allMask;
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (result & cfb->sourceMask) |
(dst_pix & cfb->destMask);
}
Copy3Bytes( puj, &result );
puj += 3;
}
else
{
StoreColorAsBGR(cp, puj);
}
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.storeSpan)( &cfb->alphaBuf );
}
return GL_FALSE;
}
/******************************Public*Routine******************************\
* Bitfield32StoreSpan
*
* Copies the current span in the renderer into a bitmap. If bDIB is TRUE,
* then the bitmap is the display in DIB format (or a memory DC). If bDIB
* is FALSE, then the bitmap is an offscreen scanline buffer and it will be
* output to the buffer by (*gengc->pfnCopyPixels)().
*
* This handles general 32-bit BITFIELDS mode. Blending is supported. There
* is no dithering.
*
* Returns:
* GL_FALSE always. Soft code ignores return value.
*
* History:
* 15-Nov-1993 -by- Gilman Wong [gilmanw]
* Wrote it.
\**************************************************************************/
//XXX The returnSpan routine follows this routine very closely. Any changes
//XXX to this routine should also be reflected in the returnSpan routine
STATIC GLboolean FASTCALL
Bitfield32StoreSpanPartial(__GLcontext *gc, GLboolean bDIB, GLint cWalls, GLint *Walls )
{
__GLcolor *cp; // current fragment color
__GLcolorBuffer *cfb; // color frame buffer
GLint xScr, yScr; // current screen (pixel) coordinates
GLuint result, *pul; // current pixel color, current pixel ptr
GLuint *pulEnd; // end of scan line
GLint w; // span width
GLboolean bDraw;
GLint NextWall;
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLuint flags;
GLuint dst_pix;
// Get span position and length.
w = gc->polygon.shader.length;
gengc = (__GLGENcontext *)gc;
cfb = gc->drawBuffer;
xScr = __GL_UNBIAS_X(gc, gc->polygon.shader.frag.x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, gc->polygon.shader.frag.y) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
flags = cfb->buf.flags;
if (cWalls & 0x01)
{
bDraw = GL_TRUE;
}
else
{
bDraw = GL_FALSE;
}
NextWall = *Walls++;
cWalls--;
// Get pointers to fragment colors array and frame buffer.
cp = gc->polygon.shader.colors;
cfb = gc->polygon.shader.cfb;
// Get pointer to bitmap.
pul = bDIB ? (GLuint *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr<<2))
: gengc->ColorsBits;
pulEnd = pul + w;
// Case: no masking, no blending
//!!!XXX -- do extra opt. for RGB and BGR cases
//!!!XXX -- we can also opt. by unrolling the loops
if ( !(cfb->buf.flags & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
for (; pul < pulEnd; pul++, cp++)
{
if (xScr++ >= NextWall)
{
if (bDraw)
bDraw = GL_FALSE;
else
bDraw = GL_TRUE;
if (cWalls <= 0)
{
NextWall = gc->constants.maxViewportWidth;
}
else
{
NextWall = *Walls++;
cWalls--;
}
}
if (bDraw == GL_FALSE)
continue;
UnditheredColorToBuffer(cp, cfb, result, GLuint);
*pul = result;
}
}
// All other cases
else
{
if( (!bDIB) && (cfb->buf.flags & NEED_FETCH) )
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
if (enables & __GL_BLEND_ENABLE)
{
int i;
SPECIAL_ALPHA_BLEND_SPAN((dst_pix = *(pul+i)));
}
for (; pul < pulEnd; pul++, cp++)
{
if (xScr++ >= NextWall)
{
if (bDraw)
bDraw = GL_FALSE;
else
bDraw = GL_TRUE;
if (cWalls <= 0)
{
NextWall = gc->constants.maxViewportWidth;
}
else
{
NextWall = *Walls++;
cWalls--;
}
}
if (bDraw == GL_FALSE)
continue;
UnditheredColorToBuffer(cp, cfb, result, GLuint);
//!!!XXX again, opt. by unrolling loop
if (cfb->buf.flags & NEED_FETCH)
{
dst_pix = *pul;
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result =
DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (dst_pix & cfb->destMask) |
(result & cfb->sourceMask);
}
}
*pul = result;
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
if( ALPHA_BUFFER_WRITE( cfb ) )
(*cfb->alphaBuf.storeSpan)( &cfb->alphaBuf );
return GL_FALSE;
}
STATIC GLboolean FASTCALL Bitfield32StoreSpan( __GLcontext *gc )
{
__GLcolor *cp; // current fragment color
__GLcolorBuffer *cfb; // color frame buffer
GLboolean bDIB;
GLint xScr, yScr; // current screen (pixel) coordinates
GLuint result, *pul; // current pixel color, current pixel ptr
GLuint *pulEnd; // end of scan line
GLint w; // span width
ULONG ulSpanVisibility; // span visibility mode
GLint cWalls;
GLint *Walls;
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLuint flags;
GLuint dst_pix;
ASSERT_CHOP_ROUND();
// Get span position and length.
w = gc->polygon.shader.length;
gengc = (__GLGENcontext *)gc;
cfb = gc->drawBuffer;
xScr = __GL_UNBIAS_X(gc, gc->polygon.shader.frag.x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, gc->polygon.shader.frag.y) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
flags = cfb->buf.flags;
bDIB = flags & DIB_FORMAT;
// Check span visibility
if( bDIB && !(flags & NO_CLIP) )
{
// Device in BITMAP format
ULONG ulSpanVisibility; // span visibility mode
ulSpanVisibility = wglSpanVisible(xScr, yScr, w, &cWalls, &Walls);
if (ulSpanVisibility == WGL_SPAN_NONE)
return GL_FALSE;
else if (ulSpanVisibility == WGL_SPAN_PARTIAL)
return Bitfield32StoreSpanPartial( gc, bDIB, cWalls, Walls );
// else span fully visible
}
// Get pointers to fragment colors array and frame buffer.
cp = gc->polygon.shader.colors;
cfb = gc->polygon.shader.cfb;
// Get pointer to bitmap.
pul = bDIB ? (GLuint *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr<<2))
: gengc->ColorsBits;
pulEnd = pul + w;
// Case: no masking, no blending
//!!!XXX -- do extra opt. for RGB and BGR cases
//!!!XXX -- we can also opt. by unrolling the loops
if ( !(cfb->buf.flags & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
if( ALPHA_PIXEL_WRITE( cfb ) ) {
for (; pul < pulEnd; pul++, cp++)
{
UnditheredRGBAColorToBuffer(cp, cfb, result, GLuint);
*pul = result;
}
} else {
for (; pul < pulEnd; pul++, cp++)
{
UnditheredRGBColorToBuffer(cp, cfb, result, GLuint);
*pul = result;
}
}
}
// All other cases
else
{
if( (!bDIB) && (cfb->buf.flags & NEED_FETCH) )
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
if (enables & __GL_BLEND_ENABLE)
{
int i;
SPECIAL_ALPHA_BLEND_SPAN((dst_pix = *(pul+i)));
}
for (; pul < pulEnd; pul++, cp++)
{
UnditheredColorToBuffer(cp, cfb, result, GLuint);
//!!!XXX again, opt. by unrolling loop
if (cfb->buf.flags & NEED_FETCH)
{
dst_pix = *pul;
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result =
DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if (cfb->buf.flags & COLORMASK_ON)
{
result = (dst_pix & cfb->destMask) |
(result & cfb->sourceMask);
}
}
*pul = result;
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
if( ALPHA_BUFFER_WRITE( cfb ) )
(*cfb->alphaBuf.storeSpan)( &cfb->alphaBuf );
return GL_FALSE;
}
STATIC GLboolean FASTCALL AlphaStoreSpan(__GLcontext *gc)
{
__GLcolorBuffer *cfb = gc->drawBuffer;
ASSERT_CHOP_ROUND();
(*cfb->alphaBuf.storeSpan)( &cfb->alphaBuf );
return GL_FALSE;
}
STATIC GLboolean FASTCALL StoreMaskedSpan(__GLcontext *gc, GLboolean masked)
{
#ifdef REWRITE
GLint x, y, len;
int i;
__GLcolor *cp;
DWORD *pul;
WORD *pus;
BYTE *puj;
__GLGENcontext *gengc = (__GLGENcontext *)gc;
len = gc->polygon.shader.length;
x = __GL_UNBIAS_X(gc, gc->polygon.shader.frag.x);
y = __GL_UNBIAS_Y(gc, gc->polygon.shader.frag.y);
cp = gc->polygon.shader.colors;
switch (gengc->iFormatDC)
{
case BMF_8BPP:
break;
case BMF_16BPP:
pus = gengc->ColorsBits;
for (i = 0; i < len; i++) {
*pus++ = __GL_COLOR_TO_BMF_16BPP(cp);
cp++;
}
break;
case BMF_24BPP:
puj = gengc->ColorsBits;
for (i = 0; i < len; i++) {
*puj++ = (BYTE)cp->b; // XXX check order
*puj++ = (BYTE)cp->g;
*puj++ = (BYTE)cp->r;
cp++;
}
break;
case BMF_32BPP:
pul = gengc->ColorsBits;
for (i = 0; i < len; i++) {
*pul++ = __GL_COLOR_TO_BMF_32BPP(cp);
cp++;
}
break;
default:
break;
}
if (masked == GL_TRUE) // XXX mask is BigEndian!!!
{
unsigned long *pulstipple;
unsigned long stip;
GLint count;
pul = gengc->StippleBits;
pulstipple = gc->polygon.shader.stipplePat;
count = (len+31)/32;
for (i = 0; i < count; i++) {
stip = *pulstipple++;
*pul++ = (stip&0xff)<<24 | (stip&0xff00)<<8 | (stip&0xff0000)>>8 |
(stip&0xff000000)>>24;
}
wglSpanBlt(CURRENT_DC, gengc->ColorsBitmap, gengc->StippleBitmap,
x, y, len);
}
else
{
wglSpanBlt(CURRENT_DC, gengc->ColorsBitmap, (HBITMAP)NULL,
x, y, len);
}
#endif
return GL_FALSE;
}
#ifdef TESTSTIPPLE
STATIC void FASTCALL MessUpStippledSpan(__GLcontext *gc)
{
__GLcolor *cp;
__GLcolorBuffer *cfb;
__GLstippleWord inMask, bit, *sp;
GLint count;
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
cp = gc->polygon.shader.colors;
cfb = gc->polygon.shader.cfb;
while (w) {
count = w;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w -= count;
inMask = *sp++;
bit = __GL_STIPPLE_SHIFT(0);
while (--count >= 0) {
if (!(inMask & bit)) {
cp->r = cfb->redMax;
cp->g = cfb->greenMax;
cp->b = cfb->blueMax;
}
cp++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
}
}
#endif
// From the PIXMAP code, calls store for each fragment
STATIC GLboolean FASTCALL SlowStoreSpan(__GLcontext *gc)
{
int x, x1;
int i;
__GLfragment frag;
__GLcolor *cp;
__GLcolorBuffer *cfb;
GLint w;
w = gc->polygon.shader.length;
frag.y = gc->polygon.shader.frag.y;
x = gc->polygon.shader.frag.x;
x1 = gc->polygon.shader.frag.x + w;
cp = gc->polygon.shader.colors;
cfb = gc->polygon.shader.cfb;
for (i = x; i < x1; i++) {
frag.x = i;
frag.color = *cp++;
(*cfb->store)(cfb, &frag);
}
return GL_FALSE;
}
// From the PIXMAP code, calls store for each fragment with mask test
STATIC GLboolean FASTCALL SlowStoreStippledSpan(__GLcontext *gc)
{
int x;
__GLfragment frag;
__GLcolor *cp;
__GLcolorBuffer *cfb;
__GLstippleWord inMask, bit, *sp;
GLint count;
GLint w;
w = gc->polygon.shader.length;
sp = gc->polygon.shader.stipplePat;
frag.y = gc->polygon.shader.frag.y;
x = gc->polygon.shader.frag.x;
cp = gc->polygon.shader.colors;
cfb = gc->polygon.shader.cfb;
while (w) {
count = w;
if (count > __GL_STIPPLE_BITS) {
count = __GL_STIPPLE_BITS;
}
w -= count;
inMask = *sp++;
bit = __GL_STIPPLE_SHIFT((__GLstippleWord)0);
while (--count >= 0) {
if (inMask & bit) {
frag.x = x;
frag.color = *cp;
(*cfb->store)(cfb, &frag);
}
x++;
cp++;
#ifdef __GL_STIPPLE_MSB
bit >>= 1;
#else
bit <<= 1;
#endif
}
}
return GL_FALSE;
}
//
// Tables to convert 4-bit index to RGB component
// These tables assume the VGA fixed palette
// History:
// 22-NOV-93 Eddie Robinson [v-eddier] Wrote it.
//
#ifdef __GL_DOUBLE
static __GLfloat vfVGAtoR[16] = {
0.0, // black
0.5, // dim red
0.0, // dim green
0.5, // dim yellow
0.0, // dim blue
0.5, // dim magenta
0.0, // dim cyan
0.5, // dim grey
0.75, // medium grey
1.0, // bright red
0.0, // bright green
1.0, // bright yellow
0.0, // bright blue
1.0, // bright magenta
0.0, // bright cyan
1.0 // white
};
static __GLfloat vfVGAtoG[16] = {
0.0, // black
0.0, // dim red
0.5, // dim green
0.5, // dim yellow
0.0, // dim blue
0.0, // dim magenta
0.5, // dim cyan
0.5, // dim grey
0.75, // medium grey
0.0, // bright red
1.0, // bright green
1.0, // bright yellow
0.0, // bright blue
0.0, // bright magenta
1.0, // bright cyan
1.0 // white
};
static __GLfloat vfVGAtoB[16] = {
0.0, // black
0.0, // dim red
0.0, // dim green
0.0, // dim yellow
0.5, // dim blue
0.5, // dim magenta
0.5, // dim cyan
0.5, // dim grey
0.75, // medium grey
0.0, // bright red
0.0, // bright green
0.0, // bright yellow
1.0, // bright blue
1.0, // bright magenta
1.0, // bright cyan
1.0 // white
};
#else
static __GLfloat vfVGAtoR[16] = {
0.0F, // black
0.5F, // dim red
0.0F, // dim green
0.5F, // dim yellow
0.0F, // dim blue
0.5F, // dim magenta
0.0F, // dim cyan
0.5F, // dim grey
0.75F, // medium grey
1.0F, // bright red
0.0F, // bright green
1.0F, // bright yellow
0.0F, // bright blue
1.0F, // bright magenta
0.0F, // bright cyan
1.0F // white
};
static __GLfloat vfVGAtoG[16] = {
0.0F, // black
0.0F, // dim red
0.5F, // dim green
0.5F, // dim yellow
0.0F, // dim blue
0.0F, // dim magenta
0.5F, // dim cyan
0.5F, // dim grey
0.75F, // medium grey
0.0F, // bright red
1.0F, // bright green
1.0F, // bright yellow
0.0F, // bright blue
0.0F, // bright magenta
1.0F, // bright cyan
1.0F // white
};
static __GLfloat vfVGAtoB[16] = {
0.0F, // black
0.0F, // dim red
0.0F, // dim green
0.0F, // dim yellow
0.5F, // dim blue
0.5F, // dim magenta
0.5F, // dim cyan
0.5F, // dim grey
0.75F, // medium grey
0.0F, // bright red
0.0F, // bright green
0.0F, // bright yellow
1.0F, // bright blue
1.0F, // bright magenta
1.0F, // bright cyan
1.0F // white
};
#endif
void
RGBFetchNone(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
result->r = 0.0F;
result->g = 0.0F;
result->b = 0.0F;
if( cfb->buf.gc->modes.alphaBits )
result->a = 0.0F;
else
result->a = cfb->alphaScale;
}
void
RGBReadSpanNone(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results,
GLint w)
{
GLint i;
__GLcolor *pResults;
__GLfloat alphaVal;
if( cfb->buf.gc->modes.alphaBits )
alphaVal = 0.0F;
else
alphaVal = cfb->alphaScale;
for (i = 0, pResults = results; i < w; i++, pResults++)
{
pResults->r = 0.0F;
pResults->g = 0.0F;
pResults->b = 0.0F;
pResults->a = alphaVal;
}
}
void
DIBIndex4RGBAFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
// Do alpha first, before x,y unbiased
if( gc->modes.alphaBits ) {
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
} else
result->a = cfb->alphaScale;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x >> 1));
pixel = *puj;
if (!(x & 1))
pixel >>= 4;
pixel = gengc->pajInvTranslateVector[pixel&0xf];
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
}
void
DIBIndex8RGBFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base + (y*cfb->buf.outerWidth) + x);
pixel = gengc->pajInvTranslateVector[*puj];
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
result->a = cfb->alphaScale;
}
void
DIBIndex8RGBAFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base + (y*cfb->buf.outerWidth) + x);
pixel = gengc->pajInvTranslateVector[*puj];
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
}
void
DIBBGRFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x * 3));
result->b = (__GLfloat) *puj++;
result->g = (__GLfloat) *puj++;
result->r = (__GLfloat) *puj;
result->a = cfb->alphaScale;
}
void
DIBBGRAFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x * 3));
result->b = (__GLfloat) *puj++;
result->g = (__GLfloat) *puj++;
result->r = (__GLfloat) *puj;
}
void
DIBRGBFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x * 3));
result->r = (__GLfloat) *puj++;
result->g = (__GLfloat) *puj++;
result->b = (__GLfloat) *puj;
result->a = cfb->alphaScale;
}
void
DIBRGBAFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x * 3));
result->r = (__GLfloat) *puj++;
result->g = (__GLfloat) *puj++;
result->b = (__GLfloat) *puj;
}
void
DIBBitfield16RGBFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLushort *pus, pixel;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
pus = (GLushort *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x << 1));
pixel = *pus;
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
result->a = cfb->alphaScale;
}
void
DIBBitfield16RGBAFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLushort *pus, pixel;
GLint xScr, yScr; // current screen (pixel) coordinates
gengc = (__GLGENcontext *)gc;
xScr = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
pus = (GLushort *)((ULONG_PTR)cfb->buf.base +
(yScr*cfb->buf.outerWidth) + (xScr << 1));
pixel = *pus;
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
if( ALPHA_IN_PIXEL( cfb ) )
result->a = (__GLfloat) ((pixel & gc->modes.alphaMask) >> cfb->alphaShift);
else
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
}
void
DIBBitfield32RGBFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint *pul, pixel;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
pul = (GLuint *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x << 2));
pixel = *pul;
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
result->a = cfb->alphaScale;
}
void
DIBBitfield32RGBAFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint *pul, pixel;
GLint xScr, yScr;
gengc = (__GLGENcontext *)gc;
xScr = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
pul = (GLuint *)((ULONG_PTR)cfb->buf.base +
(yScr*cfb->buf.outerWidth) + (xScr << 2));
pixel = *pul;
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
if( ALPHA_IN_PIXEL( cfb ) )
result->a = (__GLfloat) ((pixel & gc->modes.alphaMask) >> cfb->alphaShift);
else
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
}
void
DisplayIndex4RGBAFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
if( gc->modes.alphaBits ) {
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
} else
result->a = cfb->alphaScale;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
puj = gengc->ColorsBits;
pixel = *puj >> 4;
result->r = vfVGAtoR[pixel];
result->g = vfVGAtoG[pixel];
result->b = vfVGAtoB[pixel];
}
void
DisplayIndex8RGBFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
puj = gengc->ColorsBits;
pixel = gengc->pajInvTranslateVector[*puj];
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
result->a = cfb->alphaScale;
}
void
DisplayIndex8RGBAFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
puj = gengc->ColorsBits;
pixel = gengc->pajInvTranslateVector[*puj];
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
}
void
DisplayBGRFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
puj = gengc->ColorsBits;
result->b = (__GLfloat) *puj++;
result->g = (__GLfloat) *puj++;
result->r = (__GLfloat) *puj;
result->a = cfb->alphaScale;
}
void
DisplayBGRAFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
puj = gengc->ColorsBits;
result->b = (__GLfloat) *puj++;
result->g = (__GLfloat) *puj++;
result->r = (__GLfloat) *puj;
}
void
DisplayRGBFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
puj = gengc->ColorsBits;
result->r = (__GLfloat) *puj++;
result->g = (__GLfloat) *puj++;
result->b = (__GLfloat) *puj;
result->a = cfb->alphaScale;
}
void
DisplayRGBAFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
puj = gengc->ColorsBits;
result->r = (__GLfloat) *puj++;
result->g = (__GLfloat) *puj++;
result->b = (__GLfloat) *puj;
}
void
DisplayBitfield16RGBFetch(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLushort *pus, pixel;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
pus = gengc->ColorsBits;
pixel = *pus;
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
result->a = cfb->alphaScale;
}
void
DisplayBitfield16RGBAFetch(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLushort *pus, pixel;
GLint xScr, yScr; // current screen (pixel) coordinates
gengc = (__GLGENcontext *)gc;
xScr = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
pus = gengc->ColorsBits;
pixel = *pus;
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
if( ALPHA_IN_PIXEL( cfb ) )
result->a = (__GLfloat) ((pixel & gc->modes.alphaMask) >> cfb->alphaShift);
else
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
}
void
DisplayBitfield32RGBFetch(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint *pul, pixel;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
pul = gengc->ColorsBits;
pixel = *pul;
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
result->a = cfb->alphaScale;
}
void
DisplayBitfield32RGBAFetch(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint *pul, pixel;
GLint xScr, yScr;
gengc = (__GLGENcontext *)gc;
xScr = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, 1, FALSE);
pul = gengc->ColorsBits;
pixel = *pul;
result->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
result->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
result->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
if( ALPHA_IN_PIXEL( cfb ) )
result->a = (__GLfloat) ((pixel & gc->modes.alphaMask) >> cfb->alphaShift);
else
(*cfb->alphaBuf.fetch)(&cfb->alphaBuf, x, y, result);
}
static void
ReadAlphaSpan( __GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *pResults,
GLint w )
{
__GLcontext *gc = cfb->buf.gc;
if( gc->modes.alphaBits )
(*cfb->alphaBuf.readSpan)(&cfb->alphaBuf, x, y, w, pResults);
else {
for( ; w ; w--, pResults++ )
pResults->a = cfb->alphaScale;
}
}
void
DIBIndex4RGBAReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results,
GLint w)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
__GLcolor *pResults;
ReadAlphaSpan( cfb, x, y, results, w );
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base + (y*cfb->buf.outerWidth) +
(x >> 1));
pResults = results;
if (x & 1)
{
pixel = *puj++;
pixel = gengc->pajInvTranslateVector[pixel & 0xf];
pResults->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
pResults->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
pResults->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
pResults++;
w--;
}
while (w > 1)
{
pixel = *puj >> 4;
pixel = gengc->pajInvTranslateVector[pixel];
pResults->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
pResults->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
pResults->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
pResults++;
pixel = *puj++;
pixel = gengc->pajInvTranslateVector[pixel & 0xf];
pResults->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
pResults->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
pResults->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
pResults++;
w -= 2;
}
if (w > 0)
{
pixel = *puj >> 4;
pixel = gengc->pajInvTranslateVector[pixel];
pResults->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
pResults->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
pResults->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
}
}
void
DisplayIndex4RGBAReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *results, GLint w)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
__GLcolor *pResults;
ReadAlphaSpan( cfb, x, y, results, w );
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
puj = gengc->ColorsBits;
pResults = results;
while (w > 1)
{
pixel = *puj >> 4;
pResults->r = vfVGAtoR[pixel];
pResults->g = vfVGAtoG[pixel];
pResults->b = vfVGAtoB[pixel];
pResults++;
pixel = *puj++ & 0xf;
pResults->r = vfVGAtoR[pixel];
pResults->g = vfVGAtoG[pixel];
pResults->b = vfVGAtoB[pixel];
pResults++;
w -= 2;
}
if (w > 0)
{
pixel = *puj >> 4;
pResults->r = vfVGAtoR[pixel];
pResults->g = vfVGAtoG[pixel];
pResults->b = vfVGAtoB[pixel];
}
}
void
Index8RGBAReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *pResults,
GLint w )
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
ReadAlphaSpan( cfb, x, y, pResults, w );
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
if( cfb->buf.flags & DIB_FORMAT )
{
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base + (y*cfb->buf.outerWidth) + x);
}
else
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
puj = gengc->ColorsBits;
}
for ( ; w; w--, pResults++)
{
pixel = gengc->pajInvTranslateVector[*puj++];
pResults->r = (__GLfloat) ((pixel & gc->modes.redMask) >> cfb->redShift);
pResults->g = (__GLfloat) ((pixel & gc->modes.greenMask) >> cfb->greenShift);
pResults->b = (__GLfloat) ((pixel & gc->modes.blueMask) >> cfb->blueShift);
}
}
void
BGRAReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *pResults, GLint w )
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
ReadAlphaSpan( cfb, x, y, pResults, w );
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
if( cfb->buf.flags & DIB_FORMAT )
{
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x * 3));
}
else
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
puj = gengc->ColorsBits;
}
for ( ; w; w--, pResults++)
{
pResults->b = (__GLfloat) *puj++;
pResults->g = (__GLfloat) *puj++;
pResults->r = (__GLfloat) *puj++;
}
}
void
RGBAReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *pResults, GLint w )
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
ReadAlphaSpan( cfb, x, y, pResults, w );
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
if( cfb->buf.flags & DIB_FORMAT )
{
puj = (GLubyte *)((ULONG_PTR)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x * 3));
}
else
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
puj = gengc->ColorsBits;
}
for ( ; w; w--, pResults++)
{
pResults->r = (__GLfloat) *puj++;
pResults->g = (__GLfloat) *puj++;
pResults->b = (__GLfloat) *puj++;
}
}
void
Bitfield16RGBAReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *pResults, GLint w )
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLushort *pus, pixel;
GLint xScr, yScr;
gengc = (__GLGENcontext *)gc;
xScr = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
if( cfb->buf.flags & DIB_FORMAT )
{
pus = (GLushort *)((ULONG_PTR)cfb->buf.base +
(yScr*cfb->buf.outerWidth) + (xScr << 1));
}
else
{
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
pus = gengc->ColorsBits;
}
READ_RGBA_BITFIELD_SPAN( (pixel = *pus++) );
}
void
Bitfield32RGBAReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *pResults, GLint w )
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint *pul, pixel;
GLint xScr, yScr;
gengc = (__GLGENcontext *)gc;
xScr = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
if( cfb->buf.flags & DIB_FORMAT )
{
pul = (GLuint *)((ULONG_PTR)cfb->buf.base +
(yScr*cfb->buf.outerWidth) + (xScr << 2));
}
else
{
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
pul = gengc->ColorsBits;
}
READ_RGBA_BITFIELD_SPAN( (pixel = *pul++) );
}
/************************************************************************/
// Used in accumulation
// Accumulation helper macros and functions
// Clamp a color component between 0 and max
#define ACCUM_CLAMP_COLOR_COMPONENT( col, max ) \
if ((col) < (__GLfloat) 0.0) \
(col) = (__GLfloat) 0.0; \
else if ((col) > max ) \
(col) = max;
// Extract an accumulation buffer color component by shifting and masking, then
// multiply it by scale (Requires ap and icol defined).
#define ACCUM_SCALE_SIGNED_COLOR_COMPONENT( col, shift, sign, mask, scale ) \
icol = (*ap >> shift) & mask; \
if (icol & sign) \
icol |= ~mask; \
(col) = (icol * scale);
// Fetch and scale a span of rgba values from a 32-bit accumulation buffer
void GetClampedRGBAccum32Values(
__GLcolorBuffer *cfb, GLuint *pac, __GLcolor *cDest, GLint width,
__GLfloat scale )
{
GLint w, i;
GLint icol;
__GLfloat rval, gval, bval, aval;
__GLuicolor *shift, *mask, *sign;
GLuint *ap;
__GLcolor *cp;
__GLcontext *gc = cfb->buf.gc;
__GLaccumBuffer *afb = &gc->accumBuffer;
rval = scale * afb->oneOverRedScale;
gval = scale * afb->oneOverGreenScale;
bval = scale * afb->oneOverBlueScale;
shift = &afb->shift;
mask = &afb->mask;
sign = &afb->sign;
for ( w = width, cp = cDest, ap = pac; w; w--, cp++, ap++ ) {
ACCUM_SCALE_SIGNED_COLOR_COMPONENT( cp->r, shift->r, sign->r, mask->r, rval );
ACCUM_CLAMP_COLOR_COMPONENT( cp->r, cfb->redScale );
ACCUM_SCALE_SIGNED_COLOR_COMPONENT( cp->g, shift->g, sign->g, mask->g, gval );
ACCUM_CLAMP_COLOR_COMPONENT( cp->g, cfb->greenScale );
ACCUM_SCALE_SIGNED_COLOR_COMPONENT( cp->b, shift->b, sign->b, mask->b, bval );
ACCUM_CLAMP_COLOR_COMPONENT( cp->b, cfb->blueScale );
}
if( ! ALPHA_WRITE_ENABLED( cfb ) )
return;
aval = scale * afb->oneOverAlphaScale;
for ( w = width, cp = cDest, ap = pac; w; w--, cp++, ap++ ) {
ACCUM_SCALE_SIGNED_COLOR_COMPONENT( cp->a, shift->a, sign->a, mask->a, aval );
ACCUM_CLAMP_COLOR_COMPONENT( cp->a, cfb->alphaScale );
}
}
// Fetch and scale a span of rgba values from a 64-bit accumulation buffer
void GetClampedRGBAccum64Values(
__GLcolorBuffer *cfb, GLshort *pac, __GLcolor *cDest, GLint width,
__GLfloat scale )
{
GLint w;
__GLcontext *gc = cfb->buf.gc;
__GLaccumBuffer *afb = &gc->accumBuffer;
__GLfloat rval, gval, bval, aval;
__GLcolor *cp;
GLshort *ap;
rval = scale * afb->oneOverRedScale;
gval = scale * afb->oneOverGreenScale;
bval = scale * afb->oneOverBlueScale;
for ( w = width, cp = cDest, ap = pac; w; w--, cp++, ap+=4 ) {
cp->r = (ap[0] * rval);
ACCUM_CLAMP_COLOR_COMPONENT( cp->r, cfb->redScale );
cp->g = (ap[1] * gval);
ACCUM_CLAMP_COLOR_COMPONENT( cp->g, cfb->greenScale );
cp->b = (ap[2] * bval);
ACCUM_CLAMP_COLOR_COMPONENT( cp->b, cfb->blueScale );
}
if( ! ALPHA_WRITE_ENABLED( cfb ) )
return;
aval = scale * afb->oneOverAlphaScale;
// Offset the accumulation pointer to the alpha value:
ap = pac + 3;
for ( w = width, cp = cDest; w; w--, cp++, ap+=4 ) {
cp->a = (*ap * rval);
ACCUM_CLAMP_COLOR_COMPONENT( cp->a, cfb->alphaScale );
}
}
/******************************Public*Routine******************************\
* Index4ReturnSpan
* Reads from a 16-bit accumulation buffer and writes the span to a device or
* a DIB. Only dithering and color mask are applied. Blend is ignored.
* Since accumulation of 4-bit RGB isn't very useful, this routine is very
* general and calls through the store function pointers.
*
* History:
* 10-DEC-93 Eddie Robinson [v-eddier] Wrote it.
\**************************************************************************/
//XXX This routine follows the store span routine very closely. Any changes
//XXX to the store span routine should also be reflected here
void Index4ReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
__GLcontext *gc = cfb->buf.gc;
GLuint *ap; // current accum entry
__GLGENcontext *gengc; // generic graphics context
GLuint saveEnables; // modes enabled in graphics context
__GLaccumBuffer *afb;
__GLfragment frag;
__GLcolor *pAccumCol, *pac;
afb = &gc->accumBuffer;
ap = (GLuint *)ac;
saveEnables = gc->state.enables.general; // save current enables
gc->state.enables.general &= ~__GL_BLEND_ENABLE; // disable blend for store procs
frag.x = x;
frag.y = y;
// Pre-fetch/clamp/scale the accum buffer values
afb = &gc->accumBuffer;
pAccumCol = afb->colors;
GetClampedRGBAccum32Values( cfb, ap, pAccumCol, w, scale );
for( pac = pAccumCol ; w; w--, pac++ )
{
frag.color = *pac;
(*cfb->store)(cfb, &frag);
frag.x++;
}
gc->state.enables.general = saveEnables; // restore current enables
}
/******************************Public*Routine******************************\
* Index8ReturnSpan
* Reads from a 32-bit accumulation buffer and writes the span to a device or
* a DIB. Only dithering and color mask are applied. Blend is ignored.
*
* History:
* 10-DEC-93 Eddie Robinson [v-eddier] Wrote it.
\**************************************************************************/
//XXX This routine follows the store span routine very closely. Any changes
//XXX to the store span routine should also be reflected here
void Index8ReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w )
{
__GLcontext *gc = cfb->buf.gc;
GLuint *ap; // current accum entry
GLint xFrag, yFrag; // current window (pixel) coordinates
GLint xScr, yScr; // current screen (pixel) coordinates
GLubyte result, *puj; // current pixel color, current pixel ptr
GLubyte *pujEnd; // end of scan line
__GLfloat inc; // current dither adj.
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLboolean bDIB;
__GLaccumBuffer *afb;
GLubyte dst_pix;
__GLcolor *pAccumCol, *pac;
ASSERT_CHOP_ROUND();
gengc = (__GLGENcontext *)gc;
ap = (GLuint *)ac;
xFrag = x;
yFrag = y;
xScr = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
bDIB = cfb->buf.flags & DIB_FORMAT;
// Use to call wglSpanVisible, if window level security is added reimplement
// Get pointer to bitmap.
puj = bDIB ? (GLubyte *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + xScr)
: gengc->ColorsBits;
pujEnd = puj + w;
afb = &gc->accumBuffer;
pAccumCol = afb->colors;
GetClampedRGBAccum32Values( cfb, ap, pAccumCol, w, scale );
pac = pAccumCol;
// Case: no dithering, no masking
//
// Check for the common case (which we'll do the fastest).
if ( !(enables & (__GL_DITHER_ENABLE)) &&
!(cfb->buf.flags & COLORMASK_ON) )
{
//!!!XXX -- we can also opt. by unrolling the loops
for ( ; puj < pujEnd; puj++, pac++ )
{
result = ((BYTE) FTOL(pac->r + __glHalf) << cfb->redShift) |
((BYTE) FTOL(pac->g + __glHalf) << cfb->greenShift) |
((BYTE) FTOL(pac->b + __glHalf) << cfb->blueShift);
*puj = gengc->pajTranslateVector[result];
}
}
// Case: dithering, no masking, no blending
//
// Dithering is pretty common for 8-bit displays, so its probably
// worth special case also.
else if ( !(cfb->buf.flags & COLORMASK_ON) )
{
for ( ; puj < pujEnd; puj++, pac++, xFrag++)
{
inc = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
result = ((BYTE) FTOL(pac->r + inc) << cfb->redShift) |
((BYTE) FTOL(pac->g + inc) << cfb->greenShift) |
((BYTE) FTOL(pac->b + inc) << cfb->blueShift);
*puj = gengc->pajTranslateVector[result];
}
}
// Case: general
//
// Otherwise, we'll do it slower.
else
{
// Color mask pre-fetch
if ((cfb->buf.flags & COLORMASK_ON) && !bDIB) {
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE );
}
for ( ; puj < pujEnd; puj++, pac++ )
{
if (enables & __GL_DITHER_ENABLE)
{
inc = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
xFrag++;
}
else
{
inc = __glHalf;
}
result = ((BYTE)FTOL(pac->r + inc) << cfb->redShift) |
((BYTE)FTOL(pac->g + inc) << cfb->greenShift) |
((BYTE)FTOL(pac->b + inc) << cfb->blueShift);
// Color mask
if (cfb->buf.flags & COLORMASK_ON)
{
dst_pix = gengc->pajInvTranslateVector[*puj];
result = (GLubyte)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
*puj = gengc->pajTranslateVector[result];
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
// Store alpha values
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.storeSpan2)( &cfb->alphaBuf, x, y, w, pAccumCol );
}
/******************************Public*Routine******************************\
* RGBReturnSpan
* Reads from a 64-bit accumulation buffer and writes the span to a device or
* a DIB. Only dithering and color mask are applied. Blend is ignored.
*
* History:
* 10-DEC-93 Eddie Robinson [v-eddier] Wrote it.
\**************************************************************************/
//XXX This routine follows the store span routine very closely. Any changes
//XXX to the store span routine should also be reflected here
void RGBReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w )
{
__GLcontext *gc = cfb->buf.gc;
GLshort *ap; // current accum entry
GLint xScr, yScr; // current screen (pixel) coordinates
GLubyte *puj; // current pixel color, current pixel ptr
GLubyte *pujEnd; // end of scan line
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLboolean bDIB;
__GLaccumBuffer *afb;
__GLcolor *pAccumCol, *pac;
ASSERT_CHOP_ROUND();
afb = &gc->accumBuffer;
gengc = (__GLGENcontext *)gc;
ap = (GLshort *)ac;
xScr = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
bDIB = cfb->buf.flags & DIB_FORMAT;
// Use to call wglSpanVisible, if window level security is added reimplement
// Get pointer to bitmap.
puj = bDIB ? (GLuint *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr*3))
: gengc->ColorsBits;
pujEnd = puj + w*3;
// Pre-fetch/clamp/scale the accum buffer values
afb = &gc->accumBuffer;
pAccumCol = afb->colors;
GetClampedRGBAccum64Values( cfb, ap, pAccumCol, w, scale );
pac = pAccumCol;
// Case: no masking
if ( !(cfb->buf.flags & COLORMASK_ON) )
{
for ( ; puj < pujEnd; puj += 3, pac ++ )
{
puj[0] = (GLubyte) FTOL(pac->r);
puj[1] = (GLubyte) FTOL(pac->g);
puj[2] = (GLubyte) FTOL(pac->b);
}
}
// All other cases
else
{
GLboolean bRedMask, bGreenMask, bBlueMask;
GLubyte *pujStart = puj;
// Color mask pre-fetch
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
if( gc->state.raster.rMask ) {
for ( puj = pujStart, pac = pAccumCol; puj < pujEnd; puj += 3, pac++ )
*puj = (GLubyte) FTOL(pac->r);
}
pujStart++; pujEnd++;
if( gc->state.raster.gMask ) {
for ( puj = pujStart, pac = pAccumCol; puj < pujEnd; puj += 3, pac++ )
*puj = (GLubyte) FTOL(pac->g);
}
pujStart++; pujEnd++;
if( gc->state.raster.bMask ) {
for ( puj = pujStart, pac = pAccumCol; puj < pujEnd; puj += 3, pac++ )
*puj = (GLubyte) FTOL(pac->b);
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
// Store alpha values
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.storeSpan2)( &cfb->alphaBuf, x, y, w, pAccumCol );
}
/******************************Public*Routine******************************\
* BGRReturnSpan
* Reads from a 64-bit accumulation buffer and writes the span to a device or
* a DIB. Only dithering and color mask are applied. Blend is ignored.
*
* History:
* 10-DEC-93 Eddie Robinson [v-eddier] Wrote it.
\**************************************************************************/
//XXX This routine follows the store span routine very closely. Any changes
//XXX to the store span routine should also be reflected here
void BGRReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w )
{
__GLcontext *gc = cfb->buf.gc;
GLshort *ap; // current accum entry
__GLcolor *pAccumCol, *pac;
GLint xScr, yScr; // current screen (pixel) coordinates
GLubyte *puj; // current pixel color, current pixel ptr
GLubyte *pujEnd; // end of scan line
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLboolean bDIB;
__GLfloat r, g, b;
__GLfloat rval, gval, bval;
__GLaccumBuffer *afb;
ASSERT_CHOP_ROUND();
afb = &gc->accumBuffer;
rval = scale * afb->oneOverRedScale;
gval = scale * afb->oneOverGreenScale;
bval = scale * afb->oneOverBlueScale;
gengc = (__GLGENcontext *)gc;
ap = (GLshort *)ac;
xScr = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
bDIB = cfb->buf.flags & DIB_FORMAT;
// Use to call wglSpanVisible, if window level security is added reimplement
// Get pointer to bitmap.
puj = bDIB ? (GLuint *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr*3))
: gengc->ColorsBits;
pujEnd = puj + w*3;
// Pre-fetch/clamp/scale the accum buffer values
afb = &gc->accumBuffer;
pAccumCol = afb->colors;
GetClampedRGBAccum64Values( cfb, ap, pAccumCol, w, scale );
pac = pAccumCol;
// Case: no masking
if ( !(cfb->buf.flags & COLORMASK_ON) )
{
for ( ; puj < pujEnd; puj += 3, pac ++ )
{
puj[0] = (GLubyte) FTOL(pac->b);
puj[1] = (GLubyte) FTOL(pac->g);
puj[2] = (GLubyte) FTOL(pac->r);
}
}
// All other cases
else
{
GLboolean bRedMask, bGreenMask, bBlueMask;
GLubyte *pujStart = puj;
// Color mask pre-fetch
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
if( gc->state.raster.bMask ) {
for ( puj = pujStart, pac = pAccumCol; puj < pujEnd; puj += 3, pac++ )
*puj = (GLubyte) FTOL(pac->b);
}
pujStart++; pujEnd++;
if( gc->state.raster.gMask ) {
for ( puj = pujStart, pac = pAccumCol; puj < pujEnd; puj += 3, pac++ )
*puj = (GLubyte) FTOL(pac->g);
}
pujStart++; pujEnd++;
if( gc->state.raster.rMask ) {
for ( puj = pujStart, pac = pAccumCol; puj < pujEnd; puj += 3, pac++ )
*puj = (GLubyte) FTOL(pac->r);
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
// Store alpha values
if( ALPHA_WRITE_ENABLED( cfb ) )
(*cfb->alphaBuf.storeSpan2)( &cfb->alphaBuf, x, y, w, pAccumCol );
}
/******************************Public*Routine******************************\
* Bitfield16ReturnSpan
* Reads from a 32-bit accumulation buffer and writes the span to a device or
* a DIB. Only dithering and color mask are applied. Blend is ignored.
*
* History:
* 10-DEC-93 Eddie Robinson [v-eddier] Wrote it.
\**************************************************************************/
//XXX This routine follows the store span routine very closely. Any changes
//XXX to the store span routine should also be reflected here
void Bitfield16ReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w )
{
__GLcontext *gc = cfb->buf.gc;
GLuint *ap; // current accum entry
GLint xFrag, yFrag; // current fragment coordinates
GLint xScr, yScr; // current screen (pixel) coordinates
GLushort result, *pus; // current pixel color, current pixel ptr
GLushort *pusEnd; // end of scan line
__GLfloat inc; // current dither adj.
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLboolean bDIB;
__GLcolor *pAccumCol, *pac;
__GLaccumBuffer *afb;
ASSERT_CHOP_ROUND();
afb = &gc->accumBuffer;
gengc = (__GLGENcontext *)gc;
ap = (GLuint *)ac;
xFrag = x;
yFrag = y;
xScr = __GL_UNBIAS_X(gc, xFrag) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, yFrag) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
bDIB = cfb->buf.flags & DIB_FORMAT;
// Use to call wglSpanVisible, if window level security is added reimplement
// Get pointer to bitmap.
pus = bDIB ? (GLushort *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr<<1))
: gengc->ColorsBits;
pusEnd = pus + w;
// Pre-fetch/clamp/scale the accum buffer values
afb = &gc->accumBuffer;
pAccumCol = afb->colors;
GetClampedRGBAccum32Values( cfb, ap, pAccumCol, w, scale );
pac = pAccumCol;
// Case: no masking, no dithering
if ( !(enables & (__GL_DITHER_ENABLE)) &&
!(cfb->buf.flags & COLORMASK_ON) )
{
if( ALPHA_PIXEL_WRITE( cfb ) ) {
for ( ; pus < pusEnd; pus++, pac++ )
{
*pus = ((BYTE) FTOL(pac->r + __glHalf) << cfb->redShift) |
((BYTE) FTOL(pac->g + __glHalf) << cfb->greenShift) |
((BYTE) FTOL(pac->b + __glHalf) << cfb->blueShift) |
((BYTE) FTOL(pac->a + __glHalf) << cfb->alphaShift);
}
} else {
for ( ; pus < pusEnd; pus++, pac++ )
{
*pus = ((BYTE) FTOL(pac->r + __glHalf) << cfb->redShift) |
((BYTE) FTOL(pac->g + __glHalf) << cfb->greenShift) |
((BYTE) FTOL(pac->b + __glHalf) << cfb->blueShift);
}
}
}
// Case: dithering, no masking
else if ( !(cfb->buf.flags & COLORMASK_ON) )
{
if( ALPHA_PIXEL_WRITE( cfb ) ) {
for ( ; pus < pusEnd; pus++, pac++, xFrag++ )
{
inc = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
*pus = ((BYTE) FTOL(pac->r + inc) << cfb->redShift) |
((BYTE) FTOL(pac->g + inc) << cfb->greenShift) |
((BYTE) FTOL(pac->b + inc) << cfb->blueShift) |
((BYTE) FTOL(pac->a + inc) << cfb->alphaShift);
}
} else {
for ( ; pus < pusEnd; pus++, pac++, xFrag++ )
{
inc = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
*pus = ((BYTE) FTOL(pac->r + inc) << cfb->redShift) |
((BYTE) FTOL(pac->g + inc) << cfb->greenShift) |
((BYTE) FTOL(pac->b + inc) << cfb->blueShift);
}
}
}
// All other cases
else
{
// Color mask pre-fetch
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
for ( ; pus < pusEnd; pus++, pac++ )
{
inc = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
// Dither.
if ( enables & __GL_DITHER_ENABLE )
{
inc = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
xFrag++;
}
else
{
inc = __glHalf;
}
// Convert color to 16BPP format.
result = ((BYTE) FTOL(pac->r + inc) << cfb->redShift) |
((BYTE) FTOL(pac->g + inc) << cfb->greenShift) |
((BYTE) FTOL(pac->b + inc) << cfb->blueShift);
if( ALPHA_PIXEL_WRITE( cfb ) )
result |= ((BYTE) FTOL(pac->a + inc) << cfb->alphaShift);
// Store result with optional masking.
*pus = (GLushort)((*pus & cfb->destMask) | (result & cfb->sourceMask));
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
if( ALPHA_BUFFER_WRITE( cfb ) )
(*cfb->alphaBuf.storeSpan2)( &cfb->alphaBuf, x, y, w, pAccumCol );
}
/******************************Public*Routine******************************\
* Bitfield32ReturnSpan
* Reads from a 64-bit accumulation buffer and writes the span to a device or
* a DIB. Only dithering and color mask are applied. Blend is ignored.
*
* History:
* 10-DEC-93 Eddie Robinson [v-eddier] Wrote it.
\**************************************************************************/
//XXX This routine follows the store span routine very closely. Any changes
//XXX to the store span routine should also be reflected here
void Bitfield32ReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w )
{
__GLcontext *gc = cfb->buf.gc;
GLshort *ap; // current accum entry
GLint xScr, yScr; // current screen (pixel) coordinates
GLuint result, *pul; // current pixel color, current pixel ptr
GLuint *pulEnd; // end of scan line
__GLGENcontext *gengc; // generic graphics context
GLuint enables; // modes enabled in graphics context
GLboolean bDIB;
__GLfloat r, g, b;
__GLfloat rval, gval, bval;
__GLaccumBuffer *afb;
__GLcolor *pAccumCol, *pac;
ASSERT_CHOP_ROUND();
afb = &gc->accumBuffer;
rval = scale * afb->oneOverRedScale;
gval = scale * afb->oneOverGreenScale;
bval = scale * afb->oneOverBlueScale;
gengc = (__GLGENcontext *)gc;
ap = (GLshort *)ac;
xScr = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
yScr = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
enables = gc->state.enables.general;
bDIB = cfb->buf.flags & DIB_FORMAT;
// Use to call wglSpanVisible, if window level security is added reimplement
// Get pointer to bitmap.
pul = bDIB ? (GLuint *)((ULONG_PTR)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr<<2))
: gengc->ColorsBits;
pulEnd = pul + w;
// Pre-fetch/clamp/scale the accum buffer values
afb = &gc->accumBuffer;
pAccumCol = afb->colors;
GetClampedRGBAccum64Values( cfb, ap, pAccumCol, w, scale );
pac = pAccumCol;
// Case: no masking
if ( !(cfb->buf.flags & COLORMASK_ON) )
{
if( ALPHA_PIXEL_WRITE( cfb ) ) {
for ( ; pul < pulEnd; pul++, pac++ )
{
*pul = ((BYTE) FTOL(pac->r) << cfb->redShift) |
((BYTE) FTOL(pac->g) << cfb->greenShift) |
((BYTE) FTOL(pac->b) << cfb->blueShift) |
((BYTE) FTOL(pac->a) << cfb->alphaShift);
}
} else {
for ( ; pul < pulEnd; pul++, pac++ )
{
*pul = ((BYTE) FTOL(pac->r) << cfb->redShift) |
((BYTE) FTOL(pac->g) << cfb->greenShift) |
((BYTE) FTOL(pac->b) << cfb->blueShift);
}
}
}
// All other cases
else
{
// Color mask pre-fetch
if( !bDIB )
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
for ( ; pul < pulEnd; pul++, pac++ )
{
result = ((BYTE) FTOL(pac->r) << cfb->redShift) |
((BYTE) FTOL(pac->g) << cfb->greenShift) |
((BYTE) FTOL(pac->b) << cfb->blueShift);
if( ALPHA_PIXEL_WRITE( cfb ) )
result |= ((BYTE) FTOL(pac->a) << cfb->alphaShift);
//!!!XXX again, opt. by unrolling loop
*pul = (*pul & cfb->destMask) | (result & cfb->sourceMask);
}
}
// Output the offscreen scanline buffer to the device. The function
// (*gengc->pfnCopyPixels) should handle clipping.
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, TRUE);
if( ALPHA_BUFFER_WRITE( cfb ) )
(*cfb->alphaBuf.storeSpan2)( &cfb->alphaBuf, x, y, w, pAccumCol );
}
STATIC void __glSetDrawBuffer(__GLcolorBuffer *cfb)
{
DBGENTRY("__glSetDrawBuffer\n");
}
STATIC void setReadBuffer(__GLcolorBuffer *cfb)
{
DBGENTRY("setReadBuffer\n");
}
/************************************************************************/
STATIC void Resize(__GLGENbuffers *buffers, __GLcolorBuffer *cfb,
GLint w, GLint h)
{
DBGENTRY("Resize\n");
cfb->buf.width = w;
cfb->buf.height = h;
}
#define DBG_PICK LEVEL_ENTRY
// Called at each validate (lots of times, whenever states change)
STATIC void FASTCALL PickRGB(__GLcontext *gc, __GLcolorBuffer *cfb)
{
__GLGENcontext *gengc;
GLuint totalMask, sourceMask;
GLboolean colormask;
PIXELFORMATDESCRIPTOR *pfmt;
GLuint enables = gc->state.enables.general;
sourceMask = 0;
colormask = GL_FALSE;
if (gc->state.raster.rMask) {
sourceMask |= gc->modes.redMask;
}
if (gc->state.raster.gMask) {
sourceMask |= gc->modes.greenMask;
}
if (gc->state.raster.bMask) {
sourceMask |= gc->modes.blueMask;
}
totalMask = gc->modes.redMask | gc->modes.greenMask | gc->modes.blueMask;
gengc = (__GLGENcontext *)gc;
// If we have alpha bits, need to determine where they belong : for a
// generic pixel format, they live in the software alpha buffer, but for
// an mcd type context they will be on the mcd device (or ALPHA_IN_PIXEL ).
// This is used by all the 'slow' store/fetch procs.
if( gc->modes.alphaBits && gengc->pMcdState ) {
// Set bit in buf.flags indicating alpha is in the pixel
cfb->buf.flags = cfb->buf.flags | ALPHA_IN_PIXEL_BIT;
} else {
// Alpha is not in the pixel, or there is no alpha
cfb->buf.flags = cfb->buf.flags & ~ALPHA_IN_PIXEL_BIT;
}
if( ALPHA_IN_PIXEL( cfb ) ) {
// There are alpha bits in the pixels, so need to include alpha in mask
if (gc->state.raster.aMask) {
sourceMask |= gc->modes.alphaMask;
}
totalMask |= gc->modes.alphaMask;
}
if (sourceMask == totalMask) {
cfb->buf.flags = cfb->buf.flags & ~COLORMASK_ON;
} else {
cfb->buf.flags = cfb->buf.flags | COLORMASK_ON;
}
cfb->sourceMask = sourceMask;
cfb->destMask = totalMask & ~sourceMask;
// Determine whether writing alpha values is required
if( gc->modes.alphaBits && gc->state.raster.aMask )
cfb->buf.flags = cfb->buf.flags | ALPHA_ON;
else
cfb->buf.flags = cfb->buf.flags & ~ALPHA_ON;
// If we're doing a logic op or there is a color mask we'll need
// to fetch the destination value before we write
if ((enables & __GL_COLOR_LOGIC_OP_ENABLE) ||
(cfb->buf.flags & COLORMASK_ON))
{
cfb->buf.flags = cfb->buf.flags | NEED_FETCH;
}
else
cfb->buf.flags = cfb->buf.flags & ~NEED_FETCH;
// Figure out store routines
if (gc->state.raster.drawBuffer == GL_NONE) {
cfb->store = Store_NOT;
cfb->fetch = RGBFetchNone;
cfb->readSpan = RGBReadSpanNone;
cfb->storeSpan = StoreSpanNone;
cfb->storeStippledSpan = StoreSpanNone;
} else {
pfmt = &gengc->gsurf.pfd;
// Pick functions that work for both DIB and Display formats
switch(pfmt->cColorBits) {
case 4:
cfb->clear = Index4Clear;
cfb->returnSpan = Index4ReturnSpan;
break;
case 8:
cfb->storeSpan = Index8StoreSpan;
cfb->readSpan = Index8RGBAReadSpan;
cfb->returnSpan = Index8ReturnSpan;
cfb->clear = Index8Clear;
break;
case 16:
cfb->storeSpan = Bitfield16StoreSpan;
cfb->readSpan = Bitfield16RGBAReadSpan;
cfb->returnSpan = Bitfield16ReturnSpan;
cfb->clear = Bitfield16Clear;
break;
case 24:
if (cfb->redShift == 16)
{
cfb->storeSpan = BGRStoreSpan;
cfb->readSpan = BGRAReadSpan;
cfb->returnSpan = BGRReturnSpan;
} else {
// XXX why no RGBStoreSpan ?
cfb->readSpan = RGBAReadSpan;
cfb->returnSpan = RGBReturnSpan;
}
cfb->clear = RGBClear;
break;
case 32:
cfb->storeSpan = Bitfield32StoreSpan;
cfb->readSpan = Bitfield32RGBAReadSpan;
cfb->returnSpan = Bitfield32ReturnSpan;
cfb->clear = Bitfield32Clear;
break;
}
// Pick specific functions for DIB or Display formats
if (cfb->buf.flags & DIB_FORMAT) {
switch(pfmt->cColorBits) {
case 4:
DBGLEVEL(DBG_PICK, "DIBIndex4Store\n");
cfb->store = DIBIndex4Store;
cfb->fetch = DIBIndex4RGBAFetch;
cfb->readSpan = DIBIndex4RGBAReadSpan;
break;
case 8:
DBGLEVEL(DBG_PICK, "DIBIndex8Store, "
"Index8StoreSpan\n");
cfb->store = DIBIndex8Store;
if( gc->modes.alphaBits )
cfb->fetch = DIBIndex8RGBAFetch;
else
cfb->fetch = DIBIndex8RGBFetch;
break;
case 16:
DBGLEVEL(DBG_PICK, "DIBBitfield16Store\n");
cfb->store = DIBBitfield16Store;
if( gc->modes.alphaBits )
cfb->fetch = DIBBitfield16RGBAFetch;
else
cfb->fetch = DIBBitfield16RGBFetch;
break;
case 24:
if (cfb->redShift == 16)
{
DBGLEVEL(DBG_PICK, "DIBBGRStore\n");
cfb->store = DIBBGRStore;
if( gc->modes.alphaBits )
cfb->fetch = DIBBGRAFetch;
else
cfb->fetch = DIBBGRFetch;
}
else
{
DBGLEVEL(DBG_PICK, "DIBRGBStore\n");
cfb->store = DIBRGBAStore;
if( gc->modes.alphaBits )
cfb->fetch = DIBRGBAFetch;
else
cfb->fetch = DIBRGBFetch;
}
break;
case 32:
DBGLEVEL(DBG_PICK, "DIBBitfield32Store, "
"Bitfield32StoreSpan\n");
cfb->store = DIBBitfield32Store;
if( gc->modes.alphaBits )
cfb->fetch = DIBBitfield32RGBAFetch;
else
cfb->fetch = DIBBitfield32RGBFetch;
break;
}
} else {
switch(pfmt->cColorBits) {
case 4:
DBGLEVEL(DBG_PICK, "DisplayIndex4Store\n");
cfb->store = DisplayIndex4Store;
cfb->fetch = DisplayIndex4RGBAFetch;
cfb->readSpan = DisplayIndex4RGBAReadSpan;
break;
case 8:
DBGLEVEL(DBG_PICK, "DisplayIndex8Store, "
"Index8StoreSpan\n");
cfb->store = DisplayIndex8Store;
if( gc->modes.alphaBits )
cfb->fetch = DisplayIndex8RGBAFetch;
else
cfb->fetch = DisplayIndex8RGBFetch;
break;
case 16:
DBGLEVEL(DBG_PICK, "DisplayBitfield16Store\n");
cfb->store = DisplayBitfield16Store;
if( gc->modes.alphaBits )
cfb->fetch = DisplayBitfield16RGBAFetch;
else
cfb->fetch = DisplayBitfield16RGBFetch;
break;
case 24:
// Must be RGB or BGR
if (cfb->redShift == 16)
{
DBGLEVEL(DBG_PICK, "DisplayBGRStore\n");
cfb->store = DisplayBGRStore;
if( gc->modes.alphaBits )
cfb->fetch = DisplayBGRAFetch;
else
cfb->fetch = DisplayBGRFetch;
}
else
{
DBGLEVEL(DBG_PICK, "DisplayRGBStore\n");
cfb->store = DisplayRGBStore;
if( gc->modes.alphaBits )
cfb->fetch = DisplayRGBAFetch;
else
cfb->fetch = DisplayRGBFetch;
}
break;
case 32:
DBGLEVEL(DBG_PICK, "DisplayBitfield32Store, "
"Bitfield32StoreSpan\n");
cfb->store = DisplayBitfield32Store;
if( gc->modes.alphaBits )
cfb->fetch = DisplayBitfield32RGBAFetch;
else
cfb->fetch = DisplayBitfield32RGBFetch;
break;
}
}
// cfb->readColor is the same as cfb->fetch (so why do we need it ?)
cfb->readColor = cfb->fetch;
// If we are only writing alpha (rgb all masked), can further optimize:
// Don't bother if logicOp or blending are enabled, and only if we
// have a software alpha buffer
if( gc->modes.alphaBits &&
! ALPHA_IN_PIXEL( cfb ) &&
(sourceMask == 0) &&
gc->state.raster.aMask &&
!(enables & __GL_COLOR_LOGIC_OP_ENABLE) &&
! (enables & __GL_BLEND_ENABLE) )
{
cfb->store = AlphaStore;
cfb->storeSpan = AlphaStoreSpan;
}
}
}
/************************************************************************/
void FASTCALL __glGenFreeRGB(__GLcontext *gc, __GLcolorBuffer *cfb)
{
DBGENTRY("__glGenFreeRGB\n");
}
/************************************************************************/
// Note: this used to be defined in generic\genrgb.h
#define __GL_GENRGB_COMPONENT_SCALE_ALPHA 255
// called at makecurrent time
// need to get info out of pixel format structure
void FASTCALL __glGenInitRGB(__GLcontext *gc, __GLcolorBuffer *cfb, GLenum type)
{
__GLGENcontext *gengc = (__GLGENcontext *)gc;
PIXELFORMATDESCRIPTOR *pfmt;
__glInitGenericCB(gc, cfb);
cfb->redMax = (1 << gc->modes.redBits) - 1;
cfb->greenMax = (1 << gc->modes.greenBits) - 1;
cfb->blueMax = (1 << gc->modes.blueBits) - 1;
gc->redVertexScale = cfb->redScale = (__GLfloat)cfb->redMax;
gc->greenVertexScale = cfb->greenScale = (__GLfloat)cfb->greenMax;
gc->blueVertexScale = cfb->blueScale = (__GLfloat)cfb->blueMax;
cfb->iRedScale = cfb->redMax;
cfb->iGreenScale = cfb->greenMax;
cfb->iBlueScale = cfb->blueMax;
// Do any initialization related to alpha
if( gc->modes.alphaBits ) {
cfb->alphaMax = (1 << gc->modes.alphaBits) - 1;
cfb->iAlphaScale = cfb->alphaMax;
gc->alphaVertexScale = cfb->alphaScale = (__GLfloat)cfb->alphaMax;
// Initialize the software alpha buffer. Actually, we may not need to
// do this, since if an mcd pixel format supports alpha, we don't need
// the software alpha buffer. But this is the most convenient place to
// do it, and no memory will be allocated anyways. just function ptrs
// initialized.
__glInitAlpha( gc, cfb );
} else {
cfb->alphaMax = __GL_GENRGB_COMPONENT_SCALE_ALPHA;
cfb->iAlphaScale = __GL_GENRGB_COMPONENT_SCALE_ALPHA;
gc->alphaVertexScale = cfb->alphaScale = (__GLfloat)cfb->redMax;
}
cfb->buf.elementSize = sizeof(GLubyte); // XXX needed?
cfb->pick = PickRGB; // called at each validate
cfb->resize = Resize;
cfb->fetchSpan = __glFetchSpan;
cfb->fetchStippledSpan = __glFetchSpan;
cfb->storeSpan = SlowStoreSpan;
cfb->storeStippledSpan = SlowStoreStippledSpan;
pfmt = &gengc->gsurf.pfd;
cfb->redShift = pfmt->cRedShift;
cfb->greenShift = pfmt->cGreenShift;
cfb->blueShift = pfmt->cBlueShift;
cfb->alphaShift = pfmt->cAlphaShift;
glGenInitCommon(gengc, cfb, type);
DBGLEVEL3(LEVEL_INFO,"GeninitRGB: redMax %d, greenMax %d, blueMax %d\n",
cfb->redMax, cfb->greenMax, cfb->blueMax);
DBGLEVEL3(LEVEL_INFO," redShift %d, greenShift %d, blueShift %d\n",
cfb->redShift, cfb->greenShift, cfb->blueShift);
DBGLEVEL2(LEVEL_INFO," dwFlags %X, cColorBits %d\n",
gengc->dwCurrentFlags, pfmt->cColorBits);
}