Added support for a few colorGen_t and alphaGen_t values

This commit is contained in:
OM 2023-05-15 20:14:45 +02:00
parent 7fb4de0c6c
commit 5b141089c3
4 changed files with 263 additions and 93 deletions

View file

@ -231,6 +231,7 @@ typedef struct image_s {
typedef enum { typedef enum {
SS_BAD, SS_BAD,
SS_PORTAL, // mirrors, portals, viewscreens SS_PORTAL, // mirrors, portals, viewscreens
SS_PORTALSKY,
SS_ENVIRONMENT, // sky box SS_ENVIRONMENT, // sky box
SS_OPAQUE, // opaque SS_OPAQUE, // opaque
@ -239,8 +240,6 @@ typedef enum {
// in addition to alpha test // in addition to alpha test
SS_BANNER, SS_BANNER,
SS_FOG,
SS_UNDERWATER, // for items that should be drawn in front of the water plane SS_UNDERWATER, // for items that should be drawn in front of the water plane
SS_BLEND0, // regular transparency and filters SS_BLEND0, // regular transparency and filters
@ -336,10 +335,7 @@ typedef enum {
CGEN_SCOORD, CGEN_SCOORD,
CGEN_TCOORD, CGEN_TCOORD,
CGEN_DOT, CGEN_DOT,
CGEN_ONE_MINUS_DOT, CGEN_ONE_MINUS_DOT
CGEN_LIGHTING_DIFFUSE,
CGEN_FOG, // standard fog
CGEN_CONST // fixed color
} colorGen_t; } colorGen_t;
typedef enum { typedef enum {
@ -2079,13 +2075,21 @@ void RB_CalcModulateColorsByFog( unsigned char *dstColors );
void RB_CalcModulateAlphasByFog( unsigned char *dstColors ); void RB_CalcModulateAlphasByFog( unsigned char *dstColors );
void RB_CalcModulateRGBAsByFog( unsigned char *dstColors ); void RB_CalcModulateRGBAsByFog( unsigned char *dstColors );
void RB_CalcWaveAlpha( const waveForm_t *wf, unsigned char *dstColors ); void RB_CalcWaveAlpha( const waveForm_t *wf, unsigned char *dstColors );
void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors ); void RB_CalcWaveColor(const waveForm_t* wf, unsigned char* dstColors, unsigned char* constantColor);
void RB_CalcAlphaFromEntity( unsigned char *dstColors ); void RB_CalcAlphaFromEntity( unsigned char *dstColors );
void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors ); void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors );
void RB_CalcStretchTexCoords( const waveForm_t *wf, float *texCoords ); void RB_CalcStretchTexCoords( const waveForm_t *wf, float *texCoords );
void RB_CalcColorFromEntity( unsigned char *dstColors ); void RB_CalcColorFromEntity( unsigned char *dstColors );
void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors ); void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors );
void RB_CalcSpecularAlpha( unsigned char *alphas ); void RB_CalcColorFromConstant(unsigned char* dstColors, unsigned char* constantColor);
void RB_CalcRGBFromDot(unsigned char* colors, float alphaMin, float alphaMax);
void RB_CalcRGBFromOneMinusDot(unsigned char* colors, float alphaMin, float alphaMax);
void RB_CalcAlphaFromConstant(unsigned char* dstColors, int constantAlpha);
void RB_CalcAlphaFromDot(unsigned char* colors, float alphaMin, float alphaMax);
void RB_CalcAlphaFromOneMinusDot(unsigned char* colors, float alphaMin, float alphaMax);
void RB_CalcAlphaFromTexCoords(unsigned char* colors, float alphaMin, float alphaMax, int alphaMinCap, int alphaCap, float sWeight, float tWeight, float* st);
void RB_CalcRGBFromTexCoords(unsigned char* colors, float alphaMin, float alphaMax, int alphaMinCap, int alphaCap, float sWeight, float tWeight, float* st);
void RB_CalcSpecularAlpha(unsigned char* alphas, float alphaMax, vec3_t lightOrigin);
void RB_CalcLightGridColor(unsigned char* colors); void RB_CalcLightGridColor(unsigned char* colors);
void RB_CalcAlphaFromDotView(unsigned char* colors, float alphaMin, float alphaMax); void RB_CalcAlphaFromDotView(unsigned char* colors, float alphaMin, float alphaMax);
void RB_CalcAlphaFromOneMinusDotView(unsigned char* colors, float alphaMin, float alphaMax); void RB_CalcAlphaFromOneMinusDotView(unsigned char* colors, float alphaMin, float alphaMax);

