- added tcMod atlas. Lets you have texture page atlases, and animate them!
- Entity alpha can animate them too (for animated compatible replacement smokepuffs for example)
This commit is contained in:
@@ -221,6 +221,16 @@ typedef struct {
|
||||
float frequency;
|
||||
} waveForm_t;
|
||||
|
||||
// leilei - texture atlases
|
||||
typedef struct {
|
||||
float width; // columns
|
||||
float height; // rows
|
||||
float fps; // frames per second
|
||||
int frame; // offset frame
|
||||
float mode; // 0 - static/anim 1 - entityalpha
|
||||
} atlas_t;
|
||||
|
||||
|
||||
#define TR_MAX_TEXMODS 4
|
||||
|
||||
typedef enum {
|
||||
@@ -231,6 +241,7 @@ typedef enum {
|
||||
TMOD_SCALE,
|
||||
TMOD_STRETCH,
|
||||
TMOD_LIGHTSCALE, // leilei - cel hack
|
||||
TMOD_ATLAS, // leilei - atlases
|
||||
TMOD_ROTATE,
|
||||
TMOD_ENTITY_TRANSLATE
|
||||
} texMod_t;
|
||||
@@ -266,6 +277,8 @@ typedef struct {
|
||||
// used for TMOD_SCROLL
|
||||
float scroll[2]; // s' = s + scroll[0] * time
|
||||
// t' = t + scroll[1] * time
|
||||
// leilei - used for TMOD_ATLAS
|
||||
atlas_t atlas;
|
||||
|
||||
// + = clockwise
|
||||
// - = counterclockwise
|
||||
@@ -2130,6 +2143,7 @@ void RB_CalcAlphaFromEntity( unsigned char *dstColors );
|
||||
void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors );
|
||||
void RB_CalcStretchTexCoords( const waveForm_t *wf, float *texCoords );
|
||||
void RB_CalcLightscaleTexCoords( float *texCoords );
|
||||
void RB_CalcAtlasTexCoords( const atlas_t *at, float *st );
|
||||
void RB_CalcColorFromEntity( unsigned char *dstColors );
|
||||
void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors );
|
||||
void RB_CalcSpecularAlpha( unsigned char *alphas );
|
||||
|
@@ -1296,6 +1296,11 @@ static void ComputeTexCoords( shaderStage_t *pStage ) {
|
||||
( float * ) tess.svars.texcoords[b] );
|
||||
break;
|
||||
|
||||
case TMOD_ATLAS:
|
||||
RB_CalcAtlasTexCoords( &pStage->bundle[b].texMods[tm].atlas,
|
||||
( float * ) tess.svars.texcoords[b] );
|
||||
break;
|
||||
|
||||
case TMOD_LIGHTSCALE:
|
||||
RB_CalcLightscaleTexCoords( ( float * ) tess.svars.texcoords[b] );
|
||||
break;
|
||||
|
@@ -1372,6 +1372,96 @@ void RB_CalcRotateTexCoords( float degsPerSecond, float *st )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** RB_CalcAtlasTexCoords
|
||||
*/
|
||||
|
||||
|
||||
// TODO: refactor. There is a loop in there for now
|
||||
|
||||
void RB_CalcAtlasTexCoords( const atlas_t *at, float *st )
|
||||
{
|
||||
float p;
|
||||
texModInfo_t tmi;
|
||||
int w = (int)at->width;
|
||||
int h = (int)at->height;
|
||||
|
||||
int framex, framey;
|
||||
|
||||
// modes:
|
||||
// 0 - static / animated
|
||||
// 1 - entity alpha (i.e. cgame rocket smoke)
|
||||
|
||||
if (at->mode == 1) // follow alpha modulation
|
||||
{
|
||||
int frametotal = w * h;
|
||||
float alha = ((0.25+backEnd.currentEntity->e.shaderRGBA[3]) / (tr.identityLight * 256.0f));
|
||||
int framethere = frametotal - ((frametotal * alha));
|
||||
int f;
|
||||
framex = 0;
|
||||
for(f=0; f<framethere; f++)
|
||||
{
|
||||
framex +=1;
|
||||
|
||||
if (framex >= w){
|
||||
framey +=1; // next row!
|
||||
framex = 0; // reset column
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else // static/animated
|
||||
{
|
||||
//
|
||||
// Process frame sequence for animation
|
||||
//
|
||||
|
||||
{
|
||||
int framethere = (tess.shaderTime * at->fps) + at->frame;
|
||||
|
||||
int f;
|
||||
framex = 0;
|
||||
for(f=0; f<framethere; f++)
|
||||
{
|
||||
framex +=1;
|
||||
|
||||
if (framex >= w){
|
||||
framey +=1; // next row!
|
||||
framex = 0; // reset column
|
||||
}
|
||||
if (framey >= h){
|
||||
framey = 0; // reset row
|
||||
framex = 0; // reset column
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// now use that information to alter our coordinates
|
||||
//
|
||||
|
||||
tmi.matrix[0][0] = 1.0f / w;
|
||||
tmi.matrix[1][0] = 0;
|
||||
tmi.matrix[2][0] = 0;
|
||||
tmi.translate[0] = ((1.0f / w) * framex);
|
||||
|
||||
tmi.matrix[0][1] = 0;
|
||||
tmi.matrix[1][1] = 1.0f / h;
|
||||
tmi.matrix[2][1] = 0;
|
||||
tmi.translate[1] = ((1.0f / h) * framey);
|
||||
|
||||
RB_CalcTransformTexCoords( &tmi, st );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** RB_CalcSpecularAlpha
|
||||
**
|
||||
|
@@ -955,6 +955,55 @@ static void ParseTexMod( char *_text, shaderStage_t *stage )
|
||||
|
||||
tmi->type = TMOD_STRETCH;
|
||||
}
|
||||
//
|
||||
// leilei - atlas
|
||||
//
|
||||
else if ( !Q_stricmp( token, "atlas" ) )
|
||||
{
|
||||
token = COM_ParseExt( text, qfalse );
|
||||
if ( token[0] == 0 )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: missing atlas parms in shader '%s'\n", shader.name );
|
||||
return;
|
||||
}
|
||||
tmi->atlas.mode = atof( token );
|
||||
|
||||
token = COM_ParseExt( text, qfalse );
|
||||
if ( token[0] == 0 )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: missing atlas parms in shader '%s'\n", shader.name );
|
||||
return;
|
||||
}
|
||||
tmi->atlas.frame = atof( token );
|
||||
|
||||
token = COM_ParseExt( text, qfalse );
|
||||
if ( token[0] == 0 )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: missing atlas parms in shader '%s'\n", shader.name );
|
||||
return;
|
||||
}
|
||||
tmi->atlas.fps = atof( token );
|
||||
|
||||
token = COM_ParseExt( text, qfalse );
|
||||
if ( token[0] == 0 )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: missing atlas parms in shader '%s'\n", shader.name );
|
||||
return;
|
||||
}
|
||||
tmi->atlas.width = atof( token );
|
||||
ri.Printf( PRINT_WARNING, "shader '%s' has width %f\n", shader.name, tmi->atlas.width );
|
||||
|
||||
token = COM_ParseExt( text, qfalse );
|
||||
if ( token[0] == 0 )
|
||||
{
|
||||
ri.Printf( PRINT_WARNING, "WARNING: missing atlas parms in shader '%s'\n", shader.name );
|
||||
return;
|
||||
}
|
||||
tmi->atlas.height = atof( token );
|
||||
|
||||
tmi->type = TMOD_ATLAS;
|
||||
}
|
||||
|
||||
else if ( !Q_stricmp( token, "lightscale" ) )
|
||||
{
|
||||
token = COM_ParseExt( text, qfalse );
|
||||
|
Reference in New Issue
Block a user