diff --git a/neo/renderer/Material.cpp b/neo/renderer/Material.cpp index 2655a1b4..dc51e92a 100644 --- a/neo/renderer/Material.cpp +++ b/neo/renderer/Material.cpp @@ -1862,8 +1862,12 @@ void idMaterial::ParseDeform(idLexer& src) { idMaterial::GetDiffuseImage =================== */ -idImage* idMaterial::GetDiffuseImage(void) const { +idImage* idMaterial::GetDiffuseImage(const float* regs) const { for (int i = 0; i < numStages; i++) { + if (regs && regs[stages[i].conditionRegister] == 0) { + continue; + } + if (stages[i].lighting == SL_DIFFUSE && stages[i].texture.image) { return stages[i].texture.image; } @@ -1933,9 +1937,13 @@ idImage* idMaterial::GetSpecImage(void) const { idMaterial::GetGlowImage =================== */ -idImage* idMaterial::GetGlowImage(void) const { +idImage* idMaterial::GetGlowImage(const float *regs) const { #ifdef PREY for (int i = 0; i < numStages; i++) { + if (regs && regs[stages[i].conditionRegister] == 0) { + continue; + } + if ((stages[i].lighting == SL_GLOWMAP || stages[i].isGlow) && stages[i].texture.image) { return stages[i].texture.image; } @@ -2784,7 +2792,6 @@ void idMaterial::AddReference() { } } } - /* =============== idMaterial::EvaluateRegisters @@ -2794,13 +2801,13 @@ then all expressions are evaluated, leaving the material registers set to their apropriate values. =============== */ -void idMaterial::EvaluateRegisters( float *registers, const float shaderParms[MAX_ENTITY_SHADER_PARMS], - const viewDef_t *view, idSoundEmitter *soundEmitter ) const { +void idMaterial::EvaluateRegisters(float* registers, const float shaderParms[MAX_ENTITY_SHADER_PARMS], + const viewDef_t* view, idSoundEmitter* soundEmitter) const { int i, b; - expOp_t *op; + expOp_t* op; // copy the material constants - for ( i = EXP_REG_NUM_PREDEFINED ; i < numRegisters ; i++ ) { + for (i = EXP_REG_NUM_PREDEFINED; i < numRegisters; i++) { registers[i] = expressionRegisters[i]; } @@ -2818,7 +2825,15 @@ void idMaterial::EvaluateRegisters( float *registers, const float shaderParms[MA registers[EXP_REG_PARM9] = shaderParms[9]; registers[EXP_REG_PARM10] = shaderParms[10]; registers[EXP_REG_PARM11] = shaderParms[11]; + +#ifdef PREY + // Prey has one extra entity shader parm copied into predefined register 21. + // Make sure EXP_REG_GLOBAL0 is defined as the correct predefined register index. + registers[EXP_REG_GLOBAL0] = shaderParms[12]; +#else registers[EXP_REG_GLOBAL0] = view->renderView.shaderParms[0]; +#endif + registers[EXP_REG_GLOBAL1] = view->renderView.shaderParms[1]; registers[EXP_REG_GLOBAL2] = view->renderView.shaderParms[2]; registers[EXP_REG_GLOBAL3] = view->renderView.shaderParms[3]; @@ -2828,72 +2843,98 @@ void idMaterial::EvaluateRegisters( float *registers, const float shaderParms[MA registers[EXP_REG_GLOBAL7] = view->renderView.shaderParms[7]; op = ops; - for ( i = 0 ; i < numOps ; i++, op++ ) { - switch( op->opType ) { -#ifdef PREY - case OP_TYPE_FRAGMENTPROGRAMS: - registers[op->c] = glConfig.ARBFragmentProgramAvailable; - break; -#endif + for (i = 0; i < numOps; i++, op++) { + switch (op->opType) { case OP_TYPE_ADD: registers[op->c] = registers[op->a] + registers[op->b]; break; + case OP_TYPE_SUBTRACT: registers[op->c] = registers[op->a] - registers[op->b]; break; + case OP_TYPE_MULTIPLY: registers[op->c] = registers[op->a] * registers[op->b]; break; + case OP_TYPE_DIVIDE: +#ifdef PREY + // Prey returns 0.0 when dividing by zero. + if (registers[op->b] == 0.0f) { + registers[op->c] = 0.0f; + } + else { + registers[op->c] = registers[op->a] / registers[op->b]; + } +#else registers[op->c] = registers[op->a] / registers[op->b]; +#endif break; + case OP_TYPE_MOD: b = (int)registers[op->b]; b = b != 0 ? b : 1; registers[op->c] = (int)registers[op->a] % b; break; + case OP_TYPE_TABLE: - { - const idDeclTable *table = static_cast( declManager->DeclByIndex( DECL_TABLE, op->a ) ); - registers[op->c] = table->TableLookup( registers[op->b] ); - } - break; + { + const idDeclTable* table = static_cast(declManager->DeclByIndex(DECL_TABLE, op->a)); + registers[op->c] = table->TableLookup(registers[op->b]); + } + break; + case OP_TYPE_SOUND: - if ( soundEmitter ) { + if (soundEmitter) { registers[op->c] = soundEmitter->CurrentAmplitude(); - } else { + } + else { registers[op->c] = 0; } break; + case OP_TYPE_GT: - registers[op->c] = registers[ op->a ] > registers[op->b]; + registers[op->c] = registers[op->a] > registers[op->b]; break; + case OP_TYPE_GE: - registers[op->c] = registers[ op->a ] >= registers[op->b]; + registers[op->c] = registers[op->a] >= registers[op->b]; break; + case OP_TYPE_LT: - registers[op->c] = registers[ op->a ] < registers[op->b]; + registers[op->c] = registers[op->a] < registers[op->b]; break; + case OP_TYPE_LE: - registers[op->c] = registers[ op->a ] <= registers[op->b]; + registers[op->c] = registers[op->a] <= registers[op->b]; break; + case OP_TYPE_EQ: - registers[op->c] = registers[ op->a ] == registers[op->b]; + registers[op->c] = registers[op->a] == registers[op->b]; break; + case OP_TYPE_NE: - registers[op->c] = registers[ op->a ] != registers[op->b]; + registers[op->c] = registers[op->a] != registers[op->b]; break; + case OP_TYPE_AND: - registers[op->c] = registers[ op->a ] && registers[op->b]; + registers[op->c] = registers[op->a] && registers[op->b]; break; + case OP_TYPE_OR: - registers[op->c] = registers[ op->a ] || registers[op->b]; + registers[op->c] = registers[op->a] || registers[op->b]; break; + +#ifdef PREY + case OP_TYPE_FRAGMENTPROGRAMS: + registers[op->c] = glConfig.ARBFragmentProgramAvailable ? 1.0f : 0.0f; + break; +#endif + default: - common->FatalError( "R_EvaluateExpression: bad opcode" ); + common->FatalError("R_EvaluateExpression: bad opcode"); } } - } /* diff --git a/neo/renderer/Material.h b/neo/renderer/Material.h index ae2f5837..d9f77488 100644 --- a/neo/renderer/Material.h +++ b/neo/renderer/Material.h @@ -506,7 +506,7 @@ public: bool ReceivesFog(void) const { return (IsDrawn() && !noFog && coverage != MC_TRANSLUCENT); } // jmarshall // Returns the diffuse/albedo image used by this material stage. - idImage* GetDiffuseImage(void) const; + idImage* GetDiffuseImage(const float *regs) const; // Returns the bump/normal map image used by this material stage. idImage* GetBumpImage(void) const; @@ -515,7 +515,7 @@ public: idImage* GetSpecImage(void) const; // Returns the glow/emissive map image used by this material stage. - idImage* GetGlowImage(void) const; + idImage* GetGlowImage(const float* regs) const; // Returns true if this material participates in dynamic lighting. bool IsLitMaterial(void) const; diff --git a/neo/renderer/draw_common.cpp b/neo/renderer/draw_common.cpp index e119989c..a42a1d0b 100644 --- a/neo/renderer/draw_common.cpp +++ b/neo/renderer/draw_common.cpp @@ -534,7 +534,7 @@ void RB_T_FillDepthBuffer( const drawSurf_t *surf ) { // bind the texture GL_SelectTexture(0); glEnable(GL_TEXTURE_2D); - shader->GetDiffuseImage()->Bind(); + shader->GetDiffuseImage(regs)->Bind(); GL_SelectTexture(1); glEnable(GL_TEXTURE_2D); @@ -546,7 +546,7 @@ void RB_T_FillDepthBuffer( const drawSurf_t *surf ) { shader->GetSpecImage()->Bind(); glBindSpecularMapTexture(shader->GetSpecImage()->texnum); - idImage* glowMapImage = shader->GetGlowImage(); + idImage* glowMapImage = shader->GetGlowImage(regs); if (glowMapImage) { GL_SelectTexture(3); @@ -989,11 +989,6 @@ void RB_STD_T_RenderShaderPasses( const drawSurf_t *surf ) { continue; } - // check the stage enable condition - if (regs[pStage->conditionRegister] == 0) { - continue; - } - // select the vertex color source if ( pStage->vertexColor == SVC_IGNORE ) { glColor4fv( color );