- 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:
leilei-
2016-05-19 06:57:02 -04:00
parent d31b9ad6d9
commit 5c4712f192
4 changed files with 158 additions and 0 deletions

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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
**

View File

@@ -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 );