Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4459 lines
136 KiB

/*
** Copyright 1991, 1992, 1993, Silicon Graphics, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of Silicon Graphics, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
*/
#include "precomp.h"
#pragma hdrstop
#include "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 other 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) \
{ \
__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) \
{ \
for ( i = 0; i < w; i++, color++, frag.x++ ) \
{ \
__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 \
{ \
for ( i = 0; i < w; i++, color++, frag.x++ ) \
{ \
frag.color = *color; \
(*gc->procs.blend)( gc, cfb, &frag, color ); \
} \
}
#ifdef _X86_
// Disable 'no return value' warning
#pragma warning(disable:4035)
#define SHIFTS_OFFSET OFFSET(__GLcolorBuffer.allShifts)
#define RED_OFFSET OFFSET(__GLcolor.r)
#define GREEN_OFFSET OFFSET(__GLcolor.g)
#define BLUE_OFFSET OFFSET(__GLcolor.b)
// The x86 code generated by the macro version of this results in three calls
// to _ftol, each of which will set and reset the control word.
// By combining everything into one inline function all call overhead
// is removed, plus the extra control word manipulation and some other
// memory accesses are avoided
// Written as a macro because the compiler generates very inefficient code
// when passing arguments to __inline functions
#define DitheredColorToBuffer(col, incr, cfb, dest, type) \
{ \
LONG tmp; \
WORD old_cw, new_cw; \
\
{ \
__asm fnstcw old_cw \
__asm mov ax, old_cw \
__asm or ah, 0ch \
__asm mov new_cw, ax \
__asm fldcw new_cw \
\
__asm fld incr \
\
__asm push esi \
\
__asm mov edx, col \
__asm mov esi, cfb \
__asm mov ecx, [SHIFTS_OFFSET][esi] \
\
__asm fld st(0) \
__asm fadd dword ptr [RED_OFFSET][edx] \
__asm fistp tmp \
\
__asm mov eax, tmp \
__asm shl eax, cl \
__asm shr ecx, 8 \
\
__asm fld st(0) \
__asm fadd dword ptr [GREEN_OFFSET][edx] \
__asm fistp tmp \
\
__asm mov ebx, tmp \
__asm shl ebx, cl \
__asm shr ecx, 8 \
__asm or eax, ebx \
\
__asm fadd dword ptr [BLUE_OFFSET][edx] \
__asm fistp tmp \
__asm mov ebx, tmp \
__asm shl ebx, cl \
__asm or eax, ebx \
__asm mov tmp, eax \
\
__asm pop esi \
\
__asm fldcw old_cw \
} \
\
dest = (type)tmp; \
}
#define UnditheredColorToBuffer(col, cfb, dest, type) \
{ \
LONG tmp; \
WORD old_cw, new_cw; \
\
{ \
__asm fnstcw old_cw \
__asm mov ax, old_cw \
__asm or ah, 0ch \
__asm mov new_cw, ax \
__asm fldcw new_cw \
\
__asm push esi \
\
__asm mov edx, col \
__asm mov esi, cfb \
__asm mov ecx, [SHIFTS_OFFSET][esi] \
\
__asm fld dword ptr [RED_OFFSET][edx] \
__asm fistp tmp \
\
__asm mov eax, tmp \
__asm shl eax, cl \
__asm shr ecx, 8 \
\
__asm fld dword ptr [GREEN_OFFSET][edx] \
__asm fistp tmp \
\
__asm mov ebx, tmp \
__asm shl ebx, cl \
__asm shr ecx, 8 \
__asm or eax, ebx \
\
__asm fld dword ptr [BLUE_OFFSET][edx] \
__asm fistp tmp \
__asm mov ebx, tmp \
__asm shl ebx, cl \
__asm or eax, ebx \
__asm mov tmp, eax \
\
__asm pop esi \
\
__asm fldcw old_cw \
} \
\
dest = (type)tmp; \
}
// Store a color's components as bytes in RGB order
// Note that the macro has the side effect of advancing the pointer
// so this code does the same thing
#define StoreColorAsRgb(col, dst) \
{ \
LONG tmp; \
WORD old_cw, new_cw; \
\
__asm fnstcw old_cw \
__asm mov ax, old_cw \
__asm or ah, 0ch \
__asm mov new_cw, ax \
__asm fldcw new_cw \
\
__asm mov eax, col \
__asm mov ecx, dst \
__asm fld dword ptr [RED_OFFSET][eax] \
__asm fistp tmp \
__asm mov ebx, tmp \
__asm mov [ecx], bl \
__asm fld dword ptr [GREEN_OFFSET][eax] \
__asm fistp tmp \
__asm mov ebx, tmp \
__asm mov [ecx+1], bl \
__asm fld dword ptr [BLUE_OFFSET][eax] \
__asm add ecx, 3 \
__asm fistp tmp \
__asm mov ebx, tmp \
__asm mov [ecx-1], bl \
__asm mov dst, ecx \
\
__asm fldcw old_cw \
}
#define StoreColorAsBgr(col, dst) \
{ \
LONG tmp; \
WORD old_cw, new_cw; \
\
__asm fnstcw old_cw \
__asm mov ax, old_cw \
__asm or ah, 0ch \
__asm mov new_cw, ax \
__asm fldcw new_cw \
\
__asm mov eax, col \
__asm mov ecx, dst \
__asm fld dword ptr [BLUE_OFFSET][eax] \
__asm fistp tmp \
__asm mov ebx, tmp \
__asm mov [ecx], bl \
__asm fld dword ptr [GREEN_OFFSET][eax] \
__asm fistp tmp \
__asm mov ebx, tmp \
__asm mov [ecx+1], bl \
__asm fld dword ptr [RED_OFFSET][eax] \
__asm add ecx, 3 \
__asm fistp tmp \
__asm mov ebx, tmp \
__asm mov [ecx-1], bl \
__asm mov dst, ecx \
\
__asm fldcw old_cw \
}
// Restore warning
#pragma warning(default:4035)
#else
#define DitheredColorToBuffer(col, incr, cfb, dest, type) \
((dest) = (type)(((LONG)((col)->r+(incr)) << (cfb)->redShift) | \
((LONG)((col)->g+(incr)) << (cfb)->greenShift) | \
((LONG)((col)->b+(incr)) << (cfb)->blueShift)))
#define UnditheredColorToBuffer(col, cfb, dest, type) \
((dest) = (type)(((LONG)((col)->r) << (cfb)->redShift) | \
((LONG)((col)->g) << (cfb)->greenShift) | \
((LONG)((col)->b) << (cfb)->blueShift)))
#define StoreColorAsRgb(col, dst) \
(*(dst)++ = (BYTE)(col)->r, \
*(dst)++ = (BYTE)(col)->g, \
*(dst)++ = (BYTE)(col)->b)
#define StoreColorAsBgr(col, dst) \
(*(dst)++ = (BYTE)(col)->b, \
*(dst)++ = (BYTE)(col)->g, \
*(dst)++ = (BYTE)(col)->r)
#endif
/*
* 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;
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 ( ((GLuint)cfb->buf.other & MEMORY_DC) ||
(*gengc->pfnPixelVisible)(CURRENT_DC, x, y) )
{
incr = (enables & __GL_DITHER_ENABLE) ?
fDitherIncTable[__GL_DITHER_INDEX(frag->x, frag->y)] : __glHalf;
puj = (GLubyte *)((GLint)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);
}
DitheredColorToBuffer(color, incr, cfb, result, GLubyte);
if ((GLuint)cfb->buf.other & 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 ((GLuint)cfb->buf.other & 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;
}
}
}
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;
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 ( ((GLuint)cfb->buf.other & MEMORY_DC) ||
(*gengc->pfnPixelVisible)(CURRENT_DC, x, y) )
{
incr = (enables & __GL_DITHER_ENABLE) ?
fDitherIncTable[__GL_DITHER_INDEX(frag->x, frag->y)] : __glHalf;
puj = (GLubyte *)((GLint)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);
}
DitheredColorToBuffer(color, incr, cfb, result, GLubyte);
if ((GLuint)cfb->buf.other & 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 ((GLuint)cfb->buf.other & COLORMASK_ON)
{
result = (GLubyte)
((dst_pix & cfb->destMask) | (result & cfb->sourceMask));
}
*puj = gengc->pajTranslateVector[result];
}
}
// 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;
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 ( ((GLuint)cfb->buf.other & MEMORY_DC) ||
(*gengc->pfnPixelVisible)(CURRENT_DC, x, y) )
{
puj = (GLubyte *)((GLint)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 ((GLuint)cfb->buf.other & NEED_FETCH)
{
Copy3Bytes( &dst_pix, puj );
UnditheredColorToBuffer(color, cfb, result, GLuint);
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if ((GLuint)cfb->buf.other & COLORMASK_ON)
{
result =
(result & cfb->sourceMask) | (dst_pix & cfb->destMask);
}
Copy3Bytes( puj, &result );
}
else
{
StoreColorAsBgr(color, puj);
}
}
}
// BMF_24BPP in RGB format
STATIC void FASTCALL DIBRGBStore(__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;
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 ( ((GLuint)cfb->buf.other & MEMORY_DC) ||
(*gengc->pfnPixelVisible)(CURRENT_DC, x, y) )
{
puj = (GLubyte *)((GLint)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 ((GLuint)cfb->buf.other & NEED_FETCH)
{
Copy3Bytes( &dst_pix, puj );
UnditheredColorToBuffer(color, cfb, result, GLuint);
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result = DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if ((GLuint)cfb->buf.other & COLORMASK_ON)
{
result =
(result & cfb->sourceMask) | (dst_pix & cfb->destMask);
}
Copy3Bytes( puj, &result );
}
else
{
StoreColorAsRgb(color, puj);
}
}
}
// 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;
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 ( ((GLuint)cfb->buf.other & MEMORY_DC) ||
(*gengc->pfnPixelVisible)(CURRENT_DC, x, y) )
{
incr = (enables & __GL_DITHER_ENABLE) ?
fDitherIncTable[__GL_DITHER_INDEX(frag->x, frag->y)] : __glHalf;
pus = (GLushort *)((GLint)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 ((GLuint)cfb->buf.other & 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 ((GLuint)cfb->buf.other & COLORMASK_ON)
{
*pus = (GLushort)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
else
{
*pus = result;
}
}
}
// 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;
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 ( ((GLuint)cfb->buf.other & MEMORY_DC) ||
(*gengc->pfnPixelVisible)(CURRENT_DC, x, y) )
{
pul = (GLuint *)((GLint)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x << 2));
if( enables & __GL_BLEND_ENABLE )
{
// Can't use special alpha blending here because
// this format may actually have alpha data
color = &blendColor;
(*gc->procs.blend)(gc, cfb, frag, &blendColor);
}
else
{
color = &(frag->color);
}
UnditheredColorToBuffer(color, cfb, result, GLuint);
if ((GLuint)cfb->buf.other & 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 ((GLuint)cfb->buf.other & COLORMASK_ON)
{
*pul = (dst_pix & cfb->destMask) | (result & cfb->sourceMask);
}
else
{
*pul = result;
}
}
}
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;
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);
}
DitheredColorToBuffer(color, incr, cfb, result, GLubyte);
if ((GLuint)cfb->buf.other & 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 ((GLuint)cfb->buf.other & COLORMASK_ON)
{
result = (GLubyte)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
}
*puj = vubRGBtoVGA[result];
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, TRUE);
}
// 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;
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);
}
DitheredColorToBuffer(color, incr, cfb, result, GLubyte);
if ((GLuint)cfb->buf.other & 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 ((GLuint)cfb->buf.other & COLORMASK_ON)
{
result = (GLubyte)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
}
*puj = gengc->pajTranslateVector[result];
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, TRUE);
}
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;
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 ((GLuint)cfb->buf.other & NEED_FETCH)
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
dst_pix = *(GLuint *)puj;
UnditheredColorToBuffer(color, cfb, result, GLuint);
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result =
DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if ((GLuint)cfb->buf.other & 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);
}
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;
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 ((GLuint)cfb->buf.other & NEED_FETCH)
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, FALSE);
dst_pix = *(GLuint *)puj;
UnditheredColorToBuffer(color, cfb, result, GLuint);
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result =
DoLogicOp(gc->state.raster.logicOp, result, dst_pix) &
gc->modes.allMask;
}
if ((GLuint)cfb->buf.other & 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);
}
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;
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 ((GLuint)cfb->buf.other & 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 ((GLuint)cfb->buf.other & COLORMASK_ON)
{
result = (GLushort)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
}
*pus = result;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, TRUE);
}
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;
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 ((GLuint)cfb->buf.other & 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 ((GLuint)cfb->buf.other & COLORMASK_ON)
{
result = (dst_pix & cfb->destMask) |
(result & cfb->sourceMask);
}
}
*pul = result;
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, 1, TRUE);
}
/******************************Public*Routine******************************\
* DIBIndex8StoreSpan
* DisplayIndex8StoreSpan
*
* Stubs that calls Index8StoreSpan with bDIB set to TRUE and FALSE,
* respectively.
*
* History:
* 15-Nov-1993 -by- Gilman Wong [gilmanw]
* Wrote it.
\**************************************************************************/
STATIC GLboolean FASTCALL Index8StoreSpan(__GLcontext *, GLboolean);
STATIC GLboolean FASTCALL DIBIndex8StoreSpan(__GLcontext *gc)
{
return Index8StoreSpan(gc, TRUE);
}
STATIC GLboolean FASTCALL DisplayIndex8StoreSpan(__GLcontext *gc)
{
return Index8StoreSpan(gc, FALSE);
}
/******************************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
// XXX can nuke passing of bDIB
STATIC GLboolean FASTCALL Index8StoreSpan(__GLcontext *gc, GLboolean bDIB)
{
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;
GLubyte 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 = (GLuint)cfb->buf.other;
if (!(flags & DIB_FORMAT) || (flags & MEMORY_DC))
{
// Device managed surface or a memory dc
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 *)((GLint)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)) &&
!((GLuint)cfb->buf.other & 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;
}
DitheredColorToBuffer(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 ( !((GLuint)cfb->buf.other & 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)];
DitheredColorToBuffer(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) {
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE );
}
// Blend.
if (enables & __GL_BLEND_ENABLE)
{
__GLfragment frag;
__GLcolor *color;
int i;
// Blending requires x,y,color info in frag
frag.x = xFrag;
frag.y = yFrag;
color = gc->polygon.shader.colors;
// 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.
DitheredColorToBuffer(cp, incr, cfb, result, GLubyte);
// Color mask
if ((GLuint)cfb->buf.other & 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 ((GLuint)cfb->buf.other & 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);
}
return GL_FALSE;
}
/******************************Public*Routine******************************\
* DIBBitfield16StoreSpan
* DisplayBitfield16StoreSpan
*
* Stubs that calls Bitfield16StoreSpan with bDIB set to TRUE and FALSE,
* respectively.
*
* History:
* 08-Dec-1993 -by- Gilman Wong [gilmanw]
* Wrote it.
\**************************************************************************/
STATIC GLboolean FASTCALL Bitfield16StoreSpan(__GLcontext *, GLboolean);
STATIC GLboolean FASTCALL DIBBitfield16StoreSpan(__GLcontext *gc)
{
return Bitfield16StoreSpan(gc, TRUE);
}
STATIC GLboolean FASTCALL DisplayBitfield16StoreSpan(__GLcontext *gc)
{
return Bitfield16StoreSpan(gc, 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 no 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 Bitfield16StoreSpan(__GLcontext *gc, GLboolean bDIB)
{
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
ULONG ulSpanVisibility; // span visibility mode
GLint cWalls;
GLint *Walls;
__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 = (GLuint)cfb->buf.other;
if (!(flags & DIB_FORMAT) || (flags & MEMORY_DC))
{
// Device managed surface or a memory dc
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.
pus = bDIB ? (GLushort *)((GLint)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr<<1))
: gengc->ColorsBits;
pusEnd = pus + w;
// Case: no masking, no dithering, no blending
if ( !((GLuint)cfb->buf.other & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
incr = __glHalf;
for (; pus < pusEnd; pus++, 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;
}
DitheredColorToBuffer(cp, incr, cfb, result, GLushort);
*pus = result;
}
}
// Case: dithering, no masking, no blending
else if ( !((GLuint)cfb->buf.other & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
for (; pus < pusEnd; pus++, 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)];
DitheredColorToBuffer(cp, incr, cfb, result, GLushort);
*pus = result;
}
}
// All other cases
else
{
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
if ( enables & __GL_BLEND_ENABLE )
{
__GLfragment frag;
__GLcolor *color;
int i;
// Blending only requires x,y,color info in frag
frag.x = xFrag;
frag.y = yFrag;
color = gc->polygon.shader.colors;
// this overwrites fragment colors array with blended values
SPECIAL_ALPHA_BLEND_SPAN((dst_pix = *(pus+i)));
}
for (; pus < pusEnd; pus++, 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 color to 16BPP format.
DitheredColorToBuffer(cp, incr, cfb, result, GLushort);
// Store result with optional masking.
if ((GLuint)cfb->buf.other & 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 ( (GLushort)cfb->buf.other & COLORMASK_ON )
{
*pus = (GLushort)((dst_pix & cfb->destMask) |
(result & cfb->sourceMask));
}
else
{
*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);
}
return GL_FALSE;
}
/******************************Public*Routine******************************\
* DIBBGRStoreSpan
* DisplayBGRStoreSpan
*
* Stubs that calls BGRStoreSpan with bDIB set to TRUE and FALSE,
* respectively.
*
* History:
* 10-Jan-1994 -by- Marc Fortier [v-marcf]
* Wrote it.
\**************************************************************************/
STATIC GLboolean FASTCALL BGRStoreSpan(__GLcontext *, GLboolean);
STATIC GLboolean FASTCALL DIBBGRStoreSpan(__GLcontext *gc)
{
return BGRStoreSpan(gc, TRUE);
}
STATIC GLboolean FASTCALL DisplayBGRStoreSpan(__GLcontext *gc)
{
return BGRStoreSpan(gc, 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, GLboolean bDIB)
{
__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;
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 = (GLuint)cfb->buf.other;
if (!(flags & DIB_FORMAT) || (flags & MEMORY_DC))
{
// Device managed surface or a memory dc
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 *)((GLint)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 ( !((GLuint)cfb->buf.other & 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)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
if (enables & __GL_BLEND_ENABLE)
{
__GLfragment frag;
__GLcolor *color;
int i;
// Blending only requires x,y,color info in frag
frag.x = gc->polygon.shader.frag.x;
frag.y = gc->polygon.shader.frag.y;
color = gc->polygon.shader.colors;
// this overwrites fragment colors array with blended values
for ( i = 0; i < w; i++, color++, frag.x++ ) {
frag.color = *color;
(*gc->procs.blend)( gc, cfb, &frag, color );
}
}
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 ((GLuint)cfb->buf.other & NEED_FETCH)
{
Copy3Bytes(&dst_pix, puj);
UnditheredColorToBuffer(cp, cfb, result, GLuint);
if (enables & __GL_COLOR_LOGIC_OP_ENABLE)
{
result =
DoLogicOp(gc->state.raster.logicOp, result,
dst_pix) & gc->modes.allMask;
}
if ((GLuint)cfb->buf.other & 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);
}
return GL_FALSE;
}
/******************************Public*Routine******************************\
* DIBBitfield32StoreSpan
* DisplayBitfield32StoreSpan
*
* Stubs that calls Bitfield32StoreSpan with bDIB set to TRUE and FALSE,
* respectively.
*
* History:
* 15-Nov-1993 -by- Gilman Wong [gilmanw]
* Wrote it.
\**************************************************************************/
STATIC GLboolean FASTCALL Bitfield32StoreSpan(__GLcontext *, GLboolean);
STATIC GLboolean FASTCALL DIBBitfield32StoreSpan(__GLcontext *gc)
{
return Bitfield32StoreSpan(gc, TRUE);
}
STATIC GLboolean FASTCALL DisplayBitfield32StoreSpan(__GLcontext *gc)
{
return Bitfield32StoreSpan(gc, 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 Bitfield32StoreSpan(__GLcontext *gc, GLboolean bDIB)
{
__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
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;
// 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 = (GLuint)cfb->buf.other;
if (!(flags & DIB_FORMAT) || (flags & MEMORY_DC))
{
// Device managed surface or a memory dc
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.
pul = bDIB ? (GLuint *)((GLint)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 ( !((GLuint)cfb->buf.other & NEED_FETCH) &&
!(enables & __GL_BLEND_ENABLE) )
{
for (; pul < pulEnd; pul++, 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;
}
UnditheredColorToBuffer(cp, cfb, result, GLuint);
*pul = result;
}
}
// All other cases
else
{
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
if (enables & __GL_BLEND_ENABLE)
{
__GLfragment frag;
__GLcolor *color;
int i;
// Blending only requires x,y,color info in frag
frag.x = gc->polygon.shader.frag.x;
frag.y = gc->polygon.shader.frag.y;
color = gc->polygon.shader.colors;
// this overwrites fragment colors array with blended values
for ( i = 0; i < w; i++, color++, frag.x++ ) {
frag.color = *color;
(*gc->procs.blend)( gc, cfb, &frag, color );
}
}
for (; pul < pulEnd; pul++, 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;
}
UnditheredColorToBuffer(cp, cfb, result, GLuint);
//!!!XXX again, opt. by unrolling loop
if ((GLuint)cfb->buf.other & 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 ((GLuint)cfb->buf.other & COLORMASK_ON)
{
*pul = (dst_pix & cfb->destMask) |
(result & cfb->sourceMask);
}
else
{
*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);
}
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;
result->a = cfb->alphaScale;
}
void
RGBReadSpanNone(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results,
GLint w)
{
GLint i;
__GLcolor *pResults;
for (i = 0, pResults = results; i < w; i++, pResults++)
{
pResults->r = 0.0F;
pResults->g = 0.0F;
pResults->b = 0.0F;
pResults->a = cfb->alphaScale;
}
}
void
DIBIndex4RGBFetch(__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 *)((GLint)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);
result->a = cfb->alphaScale;
}
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 *)((GLint)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
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 *)((GLint)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
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 *)((GLint)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
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 *)((GLint)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
DIBBitfield32RGBFetch(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint *pul, pixel;
PIXELFORMATDESCRIPTOR *pfmt;
gengc = (__GLGENcontext *)gc;
pfmt = &gengc->CurrentFormat;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
pul = (GLuint *)((GLint)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);
if (pfmt->cAlphaBits)
{
result->a = (__GLfloat) ((pixel & gc->modes.alphaMask) >> cfb->alphaShift);
}
else
{
result->a = cfb->alphaScale;
}
}
void
DisplayIndex4RGBFetch(__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 = *puj >> 4;
result->r = vfVGAtoR[pixel];
result->g = vfVGAtoG[pixel];
result->b = vfVGAtoB[pixel];
result->a = cfb->alphaScale;
}
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
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
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
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
DisplayBitfield32RGBFetch(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *result)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint *pul, pixel;
PIXELFORMATDESCRIPTOR *pfmt;
gengc = (__GLGENcontext *)gc;
pfmt = &gengc->CurrentFormat;
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);
if (pfmt->cAlphaBits)
{
result->a = (__GLfloat) ((pixel & gc->modes.alphaMask) >> cfb->alphaShift);
}
else
{
result->a = cfb->alphaScale;
}
}
void
DIBIndex4RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results,
GLint w)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
__GLcolor *pResults;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
puj = (GLubyte *)((GLint)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->a = cfb->alphaScale;
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->a = cfb->alphaScale;
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->a = cfb->alphaScale;
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);
pResults->a = cfb->alphaScale;
}
}
void
DisplayIndex4RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *results, GLint w)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
__GLcolor *pResults;
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->a = cfb->alphaScale;
pResults++;
pixel = *puj++ & 0xf;
pResults->r = vfVGAtoR[pixel];
pResults->g = vfVGAtoG[pixel];
pResults->b = vfVGAtoB[pixel];
pResults->a = cfb->alphaScale;
pResults++;
w -= 2;
}
if (w > 0)
{
pixel = *puj >> 4;
pResults->r = vfVGAtoR[pixel];
pResults->g = vfVGAtoG[pixel];
pResults->b = vfVGAtoB[pixel];
pResults->a = cfb->alphaScale;
}
}
void
Index8RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results,
GLint w, GLboolean bDIB)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj, pixel;
GLint i;
__GLcolor *pResults;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
if (bDIB)
{
puj = (GLubyte *)((GLint)cfb->buf.base + (y*cfb->buf.outerWidth) + x);
}
else
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
puj = gengc->ColorsBits;
}
for (i = 0, pResults = results; i < w; i++, 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);
pResults->a = cfb->alphaScale;
}
}
void
DIBIndex8RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results,
GLint w)
{
Index8RGBReadSpan(cfb, x, y, results, w, TRUE);
}
void
DisplayIndex8RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *results, GLint w)
{
Index8RGBReadSpan(cfb, x, y, results, w, FALSE);
}
void
BGRReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results, GLint w,
GLboolean bDIB)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
GLint i;
__GLcolor *pResults;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
if (bDIB)
{
puj = (GLubyte *)((GLint)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x * 3));
}
else
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
puj = gengc->ColorsBits;
}
for (i = 0, pResults = results; i < w; i++, pResults++)
{
pResults->a = cfb->alphaScale;
pResults->b = (__GLfloat) *puj++;
pResults->g = (__GLfloat) *puj++;
pResults->r = (__GLfloat) *puj++;
}
}
void
DIBBGRReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results,
GLint w)
{
BGRReadSpan(cfb, x, y, results, w, TRUE);
}
void
DisplayBGRReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results,
GLint w)
{
BGRReadSpan(cfb, x, y, results, w, FALSE);
}
void
RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results, GLint w,
GLboolean bDIB)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLubyte *puj;
GLint i;
__GLcolor *pResults;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
if (bDIB)
{
puj = (GLubyte *)((GLint)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x * 3));
}
else
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
puj = gengc->ColorsBits;
}
for (i = 0, pResults = results; i < w; i++, pResults++)
{
pResults->r = (__GLfloat) *puj++;
pResults->g = (__GLfloat) *puj++;
pResults->b = (__GLfloat) *puj++;
pResults->a = cfb->alphaScale;
}
}
void
DIBRGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results,
GLint w)
{
RGBReadSpan(cfb, x, y, results, w, TRUE);
}
void
DisplayRGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y, __GLcolor *results,
GLint w)
{
RGBReadSpan(cfb, x, y, results, w, FALSE);
}
void
Bitfield16RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *results, GLint w, GLboolean bDIB)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLushort *pus, pixel;
GLint i;
__GLcolor *pResults;
gengc = (__GLGENcontext *)gc;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
if (bDIB)
{
pus = (GLushort *)((GLint)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x << 1));
}
else
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
pus = gengc->ColorsBits;
}
for (i = 0, pResults = results; i < w; i++, pResults++)
{
pixel = *pus++;
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;
}
}
void
DIBBitfield16RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *results, GLint w)
{
Bitfield16RGBReadSpan(cfb, x, y, results, w, TRUE);
}
void
DisplayBitfield16RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *results, GLint w)
{
Bitfield16RGBReadSpan(cfb, x, y, results, w, FALSE);
}
void
Bitfield32RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *results, GLint w, GLboolean bDIB)
{
__GLcontext *gc = cfb->buf.gc;
__GLGENcontext *gengc;
GLuint *pul, pixel;
GLint i;
__GLcolor *pResults;
PIXELFORMATDESCRIPTOR *pfmt;
gengc = (__GLGENcontext *)gc;
pfmt = &gengc->CurrentFormat;
x = __GL_UNBIAS_X(gc, x) + cfb->buf.xOrigin;
y = __GL_UNBIAS_Y(gc, y) + cfb->buf.yOrigin;
if (bDIB)
{
pul = (GLuint *)((GLint)cfb->buf.base +
(y*cfb->buf.outerWidth) + (x << 2));
}
else
{
(*gengc->pfnCopyPixels)(gengc, cfb, x, y, w, FALSE);
pul = gengc->ColorsBits;
}
if (pfmt->cAlphaBits)
{
for (i = 0, pResults = results; i < w; i++, pResults++)
{
pixel = *pul++;
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
{
for (i = 0, pResults = results; i < w; i++, pResults++)
{
pixel = *pul++;
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;
}
}
}
void
DIBBitfield32RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *results, GLint w)
{
Bitfield32RGBReadSpan(cfb, x, y, results, w, TRUE);
}
void
DisplayBitfield32RGBReadSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
__GLcolor *results, GLint w)
{
Bitfield32RGBReadSpan(cfb, x, y, results, w, FALSE);
}
/************************************************************************/
// Used in accumulation
/******************************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;
GLushort *ap; // current accum entry
__GLGENcontext *gengc; // generic graphics context
PIXELFORMATDESCRIPTOR *pfmt; // pixel format descriptor pointer
GLuint saveEnables; // modes enabled in graphics context
GLint redShift, greenShift, blueShift;
GLuint redMask, greenMask, blueMask;
GLuint redSign, greenSign, blueSign;
GLint ir, ig, ib;
__GLfloat r, g, b;
__GLfloat rval, gval, bval;
__GLaccumBuffer *afb;
__GLfragment frag;
afb = &gc->accumBuffer;
rval = scale * afb->oneOverRedScale;
gval = scale * afb->oneOverGreenScale;
bval = scale * afb->oneOverBlueScale;
gengc = (__GLGENcontext *)gc;
pfmt = &gengc->CurrentFormat;
redShift = 0;
greenShift = pfmt->cAccumRedBits;
blueShift = greenShift + pfmt->cAccumGreenBits;
redMask = (1 << pfmt->cAccumRedBits) - 1;
redSign = 1 << (pfmt->cAccumRedBits - 1);
greenMask = (1 << pfmt->cAccumGreenBits) - 1;
greenSign = 1 << (pfmt->cAccumGreenBits - 1);
blueMask = (1 << pfmt->cAccumBlueBits) - 1;
blueSign = 1 << (pfmt->cAccumBlueBits - 1);
ap = (GLushort *)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;
while (w--)
{
ir = (*ap >> redShift) & redMask;
if (ir & redSign)
ir |= ~redMask;
r = (ir * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
ig = (*ap >> greenShift) & greenMask;
if (ig & greenSign)
ig |= ~greenMask;
g = (ig * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
ib = (*ap >> blueShift) & blueMask;
if (ib & blueSign)
ib |= ~blueMask;
b = (ib * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
frag.color.r = r;
frag.color.g = g;
frag.color.b = b;
(*cfb->store)(cfb, &frag);
frag.x++;
ap++;
}
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,
GLboolean bDIB)
{
__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
PIXELFORMATDESCRIPTOR *pfmt; // pixel format descriptor pointer
GLuint enables; // modes enabled in graphics context
GLint redShift, greenShift, blueShift;
GLuint redMask, greenMask, blueMask;
GLuint redSign, greenSign, blueSign;
GLint ir, ig, ib;
__GLfloat r, g, b;
__GLfloat rval, gval, bval;
__GLaccumBuffer *afb;
GLubyte dst_pix;
afb = &gc->accumBuffer;
rval = scale * afb->oneOverRedScale;
gval = scale * afb->oneOverGreenScale;
bval = scale * afb->oneOverBlueScale;
gengc = (__GLGENcontext *)gc;
pfmt = &gengc->CurrentFormat;
redShift = 0;
greenShift = pfmt->cAccumRedBits;
blueShift = greenShift + pfmt->cAccumGreenBits;
redMask = (1 << pfmt->cAccumRedBits) - 1;
redSign = 1 << (pfmt->cAccumRedBits - 1);
greenMask = (1 << pfmt->cAccumGreenBits) - 1;
greenSign = 1 << (pfmt->cAccumGreenBits - 1);
blueMask = (1 << pfmt->cAccumBlueBits) - 1;
blueSign = 1 << (pfmt->cAccumBlueBits - 1);
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;
// Use to call wglSpanVisible, if window level security is added reimplement
// Get pointer to bitmap.
puj = bDIB ? (GLubyte *)((GLint)cfb->buf.base + (yScr*cfb->buf.outerWidth) + xScr)
: gengc->ColorsBits;
pujEnd = puj + w;
// Case: no dithering, no masking
//
// Check for the common case (which we'll do the fastest).
if ( !(enables & (__GL_DITHER_ENABLE)) &&
!((GLuint)cfb->buf.other & COLORMASK_ON) )
{
//!!!XXX -- we can also opt. by unrolling the loops
for (; puj < pujEnd; puj++, ap++)
{
ir = (*ap >> redShift) & redMask;
if (ir & redSign)
ir |= ~redMask;
r = (ir * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
ig = (*ap >> greenShift) & greenMask;
if (ig & greenSign)
ig |= ~greenMask;
g = (ig * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
ib = (*ap >> blueShift) & blueMask;
if (ib & blueSign)
ib |= ~blueMask;
b = (ib * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
result = ((BYTE)(r + __glHalf) << cfb->redShift) |
((BYTE)(g + __glHalf) << cfb->greenShift) |
((BYTE)(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 ( !((GLuint)cfb->buf.other & COLORMASK_ON) )
{
for (; puj < pujEnd; puj++, ap++, xFrag++)
{
ir = (*ap >> redShift) & redMask;
if (ir & redSign)
ir |= ~redMask;
r = (ir * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
ig = (*ap >> greenShift) & greenMask;
if (ig & greenSign)
ig |= ~greenMask;
g = (ig * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
ib = (*ap >> blueShift) & blueMask;
if (ib & blueSign)
ib |= ~blueMask;
b = (ib * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
inc = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
result = ((BYTE)(r + inc) << cfb->redShift) |
((BYTE)(g + inc) << cfb->greenShift) |
((BYTE)(b + inc) << cfb->blueShift);
*puj = gengc->pajTranslateVector[result];
}
}
// Case: general
//
// Otherwise, we'll do it slower.
else
{
// Color mask pre-fetch
if (((GLuint)cfb->buf.other & COLORMASK_ON) && !bDIB) {
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE );
}
for (; puj < pujEnd; puj++, ap++)
{
// Dither.
ir = (*ap >> redShift) & redMask;
if (ir & redSign)
ir |= ~redMask;
r = (ir * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
ig = (*ap >> greenShift) & greenMask;
if (ig & greenSign)
ig |= ~greenMask;
g = (ig * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
ib = (*ap >> blueShift) & blueMask;
if (ib & blueSign)
ib |= ~blueMask;
b = (ib * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
if (enables & __GL_DITHER_ENABLE)
{
inc = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
xFrag++;
}
else
{
inc = __glHalf;
}
// Convert the RGB color to color index.
result = ((BYTE)(r + inc) << cfb->redShift) |
((BYTE)(g + inc) << cfb->greenShift) |
((BYTE)(b + inc) << cfb->blueShift);
// Color mask
if ((GLuint)cfb->buf.other & 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);
}
void DIBIndex8ReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
Index8ReturnSpan(cfb, x, y, ac, scale, w, GL_TRUE);
}
void DisplayIndex8ReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
Index8ReturnSpan(cfb, x, y, ac, scale, w, GL_FALSE);
}
/******************************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,
GLboolean bDIB)
{
__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
__GLfloat r, g, b;
__GLfloat rval, gval, bval;
__GLaccumBuffer *afb;
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;
// Use to call wglSpanVisible, if window level security is added reimplement
// Get pointer to bitmap.
puj = bDIB ? (GLuint *)((GLint)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr*3))
: gengc->ColorsBits;
pujEnd = puj + w*3;
// Case: no masking
if ( !((GLuint)cfb->buf.other & COLORMASK_ON) )
{
for (; puj < pujEnd; puj += 3, ap += 4)
{
r = (ap[0] * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
puj[0] = (GLubyte)r;
g = (ap[1] * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
puj[1] = (GLubyte)g;
b = (ap[2] * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
puj[2] = (GLubyte)b;
}
}
// All other cases
else
{
GLboolean bRedMask, bGreenMask, bBlueMask;
// Color mask pre-fetch
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
bRedMask = gc->state.raster.rMask;
bGreenMask = gc->state.raster.gMask;
bBlueMask = gc->state.raster.bMask;
for (; puj < pujEnd; puj += 3, ap += 4)
{
if (bRedMask)
{
r = (ap[0] * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
puj[0] = (GLubyte)r;
}
if (bGreenMask)
{
g = (ap[1] * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
puj[1] = (GLubyte)g;
}
if (bBlueMask)
{
b = (ap[2] * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
puj[2] = (GLubyte)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);
}
void DisplayRGBReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
RGBReturnSpan(cfb, x, y, ac, scale, w, GL_FALSE);
}
void DIBRGBReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
RGBReturnSpan(cfb, x, y, ac, scale, w, GL_TRUE);
}
/******************************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,
GLboolean bDIB)
{
__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
__GLfloat r, g, b;
__GLfloat rval, gval, bval;
__GLaccumBuffer *afb;
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;
// Use to call wglSpanVisible, if window level security is added reimplement
// Get pointer to bitmap.
puj = bDIB ? (GLuint *)((GLint)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr*3))
: gengc->ColorsBits;
pujEnd = puj + w*3;
// Case: no masking
if ( !((GLuint)cfb->buf.other & COLORMASK_ON) )
{
for (; puj < pujEnd; puj += 3, ap += 4)
{
r = (ap[0] * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
puj[2] = (GLubyte)r;
g = (ap[1] * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
puj[1] = (GLubyte)g;
b = (ap[2] * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
puj[0] = (GLubyte)b;
}
}
// All other cases
else
{
GLboolean bRedMask, bGreenMask, bBlueMask;
// Color mask pre-fetch
if (!bDIB)
(*gengc->pfnCopyPixels)(gengc, cfb, xScr, yScr, w, FALSE);
bRedMask = gc->state.raster.rMask;
bGreenMask = gc->state.raster.gMask;
bBlueMask = gc->state.raster.bMask;
for (; puj < pujEnd; puj += 3, ap += 4)
{
if (bRedMask)
{
r = (ap[0] * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
puj[2] = (GLubyte)r;
}
if (bGreenMask)
{
g = (ap[1] * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
puj[1] = (GLubyte)g;
}
if (bBlueMask)
{
b = (ap[2] * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
puj[0] = (GLubyte)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);
}
void DisplayBGRReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
BGRReturnSpan(cfb, x, y, ac, scale, w, GL_FALSE);
}
void DIBBGRReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
BGRReturnSpan(cfb, x, y, ac, scale, w, GL_TRUE);
}
/******************************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,
GLboolean bDIB)
{
__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
PIXELFORMATDESCRIPTOR *pfmt; // pixel format descriptor pointer
GLuint enables; // modes enabled in graphics context
GLint redShift, greenShift, blueShift;
GLuint redMask, greenMask, blueMask;
GLuint redSign, greenSign, blueSign;
GLint ir, ig, ib;
__GLfloat r, g, b;
__GLfloat rval, gval, bval;
__GLaccumBuffer *afb;
afb = &gc->accumBuffer;
rval = scale * afb->oneOverRedScale;
gval = scale * afb->oneOverGreenScale;
bval = scale * afb->oneOverBlueScale;
gengc = (__GLGENcontext *)gc;
pfmt = &gengc->CurrentFormat;
redShift = 0;
greenShift = pfmt->cAccumRedBits;
blueShift = greenShift + pfmt->cAccumGreenBits;
redMask = (1 << pfmt->cAccumRedBits) - 1;
redSign = 1 << (pfmt->cAccumRedBits - 1);
greenMask = (1 << pfmt->cAccumGreenBits) - 1;
greenSign = 1 << (pfmt->cAccumGreenBits - 1);
blueMask = (1 << pfmt->cAccumBlueBits) - 1;
blueSign = 1 << (pfmt->cAccumBlueBits - 1);
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;
// Use to call wglSpanVisible, if window level security is added reimplement
// Get pointer to bitmap.
pus = bDIB ? (GLushort *)((GLint)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr<<1))
: gengc->ColorsBits;
pusEnd = pus + w;
// Case: no masking, no dithering
if ( !(enables & (__GL_DITHER_ENABLE)) &&
!((GLuint)cfb->buf.other & COLORMASK_ON) )
{
for (; pus < pusEnd; pus++, ap++)
{
ir = (*ap >> redShift) & redMask;
if (ir & redSign)
ir |= ~redMask;
r = (ir * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
ig = (*ap >> greenShift) & greenMask;
if (ig & greenSign)
ig |= ~greenMask;
g = (ig * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
ib = (*ap >> blueShift) & blueMask;
if (ib & blueSign)
ib |= ~blueMask;
b = (ib * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
*pus = ((BYTE)(r + __glHalf) << cfb->redShift) |
((BYTE)(g + __glHalf) << cfb->greenShift) |
((BYTE)(b + __glHalf) << cfb->blueShift);
}
}
// Case: dithering, no masking
else if ( !((GLuint)cfb->buf.other & COLORMASK_ON) )
{
for (; pus < pusEnd; pus++, ap++, xFrag++)
{
ir = (*ap >> redShift) & redMask;
if (ir & redSign)
ir |= ~redMask;
r = (ir * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
ig = (*ap >> greenShift) & greenMask;
if (ig & greenSign)
ig |= ~greenMask;
g = (ig * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
ib = (*ap >> blueShift) & blueMask;
if (ib & blueSign)
ib |= ~blueMask;
b = (ib * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
inc = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
*pus = ((BYTE)(r + inc) << cfb->redShift) |
((BYTE)(g + inc) << cfb->greenShift) |
((BYTE)(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++, ap++)
{
ir = (*ap >> redShift) & redMask;
if (ir & redSign)
ir |= ~redMask;
r = (ir * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
ig = (*ap >> greenShift) & greenMask;
if (ig & greenSign)
ig |= ~greenMask;
g = (ig * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
ib = (*ap >> blueShift) & blueMask;
if (ib & blueSign)
ib |= ~blueMask;
b = (ib * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
// Dither.
if ( enables & __GL_DITHER_ENABLE )
{
inc = fDitherIncTable[__GL_DITHER_INDEX(xFrag, yFrag)];
xFrag++;
}
else
{
inc = __glHalf;
}
// Convert color to 16BPP format.
result = ((BYTE)(r + inc) << cfb->redShift) |
((BYTE)(g + inc) << cfb->greenShift) |
((BYTE)(b + inc) << cfb->blueShift);
// Store result with optional masking.
if ( (GLushort)cfb->buf.other & COLORMASK_ON )
*pus = (GLushort)((*pus & cfb->destMask) | (result & cfb->sourceMask));
else
*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);
}
void DisplayBitfield16ReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
Bitfield16ReturnSpan(cfb, x, y, ac, scale, w, GL_FALSE);
}
void DIBBitfield16ReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
Bitfield16ReturnSpan(cfb, x, y, ac, scale, w, GL_TRUE);
}
/******************************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,
GLboolean bDIB)
{
__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
__GLfloat r, g, b;
__GLfloat rval, gval, bval;
__GLaccumBuffer *afb;
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;
// Use to call wglSpanVisible, if window level security is added reimplement
// Get pointer to bitmap.
pul = bDIB ? (GLuint *)((GLint)cfb->buf.base + (yScr*cfb->buf.outerWidth) + (xScr<<2))
: gengc->ColorsBits;
pulEnd = pul + w;
// Case: no masking
if ( !((GLuint)cfb->buf.other & COLORMASK_ON) )
{
for (; pul < pulEnd; pul++, ap += 4)
{
r = (ap[0] * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
g = (ap[1] * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
b = (ap[2] * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
*pul = ((BYTE)(r) << cfb->redShift) |
((BYTE)(g) << cfb->greenShift) |
((BYTE)(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++, ap += 4)
{
r = (ap[0] * rval);
if (r < (__GLfloat) 0.0)
r = (__GLfloat) 0.0;
else if (r > cfb->redScale)
r = cfb->redScale;
g = (ap[1] * gval);
if (g < (__GLfloat) 0.0)
g = (__GLfloat) 0.0;
else if (g > cfb->greenScale)
g = cfb->greenScale;
b = (ap[2] * bval);
if (b < (__GLfloat) 0.0)
b = (__GLfloat) 0.0;
else if (b > cfb->blueScale)
b = cfb->blueScale;
result = ((BYTE)(r) << cfb->redShift) |
((BYTE)(g) << cfb->greenShift) |
((BYTE)(b) << cfb->blueShift);
//!!!XXX again, opt. by unrolling loop
if((GLuint)cfb->buf.other & COLORMASK_ON) {
*pul = (*pul & cfb->destMask) | (result & cfb->sourceMask);
} else {
*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);
}
void DisplayBitfield32ReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
Bitfield32ReturnSpan(cfb, x, y, ac, scale, w, GL_FALSE);
}
void DIBBitfield32ReturnSpan(__GLcolorBuffer *cfb, GLint x, GLint y,
const __GLaccumCell *ac, __GLfloat scale, GLint w)
{
Bitfield32ReturnSpan(cfb, x, y, ac, scale, w, GL_TRUE);
}
STATIC void __glSetDrawBuffer(__GLcolorBuffer *cfb)
{
DBGENTRY("__glSetDrawBuffer\n");
}
STATIC void setReadBuffer(__GLcolorBuffer *cfb)
{
DBGENTRY("setReadBuffer\n");
}
/************************************************************************/
STATIC void Resize(__GLdrawablePrivate *dp, __GLcolorBuffer *cfb,
GLint w, GLint h)
{
DBGENTRY("Resize\n");
#ifdef __GL_LINT
dp = dp;
#endif
cfb->buf.width = w;
cfb->buf.height = h;
}
#ifdef NT_DEADCODE_RESIZE
STATIC void Move(__GLcontext *gc, __GLcolorBuffer *cfb, GLint x, GLint y)
{
DBGENTRY("Move\n");
#ifdef __GL_LINT
gc = gc;
cfb = cfb;
x = x;
y = y;
#endif
}
#endif // NT_DEADCODE_RESIZE
#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;
}
if (gc->state.raster.aMask) {
sourceMask |= gc->modes.alphaMask;
}
totalMask = gc->modes.redMask | gc->modes.greenMask |
gc->modes.blueMask | gc->modes.alphaMask;
if (sourceMask == totalMask) {
cfb->buf.other = (void *)((GLuint)cfb->buf.other & ~COLORMASK_ON);
} else {
cfb->buf.other = (void *)((GLuint)cfb->buf.other | COLORMASK_ON);
}
cfb->sourceMask = sourceMask;
cfb->destMask = totalMask & ~sourceMask;
// 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) ||
((GLuint)cfb->buf.other & COLORMASK_ON))
{
cfb->buf.other = (void *)((GLuint)cfb->buf.other | NEED_FETCH);
}
// Figure out store routine
if (gc->state.raster.drawBuffer == GL_NONE) {
cfb->store = Store_NOT;
cfb->fetch = RGBFetchNone;
cfb->readColor = RGBFetchNone;
cfb->readSpan = RGBReadSpanNone;
cfb->storeSpan = StoreSpanNone;
cfb->storeStippledSpan = StoreSpanNone;
} else {
gengc = (__GLGENcontext *)gc;
pfmt = &gengc->CurrentFormat;
if ((GLuint)cfb->buf.other & DIB_FORMAT) {
switch(pfmt->cColorBits) {
case 4:
DBGLEVEL(DBG_PICK, "DIBIndex4Store\n");
cfb->store = DIBIndex4Store;
cfb->fetch = DIBIndex4RGBFetch;
cfb->readColor = DIBIndex4RGBFetch;
cfb->readSpan = DIBIndex4RGBReadSpan;
cfb->returnSpan = Index4ReturnSpan;
cfb->clear = Index4Clear;
break;
case 8:
DBGLEVEL(DBG_PICK, "DIBIndex8Store, "
"DIBIndex8StoreSpan\n");
cfb->store = DIBIndex8Store;
cfb->storeSpan = DIBIndex8StoreSpan;
cfb->fetch = DIBIndex8RGBFetch;
cfb->readColor = DIBIndex8RGBFetch;
cfb->readSpan = DIBIndex8RGBReadSpan;
cfb->returnSpan = DIBIndex8ReturnSpan;
cfb->clear = Index8Clear;
break;
case 16:
DBGLEVEL(DBG_PICK, "DIBBitfield16Store\n");
cfb->store = DIBBitfield16Store;
cfb->storeSpan = DIBBitfield16StoreSpan;
cfb->fetch = DIBBitfield16RGBFetch;
cfb->readColor = DIBBitfield16RGBFetch;
cfb->readSpan = DIBBitfield16RGBReadSpan;
cfb->returnSpan = DIBBitfield16ReturnSpan;
cfb->clear = Bitfield16Clear;
break;
case 24:
if (cfb->redShift == 16)
{
DBGLEVEL(DBG_PICK, "DIBBGRStore\n");
cfb->store = DIBBGRStore;
cfb->storeSpan = DIBBGRStoreSpan;
cfb->fetch = DIBBGRFetch;
cfb->readColor = DIBBGRFetch;
cfb->readSpan = DIBBGRReadSpan;
cfb->returnSpan = DIBBGRReturnSpan;
}
else
{
DBGLEVEL(DBG_PICK, "DIBRGBStore\n");
cfb->store = DIBRGBStore;
cfb->fetch = DIBRGBFetch;
cfb->readColor = DIBRGBFetch;
cfb->readSpan = DIBRGBReadSpan;
cfb->returnSpan = DIBRGBReturnSpan;
}
cfb->clear = RGBClear;
break;
case 32:
DBGLEVEL(DBG_PICK, "DIBBitfield32Store, "
"DIBBitfield32StoreSpan\n");
cfb->store = DIBBitfield32Store;
cfb->storeSpan = DIBBitfield32StoreSpan;
cfb->fetch = DIBBitfield32RGBFetch;
cfb->readColor = DIBBitfield32RGBFetch;
cfb->readSpan = DIBBitfield32RGBReadSpan;
cfb->returnSpan = DIBBitfield32ReturnSpan;
cfb->clear = Bitfield32Clear;
break;
}
} else {
switch(pfmt->cColorBits) {
case 4:
DBGLEVEL(DBG_PICK, "DisplayIndex4Store\n");
cfb->store = DisplayIndex4Store;
cfb->fetch = DisplayIndex4RGBFetch;
cfb->readColor = DisplayIndex4RGBFetch;
cfb->readSpan = DisplayIndex4RGBReadSpan;
cfb->returnSpan = Index4ReturnSpan;
cfb->clear = Index4Clear;
break;
case 8:
DBGLEVEL(DBG_PICK, "DisplayIndex8Store, "
"DisplayIndex8StoreSpan\n");
cfb->store = DisplayIndex8Store;
cfb->storeSpan = DisplayIndex8StoreSpan;
cfb->fetch = DisplayIndex8RGBFetch;
cfb->readColor = DisplayIndex8RGBFetch;
cfb->readSpan = DisplayIndex8RGBReadSpan;
cfb->returnSpan = DisplayIndex8ReturnSpan;
#if DEAD_3DDDI
if (gengc->pDrvAccel) {
gengc->pDrvAccel->softClearFuncPtr =
Index8Clear;
cfb->clear = GenDrvClear;
} else
#endif
cfb->clear = Index8Clear;
break;
case 16:
DBGLEVEL(DBG_PICK, "DisplayBitfield16Store\n");
cfb->store = DisplayBitfield16Store;
cfb->storeSpan = DisplayBitfield16StoreSpan;
cfb->fetch = DisplayBitfield16RGBFetch;
cfb->readColor = DisplayBitfield16RGBFetch;
cfb->readSpan = DisplayBitfield16RGBReadSpan;
cfb->returnSpan = DisplayBitfield16ReturnSpan;
#if DEAD_3DDDI
if (gengc->pDrvAccel) {
gengc->pDrvAccel->softClearFuncPtr =
Bitfield16Clear;
cfb->clear = GenDrvClear;
} else
#endif
cfb->clear = Bitfield16Clear;
break;
case 24:
// Must be RGB or BGR
if (cfb->redShift == 16)
{
DBGLEVEL(DBG_PICK, "DisplayBGRStore\n");
cfb->store = DisplayBGRStore;
cfb->storeSpan = DisplayBGRStoreSpan;
cfb->fetch = DisplayBGRFetch;
cfb->readColor = DisplayBGRFetch;
cfb->readSpan = DisplayBGRReadSpan;
cfb->returnSpan = DisplayBGRReturnSpan;
}
else
{
DBGLEVEL(DBG_PICK, "DisplayRGBStore\n");
cfb->store = DisplayRGBStore;
cfb->fetch = DisplayRGBFetch;
cfb->readColor = DisplayRGBFetch;
cfb->readSpan = DisplayRGBReadSpan;
cfb->returnSpan = DisplayRGBReturnSpan;
}
#if DEAD_3DDDI
if (gengc->pDrvAccel) {
gengc->pDrvAccel->softClearFuncPtr =
RGBClear;
cfb->clear = GenDrvClear;
} else
#endif
cfb->clear = RGBClear;
break;
case 32:
DBGLEVEL(DBG_PICK, "DisplayBitfield32Store, "
"DisplayBitfield32StoreSpan\n");
cfb->store = DisplayBitfield32Store;
cfb->storeSpan = DisplayBitfield32StoreSpan;
cfb->fetch = DisplayBitfield32RGBFetch;
cfb->readColor = DisplayBitfield32RGBFetch;
cfb->readSpan = DisplayBitfield32RGBReadSpan;
cfb->returnSpan = DisplayBitfield32ReturnSpan;
#if DEAD_3DDDI
if (gengc->pDrvAccel) {
gengc->pDrvAccel->softClearFuncPtr =
Bitfield32Clear;
cfb->clear = GenDrvClear;
} else
#endif
cfb->clear = Bitfield32Clear;
break;
}
}
}
}
/************************************************************************/
void FASTCALL __glGenFreeRGB(__GLcontext *gc, __GLcolorBuffer *cfb)
{
DBGENTRY("__glGenFreeRGB\n");
}
/************************************************************************/
// 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;
// XXX figure out alpha
gc->alphaVertexScale = cfb->alphaScale = (__GLfloat)cfb->redMax;
cfb->iAlphaScale = __GL_GENRGB_COMPONENT_SCALE_ALPHA;
cfb->buf.elementSize = sizeof(GLubyte); // XXX needed?
cfb->pick = PickRGB; // called at each validate
cfb->resize = Resize;
#ifdef NT_DEADCODE_RESIZE
cfb->move = Move;
#endif // NT_DEADCODE_RESIZE
cfb->fetchSpan = __glFetchSpan;
cfb->fetchStippledSpan = __glFetchSpan;
cfb->storeSpan = SlowStoreSpan;
cfb->storeStippledSpan = SlowStoreStippledSpan;
pfmt = &gengc->CurrentFormat;
cfb->redShift = pfmt->cRedShift;
cfb->greenShift = pfmt->cGreenShift;
cfb->blueShift = pfmt->cBlueShift;
cfb->alphaShift = pfmt->cAlphaShift;
cfb->allShifts =
(cfb->redShift << 0) |
(cfb->greenShift << 8) |
(cfb->blueShift << 16) |
(cfb->alphaShift << 24);
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);
DBGLEVEL3(LEVEL_INFO," iSurfType %d, iDCtype, %d, cColorBits %d\n",
gengc->iSurfType, gengc->iDCType, pfmt->cColorBits);
}