diff options
author | Brian Paul <[email protected]> | 2006-09-25 23:57:39 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 2006-09-25 23:57:39 +0000 |
commit | a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4 (patch) | |
tree | b1e19031a7563c7da67386584a7e42a4603c4ba1 /src/mesa/swrast/s_fog.c | |
parent | df8632ebd87219c809810d993f56fef1e6853a25 (diff) |
Initial work for supporting different renderbuffer color depths at runtime.
Diffstat (limited to 'src/mesa/swrast/s_fog.c')
-rw-r--r-- | src/mesa/swrast/s_fog.c | 229 |
1 files changed, 139 insertions, 90 deletions
diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c index e3d6274b3fe..daa74ca0ca4 100644 --- a/src/mesa/swrast/s_fog.c +++ b/src/mesa/swrast/s_fog.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.3 + * Version: 6.5.2 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -30,7 +30,13 @@ #include "s_context.h" #include "s_fog.h" -#include "s_span.h" + + +/** XXX temporary */ +#define UBYTE_RGBA GLubyte (*rgba)[4] = span->array->color.sz1.rgba +#define USHORT_RGBA GLushort (*rgba)[4] = span->array->color.sz2.rgba +#define FLOAT_RGBA GLfloat (*rgba)[4] = span->array->color.sz4.rgba + /** @@ -67,6 +73,33 @@ _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z) /** + * Template code for computing fog blend factor and applying it to colors. + * \param TYPE either GLubyte, GLushort or GLfloat. + * \param COMPUTE_F code to compute the fog blend factor, f. + */ +#define FOG_LOOP(TYPE, COMPUTE_F) \ +do { \ + const GLfloat fogStep = span->fogStep; \ + GLfloat fogCoord = span->fog; \ + const GLfloat wStep = haveW ? span->dwdx : 0.0F; \ + GLfloat w = haveW ? span->w : 1.0F; \ + GLuint i; \ + for (i = 0; i < span->end; i++) { \ + GLfloat f, oneMinusF; \ + COMPUTE_F; \ + f = CLAMP(f, 0.0F, 1.0F); \ + oneMinusF = 1.0F - f; \ + rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \ + rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \ + rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \ + fogCoord += fogStep; \ + w += wStep; \ + } \ +} while (0) + + + +/** * Apply fog to a span of RGBA pixels. * The fog value are either in the span->array->fog array or interpolated from * the fog/fogStep values. @@ -77,11 +110,10 @@ void _swrast_fog_rgba_span( const GLcontext *ctx, struct sw_span *span ) { const SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLchan rFog = swrast->_FogColor[RCOMP]; - const GLchan gFog = swrast->_FogColor[GCOMP]; - const GLchan bFog = swrast->_FogColor[BCOMP]; + const GLfloat rFog = ctx->Fog.Color[RCOMP] * CHAN_MAX; + const GLfloat gFog = ctx->Fog.Color[GCOMP] * CHAN_MAX; + const GLfloat bFog = ctx->Fog.Color[BCOMP] * CHAN_MAX; const GLuint haveW = (span->interpMask & SPAN_W); - GLchan (*rgba)[4] = (GLchan (*)[4]) span->array->rgba; ASSERT(swrast->_FogEnabled); ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG); @@ -96,79 +128,71 @@ _swrast_fog_rgba_span( const GLcontext *ctx, struct sw_span *span ) /* The span's fog values are fog coordinates, now compute blend factors * and blend the fragment colors with the fog color. */ + const GLfloat fogEnd = ctx->Fog.End; + const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End) + ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); + const GLfloat density = -ctx->Fog.Density; + const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; + switch (swrast->_FogMode) { case GL_LINEAR: - { - const GLfloat fogEnd = ctx->Fog.End; - const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End) - ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; - GLuint i; - for (i = 0; i < span->end; i++) { - GLfloat f, oneMinusF; - f = (fogEnd - FABSF(fogCoord) / w) * fogScale; - f = CLAMP(f, 0.0F, 1.0F); - oneMinusF = 1.0F - f; - rgba[i][RCOMP] = (GLchan) (f * rgba[i][RCOMP] + oneMinusF * rFog); - rgba[i][GCOMP] = (GLchan) (f * rgba[i][GCOMP] + oneMinusF * gFog); - rgba[i][BCOMP] = (GLchan) (f * rgba[i][BCOMP] + oneMinusF * bFog); - fogCoord += fogStep; - w += wStep; - } +#define COMPUTE_F f = (fogEnd - FABSF(fogCoord) / w) * fogScale; + if (span->array->ChanType == GL_UNSIGNED_BYTE) { + UBYTE_RGBA; + FOG_LOOP(GLubyte, COMPUTE_F); + } + else if (span->array->ChanType == GL_UNSIGNED_SHORT) { + USHORT_RGBA; + FOG_LOOP(GLushort, COMPUTE_F); } + else { + FLOAT_RGBA; + ASSERT(span->array->ChanType == GL_FLOAT); + FOG_LOOP(GLfloat, COMPUTE_F); + } +#undef COMPUTE_F break; + case GL_EXP: - { - const GLfloat density = -ctx->Fog.Density; - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; - GLuint i; - for (i = 0; i < span->end; i++) { - GLfloat f, oneMinusF; - f = EXPF(density * FABSF(fogCoord) / w); - f = CLAMP(f, 0.0F, 1.0F); - oneMinusF = 1.0F - f; - rgba[i][RCOMP] = (GLchan) (f * rgba[i][RCOMP] + oneMinusF * rFog); - rgba[i][GCOMP] = (GLchan) (f * rgba[i][GCOMP] + oneMinusF * gFog); - rgba[i][BCOMP] = (GLchan) (f * rgba[i][BCOMP] + oneMinusF * bFog); - fogCoord += fogStep; - w += wStep; - } +#define COMPUTE_F f = EXPF(density * FABSF(fogCoord) / w); + if (span->array->ChanType == GL_UNSIGNED_BYTE) { + UBYTE_RGBA; + FOG_LOOP(GLubyte, COMPUTE_F); + } + else if (span->array->ChanType == GL_UNSIGNED_SHORT) { + USHORT_RGBA; + FOG_LOOP(GLushort, COMPUTE_F); + } + else { + FLOAT_RGBA; + ASSERT(span->array->ChanType == GL_FLOAT); + FOG_LOOP(GLfloat, COMPUTE_F); } +#undef COMPUTE_F break; + case GL_EXP2: - { - const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; - GLuint i; - for (i = 0; i < span->end; i++) { - const GLfloat coord = fogCoord / w; - GLfloat tmp = negDensitySquared * coord * coord; - GLfloat f, oneMinusF; -#if defined(__alpha__) || defined(__alpha) - /* XXX this underflow check may be needed for other systems*/ - if (tmp < FLT_MIN_10_EXP) - tmp = FLT_MIN_10_EXP; -#endif - f = EXPF(tmp); - f = CLAMP(f, 0.0F, 1.0F); - oneMinusF = 1.0F - f; - rgba[i][RCOMP] = (GLchan) (f * rgba[i][RCOMP] + oneMinusF * rFog); - rgba[i][GCOMP] = (GLchan) (f * rgba[i][GCOMP] + oneMinusF * gFog); - rgba[i][BCOMP] = (GLchan) (f * rgba[i][BCOMP] + oneMinusF * bFog); - fogCoord += fogStep; - w += wStep; - } +#define COMPUTE_F const GLfloat coord = fogCoord / w; \ + GLfloat tmp = negDensitySquared * coord * coord; \ + if (tmp < FLT_MIN_10_EXP) \ + tmp = FLT_MIN_10_EXP; \ + f = EXPF(tmp); + if (span->array->ChanType == GL_UNSIGNED_BYTE) { + UBYTE_RGBA; + FOG_LOOP(GLubyte, COMPUTE_F); + } + else if (span->array->ChanType == GL_UNSIGNED_SHORT) { + USHORT_RGBA; + FOG_LOOP(GLushort, COMPUTE_F); + } + else { + FLOAT_RGBA; + ASSERT(span->array->ChanType == GL_FLOAT); + FOG_LOOP(GLfloat, COMPUTE_F); } +#undef COMPUTE_F break; + default: _mesa_problem(ctx, "Bad fog mode in _swrast_fog_rgba_span"); return; @@ -179,33 +203,58 @@ _swrast_fog_rgba_span( const GLcontext *ctx, struct sw_span *span ) * They were previously computed per-vertex. */ GLuint i; - for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->fog[i]; - const GLfloat oneMinusF = 1.0F - f; - rgba[i][RCOMP] = (GLchan) (f * rgba[i][RCOMP] + oneMinusF * rFog); - rgba[i][GCOMP] = (GLchan) (f * rgba[i][GCOMP] + oneMinusF * gFog); - rgba[i][BCOMP] = (GLchan) (f * rgba[i][BCOMP] + oneMinusF * bFog); + if (span->array->ChanType == GL_UNSIGNED_BYTE) { + UBYTE_RGBA; + for (i = 0; i < span->end; i++) { + const GLfloat f = span->array->fog[i]; + const GLfloat oneMinusF = 1.0F - f; + rgba[i][RCOMP] = (GLubyte) (f * rgba[i][RCOMP] + oneMinusF * rFog); + rgba[i][GCOMP] = (GLubyte) (f * rgba[i][GCOMP] + oneMinusF * gFog); + rgba[i][BCOMP] = (GLubyte) (f * rgba[i][BCOMP] + oneMinusF * bFog); + } + } + else if (span->array->ChanType == GL_UNSIGNED_SHORT) { + USHORT_RGBA; + for (i = 0; i < span->end; i++) { + const GLfloat f = span->array->fog[i]; + const GLfloat oneMinusF = 1.0F - f; + rgba[i][RCOMP] = (GLushort) (f * rgba[i][RCOMP] + oneMinusF * rFog); + rgba[i][GCOMP] = (GLushort) (f * rgba[i][GCOMP] + oneMinusF * gFog); + rgba[i][BCOMP] = (GLushort) (f * rgba[i][BCOMP] + oneMinusF * bFog); + } + } + else { + FLOAT_RGBA; + ASSERT(span->array->ChanType == GL_FLOAT); + for (i = 0; i < span->end; i++) { + const GLfloat f = span->array->fog[i]; + const GLfloat oneMinusF = 1.0F - f; + rgba[i][RCOMP] = f * rgba[i][RCOMP] + oneMinusF * rFog; + rgba[i][GCOMP] = f * rgba[i][GCOMP] + oneMinusF * gFog; + rgba[i][BCOMP] = f * rgba[i][BCOMP] + oneMinusF * bFog; + } } + } else { /* The span's fog start/step values are blend factors. * They were previously computed per-vertex. */ - const GLfloat fogStep = span->fogStep; - GLfloat fog = span->fog; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; - GLuint i; - ASSERT(span->interpMask & SPAN_FOG); - for (i = 0; i < span->end; i++) { - const GLfloat fact = fog / w; - const GLfloat oneMinusF = 1.0F - fact; - rgba[i][RCOMP] = (GLchan) (fact * rgba[i][RCOMP] + oneMinusF * rFog); - rgba[i][GCOMP] = (GLchan) (fact * rgba[i][GCOMP] + oneMinusF * gFog); - rgba[i][BCOMP] = (GLchan) (fact * rgba[i][BCOMP] + oneMinusF * bFog); - fog += fogStep; - w += wStep; +#define COMPUTE_F f = fogCoord / w; + if (span->array->ChanType == GL_UNSIGNED_BYTE) { + UBYTE_RGBA; + FOG_LOOP(GLubyte, COMPUTE_F); + } + else if (span->array->ChanType == GL_UNSIGNED_SHORT) { + USHORT_RGBA; + FOG_LOOP(GLushort, COMPUTE_F); + } + else { + FLOAT_RGBA; + ASSERT(span->array->ChanType == GL_FLOAT); + FOG_LOOP(GLfloat, COMPUTE_F); } +#undef COMPUTE_F } } |