From: Brian Paul Date: Wed, 13 Dec 2000 00:46:21 +0000 (+0000) Subject: improved precision of glReadPixels for colorbuffers < 24bpp X-Git-Tag: 062012170305~27606 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=062bc07bde9520d12c3cc051779d67a9543c0ff7;p=profile%2Fivi%2Fmesa.git improved precision of glReadPixels for colorbuffers < 24bpp --- diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c index efd89ca..cb0818c 100644 --- a/src/mesa/main/pixel.c +++ b/src/mesa/main/pixel.c @@ -1,4 +1,4 @@ -/* $Id: pixel.c,v 1.20 2000/11/28 00:07:51 brianp Exp $ */ +/* $Id: pixel.c,v 1.21 2000/12/13 00:46:21 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -1109,3 +1109,48 @@ _mesa_map_stencil( const GLcontext *ctx, GLuint n, GLstencil stencil[] ) stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ]; } } + + + +/* + * This function converts an array of GLchan colors to GLfloat colors. + * Most importantly, it undoes the non-uniform quantization of pixel + * values introduced when we convert shallow (< 8 bit) pixel values + * to GLubytes in the ctx->Driver.ReadRGBASpan() functions. + * This fixes a number of OpenGL conformance failures when running on + * 16bpp displays, for example. + */ +void +_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n, + CONST GLchan rgba[][4], GLfloat rgbaf[][4]) +{ + const GLuint rShift = CHAN_BITS - ctx->Visual.RedBits; + const GLuint gShift = CHAN_BITS - ctx->Visual.GreenBits; + const GLuint bShift = CHAN_BITS - ctx->Visual.BlueBits; + GLuint aShift; + const GLfloat rScale = 1.0 / (GLfloat) ((1 << ctx->Visual.RedBits ) - 1); + const GLfloat gScale = 1.0 / (GLfloat) ((1 << ctx->Visual.GreenBits) - 1); + const GLfloat bScale = 1.0 / (GLfloat) ((1 << ctx->Visual.BlueBits ) - 1); + GLfloat aScale; + GLuint i; + + if (ctx->Visual.AlphaBits > 0) { + aShift = CHAN_BITS - ctx->Visual.AlphaBits; + aScale = 1.0 / (GLfloat) ((1 << ctx->Visual.AlphaBits) - 1); + } + else { + aShift = 0; + aScale = 1.0F / CHAN_MAXF; + } + + for (i = 0; i < n; i++) { + const GLint r = rgba[i][RCOMP] >> rShift; + const GLint g = rgba[i][GCOMP] >> gShift; + const GLint b = rgba[i][BCOMP] >> bShift; + const GLint a = rgba[i][ACOMP] >> aShift; + rgbaf[i][RCOMP] = (GLfloat) r * rScale; + rgbaf[i][GCOMP] = (GLfloat) g * gScale; + rgbaf[i][BCOMP] = (GLfloat) b * bScale; + rgbaf[i][ACOMP] = (GLfloat) a * aScale; + } +} diff --git a/src/mesa/main/pixel.h b/src/mesa/main/pixel.h index db6dd78..6698d8c 100644 --- a/src/mesa/main/pixel.h +++ b/src/mesa/main/pixel.h @@ -1,4 +1,4 @@ -/* $Id: pixel.h,v 1.8 2000/11/28 00:07:51 brianp Exp $ */ +/* $Id: pixel.h,v 1.9 2000/12/13 00:46:21 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -131,4 +131,9 @@ extern void _mesa_map_stencil(const GLcontext *ctx, GLuint n, GLstencil index[]); +extern void +_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n, + CONST GLchan rgba[][4], GLfloat rgbaf[][4]); + + #endif diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 4c5e154..4cc3dbd 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -1,4 +1,4 @@ -/* $Id: s_readpix.c,v 1.4 2000/11/28 00:04:39 brianp Exp $ */ +/* $Id: s_readpix.c,v 1.5 2000/12/13 00:46:22 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -716,9 +716,27 @@ static void read_rgba_pixels( GLcontext *ctx, } dst = _mesa_image_address(packing, pixels, width, height, format, type, 0, row, 0); - _mesa_pack_rgba_span(ctx, readWidth, (const GLchan (*)[4]) rgba, - format, type, dst, packing, - ctx->_ImageTransferState); + if (ctx->Visual.RedBits < CHAN_BITS || + ctx->Visual.GreenBits < CHAN_BITS || + ctx->Visual.BlueBits < CHAN_BITS) { + /* Requantize the color values into floating point and go from + * there. This fixes conformance failures with 16-bit color + * buffers, for example. + */ + GLfloat rgbaf[MAX_WIDTH][4]; + _mesa_chan_to_float_span(ctx, readWidth, + (CONST GLchan (*)[4]) rgba, rgbaf); + _mesa_pack_float_rgba_span(ctx, readWidth, + (CONST GLfloat (*)[4]) rgbaf, + format, type, dst, packing, + ctx->_ImageTransferState); + } + else { + /* GLubytes are fine */ + _mesa_pack_rgba_span(ctx, readWidth, (CONST GLchan (*)[4]) rgba, + format, type, dst, packing, + ctx->_ImageTransferState); + } } }