/quake3/trunk/code/renderer/tr_shade_calc.c

# · C · 1207 lines · 787 code · 203 blank · 217 comment · 97 complexity · c1c068241dc707d3aa9d9f3789198db8 MD5 · raw file

  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. // tr_shade_calc.c
  19. #include "tr_local.h"
  20. #define WAVEVALUE( table, base, amplitude, phase, freq ) ((base) + table[ myftol( ( ( (phase) + tess.shaderTime * (freq) ) * FUNCTABLE_SIZE ) ) & FUNCTABLE_MASK ] * (amplitude))
  21. static float *TableForFunc( genFunc_t func )
  22. {
  23. switch ( func )
  24. {
  25. case GF_SIN:
  26. return tr.sinTable;
  27. case GF_TRIANGLE:
  28. return tr.triangleTable;
  29. case GF_SQUARE:
  30. return tr.squareTable;
  31. case GF_SAWTOOTH:
  32. return tr.sawToothTable;
  33. case GF_INVERSE_SAWTOOTH:
  34. return tr.inverseSawToothTable;
  35. case GF_NONE:
  36. default:
  37. break;
  38. }
  39. ri.Error( ERR_DROP, "TableForFunc called with invalid function '%d' in shader '%s'\n", func, tess.shader->name );
  40. return NULL;
  41. }
  42. /*
  43. ** EvalWaveForm
  44. **
  45. ** Evaluates a given waveForm_t, referencing backEnd.refdef.time directly
  46. */
  47. static float EvalWaveForm( const waveForm_t *wf )
  48. {
  49. float *table;
  50. table = TableForFunc( wf->func );
  51. return WAVEVALUE( table, wf->base, wf->amplitude, wf->phase, wf->frequency );
  52. }
  53. static float EvalWaveFormClamped( const waveForm_t *wf )
  54. {
  55. float glow = EvalWaveForm( wf );
  56. if ( glow < 0 )
  57. {
  58. return 0;
  59. }
  60. if ( glow > 1 )
  61. {
  62. return 1;
  63. }
  64. return glow;
  65. }
  66. /*
  67. ** RB_CalcStretchTexCoords
  68. */
  69. void RB_CalcStretchTexCoords( const waveForm_t *wf, float *st )
  70. {
  71. float p;
  72. texModInfo_t tmi;
  73. p = 1.0f / EvalWaveForm( wf );
  74. tmi.matrix[0][0] = p;
  75. tmi.matrix[1][0] = 0;
  76. tmi.translate[0] = 0.5f - 0.5f * p;
  77. tmi.matrix[0][1] = 0;
  78. tmi.matrix[1][1] = p;
  79. tmi.translate[1] = 0.5f - 0.5f * p;
  80. RB_CalcTransformTexCoords( &tmi, st );
  81. }
  82. /*
  83. ====================================================================
  84. DEFORMATIONS
  85. ====================================================================
  86. */
  87. /*
  88. ========================
  89. RB_CalcDeformVertexes
  90. ========================
  91. */
  92. void RB_CalcDeformVertexes( deformStage_t *ds )
  93. {
  94. int i;
  95. vec3_t offset;
  96. float scale;
  97. float *xyz = ( float * ) tess.xyz;
  98. float *normal = ( float * ) tess.normal;
  99. float *table;
  100. if ( ds->deformationWave.frequency == 0 )
  101. {
  102. scale = EvalWaveForm( &ds->deformationWave );
  103. for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
  104. {
  105. VectorScale( normal, scale, offset );
  106. xyz[0] += offset[0];
  107. xyz[1] += offset[1];
  108. xyz[2] += offset[2];
  109. }
  110. }
  111. else
  112. {
  113. table = TableForFunc( ds->deformationWave.func );
  114. for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 )
  115. {
  116. float off = ( xyz[0] + xyz[1] + xyz[2] ) * ds->deformationSpread;
  117. scale = WAVEVALUE( table, ds->deformationWave.base,
  118. ds->deformationWave.amplitude,
  119. ds->deformationWave.phase + off,
  120. ds->deformationWave.frequency );
  121. VectorScale( normal, scale, offset );
  122. xyz[0] += offset[0];
  123. xyz[1] += offset[1];
  124. xyz[2] += offset[2];
  125. }
  126. }
  127. }
  128. /*
  129. =========================
  130. RB_CalcDeformNormals
  131. Wiggle the normals for wavy environment mapping
  132. =========================
  133. */
  134. void RB_CalcDeformNormals( deformStage_t *ds ) {
  135. int i;
  136. float scale;
  137. float *xyz = ( float * ) tess.xyz;
  138. float *normal = ( float * ) tess.normal;
  139. for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) {
  140. scale = 0.98f;
  141. scale = R_NoiseGet4f( xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
  142. tess.shaderTime * ds->deformationWave.frequency );
  143. normal[ 0 ] += ds->deformationWave.amplitude * scale;
  144. scale = 0.98f;
  145. scale = R_NoiseGet4f( 100 + xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
  146. tess.shaderTime * ds->deformationWave.frequency );
  147. normal[ 1 ] += ds->deformationWave.amplitude * scale;
  148. scale = 0.98f;
  149. scale = R_NoiseGet4f( 200 + xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
  150. tess.shaderTime * ds->deformationWave.frequency );
  151. normal[ 2 ] += ds->deformationWave.amplitude * scale;
  152. VectorNormalizeFast( normal );
  153. }
  154. }
  155. /*
  156. ========================
  157. RB_CalcBulgeVertexes
  158. ========================
  159. */
  160. void RB_CalcBulgeVertexes( deformStage_t *ds ) {
  161. int i;
  162. const float *st = ( const float * ) tess.texCoords[0];
  163. float *xyz = ( float * ) tess.xyz;
  164. float *normal = ( float * ) tess.normal;
  165. float now;
  166. now = backEnd.refdef.time * ds->bulgeSpeed * 0.001f;
  167. for ( i = 0; i < tess.numVertexes; i++, xyz += 4, st += 4, normal += 4 ) {
  168. int off;
  169. float scale;
  170. off = (float)( FUNCTABLE_SIZE / (M_PI*2) ) * ( st[0] * ds->bulgeWidth + now );
  171. scale = tr.sinTable[ off & FUNCTABLE_MASK ] * ds->bulgeHeight;
  172. xyz[0] += normal[0] * scale;
  173. xyz[1] += normal[1] * scale;
  174. xyz[2] += normal[2] * scale;
  175. }
  176. }
  177. /*
  178. ======================
  179. RB_CalcMoveVertexes
  180. A deformation that can move an entire surface along a wave path
  181. ======================
  182. */
  183. void RB_CalcMoveVertexes( deformStage_t *ds ) {
  184. int i;
  185. float *xyz;
  186. float *table;
  187. float scale;
  188. vec3_t offset;
  189. table = TableForFunc( ds->deformationWave.func );
  190. scale = WAVEVALUE( table, ds->deformationWave.base,
  191. ds->deformationWave.amplitude,
  192. ds->deformationWave.phase,
  193. ds->deformationWave.frequency );
  194. VectorScale( ds->moveVector, scale, offset );
  195. xyz = ( float * ) tess.xyz;
  196. for ( i = 0; i < tess.numVertexes; i++, xyz += 4 ) {
  197. VectorAdd( xyz, offset, xyz );
  198. }
  199. }
  200. /*
  201. =============
  202. DeformText
  203. Change a polygon into a bunch of text polygons
  204. =============
  205. */
  206. void DeformText( const char *text ) {
  207. int i;
  208. vec3_t origin, width, height;
  209. int len;
  210. int ch;
  211. byte color[4];
  212. float bottom, top;
  213. vec3_t mid;
  214. height[0] = 0;
  215. height[1] = 0;
  216. height[2] = -1;
  217. CrossProduct( tess.normal[0], height, width );
  218. // find the midpoint of the box
  219. VectorClear( mid );
  220. bottom = 999999;
  221. top = -999999;
  222. for ( i = 0 ; i < 4 ; i++ ) {
  223. VectorAdd( tess.xyz[i], mid, mid );
  224. if ( tess.xyz[i][2] < bottom ) {
  225. bottom = tess.xyz[i][2];
  226. }
  227. if ( tess.xyz[i][2] > top ) {
  228. top = tess.xyz[i][2];
  229. }
  230. }
  231. VectorScale( mid, 0.25f, origin );
  232. // determine the individual character size
  233. height[0] = 0;
  234. height[1] = 0;
  235. height[2] = ( top - bottom ) * 0.5f;
  236. VectorScale( width, height[2] * -0.75f, width );
  237. // determine the starting position
  238. len = strlen( text );
  239. VectorMA( origin, (len-1), width, origin );
  240. // clear the shader indexes
  241. tess.numIndexes = 0;
  242. tess.numVertexes = 0;
  243. color[0] = color[1] = color[2] = color[3] = 255;
  244. // draw each character
  245. for ( i = 0 ; i < len ; i++ ) {
  246. ch = text[i];
  247. ch &= 255;
  248. if ( ch != ' ' ) {
  249. int row, col;
  250. float frow, fcol, size;
  251. row = ch>>4;
  252. col = ch&15;
  253. frow = row*0.0625f;
  254. fcol = col*0.0625f;
  255. size = 0.0625f;
  256. RB_AddQuadStampExt( origin, width, height, color, fcol, frow, fcol + size, frow + size );
  257. }
  258. VectorMA( origin, -2, width, origin );
  259. }
  260. }
  261. /*
  262. ==================
  263. GlobalVectorToLocal
  264. ==================
  265. */
  266. static void GlobalVectorToLocal( const vec3_t in, vec3_t out ) {
  267. out[0] = DotProduct( in, backEnd.or.axis[0] );
  268. out[1] = DotProduct( in, backEnd.or.axis[1] );
  269. out[2] = DotProduct( in, backEnd.or.axis[2] );
  270. }
  271. /*
  272. =====================
  273. AutospriteDeform
  274. Assuming all the triangles for this shader are independant
  275. quads, rebuild them as forward facing sprites
  276. =====================
  277. */
  278. static void AutospriteDeform( void ) {
  279. int i;
  280. int oldVerts;
  281. float *xyz;
  282. vec3_t mid, delta;
  283. float radius;
  284. vec3_t left, up;
  285. vec3_t leftDir, upDir;
  286. if ( tess.numVertexes & 3 ) {
  287. ri.Printf( PRINT_WARNING, "Autosprite shader %s had odd vertex count", tess.shader->name );
  288. }
  289. if ( tess.numIndexes != ( tess.numVertexes >> 2 ) * 6 ) {
  290. ri.Printf( PRINT_WARNING, "Autosprite shader %s had odd index count", tess.shader->name );
  291. }
  292. oldVerts = tess.numVertexes;
  293. tess.numVertexes = 0;
  294. tess.numIndexes = 0;
  295. if ( backEnd.currentEntity != &tr.worldEntity ) {
  296. GlobalVectorToLocal( backEnd.viewParms.or.axis[1], leftDir );
  297. GlobalVectorToLocal( backEnd.viewParms.or.axis[2], upDir );
  298. } else {
  299. VectorCopy( backEnd.viewParms.or.axis[1], leftDir );
  300. VectorCopy( backEnd.viewParms.or.axis[2], upDir );
  301. }
  302. for ( i = 0 ; i < oldVerts ; i+=4 ) {
  303. // find the midpoint
  304. xyz = tess.xyz[i];
  305. mid[0] = 0.25f * (xyz[0] + xyz[4] + xyz[8] + xyz[12]);
  306. mid[1] = 0.25f * (xyz[1] + xyz[5] + xyz[9] + xyz[13]);
  307. mid[2] = 0.25f * (xyz[2] + xyz[6] + xyz[10] + xyz[14]);
  308. VectorSubtract( xyz, mid, delta );
  309. radius = VectorLength( delta ) * 0.707f; // / sqrt(2)
  310. VectorScale( leftDir, radius, left );
  311. VectorScale( upDir, radius, up );
  312. if ( backEnd.viewParms.isMirror ) {
  313. VectorSubtract( vec3_origin, left, left );
  314. }
  315. // compensate for scale in the axes if necessary
  316. if ( backEnd.currentEntity->e.nonNormalizedAxes ) {
  317. float axisLength;
  318. axisLength = VectorLength( backEnd.currentEntity->e.axis[0] );
  319. if ( !axisLength ) {
  320. axisLength = 0;
  321. } else {
  322. axisLength = 1.0f / axisLength;
  323. }
  324. VectorScale(left, axisLength, left);
  325. VectorScale(up, axisLength, up);
  326. }
  327. RB_AddQuadStamp( mid, left, up, tess.vertexColors[i] );
  328. }
  329. }
  330. /*
  331. =====================
  332. Autosprite2Deform
  333. Autosprite2 will pivot a rectangular quad along the center of its long axis
  334. =====================
  335. */
  336. int edgeVerts[6][2] = {
  337. { 0, 1 },
  338. { 0, 2 },
  339. { 0, 3 },
  340. { 1, 2 },
  341. { 1, 3 },
  342. { 2, 3 }
  343. };
  344. static void Autosprite2Deform( void ) {
  345. int i, j, k;
  346. int indexes;
  347. float *xyz;
  348. vec3_t forward;
  349. if ( tess.numVertexes & 3 ) {
  350. ri.Printf( PRINT_WARNING, "Autosprite2 shader %s had odd vertex count", tess.shader->name );
  351. }
  352. if ( tess.numIndexes != ( tess.numVertexes >> 2 ) * 6 ) {
  353. ri.Printf( PRINT_WARNING, "Autosprite2 shader %s had odd index count", tess.shader->name );
  354. }
  355. if ( backEnd.currentEntity != &tr.worldEntity ) {
  356. GlobalVectorToLocal( backEnd.viewParms.or.axis[0], forward );
  357. } else {
  358. VectorCopy( backEnd.viewParms.or.axis[0], forward );
  359. }
  360. // this is a lot of work for two triangles...
  361. // we could precalculate a lot of it is an issue, but it would mess up
  362. // the shader abstraction
  363. for ( i = 0, indexes = 0 ; i < tess.numVertexes ; i+=4, indexes+=6 ) {
  364. float lengths[2];
  365. int nums[2];
  366. vec3_t mid[2];
  367. vec3_t major, minor;
  368. float *v1, *v2;
  369. // find the midpoint
  370. xyz = tess.xyz[i];
  371. // identify the two shortest edges
  372. nums[0] = nums[1] = 0;
  373. lengths[0] = lengths[1] = 999999;
  374. for ( j = 0 ; j < 6 ; j++ ) {
  375. float l;
  376. vec3_t temp;
  377. v1 = xyz + 4 * edgeVerts[j][0];
  378. v2 = xyz + 4 * edgeVerts[j][1];
  379. VectorSubtract( v1, v2, temp );
  380. l = DotProduct( temp, temp );
  381. if ( l < lengths[0] ) {
  382. nums[1] = nums[0];
  383. lengths[1] = lengths[0];
  384. nums[0] = j;
  385. lengths[0] = l;
  386. } else if ( l < lengths[1] ) {
  387. nums[1] = j;
  388. lengths[1] = l;
  389. }
  390. }
  391. for ( j = 0 ; j < 2 ; j++ ) {
  392. v1 = xyz + 4 * edgeVerts[nums[j]][0];
  393. v2 = xyz + 4 * edgeVerts[nums[j]][1];
  394. mid[j][0] = 0.5f * (v1[0] + v2[0]);
  395. mid[j][1] = 0.5f * (v1[1] + v2[1]);
  396. mid[j][2] = 0.5f * (v1[2] + v2[2]);
  397. }
  398. // find the vector of the major axis
  399. VectorSubtract( mid[1], mid[0], major );
  400. // cross this with the view direction to get minor axis
  401. CrossProduct( major, forward, minor );
  402. VectorNormalize( minor );
  403. // re-project the points
  404. for ( j = 0 ; j < 2 ; j++ ) {
  405. float l;
  406. v1 = xyz + 4 * edgeVerts[nums[j]][0];
  407. v2 = xyz + 4 * edgeVerts[nums[j]][1];
  408. l = 0.5 * sqrt( lengths[j] );
  409. // we need to see which direction this edge
  410. // is used to determine direction of projection
  411. for ( k = 0 ; k < 5 ; k++ ) {
  412. if ( tess.indexes[ indexes + k ] == i + edgeVerts[nums[j]][0]
  413. && tess.indexes[ indexes + k + 1 ] == i + edgeVerts[nums[j]][1] ) {
  414. break;
  415. }
  416. }
  417. if ( k == 5 ) {
  418. VectorMA( mid[j], l, minor, v1 );
  419. VectorMA( mid[j], -l, minor, v2 );
  420. } else {
  421. VectorMA( mid[j], -l, minor, v1 );
  422. VectorMA( mid[j], l, minor, v2 );
  423. }
  424. }
  425. }
  426. }
  427. /*
  428. =====================
  429. RB_DeformTessGeometry
  430. =====================
  431. */
  432. void RB_DeformTessGeometry( void ) {
  433. int i;
  434. deformStage_t *ds;
  435. for ( i = 0 ; i < tess.shader->numDeforms ; i++ ) {
  436. ds = &tess.shader->deforms[ i ];
  437. switch ( ds->deformation ) {
  438. case DEFORM_NONE:
  439. break;
  440. case DEFORM_NORMALS:
  441. RB_CalcDeformNormals( ds );
  442. break;
  443. case DEFORM_WAVE:
  444. RB_CalcDeformVertexes( ds );
  445. break;
  446. case DEFORM_BULGE:
  447. RB_CalcBulgeVertexes( ds );
  448. break;
  449. case DEFORM_MOVE:
  450. RB_CalcMoveVertexes( ds );
  451. break;
  452. case DEFORM_PROJECTION_SHADOW:
  453. RB_ProjectionShadowDeform();
  454. break;
  455. case DEFORM_AUTOSPRITE:
  456. AutospriteDeform();
  457. break;
  458. case DEFORM_AUTOSPRITE2:
  459. Autosprite2Deform();
  460. break;
  461. case DEFORM_TEXT0:
  462. case DEFORM_TEXT1:
  463. case DEFORM_TEXT2:
  464. case DEFORM_TEXT3:
  465. case DEFORM_TEXT4:
  466. case DEFORM_TEXT5:
  467. case DEFORM_TEXT6:
  468. case DEFORM_TEXT7:
  469. DeformText( backEnd.refdef.text[ds->deformation - DEFORM_TEXT0] );
  470. break;
  471. }
  472. }
  473. }
  474. /*
  475. ====================================================================
  476. COLORS
  477. ====================================================================
  478. */
  479. /*
  480. ** RB_CalcColorFromEntity
  481. */
  482. void RB_CalcColorFromEntity( unsigned char *dstColors )
  483. {
  484. int i;
  485. int *pColors = ( int * ) dstColors;
  486. int c;
  487. if ( !backEnd.currentEntity )
  488. return;
  489. c = * ( int * ) backEnd.currentEntity->e.shaderRGBA;
  490. for ( i = 0; i < tess.numVertexes; i++, pColors++ )
  491. {
  492. *pColors = c;
  493. }
  494. }
  495. /*
  496. ** RB_CalcColorFromOneMinusEntity
  497. */
  498. void RB_CalcColorFromOneMinusEntity( unsigned char *dstColors )
  499. {
  500. int i;
  501. int *pColors = ( int * ) dstColors;
  502. unsigned char invModulate[3];
  503. int c;
  504. if ( !backEnd.currentEntity )
  505. return;
  506. invModulate[0] = 255 - backEnd.currentEntity->e.shaderRGBA[0];
  507. invModulate[1] = 255 - backEnd.currentEntity->e.shaderRGBA[1];
  508. invModulate[2] = 255 - backEnd.currentEntity->e.shaderRGBA[2];
  509. invModulate[3] = 255 - backEnd.currentEntity->e.shaderRGBA[3]; // this trashes alpha, but the AGEN block fixes it
  510. c = * ( int * ) invModulate;
  511. for ( i = 0; i < tess.numVertexes; i++, pColors++ )
  512. {
  513. *pColors = * ( int * ) invModulate;
  514. }
  515. }
  516. /*
  517. ** RB_CalcAlphaFromEntity
  518. */
  519. void RB_CalcAlphaFromEntity( unsigned char *dstColors )
  520. {
  521. int i;
  522. if ( !backEnd.currentEntity )
  523. return;
  524. dstColors += 3;
  525. for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
  526. {
  527. *dstColors = backEnd.currentEntity->e.shaderRGBA[3];
  528. }
  529. }
  530. /*
  531. ** RB_CalcAlphaFromOneMinusEntity
  532. */
  533. void RB_CalcAlphaFromOneMinusEntity( unsigned char *dstColors )
  534. {
  535. int i;
  536. if ( !backEnd.currentEntity )
  537. return;
  538. dstColors += 3;
  539. for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
  540. {
  541. *dstColors = 0xff - backEnd.currentEntity->e.shaderRGBA[3];
  542. }
  543. }
  544. /*
  545. ** RB_CalcWaveColor
  546. */
  547. void RB_CalcWaveColor( const waveForm_t *wf, unsigned char *dstColors )
  548. {
  549. int i;
  550. int v;
  551. float glow;
  552. int *colors = ( int * ) dstColors;
  553. byte color[4];
  554. if ( wf->func == GF_NOISE ) {
  555. glow = wf->base + R_NoiseGet4f( 0, 0, 0, ( tess.shaderTime + wf->phase ) * wf->frequency ) * wf->amplitude;
  556. } else {
  557. glow = EvalWaveForm( wf ) * tr.identityLight;
  558. }
  559. if ( glow < 0 ) {
  560. glow = 0;
  561. }
  562. else if ( glow > 1 ) {
  563. glow = 1;
  564. }
  565. v = myftol( 255 * glow );
  566. color[0] = color[1] = color[2] = v;
  567. color[3] = 255;
  568. v = *(int *)color;
  569. for ( i = 0; i < tess.numVertexes; i++, colors++ ) {
  570. *colors = v;
  571. }
  572. }
  573. /*
  574. ** RB_CalcWaveAlpha
  575. */
  576. void RB_CalcWaveAlpha( const waveForm_t *wf, unsigned char *dstColors )
  577. {
  578. int i;
  579. int v;
  580. float glow;
  581. glow = EvalWaveFormClamped( wf );
  582. v = 255 * glow;
  583. for ( i = 0; i < tess.numVertexes; i++, dstColors += 4 )
  584. {
  585. dstColors[3] = v;
  586. }
  587. }
  588. /*
  589. ** RB_CalcModulateColorsByFog
  590. */
  591. void RB_CalcModulateColorsByFog( unsigned char *colors ) {
  592. int i;
  593. float texCoords[SHADER_MAX_VERTEXES][2];
  594. // calculate texcoords so we can derive density
  595. // this is not wasted, because it would only have
  596. // been previously called if the surface was opaque
  597. RB_CalcFogTexCoords( texCoords[0] );
  598. for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) {
  599. float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] );
  600. colors[0] *= f;
  601. colors[1] *= f;
  602. colors[2] *= f;
  603. }
  604. }
  605. /*
  606. ** RB_CalcModulateAlphasByFog
  607. */
  608. void RB_CalcModulateAlphasByFog( unsigned char *colors ) {
  609. int i;
  610. float texCoords[SHADER_MAX_VERTEXES][2];
  611. // calculate texcoords so we can derive density
  612. // this is not wasted, because it would only have
  613. // been previously called if the surface was opaque
  614. RB_CalcFogTexCoords( texCoords[0] );
  615. for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) {
  616. float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] );
  617. colors[3] *= f;
  618. }
  619. }
  620. /*
  621. ** RB_CalcModulateRGBAsByFog
  622. */
  623. void RB_CalcModulateRGBAsByFog( unsigned char *colors ) {
  624. int i;
  625. float texCoords[SHADER_MAX_VERTEXES][2];
  626. // calculate texcoords so we can derive density
  627. // this is not wasted, because it would only have
  628. // been previously called if the surface was opaque
  629. RB_CalcFogTexCoords( texCoords[0] );
  630. for ( i = 0; i < tess.numVertexes; i++, colors += 4 ) {
  631. float f = 1.0 - R_FogFactor( texCoords[i][0], texCoords[i][1] );
  632. colors[0] *= f;
  633. colors[1] *= f;
  634. colors[2] *= f;
  635. colors[3] *= f;
  636. }
  637. }
  638. /*
  639. ====================================================================
  640. TEX COORDS
  641. ====================================================================
  642. */
  643. /*
  644. ========================
  645. RB_CalcFogTexCoords
  646. To do the clipped fog plane really correctly, we should use
  647. projected textures, but I don't trust the drivers and it
  648. doesn't fit our shader data.
  649. ========================
  650. */
  651. void RB_CalcFogTexCoords( float *st ) {
  652. int i;
  653. float *v;
  654. float s, t;
  655. float eyeT;
  656. qboolean eyeOutside;
  657. fog_t *fog;
  658. vec3_t local;
  659. vec4_t fogDistanceVector, fogDepthVector;
  660. memset (fogDepthVector, 0, sizeof (fogDepthVector));
  661. fog = tr.world->fogs + tess.fogNum;
  662. // all fogging distance is based on world Z units
  663. VectorSubtract( backEnd.or.origin, backEnd.viewParms.or.origin, local );
  664. fogDistanceVector[0] = -backEnd.or.modelMatrix[2];
  665. fogDistanceVector[1] = -backEnd.or.modelMatrix[6];
  666. fogDistanceVector[2] = -backEnd.or.modelMatrix[10];
  667. fogDistanceVector[3] = DotProduct( local, backEnd.viewParms.or.axis[0] );
  668. // scale the fog vectors based on the fog's thickness
  669. fogDistanceVector[0] *= fog->tcScale;
  670. fogDistanceVector[1] *= fog->tcScale;
  671. fogDistanceVector[2] *= fog->tcScale;
  672. fogDistanceVector[3] *= fog->tcScale;
  673. // rotate the gradient vector for this orientation
  674. if ( fog->hasSurface ) {
  675. fogDepthVector[0] = fog->surface[0] * backEnd.or.axis[0][0] +
  676. fog->surface[1] * backEnd.or.axis[0][1] + fog->surface[2] * backEnd.or.axis[0][2];
  677. fogDepthVector[1] = fog->surface[0] * backEnd.or.axis[1][0] +
  678. fog->surface[1] * backEnd.or.axis[1][1] + fog->surface[2] * backEnd.or.axis[1][2];
  679. fogDepthVector[2] = fog->surface[0] * backEnd.or.axis[2][0] +
  680. fog->surface[1] * backEnd.or.axis[2][1] + fog->surface[2] * backEnd.or.axis[2][2];
  681. fogDepthVector[3] = -fog->surface[3] + DotProduct( backEnd.or.origin, fog->surface );
  682. eyeT = DotProduct( backEnd.or.viewOrigin, fogDepthVector ) + fogDepthVector[3];
  683. } else {
  684. eyeT = 1; // non-surface fog always has eye inside
  685. }
  686. // see if the viewpoint is outside
  687. // this is needed for clipping distance even for constant fog
  688. if ( eyeT < 0 ) {
  689. eyeOutside = qtrue;
  690. } else {
  691. eyeOutside = qfalse;
  692. }
  693. fogDistanceVector[3] += 1.0/512;
  694. // calculate density for each point
  695. for (i = 0, v = tess.xyz[0] ; i < tess.numVertexes ; i++, v += 4) {
  696. // calculate the length in fog
  697. s = DotProduct( v, fogDistanceVector ) + fogDistanceVector[3];
  698. t = DotProduct( v, fogDepthVector ) + fogDepthVector[3];
  699. // partially clipped fogs use the T axis
  700. if ( eyeOutside ) {
  701. if ( t < 1.0 ) {
  702. t = 1.0/32; // point is outside, so no fogging
  703. } else {
  704. t = 1.0/32 + 30.0/32 * t / ( t - eyeT ); // cut the distance at the fog plane
  705. }
  706. } else {
  707. if ( t < 0 ) {
  708. t = 1.0/32; // point is outside, so no fogging
  709. } else {
  710. t = 31.0/32;
  711. }
  712. }
  713. st[0] = s;
  714. st[1] = t;
  715. st += 2;
  716. }
  717. }
  718. /*
  719. ** RB_CalcEnvironmentTexCoords
  720. */
  721. void RB_CalcEnvironmentTexCoords( float *st )
  722. {
  723. int i;
  724. float *v, *normal;
  725. vec3_t viewer, reflected;
  726. float d;
  727. v = tess.xyz[0];
  728. normal = tess.normal[0];
  729. for (i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 )
  730. {
  731. VectorSubtract (backEnd.or.viewOrigin, v, viewer);
  732. VectorNormalizeFast (viewer);
  733. d = DotProduct (normal, viewer);
  734. reflected[0] = normal[0]*2*d - viewer[0];
  735. reflected[1] = normal[1]*2*d - viewer[1];
  736. reflected[2] = normal[2]*2*d - viewer[2];
  737. st[0] = 0.5 + reflected[1] * 0.5;
  738. st[1] = 0.5 - reflected[2] * 0.5;
  739. }
  740. }
  741. /*
  742. ** RB_CalcTurbulentTexCoords
  743. */
  744. void RB_CalcTurbulentTexCoords( const waveForm_t *wf, float *st )
  745. {
  746. int i;
  747. float now;
  748. now = ( wf->phase + tess.shaderTime * wf->frequency );
  749. for ( i = 0; i < tess.numVertexes; i++, st += 2 )
  750. {
  751. float s = st[0];
  752. float t = st[1];
  753. 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;
  754. st[1] = t + tr.sinTable[ ( ( int ) ( ( tess.xyz[i][1] * 1.0/128 * 0.125 + now ) * FUNCTABLE_SIZE ) ) & ( FUNCTABLE_MASK ) ] * wf->amplitude;
  755. }
  756. }
  757. /*
  758. ** RB_CalcScaleTexCoords
  759. */
  760. void RB_CalcScaleTexCoords( const float scale[2], float *st )
  761. {
  762. int i;
  763. for ( i = 0; i < tess.numVertexes; i++, st += 2 )
  764. {
  765. st[0] *= scale[0];
  766. st[1] *= scale[1];
  767. }
  768. }
  769. /*
  770. ** RB_CalcScrollTexCoords
  771. */
  772. void RB_CalcScrollTexCoords( const float scrollSpeed[2], float *st )
  773. {
  774. int i;
  775. float timeScale = tess.shaderTime;
  776. float adjustedScrollS, adjustedScrollT;
  777. adjustedScrollS = scrollSpeed[0] * timeScale;
  778. adjustedScrollT = scrollSpeed[1] * timeScale;
  779. // clamp so coordinates don't continuously get larger, causing problems
  780. // with hardware limits
  781. adjustedScrollS = adjustedScrollS - floor( adjustedScrollS );
  782. adjustedScrollT = adjustedScrollT - floor( adjustedScrollT );
  783. for ( i = 0; i < tess.numVertexes; i++, st += 2 )
  784. {
  785. st[0] += adjustedScrollS;
  786. st[1] += adjustedScrollT;
  787. }
  788. }
  789. /*
  790. ** RB_CalcTransformTexCoords
  791. */
  792. void RB_CalcTransformTexCoords( const texModInfo_t *tmi, float *st )
  793. {
  794. int i;
  795. for ( i = 0; i < tess.numVertexes; i++, st += 2 )
  796. {
  797. float s = st[0];
  798. float t = st[1];
  799. st[0] = s * tmi->matrix[0][0] + t * tmi->matrix[1][0] + tmi->translate[0];
  800. st[1] = s * tmi->matrix[0][1] + t * tmi->matrix[1][1] + tmi->translate[1];
  801. }
  802. }
  803. /*
  804. ** RB_CalcRotateTexCoords
  805. */
  806. void RB_CalcRotateTexCoords( float degsPerSecond, float *st )
  807. {
  808. float timeScale = tess.shaderTime;
  809. float degs;
  810. int index;
  811. float sinValue, cosValue;
  812. texModInfo_t tmi;
  813. degs = -degsPerSecond * timeScale;
  814. index = degs * ( FUNCTABLE_SIZE / 360.0f );
  815. sinValue = tr.sinTable[ index & FUNCTABLE_MASK ];
  816. cosValue = tr.sinTable[ ( index + FUNCTABLE_SIZE / 4 ) & FUNCTABLE_MASK ];
  817. tmi.matrix[0][0] = cosValue;
  818. tmi.matrix[1][0] = -sinValue;
  819. tmi.translate[0] = 0.5 - 0.5 * cosValue + 0.5 * sinValue;
  820. tmi.matrix[0][1] = sinValue;
  821. tmi.matrix[1][1] = cosValue;
  822. tmi.translate[1] = 0.5 - 0.5 * sinValue - 0.5 * cosValue;
  823. RB_CalcTransformTexCoords( &tmi, st );
  824. }
  825. #if id386 && !( (defined __linux__ || defined __FreeBSD__ ) && (defined __i386__ ) ) // rb010123
  826. long myftol( float f ) {
  827. static int tmp;
  828. __asm fld f
  829. __asm fistp tmp
  830. __asm mov eax, tmp
  831. }
  832. #endif
  833. /*
  834. ** RB_CalcSpecularAlpha
  835. **
  836. ** Calculates specular coefficient and places it in the alpha channel
  837. */
  838. vec3_t lightOrigin = { -960, 1980, 96 }; // FIXME: track dynamically
  839. void RB_CalcSpecularAlpha( unsigned char *alphas ) {
  840. int i;
  841. float *v, *normal;
  842. vec3_t viewer, reflected;
  843. float l, d;
  844. int b;
  845. vec3_t lightDir;
  846. int numVertexes;
  847. v = tess.xyz[0];
  848. normal = tess.normal[0];
  849. alphas += 3;
  850. numVertexes = tess.numVertexes;
  851. for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4, alphas += 4) {
  852. float ilength;
  853. VectorSubtract( lightOrigin, v, lightDir );
  854. // ilength = Q_rsqrt( DotProduct( lightDir, lightDir ) );
  855. VectorNormalizeFast( lightDir );
  856. // calculate the specular color
  857. d = DotProduct (normal, lightDir);
  858. // d *= ilength;
  859. // we don't optimize for the d < 0 case since this tends to
  860. // cause visual artifacts such as faceted "snapping"
  861. reflected[0] = normal[0]*2*d - lightDir[0];
  862. reflected[1] = normal[1]*2*d - lightDir[1];
  863. reflected[2] = normal[2]*2*d - lightDir[2];
  864. VectorSubtract (backEnd.or.viewOrigin, v, viewer);
  865. ilength = Q_rsqrt( DotProduct( viewer, viewer ) );
  866. l = DotProduct (reflected, viewer);
  867. l *= ilength;
  868. if (l < 0) {
  869. b = 0;
  870. } else {
  871. l = l*l;
  872. l = l*l;
  873. b = l * 255;
  874. if (b > 255) {
  875. b = 255;
  876. }
  877. }
  878. *alphas = b;
  879. }
  880. }
  881. /*
  882. ** RB_CalcDiffuseColor
  883. **
  884. ** The basic vertex lighting calc
  885. */
  886. void RB_CalcDiffuseColor( unsigned char *colors )
  887. {
  888. int i, j;
  889. float *v, *normal;
  890. float incoming;
  891. trRefEntity_t *ent;
  892. int ambientLightInt;
  893. vec3_t ambientLight;
  894. vec3_t lightDir;
  895. vec3_t directedLight;
  896. int numVertexes;
  897. #if idppc_altivec
  898. vector unsigned char vSel = (vector unsigned char)(0x00, 0x00, 0x00, 0xff,
  899. 0x00, 0x00, 0x00, 0xff,
  900. 0x00, 0x00, 0x00, 0xff,
  901. 0x00, 0x00, 0x00, 0xff);
  902. vector float ambientLightVec;
  903. vector float directedLightVec;
  904. vector float lightDirVec;
  905. vector float normalVec0, normalVec1;
  906. vector float incomingVec0, incomingVec1, incomingVec2;
  907. vector float zero, jVec;
  908. vector signed int jVecInt;
  909. vector signed short jVecShort;
  910. vector unsigned char jVecChar, normalPerm;
  911. #endif
  912. ent = backEnd.currentEntity;
  913. ambientLightInt = ent->ambientLightInt;
  914. #if idppc_altivec
  915. // A lot of this could be simplified if we made sure
  916. // entities light info was 16-byte aligned.
  917. jVecChar = vec_lvsl(0, ent->ambientLight);
  918. ambientLightVec = vec_ld(0, (vector float *)ent->ambientLight);
  919. jVec = vec_ld(11, (vector float *)ent->ambientLight);
  920. ambientLightVec = vec_perm(ambientLightVec,jVec,jVecChar);
  921. jVecChar = vec_lvsl(0, ent->directedLight);
  922. directedLightVec = vec_ld(0,(vector float *)ent->directedLight);
  923. jVec = vec_ld(11,(vector float *)ent->directedLight);
  924. directedLightVec = vec_perm(directedLightVec,jVec,jVecChar);
  925. jVecChar = vec_lvsl(0, ent->lightDir);
  926. lightDirVec = vec_ld(0,(vector float *)ent->lightDir);
  927. jVec = vec_ld(11,(vector float *)ent->lightDir);
  928. lightDirVec = vec_perm(lightDirVec,jVec,jVecChar);
  929. zero = (vector float)vec_splat_s8(0);
  930. VectorCopy( ent->lightDir, lightDir );
  931. #else
  932. VectorCopy( ent->ambientLight, ambientLight );
  933. VectorCopy( ent->directedLight, directedLight );
  934. VectorCopy( ent->lightDir, lightDir );
  935. #endif
  936. v = tess.xyz[0];
  937. normal = tess.normal[0];
  938. #if idppc_altivec
  939. normalPerm = vec_lvsl(0,normal);
  940. #endif
  941. numVertexes = tess.numVertexes;
  942. for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
  943. #if idppc_altivec
  944. normalVec0 = vec_ld(0,(vector float *)normal);
  945. normalVec1 = vec_ld(11,(vector float *)normal);
  946. normalVec0 = vec_perm(normalVec0,normalVec1,normalPerm);
  947. incomingVec0 = vec_madd(normalVec0, lightDirVec, zero);
  948. incomingVec1 = vec_sld(incomingVec0,incomingVec0,4);
  949. incomingVec2 = vec_add(incomingVec0,incomingVec1);
  950. incomingVec1 = vec_sld(incomingVec1,incomingVec1,4);
  951. incomingVec2 = vec_add(incomingVec2,incomingVec1);
  952. incomingVec0 = vec_splat(incomingVec2,0);
  953. incomingVec0 = vec_max(incomingVec0,zero);
  954. normalPerm = vec_lvsl(12,normal);
  955. jVec = vec_madd(incomingVec0, directedLightVec, ambientLightVec);
  956. jVecInt = vec_cts(jVec,0); // RGBx
  957. jVecShort = vec_pack(jVecInt,jVecInt); // RGBxRGBx
  958. jVecChar = vec_packsu(jVecShort,jVecShort); // RGBxRGBxRGBxRGBx
  959. jVecChar = vec_sel(jVecChar,vSel,vSel); // RGBARGBARGBARGBA replace alpha with 255
  960. vec_ste((vector unsigned int)jVecChar,0,(unsigned int *)&colors[i*4]); // store color
  961. #else
  962. incoming = DotProduct (normal, lightDir);
  963. if ( incoming <= 0 ) {
  964. *(int *)&colors[i*4] = ambientLightInt;
  965. continue;
  966. }
  967. j = myftol( ambientLight[0] + incoming * directedLight[0] );
  968. if ( j > 255 ) {
  969. j = 255;
  970. }
  971. colors[i*4+0] = j;
  972. j = myftol( ambientLight[1] + incoming * directedLight[1] );
  973. if ( j > 255 ) {
  974. j = 255;
  975. }
  976. colors[i*4+1] = j;
  977. j = myftol( ambientLight[2] + incoming * directedLight[2] );
  978. if ( j > 255 ) {
  979. j = 255;
  980. }
  981. colors[i*4+2] = j;
  982. colors[i*4+3] = 255;
  983. #endif
  984. }
  985. }