diff options
author | Michel Dänzer <michel@daenzer.net> | 2004-01-23 03:19:47 +0000 |
---|---|---|
committer | Michel Dänzer <michel@daenzer.net> | 2004-01-23 03:19:47 +0000 |
commit | 5d00e131d8a264498b8d050c3eded093ee5c42f2 (patch) | |
tree | c6cf958662658c178807c0330fb4110760632244 /src/mesa/drivers/dri/r200/r200_state.c | |
parent | 4f295cee73bae1f687efe2dc062522b40d90b1e4 (diff) |
Fix attenuation hardware state handling, inspired by the R200 DDK reference
driver (our r200 driver basically didn't do this at all, maybe got lost
along the way?)
Diffstat (limited to 'src/mesa/drivers/dri/r200/r200_state.c')
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_state.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 37da564986..7ea45f3d78 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -1104,6 +1104,10 @@ static void r200Lightfv( GLcontext *ctx, GLenum light, case GL_CONSTANT_ATTENUATION: R200_STATECHANGE(rmesa, lit[p]); fcmd[LIT_ATTEN_CONST] = params[0]; + if ( params[0] == 0.0 ) + fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX; + else + fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0]; break; case GL_LINEAR_ATTENUATION: R200_STATECHANGE(rmesa, lit[p]); @@ -1117,6 +1121,41 @@ static void r200Lightfv( GLcontext *ctx, GLenum light, return; } + /* Set RANGE_ATTEN only when needed */ + switch (pname) { + case GL_POSITION: + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: { + GLuint *icmd = (GLuint *)R200_DB_STATE( tcl ); + GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; + GLuint atten_flag = ( p&1 ) ? R200_LIGHT_1_ENABLE_RANGE_ATTEN + : R200_LIGHT_0_ENABLE_RANGE_ATTEN; + GLuint atten_const_flag = ( p&1 ) ? R200_LIGHT_1_CONSTANT_RANGE_ATTEN + : R200_LIGHT_0_CONSTANT_RANGE_ATTEN; + + if ( l->EyePosition[3] == 0.0F || + ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) && + fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) { + /* Disable attenuation */ + icmd[idx] &= ~atten_flag; + } else { + if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) { + /* Enable only constant portion of attenuation calculation */ + icmd[idx] |= ( atten_flag | atten_const_flag ); + } else { + /* Enable full attenuation calculation */ + icmd[idx] &= ~atten_const_flag; + icmd[idx] |= atten_flag; + } + } + + R200_DB_STATECHANGE( rmesa, &rmesa->hw.tcl ); + break; + } + default: + break; + } } |