📄 tr_shade.c
字号:
origin0 = dl->transformed[0];
origin1 = dl->transformed[1];
origin2 = dl->transformed[2];
#else
VectorCopy( dl->transformed, origin );
#endif
radius = dl->radius;
scale = 1.0f / radius;
floatColor[0] = dl->color[0] * 255.0f;
floatColor[1] = dl->color[1] * 255.0f;
floatColor[2] = dl->color[2] * 255.0f;
#if idppc_altivec
floatColorVec0 = vec_ld(0, floatColor);
floatColorVec1 = vec_ld(11, floatColor);
floatColorVec0 = vec_perm(floatColorVec0,floatColorVec0,floatColorVecPerm);
#endif
for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) {
#if idppc_altivec
vec_t dist0, dist1, dist2;
#else
vec3_t dist;
#endif
int clip;
backEnd.pc.c_dlightVertexes++;
#if idppc_altivec
//VectorSubtract( origin, tess.xyz[i], dist );
dist0 = origin0 - tess.xyz[i][0];
dist1 = origin1 - tess.xyz[i][1];
dist2 = origin2 - tess.xyz[i][2];
texCoords0 = 0.5f + dist0 * scale;
texCoords1 = 0.5f + dist1 * scale;
clip = 0;
if ( texCoords0 < 0.0f ) {
clip |= 1;
} else if ( texCoords0 > 1.0f ) {
clip |= 2;
}
if ( texCoords1 < 0.0f ) {
clip |= 4;
} else if ( texCoords1 > 1.0f ) {
clip |= 8;
}
texCoords[0] = texCoords0;
texCoords[1] = texCoords1;
// modulate the strength based on the height and color
if ( dist2 > radius ) {
clip |= 16;
modulate = 0.0f;
} else if ( dist2 < -radius ) {
clip |= 32;
modulate = 0.0f;
} else {
dist2 = Q_fabs(dist2);
if ( dist2 < radius * 0.5f ) {
modulate = 1.0f;
} else {
modulate = 2.0f * (radius - dist2) * scale;
}
}
clipBits[i] = clip;
modulateVec = vec_ld(0,(float *)&modulate);
modulateVec = vec_perm(modulateVec,modulateVec,modulatePerm);
colorVec = vec_madd(floatColorVec0,modulateVec,zero);
colorInt = vec_cts(colorVec,0); // RGBx
colorShort = vec_pack(colorInt,colorInt); // RGBxRGBx
colorChar = vec_packsu(colorShort,colorShort); // RGBxRGBxRGBxRGBx
colorChar = vec_sel(colorChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255
vec_ste((vector unsigned int)colorChar,0,(unsigned int *)colors); // store color
#else
VectorSubtract( origin, tess.xyz[i], dist );
texCoords[0] = 0.5f + dist[0] * scale;
texCoords[1] = 0.5f + dist[1] * scale;
clip = 0;
if ( texCoords[0] < 0.0f ) {
clip |= 1;
} else if ( texCoords[0] > 1.0f ) {
clip |= 2;
}
if ( texCoords[1] < 0.0f ) {
clip |= 4;
} else if ( texCoords[1] > 1.0f ) {
clip |= 8;
}
// modulate the strength based on the height and color
if ( dist[2] > radius ) {
clip |= 16;
modulate = 0.0f;
} else if ( dist[2] < -radius ) {
clip |= 32;
modulate = 0.0f;
} else {
dist[2] = Q_fabs(dist[2]);
if ( dist[2] < radius * 0.5f ) {
modulate = 1.0f;
} else {
modulate = 2.0f * (radius - dist[2]) * scale;
}
}
clipBits[i] = clip;
colors[0] = myftol(floatColor[0] * modulate);
colors[1] = myftol(floatColor[1] * modulate);
colors[2] = myftol(floatColor[2] * modulate);
colors[3] = 255;
#endif
}
// build a list of triangles that need light
numIndexes = 0;
for ( i = 0 ; i < tess.numIndexes ; i += 3 ) {
int a, b, c;
a = tess.indexes[i];
b = tess.indexes[i+1];
c = tess.indexes[i+2];
if ( clipBits[a] & clipBits[b] & clipBits[c] ) {
continue; // not lighted
}
hitIndexes[numIndexes] = a;
hitIndexes[numIndexes+1] = b;
hitIndexes[numIndexes+2] = c;
numIndexes += 3;
}
if ( !numIndexes ) {
continue;
}
qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] );
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray );
GL_Bind( tr.dlightImage );
// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
// where they aren't rendered
if ( dl->additive ) {
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
}
else {
GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
}
R_DrawElements( numIndexes, hitIndexes );
backEnd.pc.c_totalIndexes += numIndexes;
backEnd.pc.c_dlightIndexes += numIndexes;
}
}
/*
===================
RB_FogPass
Blends a fog texture on top of everything else
===================
*/
static void RB_FogPass( void ) {
fog_t *fog;
int i;
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] );
fog = tr.world->fogs + tess.fogNum;
for ( i = 0; i < tess.numVertexes; i++ ) {
* ( int * )&tess.svars.colors[i] = fog->colorInt;
}
RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[0] );
GL_Bind( tr.fogImage );
if ( tess.shader->fogPass == FP_EQUAL ) {
GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL );
} else {
GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
}
R_DrawElements( tess.numIndexes, tess.indexes );
}
/*
===============
ComputeColors
===============
*/
static void ComputeColors( shaderStage_t *pStage )
{
int i;
//
// rgbGen
//
switch ( pStage->rgbGen )
{
case CGEN_IDENTITY:
Com_Memset( tess.svars.colors, 0xff, tess.numVertexes * 4 );
break;
default:
case CGEN_IDENTITY_LIGHTING:
Com_Memset( tess.svars.colors, tr.identityLightByte, tess.numVertexes * 4 );
break;
case CGEN_LIGHTING_DIFFUSE:
RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors );
break;
case CGEN_EXACT_VERTEX:
Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) );
break;
case CGEN_CONST:
for ( i = 0; i < tess.numVertexes; i++ ) {
*(int *)tess.svars.colors[i] = *(int *)pStage->constantColor;
}
break;
case CGEN_VERTEX:
if ( tr.identityLight == 1 )
{
Com_Memcpy( tess.svars.colors, tess.vertexColors, tess.numVertexes * sizeof( tess.vertexColors[0] ) );
}
else
{
for ( i = 0; i < tess.numVertexes; i++ )
{
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][2] = tess.vertexColors[i][2] * tr.identityLight;
tess.svars.colors[i][3] = tess.vertexColors[i][3];
}
}
break;
case CGEN_ONE_MINUS_VERTEX:
if ( tr.identityLight == 1 )
{
for ( i = 0; i < tess.numVertexes; i++ )
{
tess.svars.colors[i][0] = 255 - tess.vertexColors[i][0];
tess.svars.colors[i][1] = 255 - tess.vertexColors[i][1];
tess.svars.colors[i][2] = 255 - tess.vertexColors[i][2];
}
}
else
{
for ( i = 0; i < tess.numVertexes; i++ )
{
tess.svars.colors[i][0] = ( 255 - tess.vertexColors[i][0] ) * tr.identityLight;
tess.svars.colors[i][1] = ( 255 - tess.vertexColors[i][1] ) * tr.identityLight;
tess.svars.colors[i][2] = ( 255 - tess.vertexColors[i][2] ) * tr.identityLight;
}
}
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:
RB_CalcWaveColor( &pStage->rgbWave, ( unsigned char * ) tess.svars.colors );
break;
case CGEN_ENTITY:
RB_CalcColorFromEntity( ( unsigned char * ) tess.svars.colors );
break;
case CGEN_ONE_MINUS_ENTITY:
RB_CalcColorFromOneMinusEntity( ( unsigned char * ) tess.svars.colors );
break;
}
//
// alphaGen
//
switch ( pStage->alphaGen )
{
case AGEN_SKIP:
break;
case AGEN_IDENTITY:
if ( pStage->rgbGen != CGEN_IDENTITY ) {
if ( ( pStage->rgbGen == CGEN_VERTEX && tr.identityLight != 1 ) ||
pStage->rgbGen != CGEN_VERTEX ) {
for ( i = 0; i < tess.numVertexes; i++ ) {
tess.svars.colors[i][3] = 0xff;
}
}
}
break;
case AGEN_CONST:
if ( pStage->rgbGen != CGEN_CONST ) {
for ( i = 0; i < tess.numVertexes; i++ ) {
tess.svars.colors[i][3] = pStage->constantColor[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:
RB_CalcAlphaFromEntity( ( unsigned char * ) tess.svars.colors );
break;
case AGEN_ONE_MINUS_ENTITY:
RB_CalcAlphaFromOneMinusEntity( ( unsigned char * ) tess.svars.colors );
break;
case AGEN_VERTEX:
if ( pStage->rgbGen != CGEN_VERTEX ) {
for ( i = 0; i < tess.numVertexes; i++ ) {
tess.svars.colors[i][3] = tess.vertexColors[i][3];
}
}
break;
case AGEN_ONE_MINUS_VERTEX:
for ( i = 0; i < tess.numVertexes; i++ )
{
tess.svars.colors[i][3] = 255 - tess.vertexColors[i][3];
}
break;
case AGEN_PORTAL:
{
unsigned char alpha;
for ( i = 0; i < tess.numVertexes; i++ )
{
float len;
vec3_t v;
VectorSubtract( tess.xyz[i], backEnd.viewParms.or.origin, v );
len = VectorLength( v );
len /= tess.shader->portalRange;
if ( len < 0 )
{
alpha = 0;
}
else if ( len > 1 )
{
alpha = 0xff;
}
else
{
alpha = len * 0xff;
}
tess.svars.colors[i][3] = alpha;
}
}
break;
}
//
// fog adjustment for colors to fade out as fog increases
//
if ( tess.fogNum )
{
switch ( pStage->adjustColorsForFog )
{
case ACFF_MODULATE_RGB:
RB_CalcModulateColorsByFog( ( unsigned char * ) tess.svars.colors );
break;
case ACFF_MODULATE_ALPHA:
RB_CalcModulateAlphasByFog( ( unsigned char * ) tess.svars.colors );
break;
case ACFF_MODULATE_RGBA:
RB_CalcModulateRGBAsByFog( ( unsigned char * ) tess.svars.colors );
break;
case ACFF_NONE:
break;
}
}
}
/*
===============
ComputeTexCoords
===============
*/
static void ComputeTexCoords( shaderStage_t *pStage ) {
int i;
int b;
for ( b = 0; b < NUM_TEXTURE_BUNDLES; b++ ) {
int tm;
//
// generate the texture coordinates
//
switch ( pStage->bundle[b].tcGen )
{
case TCGEN_IDENTITY:
Com_Memset( tess.svars.texcoords[b], 0, sizeof( float ) * 2 * tess.numVertexes );
break;
case TCGEN_TEXTURE:
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
tess.svars.texcoords[b][i][0] = tess.texCoords[i][0][0];
tess.svars.texcoords[b][i][1] = tess.texCoords[i][0][1];
}
break;
case TCGEN_LIGHTMAP:
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
tess.svars.texcoords[b][i][0] = tess.texCoords[i][1][0];
tess.svars.texcoords[b][i][1] = tess.texCoords[i][1][1];
}
break;
case TCGEN_VECTOR:
for ( i = 0 ; i < tess.numVertexes ; i++ ) {
tess.svars.texcoords[b][i][0] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[0] );
tess.svars.texcoords[b][i][1] = DotProduct( tess.xyz[i], pStage->bundle[b].tcGenVectors[1] );
}
break;
case TCGEN_FOG:
RB_CalcFogTexCoords( ( float * ) tess.svars.texcoords[b] );
break;
case TCGEN_ENVIRONMENT_MAPPED:
RB_CalcEnvironmentTexCoords( ( float * ) tess.svars.texcoords[b] );
break;
case TCGEN_BAD:
return;
}
//
// alter texture coordinates
//
for ( tm = 0; tm < pStage->bundle[b].numTexMods ; tm++ ) {
switch ( pStage->bundle[b].texMods[tm].type )
{
case TMOD_NONE:
tm = TR_MAX_TEXMODS; // break out of for loop
break;
case TMOD_TURBULENT:
RB_CalcTurbulentTexCoords( &pStage->bundle[b].texMods[tm].wave,
( float * ) tess.svars.texcoords[b] );
break;
case TMOD_ENTITY_TRANSLATE:
RB_CalcScrollTexCoords( backEnd.currentEntity->e.shaderTexCoord,
( float * ) tess.svars.texcoords[b] );
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -