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