00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "tr_local.h"
00025
00026
00027 #define WAVEVALUE( table, base, amplitude, phase, freq ) ((base) + table[ myftol( ( ( (phase) + tess.shaderTime * (freq) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * (amplitude))
00028
00029 static float *TableForFunc( genFunc_t func )
00030 {
00031 switch ( func )
00032 {
00033 case GF_SIN:
00034 return tr.sinTable;
00035 case GF_TRIANGLE:
00036 return tr.triangleTable;
00037 case GF_SQUARE:
00038 return tr.squareTable;
00039 case GF_SAWTOOTH:
00040 return tr.sawToothTable;
00041 case GF_INVERSE_SAWTOOTH:
00042 return tr.inverseSawToothTable;
00043 case GF_NONE:
00044 default:
00045 break;
00046 }
00047
00048 ri.Error( ERR_DROP, "TableForFunc called with invalid function '%d' in shader '%s'\n", func, tess.shader->name );
00049 return NULL;
00050 }
00051
00052
00053
00054
00055
00056
00057 static float EvalWaveForm( const waveForm_t *wf )
00058 {
00059 float *table;
00060
00061 table = TableForFunc( wf->func );
00062
00063 return WAVEVALUE( table, wf->base, wf->amplitude, wf->phase, wf->frequency );
00064 }
00065
00066 static float EvalWaveFormClamped( const waveForm_t *wf )
00067 {
00068 float glow = EvalWaveForm( wf );
00069
00070 if ( glow < 0 )
00071 {
00072 return 0;
00073 }
00074
00075 if ( glow > 1 )
00076 {
00077 return 1;
00078 }
00079
00080 return glow;
00081 }
00082
00083
00084
00085
00086 void RB_CalcStretchTexCoords( const waveForm_t *wf, float *st )
00087 {
00088 float p;
00089 texModInfo_t tmi;
00090
00091 p = 1.0f / EvalWaveForm( wf );
00092
00093 tmi.matrix[0][0] = p;
00094 tmi.matrix[1][0] = 0;
00095 tmi.translate[0] = 0.5f - 0.5f * p;
00096
00097 tmi.matrix[0][1] = 0;
00098 tmi.matrix[1][1] = p;
00099 tmi.translate[1] = 0.5f - 0.5f * p;
00100
00101 RB_CalcTransformTexCoords( &tmi, st );
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 void RB_CalcDeformVertexes( deformStage_t *ds )
00119 {
00120 int i;
00121 vec3_t offset;
00122 float scale;
00123 float *xyz = ( float * ) tess.xyz;
00124 float *normal = ( float * ) tess.normal;
00125 float *table;
00126
00127 if ( ds->deformationWave.frequency == 0 )
00128 {
00129 scale = EvalWaveForm( &ds->deformationWave );
00130
00131 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
00132 {
00133 VectorScale( normal, scale, offset );
00134
00135 xyz[0] += offset[0];
00136 xyz[1] += offset[1];
00137 xyz[2] += offset[2];
00138 }
00139 }
00140 else
00141 {
00142 table = TableForFunc( ds->deformationWave.func );
00143
00144 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
00145 {
00146 float off = ( xyz[0] + xyz[1] + xyz[2] ) * ds->deformationSpread;
00147
00148 scale = WAVEVALUE( table, ds->deformationWave.base,
00149 ds->deformationWave.amplitude,
00150 ds->deformationWave.phase + off,
00151 ds->deformationWave.frequency );
00152
00153 VectorScale( normal, scale, offset );
00154
00155 xyz[0] += offset[0];
00156 xyz[1] += offset[1];
00157 xyz[2] += offset[2];
00158 }
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169 void RB_CalcDeformNormals( deformStage_t *ds ) {
00170 int i;
00171 float scale;
00172 float *xyz = ( float * ) tess.xyz;
00173 float *normal = ( float * ) tess.normal;
00174
00175 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) {
00176 scale = 0.98f;
00177 scale = R_NoiseGet4f( xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
00178 tess.shaderTime * ds->deformationWave.frequency );
00179 normal[ 0 ] += ds->deformationWave.amplitude * scale;
00180
00181 scale = 0.98f;
00182 scale = R_NoiseGet4f( 100 + xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
00183 tess.shaderTime * ds->deformationWave.frequency );
00184 normal[ 1 ] += ds->deformationWave.amplitude * scale;
00185
00186 scale = 0.98f;
00187 scale = R_NoiseGet4f( 200 + xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
00188 tess.shaderTime * ds->deformationWave.frequency );
00189 normal[ 2 ] += ds->deformationWave.amplitude * scale;
00190
00191 VectorNormalizeFast( normal );
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 void RB_CalcBulgeVertexes( deformStage_t *ds ) {
00202 int i;
00203 const float *st = ( const float * ) tess.texCoords[0];
00204 float *xyz = ( float * ) tess.xyz;
00205 float *normal = ( float * ) tess.normal;
00206 float now;
00207
00208 now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
00209
00210 for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
00211 int off;
00212 float scale;
00213
00214 off = (float)( FUNCTABLE_SIZE / (M_PI*2) ) * ( st[0] * ds->bulgeWidth + now );
00215
00216 scale = tr.sinTable[ off & FUNCTABLE_MASK ] * ds->bulgeHeight;
00217
00218 xyz[0] += normal[0] * scale;
00219 xyz[1] += normal[1] * scale;
00220 xyz[2] += normal[2] * scale;
00221 }
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 void RB_CalcMoveVertexes( deformStage_t *ds ) {
00233 int i;
00234 float *xyz;
00235 float *table;
00236 float scale;
00237 vec3_t offset;
00238
00239 table = TableForFunc( ds->deformationWave.func );
00240
00241 scale = WAVEVALUE( table, ds->deformationWave.base,
00242 ds->deformationWave.amplitude,
00243 ds->deformationWave.phase,
00244 ds->deformationWave.frequency );
00245
00246 VectorScale( ds->moveVector, scale, offset );
00247
00248 xyz = ( float * ) tess.xyz;
00249 for ( i = 0; i < tess.numVertexes; i++, xyz += 4 ) {
00250 VectorAdd( xyz, offset, xyz );
00251 }
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 void DeformText( const char *text ) {
00263 int i;
00264 vec3_t origin, width, height;
00265 int len;
00266 int ch;
00267 byte color[4];
00268 float bottom, top;
00269 vec3_t mid;
00270
00271 height[0] = 0;
00272 height[1] = 0;
00273 height[2] = -1;
00274 CrossProduct( tess.normal[0], height, width );
00275
00276
00277 VectorClear( mid );
00278 bottom = 999999;
00279 top = -999999;
00280 for ( i = 0 ; i < 4 ; i++ ) {
00281 VectorAdd( tess.xyz[i], mid, mid );
00282 if ( tess.xyz[i][2] < bottom ) {
00283 bottom = tess.xyz[i][2];
00284 }
00285 if ( tess.xyz[i][2] > top ) {
00286 top = tess.xyz[i][2];
00287 }
00288 }
00289 VectorScale( mid, 0.25f, origin );
00290
00291
00292 height[0] = 0;
00293 height[1] = 0;
00294 height[2] = ( top - bottom ) * 0.5f;
00295
00296 VectorScale( width, height[2] * -0.75f, width );
00297
00298
00299 len = strlen( text );
00300 VectorMA( origin, (len-1), width, origin );
00301
00302
00303 tess.numIndexes = 0;
00304 tess.numVertexes = 0;
00305
00306 color[0] = color[1] = color[2] = color[3] = 255;
00307
00308
00309 for ( i = 0 ; i < len ; i++ ) {
00310 ch = text[i];
00311 ch &= 255;
00312
00313 if ( ch != ' ' ) {
00314 int row, col;
00315 float frow, fcol, size;
00316
00317 row = ch>>4;
00318 col = ch&15;
00319
00320 frow = row*0.0625f;
00321 fcol = col*0.0625f;
00322 size = 0.0625f;
00323
00324 RB_AddQuadStampExt( origin, width, height, color, fcol, frow, fcol + size, frow + size );
00325 }
00326 VectorMA( origin, -2, width, origin );
00327 }
00328 }
00329
00330
00331
00332
00333
00334
00335 static void GlobalVectorToLocal( const vec3_t in, vec3_t out ) {
00336 out[0] = DotProduct( in, backEnd.or.axis[0] );
00337 out[1] = DotProduct( in, backEnd.or.axis[1] );
00338 out[2] = DotProduct( in, backEnd.or.axis[2] );
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 static void AutospriteDeform( void ) {
00350 int i;
00351 int oldVerts;
00352 float *xyz;
00353 vec3_t mid, delta;
00354 float radius;
00355 vec3_t left, up;
00356 vec3_t leftDir, upDir;
00357
00358 if ( tess.numVertexes & 3 ) {
00359 ri.Printf( PRINT_WARNING, "Autosprite shader %s had odd vertex count", tess.shader->name );
00360 }
00361 if ( tess.numIndexes != ( tess.numVertexes >> 2 ) * 6 ) {
00362 ri.Printf( PRINT_WARNING, "Autosprite shader %s had odd index count", tess.shader->name );
00363 }
00364
00365 oldVerts = tess.numVertexes;
00366 tess.numVertexes = 0;
00367 tess.numIndexes = 0;
00368
00369 if ( backEnd.currentEntity != &tr.worldEntity ) {
00370 GlobalVectorToLocal( backEnd.viewParms.or.axis[1], leftDir );
00371 GlobalVectorToLocal( backEnd.viewParms.or.axis[2], upDir );
00372 } else {
00373 VectorCopy( backEnd.viewParms.or.axis[1], leftDir );
00374 VectorCopy( backEnd.viewParms.or.axis[2], upDir );
00375 }
00376
00377 for ( i = 0 ; i < oldVerts ; i+=4 ) {
00378
00379 xyz = tess.xyz[i];
00380
00381 mid[0] = 0.25f * (xyz[0] + xyz[4] + xyz[8] + xyz[12]);
00382 mid[1] = 0.25f * (xyz[1] + xyz[5] + xyz[9] + xyz[13]);
00383 mid[2] = 0.25f * (xyz[2] + xyz[6] + xyz[10] + xyz[14]);
00384
00385 VectorSubtract( xyz, mid, delta );
00386 radius = VectorLength( delta ) * 0.707f;
00387
00388 VectorScale( leftDir, radius, left );
00389 VectorScale( upDir, radius, up );
00390
00391 if ( backEnd.viewParms.isMirror ) {
00392 VectorSubtract( vec3_origin, left, left );
00393 }
00394
00395
00396 if ( backEnd.currentEntity->e.nonNormalizedAxes ) {
00397 float axisLength;
00398 axisLength = VectorLength( backEnd.currentEntity->e.axis[0] );
00399 if ( !axisLength ) {
00400 axisLength = 0;
00401 } else {
00402 axisLength = 1.0f / axisLength;
00403 }
00404 VectorScale(left, axisLength, left);
00405 VectorScale(up, axisLength, up);
00406 }
00407
00408 RB_AddQuadStamp( mid, left, up, tess.vertexColors[i] );
00409 }
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 int edgeVerts[6][2] = {
00421 { 0, 1 },
00422 { 0, 2 },
00423 { 0, 3 },
00424 { 1, 2 },
00425 { 1, 3 },
00426 { 2, 3 }
00427 };
00428
00429 static void Autosprite2Deform( void ) {
00430 int i, j, k;
00431 int indexes;
00432 float *xyz;
00433 vec3_t forward;
00434
00435 if ( tess.numVertexes & 3 ) {
00436 ri.Printf( PRINT_WARNING, "Autosprite2 shader %s had odd vertex count", tess.shader->name );
00437 }
00438 if ( tess.numIndexes != ( tess.numVertexes >> 2 ) * 6 ) {
00439 ri.Printf( PRINT_WARNING, "Autosprite2 shader %s had odd index count", tess.shader->name );
00440 }
00441
00442 if ( backEnd.currentEntity != &tr.worldEntity ) {
00443 GlobalVectorToLocal( backEnd.viewParms.or.axis[0], forward );
00444 } else {
00445 VectorCopy( backEnd.viewParms.or.axis[0], forward );
00446 }
00447
00448
00449
00450
00451 for ( i = 0, indexes = 0 ; i < tess.numVertexes ; i+=4, indexes+=6 ) {
00452 float lengths[2];
00453 int nums[2];
00454 vec3_t mid[2];
00455 vec3_t major, minor;
00456 float *v1, *v2;
00457
00458
00459 xyz = tess.xyz[i];
00460
00461
00462 nums[0] = nums[1] = 0;
00463 lengths[0] = lengths[1] = 999999;
00464
00465 for ( j = 0 ; j < 6 ; j++ ) {
00466 float l;
00467 vec3_t temp;
00468
00469 v1 = xyz + 4 * edgeVerts[j][0];
00470 v2 = xyz + 4 * edgeVerts[j][1];
00471
00472 VectorSubtract( v1, v2, temp );
00473
00474 l = DotProduct( temp, temp );
00475 if ( l < lengths[0] ) {
00476 nums[1] = nums[0];
00477 lengths[1] = lengths[0];
00478 nums[0] = j;
00479 lengths[0] = l;
00480 } else if ( l < lengths[1] ) {
00481 nums[1] = j;
00482 lengths[1] = l;
00483 }
00484 }
00485
00486 for ( j = 0 ; j < 2 ; j++ ) {
00487 v1 = xyz + 4 * edgeVerts[nums[j]][0];
00488 v2 = xyz + 4 * edgeVerts[nums[j]][1];
00489
00490 mid[j][0] = 0.5f * (v1[0] + v2[0]);
00491 mid[j][1] = 0.5f * (v1[1] + v2[1]);
00492 mid[j][2] = 0.5f * (v1[2] + v2[2]);
00493 }
00494
00495
00496 VectorSubtract( mid[1], mid[0], major );
00497
00498
00499 CrossProduct( major, forward, minor );
00500 VectorNormalize( minor );
00501
00502
00503 for ( j = 0 ; j < 2 ; j++ ) {
00504 float l;
00505
00506 v1 = xyz + 4 * edgeVerts[nums[j]][0];
00507 v2 = xyz + 4 * edgeVerts[nums[j]][1];
00508
00509 l = 0.5 * sqrt( lengths[j] );
00510
00511
00512
00513 for ( k = 0 ; k < 5 ; k++ ) {
00514 if ( tess.indexes[ indexes + k ] == i + edgeVerts[nums[j]][0]
00515 && tess.indexes[ indexes + k + 1 ] == i + edgeVerts[nums[j]][1] ) {
00516 break;
00517 }
00518 }
00519
00520 if ( k == 5 ) {
00521 VectorMA( mid[j], l, minor, v1 );
00522 VectorMA( mid[j], -l, minor, v2 );
00523 } else {
00524 VectorMA( mid[j], -l, minor, v1 );
00525 VectorMA( mid[j], l, minor, v2 );
00526 }
00527 }
00528 }
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538 void RB_DeformTessGeometry( void ) {
00539 int i;
00540 deformStage_t *ds;
00541
00542 for ( i = 0 ; i < tess.shader->numDeforms ; i++ ) {
00543 ds = &tess.shader->deforms[ i ];
00544
00545 switch ( ds->deformation ) {
00546 case DEFORM_NONE:
00547 break;
00548 case DEFORM_NORMALS:
00549 RB_CalcDeformNormals( ds );
00550 break;
00551 case DEFORM_WAVE:
00552 RB_CalcDeformVertexes( ds );
00553 break;
00554 case DEFORM_BULGE:
00555 RB_CalcBulgeVertexes( ds );
00556 break;
00557 case DEFORM_MOVE:
00558 RB_CalcMoveVertexes( ds );
00559 break;
00560 case DEFORM_PROJECTION_SHADOW:
00561 RB_ProjectionShadowDeform();
00562 break;
00563 case DEFORM_AUTOSPRITE:
00564 AutospriteDeform();
00565 break;
00566 case DEFORM_AUTOSPRITE2:
00567 Autosprite2Deform();
00568 break;
00569 case DEFORM_TEXT0:
00570 case DEFORM_TEXT1:
00571 case DEFORM_TEXT2:
00572 case DEFORM_TEXT3:
00573 case DEFORM_TEXT4:
00574 case DEFORM_TEXT5:
00575 case DEFORM_TEXT6:
00576 case DEFORM_TEXT7:
00577 DeformText( backEnd.refdef.text[ds->deformation - DEFORM_TEXT0] );
00578 break;
00579 }
00580 }
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 void RB_CalcColorFromEntity( unsigned char *dstColors )
00596 {
00597 int i;
00598 int *pColors = ( int * ) dstColors;
00599 int c;
00600
00601 if ( !backEnd.currentEntity )
00602 return;
00603
00604 c = * ( int * ) backEnd.currentEntity->e.shaderRGBA;
00605
00606 for ( i = 0; i < tess.numVertexes; i++, pColors++ )
00607 {
00608 *pColors = c;
00609 }
00610 }
00611
00612
00613
00614
00615 void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors )
00616 {
00617 int i;
00618 int *pColors = ( int * ) dstColors;
00619 unsigned char invModulate[3];
00620 int c;
00621
00622 if ( !backEnd.currentEntity )
00623 return;
00624
00625 invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0];
00626 invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1];
00627 invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2];
00628 invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3];
00629
00630 c = * ( int * ) invModulate;
00631
00632 for ( i = 0; i < tess.numVertexes; i++, pColors++ )
00633 {
00634 *pColors = * ( int * ) invModulate;
00635 }
00636 }
00637
00638
00639
00640
00641 void RB_CalcAlphaFromEntity( unsigned char *dstColors )
00642 {
00643 int i;
00644
00645 if ( !backEnd.currentEntity )
00646 return;
00647
00648 dstColors += 3;
00649
00650 for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
00651 {
00652 *dstColors = backEnd.currentEntity->e.shaderRGBA[3];
00653 }
00654 }
00655
00656
00657
00658
00659 void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors )
00660 {
00661 int i;
00662
00663 if ( !backEnd.currentEntity )
00664 return;
00665
00666 dstColors += 3;
00667
00668 for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
00669 {
00670 *dstColors = 0xff - backEnd.currentEntity->e.shaderRGBA[3];
00671 }
00672 }
00673
00674
00675
00676
00677 void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors )
00678 {
00679 int i;
00680 int v;
00681 float glow;
00682 int *colors = ( int * ) dstColors;
00683 byte color[4];
00684
00685
00686 if ( wf->func == GF_NOISE ) {
00687 glow = wf->base + R_NoiseGet4f( 0, 0, 0, ( tess.shaderTime + wf->phase ) * wf->frequency ) * wf->amplitude;
00688 } else {
00689 glow = EvalWaveForm( wf ) * tr.identityLight;
00690 }
00691
00692 if ( glow < 0 ) {
00693 glow = 0;
00694 }
00695 else if ( glow > 1 ) {
00696 glow = 1;
00697 }
00698
00699 v = myftol( 255 * glow );
00700 color[0] = color[1] = color[2] = v;
00701 color[3] = 255;
00702 v = *(int *)color;
00703
00704 for ( i = 0; i < tess.numVertexes; i++, colors++ ) {
00705 *colors = v;
00706 }
00707 }
00708
00709
00710
00711
00712 void RB_CalcWaveAlpha( const waveForm_t *wf, unsigned char *dstColors )
00713 {
00714 int i;
00715 int v;
00716 float glow;
00717
00718 glow = EvalWaveFormClamped( wf );
00719
00720 v = 255 * glow;
00721
00722 for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
00723 {
00724 dstColors[3] = v;
00725 }
00726 }
00727
00728
00729
00730
00731 void RB_CalcModulateColorsByFog( unsigned char *colors ) {
00732 int i;
00733 float texCoords[SHADER_MAX_VERTEXES][2];
00734
00735
00736
00737
00738 RB_CalcFogTexCoords( texCoords[0] );
00739
00740 for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) {
00741 float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] );
00742 colors[0] *= f;
00743 colors[1] *= f;
00744 colors[2] *= f;
00745 }
00746 }
00747
00748
00749
00750
00751 void RB_CalcModulateAlphasByFog( unsigned char *colors ) {
00752 int i;
00753 float texCoords[SHADER_MAX_VERTEXES][2];
00754
00755
00756
00757
00758 RB_CalcFogTexCoords( texCoords[0] );
00759
00760 for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) {
00761 float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] );
00762 colors[3] *= f;
00763 }
00764 }
00765
00766
00767
00768
00769 void RB_CalcModulateRGBAsByFog( unsigned char *colors ) {
00770 int i;
00771 float texCoords[SHADER_MAX_VERTEXES][2];
00772
00773
00774
00775
00776 RB_CalcFogTexCoords( texCoords[0] );
00777
00778 for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) {
00779 float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] );
00780 colors[0] *= f;
00781 colors[1] *= f;
00782 colors[2] *= f;
00783 colors[3] *= f;
00784 }
00785 }
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 void RB_CalcFogTexCoords( float *st ) {
00806 int i;
00807 float *v;
00808 float s, t;
00809 float eyeT;
00810 qboolean eyeOutside;
00811 fog_t *fog;
00812 vec3_t local;
00813 vec4_t fogDistanceVector, fogDepthVector;
00814
00815 fog = tr.world->fogs + tess.fogNum;
00816
00817
00818 VectorSubtract( backEnd.or.origin, backEnd.viewParms.or.origin, local );
00819 fogDistanceVector[0] = -backEnd.or.modelMatrix[2];
00820 fogDistanceVector[1] = -backEnd.or.modelMatrix[6];
00821 fogDistanceVector[2] = -backEnd.or.modelMatrix[10];
00822 fogDistanceVector[3] = DotProduct( local, backEnd.viewParms.or.axis[0] );
00823
00824
00825 fogDistanceVector[0] *= fog->tcScale;
00826 fogDistanceVector[1] *= fog->tcScale;
00827 fogDistanceVector[2] *= fog->tcScale;
00828 fogDistanceVector[3] *= fog->tcScale;
00829
00830
00831 if ( fog->hasSurface ) {
00832 fogDepthVector[0] = fog->surface[0] * backEnd.or.axis[0][0] +
00833 fog->surface[1] * backEnd.or.axis[0][1] + fog->surface[2] * backEnd.or.axis[0][2];
00834 fogDepthVector[1] = fog->surface[0] * backEnd.or.axis[1][0] +
00835 fog->surface[1] * backEnd.or.axis[1][1] + fog->surface[2] * backEnd.or.axis[1][2];
00836 fogDepthVector[2] = fog->surface[0] * backEnd.or.axis[2][0] +
00837 fog->surface[1] * backEnd.or.axis[2][1] + fog->surface[2] * backEnd.or.axis[2][2];
00838 fogDepthVector[3] = -fog->surface[3] + DotProduct( backEnd.or.origin, fog->surface );
00839
00840 eyeT = DotProduct( backEnd.or.viewOrigin, fogDepthVector ) + fogDepthVector[3];
00841 } else {
00842 eyeT = 1;
00843 }
00844
00845
00846
00847
00848 if ( eyeT < 0 ) {
00849 eyeOutside = qtrue;
00850 } else {
00851 eyeOutside = qfalse;
00852 }
00853
00854 fogDistanceVector[3] += 1.0/512;
00855
00856
00857 for (i = 0, v = tess.xyz[0] ; i < tess.numVertexes ; i++, v += 4) {
00858
00859 s = DotProduct( v, fogDistanceVector ) + fogDistanceVector[3];
00860 t = DotProduct( v, fogDepthVector ) + fogDepthVector[3];
00861
00862
00863 if ( eyeOutside ) {
00864 if ( t < 1.0 ) {
00865 t = 1.0/32;
00866 } else {
00867 t = 1.0/32 + 30.0/32 * t / ( t - eyeT );
00868 }
00869 } else {
00870 if ( t < 0 ) {
00871 t = 1.0/32;
00872 } else {
00873 t = 31.0/32;
00874 }
00875 }
00876
00877 st[0] = s;
00878 st[1] = t;
00879 st += 2;
00880 }
00881 }
00882
00883
00884
00885
00886
00887
00888 void RB_CalcEnvironmentTexCoords( float *st )
00889 {
00890 int i;
00891 float *v, *normal;
00892 vec3_t viewer, reflected;
00893 float d;
00894
00895 v = tess.xyz[0];
00896 normal = tess.normal[0];
00897
00898 for (i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 )
00899 {
00900 VectorSubtract (backEnd.or.viewOrigin, v, viewer);
00901 VectorNormalizeFast (viewer);
00902
00903 d = DotProduct (normal, viewer);
00904
00905 reflected[0] = normal[0]*2*d - viewer[0];
00906 reflected[1] = normal[1]*2*d - viewer[1];
00907 reflected[2] = normal[2]*2*d - viewer[2];
00908
00909 st[0] = 0.5 + reflected[1] * 0.5;
00910 st[1] = 0.5 - reflected[2] * 0.5;
00911 }
00912 }
00913
00914
00915
00916
00917 void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st )
00918 {
00919 int i;
00920 float now;
00921
00922 now = ( wf->phase + tess.shaderTime * wf->frequency );
00923
00924 for ( i = 0; i < tess.numVertexes; i++, st += 2 )
00925 {
00926 float s = st[0];
00927 float t = st[1];
00928
00929 st[0] = s + tr.sinTable[ ( ( int ) ( ( ( tess.xyz[i][0] + tess.xyz[i][2] )* 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
00930 st[1] = t + tr.sinTable[ ( ( int ) ( ( tess.xyz[i][1] * 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
00931 }
00932 }
00933
00934
00935
00936
00937 void RB_CalcScaleTexCoords( const float scale[2], float *st )
00938 {
00939 int i;
00940
00941 for ( i = 0; i < tess.numVertexes; i++, st += 2 )
00942 {
00943 st[0] *= scale[0];
00944 st[1] *= scale[1];
00945 }
00946 }
00947
00948
00949
00950
00951 void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st )
00952 {
00953 int i;
00954 float timeScale = tess.shaderTime;
00955 float adjustedScrollS, adjustedScrollT;
00956
00957 adjustedScrollS = scrollSpeed[0] * timeScale;
00958 adjustedScrollT = scrollSpeed[1] * timeScale;
00959
00960
00961
00962 adjustedScrollS = adjustedScrollS - floor( adjustedScrollS );
00963 adjustedScrollT = adjustedScrollT - floor( adjustedScrollT );
00964
00965 for ( i = 0; i < tess.numVertexes; i++, st += 2 )
00966 {
00967 st[0] += adjustedScrollS;
00968 st[1] += adjustedScrollT;
00969 }
00970 }
00971
00972
00973
00974
00975 void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *st )
00976 {
00977 int i;
00978
00979 for ( i = 0; i < tess.numVertexes; i++, st += 2 )
00980 {
00981 float s = st[0];
00982 float t = st[1];
00983
00984 st[0] = s * tmi->matrix[0][0] + t * tmi->matrix[1][0] + tmi->translate[0];
00985 st[1] = s * tmi->matrix[0][1] + t * tmi->matrix[1][1] + tmi->translate[1];
00986 }
00987 }
00988
00989
00990
00991
00992 void RB_CalcRotateTexCoords( float degsPerSecond, float *st )
00993 {
00994 float timeScale = tess.shaderTime;
00995 float degs;
00996 int index;
00997 float sinValue, cosValue;
00998 texModInfo_t tmi;
00999
01000 degs = -degsPerSecond * timeScale;
01001 index = degs * ( FUNCTABLE_SIZE / 360.0f );
01002
01003 sinValue = tr.sinTable[ index & FUNCTABLE_MASK ];
01004 cosValue = tr.sinTable[ ( index + FUNCTABLE_SIZE / 4 ) & FUNCTABLE_MASK ];
01005
01006 tmi.matrix[0][0] = cosValue;
01007 tmi.matrix[1][0] = -sinValue;
01008 tmi.translate[0] = 0.5 - 0.5 * cosValue + 0.5 * sinValue;
01009
01010 tmi.matrix[0][1] = sinValue;
01011 tmi.matrix[1][1] = cosValue;
01012 tmi.translate[1] = 0.5 - 0.5 * sinValue - 0.5 * cosValue;
01013
01014 RB_CalcTransformTexCoords( &tmi, st );
01015 }
01016
01017
01018
01019
01020
01021
01022 #if id386 && !( (defined __linux__ || defined __FreeBSD__ ) && (defined __i386__ ) ) // rb010123
01023
01024 long myftol( float f ) {
01025 static int tmp;
01026 __asm fld f
01027 __asm fistp tmp
01028 __asm mov eax, tmp
01029 }
01030
01031 #endif
01032
01033
01034
01035
01036
01037
01038 vec3_t lightOrigin = { -960, 1980, 96 };
01039
01040 void RB_CalcSpecularAlpha( unsigned char *alphas ) {
01041 int i;
01042 float *v, *normal;
01043 vec3_t viewer, reflected;
01044 float l, d;
01045 int b;
01046 vec3_t lightDir;
01047 int numVertexes;
01048
01049 v = tess.xyz[0];
01050 normal = tess.normal[0];
01051
01052 alphas += 3;
01053
01054 numVertexes = tess.numVertexes;
01055 for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4, alphas += 4) {
01056 float ilength;
01057
01058 VectorSubtract( lightOrigin, v, lightDir );
01059
01060 VectorNormalizeFast( lightDir );
01061
01062
01063 d = DotProduct (normal, lightDir);
01064
01065
01066
01067
01068 reflected[0] = normal[0]*2*d - lightDir[0];
01069 reflected[1] = normal[1]*2*d - lightDir[1];
01070 reflected[2] = normal[2]*2*d - lightDir[2];
01071
01072 VectorSubtract (backEnd.or.viewOrigin, v, viewer);
01073 ilength = Q_rsqrt( DotProduct( viewer, viewer ) );
01074 l = DotProduct (reflected, viewer);
01075 l *= ilength;
01076
01077 if (l < 0) {
01078 b = 0;
01079 } else {
01080 l = l*l;
01081 l = l*l;
01082 b = l * 255;
01083 if (b > 255) {
01084 b = 255;
01085 }
01086 }
01087
01088 *alphas = b;
01089 }
01090 }
01091
01092
01093
01094
01095
01096
01097 void RB_CalcDiffuseColor( unsigned char *colors )
01098 {
01099 int i, j;
01100 float *v, *normal;
01101 float incoming;
01102 trRefEntity_t *ent;
01103 int ambientLightInt;
01104 vec3_t ambientLight;
01105 vec3_t lightDir;
01106 vec3_t directedLight;
01107 int numVertexes;
01108 #if idppc_altivec
01109 vector unsigned char vSel = (vector unsigned char)(0x00, 0x00, 0x00, 0xff,
01110 0x00, 0x00, 0x00, 0xff,
01111 0x00, 0x00, 0x00, 0xff,
01112 0x00, 0x00, 0x00, 0xff);
01113 vector float ambientLightVec;
01114 vector float directedLightVec;
01115 vector float lightDirVec;
01116 vector float normalVec0, normalVec1;
01117 vector float incomingVec0, incomingVec1, incomingVec2;
01118 vector float zero, jVec;
01119 vector signed int jVecInt;
01120 vector signed short jVecShort;
01121 vector unsigned char jVecChar, normalPerm;
01122 #endif
01123 ent = backEnd.currentEntity;
01124 ambientLightInt = ent->ambientLightInt;
01125 #if idppc_altivec
01126
01127
01128 jVecChar = vec_lvsl(0, ent->ambientLight);
01129 ambientLightVec = vec_ld(0, (vector float *)ent->ambientLight);
01130 jVec = vec_ld(11, (vector float *)ent->ambientLight);
01131 ambientLightVec = vec_perm(ambientLightVec,jVec,jVecChar);
01132
01133 jVecChar = vec_lvsl(0, ent->directedLight);
01134 directedLightVec = vec_ld(0,(vector float *)ent->directedLight);
01135 jVec = vec_ld(11,(vector float *)ent->directedLight);
01136 directedLightVec = vec_perm(directedLightVec,jVec,jVecChar);
01137
01138 jVecChar = vec_lvsl(0, ent->lightDir);
01139 lightDirVec = vec_ld(0,(vector float *)ent->lightDir);
01140 jVec = vec_ld(11,(vector float *)ent->lightDir);
01141 lightDirVec = vec_perm(lightDirVec,jVec,jVecChar);
01142
01143 zero = (vector float)vec_splat_s8(0);
01144 VectorCopy( ent->lightDir, lightDir );
01145 #else
01146 VectorCopy( ent->ambientLight, ambientLight );
01147 VectorCopy( ent->directedLight, directedLight );
01148 VectorCopy( ent->lightDir, lightDir );
01149 #endif
01150
01151 v = tess.xyz[0];
01152 normal = tess.normal[0];
01153
01154 #if idppc_altivec
01155 normalPerm = vec_lvsl(0,normal);
01156 #endif
01157 numVertexes = tess.numVertexes;
01158 for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
01159 #if idppc_altivec
01160 normalVec0 = vec_ld(0,(vector float *)normal);
01161 normalVec1 = vec_ld(11,(vector float *)normal);
01162 normalVec0 = vec_perm(normalVec0,normalVec1,normalPerm);
01163 incomingVec0 = vec_madd(normalVec0, lightDirVec, zero);
01164 incomingVec1 = vec_sld(incomingVec0,incomingVec0,4);
01165 incomingVec2 = vec_add(incomingVec0,incomingVec1);
01166 incomingVec1 = vec_sld(incomingVec1,incomingVec1,4);
01167 incomingVec2 = vec_add(incomingVec2,incomingVec1);
01168 incomingVec0 = vec_splat(incomingVec2,0);
01169 incomingVec0 = vec_max(incomingVec0,zero);
01170 normalPerm = vec_lvsl(12,normal);
01171 jVec = vec_madd(incomingVec0, directedLightVec, ambientLightVec);
01172 jVecInt = vec_cts(jVec,0);
01173 jVecShort = vec_pack(jVecInt,jVecInt);
01174 jVecChar = vec_packsu(jVecShort,jVecShort);
01175 jVecChar = vec_sel(jVecChar,vSel,vSel);
01176 vec_ste((vector unsigned int)jVecChar,0,(unsigned int *)&colors[i*4]);
01177 #else
01178 incoming = DotProduct (normal, lightDir);
01179 if ( incoming <= 0 ) {
01180 *(int *)&colors[i*4] = ambientLightInt;
01181 continue;
01182 }
01183 j = myftol( ambientLight[0] + incoming * directedLight[0] );
01184 if ( j > 255 ) {
01185 j = 255;
01186 }
01187 colors[i*4+0] = j;
01188
01189 j = myftol( ambientLight[1] + incoming * directedLight[1] );
01190 if ( j > 255 ) {
01191 j = 255;
01192 }
01193 colors[i*4+1] = j;
01194
01195 j = myftol( ambientLight[2] + incoming * directedLight[2] );
01196 if ( j > 255 ) {
01197 j = 255;
01198 }
01199 colors[i*4+2] = j;
01200
01201 colors[i*4+3] = 255;
01202 #endif
01203 }
01204 }
01205