View file

@ -693,25 +693,37 @@ static void ComputeColors( shaderStage_t *pStage )
case CGEN_IDENTITY_LIGHTING: case CGEN_IDENTITY_LIGHTING:
Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 ); Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 );
break; break;
case CGEN_LIGHTING_DIFFUSE: case CGEN_ENTITY:
RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors ); RB_CalcColorFromEntity((unsigned char*)tess.svars.colors);
break;
case CGEN_ONE_MINUS_ENTITY:
RB_CalcColorFromOneMinusEntity((unsigned char*)tess.svars.colors);
break; break;
case CGEN_EXACT_VERTEX: case CGEN_EXACT_VERTEX:
if (!tess.vertexColorValid) {
ri.Printf(
PRINT_WARNING,
"Vertex color specified for shader '%s', but vertex colors are not valid for this model\n",
tess.shader->name);
break;
}
Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) ); Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) );
break; break;
case CGEN_CONST:
for ( i = 0; i < tess.numVertexes; i++ ) {
*(int *)tess.svars.colors[i] = *(int *)pStage->colorConst;
}
break;
case CGEN_VERTEX: case CGEN_VERTEX:
if ( tr.identityLight == 1 ) if (!tess.vertexColorValid) {
ri.Printf(
PRINT_WARNING,
"Vertex color specified for shader '%s', but vertex colors are not valid for this model\n",
tess.shader->name);
break;
}
if (tr.identityLight == 1)
{ {
Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) ); Com_Memcpy(tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof(tess.vertexColors[0]));
} }
else else
{ {
for ( i = 0; i < tess.numVertexes; i++ ) for (i = 0; i < tess.numVertexes; i++)
{ {
tess.svars.colors[i][0] = tess.vertexColors[i][0] * tr.identityLight; tess.svars.colors[i][0] = tess.vertexColors[i][0] * tr.identityLight;
tess.svars.colors[i][1] = tess.vertexColors[i][1] * tr.identityLight; tess.svars.colors[i][1] = tess.vertexColors[i][1] * tr.identityLight;
@ -740,25 +752,56 @@ static void ComputeColors( shaderStage_t *pStage )
} }
} }
break; break;
case CGEN_FOG:
{
fog_t *fog;
fog = tr.world->fogs + tess.fogNum;
for ( i = 0; i < tess.numVertexes; i++ ) {
* ( int * )&tess.svars.colors[i] = fog->colorInt;
}
}
break;
case CGEN_WAVEFORM: case CGEN_WAVEFORM:
RB_CalcWaveColor( &pStage->rgbWave, ( unsigned char * ) tess.svars.colors ); RB_CalcWaveColor(&pStage->rgbWave, (unsigned char*)tess.svars.colors, NULL);
break; break;
case CGEN_ENTITY: case CGEN_MULTIPLY_BY_WAVEFORM:
RB_CalcColorFromEntity( ( unsigned char * ) tess.svars.colors ); RB_CalcWaveColor(&pStage->rgbWave, (unsigned char*)tess.svars.colors, pStage->colorConst);
break; break;
case CGEN_ONE_MINUS_ENTITY: case CGEN_LIGHTING_GRID:
RB_CalcColorFromOneMinusEntity( ( unsigned char * ) tess.svars.colors ); RB_CalcLightGridColor((unsigned int*)tess.svars.colors);
break;
case CGEN_LIGHTING_SPHERICAL:
case CGEN_STATIC:
if (!r_drawspherelights->integer)
break;
// FIXME: unimplemented
break;
case CGEN_CONSTANT:
RB_CalcColorFromConstant((unsigned char*)tess.svars.colors, pStage->colorConst);
break;
case CGEN_GLOBAL_COLOR:
RB_CalcColorFromConstant((unsigned char*)tess.svars.colors, backEnd.color2D);
break;
case CGEN_SCOORD:
RB_CalcRGBFromTexCoords(
(unsigned char*)tess.svars.colors,
pStage->alphaMin,
pStage->alphaMax,
pStage->alphaConstMin,
pStage->alphaConst,
1.0,
0.0,
tess.svars.texcoords[0][0]
);
break;
case CGEN_TCOORD:
RB_CalcRGBFromTexCoords(
(unsigned char*)tess.svars.colors,
pStage->alphaMin,
pStage->alphaMax,
pStage->alphaConstMin,
pStage->alphaConst,
0.0,
1.0,
tess.svars.texcoords[0][0]
);
break;
case CGEN_DOT:
RB_CalcRGBFromDot((unsigned char*)tess.svars.colors, pStage->alphaMin, pStage->alphaMax);
break;
case CGEN_ONE_MINUS_DOT:
RB_CalcRGBFromOneMinusDot((unsigned char*)tess.svars.colors, pStage->alphaMin, pStage->alphaMax);
break; break;
} }
@ -779,38 +822,31 @@ static void ComputeColors( shaderStage_t *pStage )
} }
} }
break; break;
case AGEN_CONSTANT:
if ( pStage->rgbGen != CGEN_CONST ) {
for ( i = 0; i < tess.numVertexes; i++ ) {
tess.svars.colors[i][3] = pStage->colorConst[3];
}
}
break;
case AGEN_WAVEFORM:
RB_CalcWaveAlpha( &pStage->alphaWave, ( unsigned char * ) tess.svars.colors );
break;
case AGEN_LIGHTING_SPECULAR:
RB_CalcSpecularAlpha( ( unsigned char * ) tess.svars.colors );
break;
case AGEN_ENTITY: case AGEN_ENTITY:
RB_CalcAlphaFromEntity( ( unsigned char * ) tess.svars.colors ); RB_CalcAlphaFromEntity((unsigned char*)tess.svars.colors);
break; break;
case AGEN_ONE_MINUS_ENTITY: case AGEN_ONE_MINUS_ENTITY:
RB_CalcAlphaFromOneMinusEntity( ( unsigned char * ) tess.svars.colors ); RB_CalcAlphaFromOneMinusEntity((unsigned char*)tess.svars.colors);
break; break;
case AGEN_VERTEX: case AGEN_VERTEX:
if ( pStage->rgbGen != CGEN_VERTEX ) { if (pStage->rgbGen != CGEN_VERTEX) {
for ( i = 0; i < tess.numVertexes; i++ ) { for (i = 0; i < tess.numVertexes; i++) {
tess.svars.colors[i][3] = tess.vertexColors[i][3]; tess.svars.colors[i][3] = tess.vertexColors[i][3];
} }
} }
break; break;
case AGEN_ONE_MINUS_VERTEX: case AGEN_ONE_MINUS_VERTEX:
for ( i = 0; i < tess.numVertexes; i++ ) for (i = 0; i < tess.numVertexes; i++)
{ {
tess.svars.colors[i][3] = 255 - tess.vertexColors[i][3]; tess.svars.colors[i][3] = 255 - tess.vertexColors[i][3];
} }
break; break;
case AGEN_LIGHTING_SPECULAR:
RB_CalcSpecularAlpha((unsigned char*)tess.svars.colors, pStage->alphaMax, pStage->specOrigin);
break;
case AGEN_WAVEFORM:
RB_CalcWaveAlpha(&pStage->alphaWave, (unsigned char*)tess.svars.colors);
break;
case AGEN_PORTAL: case AGEN_PORTAL:
{ {
unsigned char alpha; unsigned char alpha;
@ -842,6 +878,62 @@ static void ComputeColors( shaderStage_t *pStage )
} }
} }
break; break;
case AGEN_DOT:
RB_CalcAlphaFromDot((unsigned char*)tess.svars.colors, pStage->alphaMin, pStage->alphaMax);
return;
case AGEN_ONE_MINUS_DOT:
RB_CalcAlphaFromOneMinusDot((unsigned char*)tess.svars.colors, pStage->alphaMin, pStage->alphaMax);
return;
case AGEN_CONSTANT:
RB_CalcAlphaFromConstant((unsigned char*)tess.svars.colors, pStage->colorConst[3]);
break;
case AGEN_GLOBAL_ALPHA:
RB_CalcAlphaFromConstant((unsigned char*)tess.svars.colors, backEnd.color2D[3]);
break;
case AGEN_SKYALPHA:
RB_CalcAlphaFromConstant((unsigned char*)tess.svars.colors, tr.refdef.sky_alpha * 255.0);
break;
case AGEN_ONE_MINUS_SKYALPHA:
RB_CalcAlphaFromConstant((unsigned char*)tess.svars.colors, (1.0 - tr.refdef.sky_alpha) * 255.0);
break;
case AGEN_SCOORD:
RB_CalcAlphaFromTexCoords(
(unsigned char*)tess.svars.colors,
pStage->alphaMin,
pStage->alphaMax,
pStage->alphaConstMin,
pStage->alphaConst,
1.0,
0.0,
tess.svars.texcoords[0][0]
);
break;
case AGEN_TCOORD:
RB_CalcAlphaFromTexCoords(
(unsigned char*)tess.svars.colors,
pStage->alphaMin,
pStage->alphaMax,
pStage->alphaConstMin,
pStage->alphaConst,
0.0,
1.0,
tess.svars.texcoords[0][0]
);
break;
case AGEN_DIST_FADE:
// FIXME: unimplemented
break;
case AGEN_ONE_MINUS_DIST_FADE:
// FIXME: unimplemented
break;
case AGEN_DOT_VIEW:
RB_CalcAlphaFromDotView((unsigned char*)tess.svars.colors, pStage->alphaMin, pStage->alphaMax);
break;
case AGEN_ONE_MINUS_DOT_VIEW:
RB_CalcAlphaFromOneMinusDotView((unsigned char*)tess.svars.colors, pStage->alphaMin, pStage->alphaMax);
break;
default:
break;
} }
} }

