Diffuse and glow images now respect shader registers.

This commit is contained in:
Justin Marshall
2026-05-08 14:52:45 -07:00
parent 1d66b72a8f
commit 0282b742b5
3 changed files with 76 additions and 40 deletions
+72 -31
View File
@@ -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<const idDeclTable *>( declManager->DeclByIndex( DECL_TABLE, op->a ) );
registers[op->c] = table->TableLookup( registers[op->b] );
}
break;
{
const idDeclTable* table = static_cast<const idDeclTable*>(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");
}
}
}
/*
+2 -2
View File
@@ -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;
+2 -7
View File
@@ -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 );