diff options
author | Brian Paul <[email protected]> | 2004-02-17 21:03:03 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 2004-02-17 21:03:03 +0000 |
commit | 09da0b8e6621a831e3eeb9381430f2bed18a22ad (patch) | |
tree | e7e307c3a5ddd773b469cf17d0331822388b466e /src/mesa/tnl/t_vb_fog.c | |
parent | 9a389d4bdb8026063034767e1599be975cb4e2f2 (diff) |
A bit of an overhaul of the fog code.
glFogCoord didn't always work reliably.
ARB fragment program fog options work now.
Per-fragment fog computations are now perspective corrected.
Diffstat (limited to 'src/mesa/tnl/t_vb_fog.c')
-rw-r--r-- | src/mesa/tnl/t_vb_fog.c | 58 |
1 files changed, 37 insertions, 21 deletions
diff --git a/src/mesa/tnl/t_vb_fog.c b/src/mesa/tnl/t_vb_fog.c index 34f1e811cc3..3be62e887bd 100644 --- a/src/mesa/tnl/t_vb_fog.c +++ b/src/mesa/tnl/t_vb_fog.c @@ -71,7 +71,11 @@ do { \ #endif -static void init_static_data( void ) +/** + * Initialize the exp_table[] lookup table for approximating exp(). + */ +static void +init_static_data( void ) { GLfloat f = 0.0F; GLint i = 0; @@ -89,8 +93,8 @@ static void init_static_data( void ) * near and far clip plane distances). * Fog blend factors are in the range [0,1]. */ -static void compute_fog_blend_factors( GLcontext *ctx, GLvector4f *out, - const GLvector4f *in ) +static void +compute_fog_blend_factors(GLcontext *ctx, GLvector4f *out, const GLvector4f *in) { GLfloat end = ctx->Fog.End; GLfloat *v = in->start; @@ -109,19 +113,22 @@ static void compute_fog_blend_factors( GLcontext *ctx, GLvector4f *out, else d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { - GLfloat f = (end - FABSF(*v)) * d; + const GLfloat z = FABSF(*v); + GLfloat f = (end - z) * d; data[i][0] = CLAMP(f, 0.0F, 1.0F); } break; case GL_EXP: d = ctx->Fog.Density; - for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) - NEG_EXP( data[i][0], d * FABSF(*v) ); + for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) { + const GLfloat z = FABSF(*v); + NEG_EXP( data[i][0], d * z ); + } break; case GL_EXP2: d = ctx->Fog.Density*ctx->Fog.Density; for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { - GLfloat z = *v; + const GLfloat z = *v; NEG_EXP( data[i][0], d * z * z ); } break; @@ -132,10 +139,11 @@ static void compute_fog_blend_factors( GLcontext *ctx, GLvector4f *out, } -static GLboolean run_fog_stage( GLcontext *ctx, - struct tnl_pipeline_stage *stage ) +static GLboolean +run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) { - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; struct fog_stage_data *store = FOG_STAGE_DATA(stage); GLvector4f *input; @@ -143,12 +151,13 @@ static GLboolean run_fog_stage( GLcontext *ctx, return GL_TRUE; if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) { - /* fog computed from Z depth */ + /* Fog is computed from vertex or fragment Z values */ /* source = VB->ObjPtr or VB->EyePtr coords */ /* dest = VB->FogCoordPtr = fog stage private storage */ VB->FogCoordPtr = &store->fogcoord; if (!ctx->_NeedEyeCoords) { + /* compute fog coords from object coords */ const GLfloat *m = ctx->ModelviewMatrixStack.Top->m; GLfloat plane[4]; @@ -171,6 +180,7 @@ static GLboolean run_fog_stage( GLcontext *ctx, input->count = VB->ObjPtr->count; } else { + /* fog coordinates = eye Z coordinates (use ABS later) */ input = &store->input; if (VB->EyePtr->size < 2) @@ -184,21 +194,26 @@ static GLboolean run_fog_stage( GLcontext *ctx, } else { /* use glFogCoord() coordinates */ - /* source = VB->FogCoordPtr */ - input = VB->FogCoordPtr; - /* dest = fog stage private storage */ - VB->FogCoordPtr = &store->fogcoord; + input = VB->FogCoordPtr; /* source data */ + VB->FogCoordPtr = &store->fogcoord; /* dest data */ } - /* compute blend factors from fog coordinates */ - compute_fog_blend_factors( ctx, VB->FogCoordPtr, input ); + if (tnl->_DoVertexFog) { + /* compute blend factors from fog coordinates */ + compute_fog_blend_factors( ctx, VB->FogCoordPtr, input ); + } + else { + /* results = incoming fog coords (compute fog per-fragment later) */ + VB->FogCoordPtr = input; + } VB->AttribPtr[_TNL_ATTRIB_FOG] = VB->FogCoordPtr; return GL_TRUE; } -static void check_fog_stage( GLcontext *ctx, struct tnl_pipeline_stage *stage ) +static void +check_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) { stage->active = ctx->Fog.Enabled && !ctx->VertexProgram.Enabled; @@ -211,8 +226,8 @@ static void check_fog_stage( GLcontext *ctx, struct tnl_pipeline_stage *stage ) /* Called the first time stage->run() is invoked. */ -static GLboolean alloc_fog_data( GLcontext *ctx, - struct tnl_pipeline_stage *stage ) +static GLboolean +alloc_fog_data(GLcontext *ctx, struct tnl_pipeline_stage *stage) { TNLcontext *tnl = TNL_CONTEXT(ctx); struct fog_stage_data *store; @@ -234,7 +249,8 @@ static GLboolean alloc_fog_data( GLcontext *ctx, } -static void free_fog_data( struct tnl_pipeline_stage *stage ) +static void +free_fog_data(struct tnl_pipeline_stage *stage) { struct fog_stage_data *store = FOG_STAGE_DATA(stage); if (store) { |