View file

@ -262,7 +262,7 @@ Change a polygon into a bunch of text polygons
void DeformText( const char *text ) { void DeformText( const char *text ) {
int i; int i;
vec3_t origin, width, height; vec3_t origin, width, height;
int len; size_t len;
int ch; int ch;
byte color[4]; byte color[4];
float bottom, top; float bottom, top;
@ -632,6 +632,60 @@ void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors )
} }
} }
/*
** RB_CalcColorFromConstant
*/
void RB_CalcColorFromConstant(unsigned char* dstColors, unsigned char* constantColor)
{
int i;
for (i = 0; i < tess.numVertexes; i++) {
dstColors[i * 4] = constantColor[i * 4];
dstColors[i * 4 + 1] = constantColor[i * 4 + 1];
dstColors[i * 4 + 2] = constantColor[i * 4 + 2];
dstColors[i * 4 + 3] = constantColor[i * 4 + 3];
}
}
void RB_CalcRGBFromDot(unsigned char* colors, float alphaMin, float alphaMax)
{
// FIXME: unimplemented
}
void RB_CalcRGBFromOneMinusDot(unsigned char* colors, float alphaMin, float alphaMax)
{
// FIXME: unimplemented
}
void RB_CalcAlphaFromConstant(unsigned char* dstColors, int constantAlpha)
{
int i;
for (i = 0; i < tess.numVertexes; i++) {
dstColors[i * 4 + 3] = constantAlpha;
}
}
void RB_CalcAlphaFromDot(unsigned char* colors, float alphaMin, float alphaMax)
{
// FIXME: unimplemented
}
void RB_CalcAlphaFromOneMinusDot(unsigned char* colors, float alphaMin, float alphaMax)
{
// FIXME: unimplemented
}
void RB_CalcAlphaFromTexCoords(unsigned char* colors, float alphaMin, float alphaMax, int alphaMinCap, int alphaCap, float sWeight, float tWeight, float* st)
{
// FIXME: unimplemented
}
void RB_CalcRGBFromTexCoords(unsigned char* colors, float alphaMin, float alphaMax, int alphaMinCap, int alphaCap, float sWeight, float tWeight, float* st)
{
// FIXME: unimplemented
}
/* /*
** RB_CalcAlphaFromEntity ** RB_CalcAlphaFromEntity
*/ */
@ -671,7 +725,7 @@ void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors )
/* /*
** RB_CalcWaveColor ** RB_CalcWaveColor
*/ */
void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors ) void RB_CalcWaveColor(const waveForm_t* wf, unsigned char* dstColors, unsigned char* constantColor)
{ {
int i; int i;
int v; int v;
@ -693,10 +747,20 @@ void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors )
glow = 1; glow = 1;
} }
v = myftol( 255 * glow ); if (constantColor)
color[0] = color[1] = color[2] = v; {
color[0] = constantColor[0] * glow;
color[1] = constantColor[1] * glow;
color[2] = constantColor[2] * glow;
}
else
{
v = myftol(255 * glow);
color[0] = color[1] = color[2] = v;
}
color[3] = 255; color[3] = 255;
v = *(int *)color; v = *(int*)color;
for ( i = 0; i < tess.numVertexes; i++, colors++ ) { for ( i = 0; i < tess.numVertexes; i++, colors++ ) {
*colors = v; *colors = v;
@ -1034,7 +1098,7 @@ long myftol( float f ) {
*/ */
vec3_t lightOrigin = { -960, 1980, 96 }; // FIXME: track dynamically vec3_t lightOrigin = { -960, 1980, 96 }; // FIXME: track dynamically
void RB_CalcSpecularAlpha( unsigned char *alphas ) { void RB_CalcSpecularAlpha(unsigned char* alphas, float alphaMax, vec3_t lightOrigin) {
int i; int i;
float *v, *normal; float *v, *normal;
vec3_t viewer, reflected; vec3_t viewer, reflected;

View file

@ -853,7 +853,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
stage->colorConst[1] = 255 * color[1]; stage->colorConst[1] = 255 * color[1];
stage->colorConst[2] = 255 * color[2]; stage->colorConst[2] = 255 * color[2];
stage->rgbGen = CGEN_CONST; stage->rgbGen = CGEN_CONSTANT;
} }
else if ( !Q_stricmp( token, "identity" ) ) else if ( !Q_stricmp( token, "identity" ) )
{ {
@ -882,9 +882,13 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
{ {
stage->rgbGen = CGEN_EXACT_VERTEX; stage->rgbGen = CGEN_EXACT_VERTEX;
} }
else if ( !Q_stricmp( token, "lightingDiffuse" ) ) else if ( !Q_stricmp( token, "lightingGrid" ) )
{ {
stage->rgbGen = CGEN_LIGHTING_DIFFUSE; stage->rgbGen = CGEN_LIGHTING_GRID;
}
else if ( !Q_stricmp( token, "lightingSpherical" ) )
{
stage->rgbGen = CGEN_LIGHTING_SPHERICAL;
} }
else if ( !Q_stricmp( token, "oneMinusVertex" ) ) else if ( !Q_stricmp( token, "oneMinusVertex" ) )
{ {
@ -1084,7 +1088,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
// decide which agens we can skip // decide which agens we can skip
if ( stage->alphaGen == CGEN_IDENTITY ) { if ( stage->alphaGen == CGEN_IDENTITY ) {
if ( stage->rgbGen == CGEN_IDENTITY if ( stage->rgbGen == CGEN_IDENTITY
|| stage->rgbGen == CGEN_LIGHTING_DIFFUSE ) { || stage->rgbGen == CGEN_LIGHTING_GRID
|| stage->rgbGen == CGEN_LIGHTING_SPHERICAL ) {
stage->alphaGen = AGEN_SKIP; stage->alphaGen = AGEN_SKIP;
} }
} }
@ -1695,11 +1700,11 @@ static void ComputeStageIteratorFunc( void )
// //
if ( shader.numUnfoggedPasses == 1 ) if ( shader.numUnfoggedPasses == 1 )
{ {
if ( unfoggedStages[0].rgbGen == CGEN_LIGHTING_DIFFUSE ) if ( unfoggedStages[0].rgbGen == CGEN_LIGHTING_GRID || unfoggedStages[0].rgbGen == CGEN_LIGHTING_SPHERICAL )
{ {
if ( unfoggedStages[0].alphaGen == AGEN_IDENTITY ) if ( unfoggedStages[0].alphaGen == AGEN_IDENTITY || unfoggedStages[0].alphaGen == AGEN_SKIP)
{ {
if ( unfoggedStages[0].bundle[0].tcGen == TCGEN_TEXTURE ) if ( unfoggedStages[0].bundle[0].tcGen == TCGEN_TEXTURE && unfoggedStages[0].bundle[1].tcGen == TCGEN_LIGHTMAP)
{ {
if ( !shader.polygonOffset ) if ( !shader.polygonOffset )
{ {
@ -1722,7 +1727,7 @@ static void ComputeStageIteratorFunc( void )
// //
if ( shader.numUnfoggedPasses == 1 ) if ( shader.numUnfoggedPasses == 1 )
{ {
if ( ( unfoggedStages[0].rgbGen == CGEN_IDENTITY ) && ( unfoggedStages[0].alphaGen == AGEN_IDENTITY ) ) if ( ( unfoggedStages[0].rgbGen == CGEN_IDENTITY ) && ( unfoggedStages[0].alphaGen == AGEN_IDENTITY || unfoggedStages[0].alphaGen == AGEN_SKIP ) )
{ {
if ( unfoggedStages[0].bundle[0].tcGen == TCGEN_TEXTURE && if ( unfoggedStages[0].bundle[0].tcGen == TCGEN_TEXTURE &&
unfoggedStages[0].bundle[1].tcGen == TCGEN_LIGHTMAP ) unfoggedStages[0].bundle[1].tcGen == TCGEN_LIGHTMAP )
@ -2120,7 +2125,7 @@ static void VertexLightingCollapse( void ) {
unfoggedStages[0].stateBits &= ~( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS ); unfoggedStages[0].stateBits &= ~( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
unfoggedStages[0].stateBits |= GLS_DEPTHMASK_TRUE; unfoggedStages[0].stateBits |= GLS_DEPTHMASK_TRUE;
if ( shader.lightmapIndex == LIGHTMAP_NONE ) { if ( shader.lightmapIndex == LIGHTMAP_NONE ) {
unfoggedStages[0].rgbGen = CGEN_LIGHTING_DIFFUSE; unfoggedStages[0].rgbGen = CGEN_LIGHTING_GRID;
} else { } else {
unfoggedStages[0].rgbGen = CGEN_EXACT_VERTEX; unfoggedStages[0].rgbGen = CGEN_EXACT_VERTEX;
} }
@ -2203,10 +2208,6 @@ static shader_t *FinishShader( void ) {
for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) { for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) {
shaderStage_t *pStage = &unfoggedStages[stage]; shaderStage_t *pStage = &unfoggedStages[stage];
if ( !pStage->active ) {
break;
}
// check for a missing texture // check for a missing texture
if ( !pStage->bundle[0].image[0] ) { if ( !pStage->bundle[0].image[0] ) {
ri.Printf( PRINT_WARNING, "Shader %s has a stage with no image\n", shader.name ); ri.Printf( PRINT_WARNING, "Shader %s has a stage with no image\n", shader.name );
@ -2214,6 +2215,12 @@ static shader_t *FinishShader( void ) {
continue; continue;
} }
if (pStage->rgbGen == CGEN_LIGHTING_GRID) {
shader.needsLGrid = 1;
} else if (pStage->rgbGen == CGEN_LIGHTING_SPHERICAL || pStage->rgbGen == CGEN_STATIC) {
shader.needsLSpherical = 1;
}
// //
// default texture coordinate generation // default texture coordinate generation
// //
@ -2266,7 +2273,7 @@ static shader_t *FinishShader( void ) {
// //
// if we are in r_vertexLight mode, never use a lightmap texture // if we are in r_vertexLight mode, never use a lightmap texture
// //
if ( stage > 1 && ( r_vertexLight->integer || glConfig.hardwareType == GLHW_PERMEDIA2 ) ) { if ( stage > 1 && r_vertexLight->integer ) {
VertexLightingCollapse(); VertexLightingCollapse();
stage = 1; stage = 1;
hasLightmapStage = qfalse; hasLightmapStage = qfalse;
@ -2275,28 +2282,31 @@ static shader_t *FinishShader( void ) {
// //
// look for multitexture potential // look for multitexture potential
// //
if ( stage > 1 && CollapseMultitexture() ) { if (stage > 1 && qglActiveTextureARB) {
stage--; CollapseMultitexture();
};
// FIXME: fog shader
// fogonly shaders don't have any normal passes
if (stage == 0) {
shader.sort = SS_OPAQUE;
} }
if ( shader.lightmapIndex >= 0 && !hasLightmapStage ) { if (shader.lightmapIndex >= 0 && !hasLightmapStage) {
if (vertexLightmap) { ri.Printf(PRINT_DEVELOPER, "WARNING: shader '%s' has lightmap but no lightmap stage!\n", shader.name);
ri.Printf( PRINT_DEVELOPER, "WARNING: shader '%s' has VERTEX forced lightmap!\n", shader.name ); shader.lightmapIndex = LIGHTMAP_NONE;
} else {
ri.Printf( PRINT_DEVELOPER, "WARNING: shader '%s' has lightmap but no lightmap stage!\n", shader.name );
shader.lightmapIndex = LIGHTMAP_NONE;
}
} }
// //
// compute number of passes // compute number of passes
// //
shader.numUnfoggedPasses = stage; shader.numUnfoggedPasses = 0;
for (stage = 0; stage < MAX_SHADER_STAGES; stage++) {
// fogonly shaders don't have any normal passes shaderStage_t* pStage = &unfoggedStages[stage];
if ( stage == 0 ) { if (pStage->active) {
shader.sort = SS_FOG; shader.numUnfoggedPasses++;
}
} }
// determine which stage iterator function is appropriate // determine which stage iterator function is appropriate