gl_mesh.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // gl_mesh.c: triangle model functions
  16. #include "gl_local.h"
  17. /*
  18. =============================================================
  19. ALIAS MODELS
  20. =============================================================
  21. */
  22. #define NUMVERTEXNORMALS 162
  23. float r_avertexnormals[NUMVERTEXNORMALS][3] = {
  24. #include "anorms.h"
  25. };
  26. typedef float vec4_t[4];
  27. static vec4_t s_lerped[MAX_VERTS];
  28. //static vec3_t lerped[MAX_VERTS];
  29. vec3_t shadevector;
  30. float shadelight[3];
  31. // precalculated dot products for quantized angles
  32. #define SHADEDOT_QUANT 16
  33. float r_avertexnormal_dots[SHADEDOT_QUANT][256] =
  34. #include "anormtab.h"
  35. ;
  36. float *shadedots = r_avertexnormal_dots[0];
  37. void GL_LerpVerts( int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx_t *verts, float *lerp, float move[3], float frontv[3], float backv[3] )
  38. {
  39. int i;
  40. //PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM
  41. if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
  42. {
  43. for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4 )
  44. {
  45. float *normal = r_avertexnormals[verts[i].lightnormalindex];
  46. lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0] + normal[0] * POWERSUIT_SCALE;
  47. lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1] + normal[1] * POWERSUIT_SCALE;
  48. lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2] + normal[2] * POWERSUIT_SCALE;
  49. }
  50. }
  51. else
  52. {
  53. for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4)
  54. {
  55. lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0];
  56. lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1];
  57. lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2];
  58. }
  59. }
  60. }
  61. /*
  62. =============
  63. GL_DrawAliasFrameLerp
  64. interpolates between two frames and origins
  65. FIXME: batch lerp all vertexes
  66. =============
  67. */
  68. void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
  69. {
  70. float l;
  71. daliasframe_t *frame, *oldframe;
  72. dtrivertx_t *v, *ov, *verts;
  73. int *order;
  74. int count;
  75. float frontlerp;
  76. float alpha;
  77. vec3_t move, delta, vectors[3];
  78. vec3_t frontv, backv;
  79. int i;
  80. int index_xyz;
  81. float *lerp;
  82. frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
  83. + currententity->frame * paliashdr->framesize);
  84. verts = v = frame->verts;
  85. oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
  86. + currententity->oldframe * paliashdr->framesize);
  87. ov = oldframe->verts;
  88. order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
  89. // glTranslatef (frame->translate[0], frame->translate[1], frame->translate[2]);
  90. // glScalef (frame->scale[0], frame->scale[1], frame->scale[2]);
  91. if (currententity->flags & RF_TRANSLUCENT)
  92. alpha = currententity->alpha;
  93. else
  94. alpha = 1.0;
  95. // PMM - added double shell
  96. if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
  97. qglDisable( GL_TEXTURE_2D );
  98. frontlerp = 1.0 - backlerp;
  99. // move should be the delta back to the previous frame * backlerp
  100. VectorSubtract (currententity->oldorigin, currententity->origin, delta);
  101. AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]);
  102. move[0] = DotProduct (delta, vectors[0]); // forward
  103. move[1] = -DotProduct (delta, vectors[1]); // left
  104. move[2] = DotProduct (delta, vectors[2]); // up
  105. VectorAdd (move, oldframe->translate, move);
  106. for (i=0 ; i<3 ; i++)
  107. {
  108. move[i] = backlerp*move[i] + frontlerp*frame->translate[i];
  109. }
  110. for (i=0 ; i<3 ; i++)
  111. {
  112. frontv[i] = frontlerp*frame->scale[i];
  113. backv[i] = backlerp*oldframe->scale[i];
  114. }
  115. lerp = s_lerped[0];
  116. GL_LerpVerts( paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv );
  117. if ( gl_vertex_arrays->value )
  118. {
  119. float colorArray[MAX_VERTS*4];
  120. qglEnableClientState( GL_VERTEX_ARRAY );
  121. qglVertexPointer( 3, GL_FLOAT, 16, s_lerped ); // padded for SIMD
  122. // if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )
  123. // PMM - added double damage shell
  124. if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
  125. {
  126. qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha );
  127. }
  128. else
  129. {
  130. qglEnableClientState( GL_COLOR_ARRAY );
  131. qglColorPointer( 3, GL_FLOAT, 0, colorArray );
  132. //
  133. // pre light everything
  134. //
  135. for ( i = 0; i < paliashdr->num_xyz; i++ )
  136. {
  137. float l = shadedots[verts[i].lightnormalindex];
  138. colorArray[i*3+0] = l * shadelight[0];
  139. colorArray[i*3+1] = l * shadelight[1];
  140. colorArray[i*3+2] = l * shadelight[2];
  141. }
  142. }
  143. if ( qglLockArraysEXT != 0 )
  144. qglLockArraysEXT( 0, paliashdr->num_xyz );
  145. while (1)
  146. {
  147. // get the vertex count and primitive type
  148. count = *order++;
  149. if (!count)
  150. break; // done
  151. if (count < 0)
  152. {
  153. count = -count;
  154. qglBegin (GL_TRIANGLE_FAN);
  155. }
  156. else
  157. {
  158. qglBegin (GL_TRIANGLE_STRIP);
  159. }
  160. // PMM - added double damage shell
  161. if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
  162. {
  163. do
  164. {
  165. index_xyz = order[2];
  166. order += 3;
  167. qglVertex3fv( s_lerped[index_xyz] );
  168. } while (--count);
  169. }
  170. else
  171. {
  172. do
  173. {
  174. // texture coordinates come from the draw list
  175. qglTexCoord2f (((float *)order)[0], ((float *)order)[1]);
  176. index_xyz = order[2];
  177. order += 3;
  178. // normals and vertexes come from the frame list
  179. // l = shadedots[verts[index_xyz].lightnormalindex];
  180. // qglColor4f (l* shadelight[0], l*shadelight[1], l*shadelight[2], alpha);
  181. qglArrayElement( index_xyz );
  182. } while (--count);
  183. }
  184. qglEnd ();
  185. }
  186. if ( qglUnlockArraysEXT != 0 )
  187. qglUnlockArraysEXT();
  188. }
  189. else
  190. {
  191. while (1)
  192. {
  193. // get the vertex count and primitive type
  194. count = *order++;
  195. if (!count)
  196. break; // done
  197. if (count < 0)
  198. {
  199. count = -count;
  200. qglBegin (GL_TRIANGLE_FAN);
  201. }
  202. else
  203. {
  204. qglBegin (GL_TRIANGLE_STRIP);
  205. }
  206. if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )
  207. {
  208. do
  209. {
  210. index_xyz = order[2];
  211. order += 3;
  212. qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha);
  213. qglVertex3fv (s_lerped[index_xyz]);
  214. } while (--count);
  215. }
  216. else
  217. {
  218. do
  219. {
  220. // texture coordinates come from the draw list
  221. qglTexCoord2f (((float *)order)[0], ((float *)order)[1]);
  222. index_xyz = order[2];
  223. order += 3;
  224. // normals and vertexes come from the frame list
  225. l = shadedots[verts[index_xyz].lightnormalindex];
  226. qglColor4f (l* shadelight[0], l*shadelight[1], l*shadelight[2], alpha);
  227. qglVertex3fv (s_lerped[index_xyz]);
  228. } while (--count);
  229. }
  230. qglEnd ();
  231. }
  232. }
  233. // if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )
  234. // PMM - added double damage shell
  235. if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
  236. qglEnable( GL_TEXTURE_2D );
  237. }
  238. #if 1
  239. /*
  240. =============
  241. GL_DrawAliasShadow
  242. =============
  243. */
  244. extern vec3_t lightspot;
  245. void GL_DrawAliasShadow (dmdl_t *paliashdr, int posenum)
  246. {
  247. dtrivertx_t *verts;
  248. int *order;
  249. vec3_t point;
  250. float height, lheight;
  251. int count;
  252. daliasframe_t *frame;
  253. lheight = currententity->origin[2] - lightspot[2];
  254. frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
  255. + currententity->frame * paliashdr->framesize);
  256. verts = frame->verts;
  257. height = 0;
  258. order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
  259. height = -lheight + 1.0;
  260. while (1)
  261. {
  262. // get the vertex count and primitive type
  263. count = *order++;
  264. if (!count)
  265. break; // done
  266. if (count < 0)
  267. {
  268. count = -count;
  269. qglBegin (GL_TRIANGLE_FAN);
  270. }
  271. else
  272. qglBegin (GL_TRIANGLE_STRIP);
  273. do
  274. {
  275. // normals and vertexes come from the frame list
  276. /*
  277. point[0] = verts[order[2]].v[0] * frame->scale[0] + frame->translate[0];
  278. point[1] = verts[order[2]].v[1] * frame->scale[1] + frame->translate[1];
  279. point[2] = verts[order[2]].v[2] * frame->scale[2] + frame->translate[2];
  280. */
  281. memcpy( point, s_lerped[order[2]], sizeof( point ) );
  282. point[0] -= shadevector[0]*(point[2]+lheight);
  283. point[1] -= shadevector[1]*(point[2]+lheight);
  284. point[2] = height;
  285. // height -= 0.001;
  286. qglVertex3fv (point);
  287. order += 3;
  288. // verts++;
  289. } while (--count);
  290. qglEnd ();
  291. }
  292. }
  293. #endif
  294. /*
  295. ** R_CullAliasModel
  296. */
  297. static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e )
  298. {
  299. int i;
  300. vec3_t mins, maxs;
  301. dmdl_t *paliashdr;
  302. vec3_t vectors[3];
  303. vec3_t thismins, oldmins, thismaxs, oldmaxs;
  304. daliasframe_t *pframe, *poldframe;
  305. vec3_t angles;
  306. paliashdr = (dmdl_t *)currentmodel->extradata;
  307. if ( ( e->frame >= paliashdr->num_frames ) || ( e->frame < 0 ) )
  308. {
  309. ri.Con_Printf (PRINT_ALL, "R_CullAliasModel %s: no such frame %d\n",
  310. currentmodel->name, e->frame);
  311. e->frame = 0;
  312. }
  313. if ( ( e->oldframe >= paliashdr->num_frames ) || ( e->oldframe < 0 ) )
  314. {
  315. ri.Con_Printf (PRINT_ALL, "R_CullAliasModel %s: no such oldframe %d\n",
  316. currentmodel->name, e->oldframe);
  317. e->oldframe = 0;
  318. }
  319. pframe = ( daliasframe_t * ) ( ( byte * ) paliashdr +
  320. paliashdr->ofs_frames +
  321. e->frame * paliashdr->framesize);
  322. poldframe = ( daliasframe_t * ) ( ( byte * ) paliashdr +
  323. paliashdr->ofs_frames +
  324. e->oldframe * paliashdr->framesize);
  325. /*
  326. ** compute axially aligned mins and maxs
  327. */
  328. if ( pframe == poldframe )
  329. {
  330. for ( i = 0; i < 3; i++ )
  331. {
  332. mins[i] = pframe->translate[i];
  333. maxs[i] = mins[i] + pframe->scale[i]*255;
  334. }
  335. }
  336. else
  337. {
  338. for ( i = 0; i < 3; i++ )
  339. {
  340. thismins[i] = pframe->translate[i];
  341. thismaxs[i] = thismins[i] + pframe->scale[i]*255;
  342. oldmins[i] = poldframe->translate[i];
  343. oldmaxs[i] = oldmins[i] + poldframe->scale[i]*255;
  344. if ( thismins[i] < oldmins[i] )
  345. mins[i] = thismins[i];
  346. else
  347. mins[i] = oldmins[i];
  348. if ( thismaxs[i] > oldmaxs[i] )
  349. maxs[i] = thismaxs[i];
  350. else
  351. maxs[i] = oldmaxs[i];
  352. }
  353. }
  354. /*
  355. ** compute a full bounding box
  356. */
  357. for ( i = 0; i < 8; i++ )
  358. {
  359. vec3_t tmp;
  360. if ( i & 1 )
  361. tmp[0] = mins[0];
  362. else
  363. tmp[0] = maxs[0];
  364. if ( i & 2 )
  365. tmp[1] = mins[1];
  366. else
  367. tmp[1] = maxs[1];
  368. if ( i & 4 )
  369. tmp[2] = mins[2];
  370. else
  371. tmp[2] = maxs[2];
  372. VectorCopy( tmp, bbox[i] );
  373. }
  374. /*
  375. ** rotate the bounding box
  376. */
  377. VectorCopy( e->angles, angles );
  378. angles[YAW] = -angles[YAW];
  379. AngleVectors( angles, vectors[0], vectors[1], vectors[2] );
  380. for ( i = 0; i < 8; i++ )
  381. {
  382. vec3_t tmp;
  383. VectorCopy( bbox[i], tmp );
  384. bbox[i][0] = DotProduct( vectors[0], tmp );
  385. bbox[i][1] = -DotProduct( vectors[1], tmp );
  386. bbox[i][2] = DotProduct( vectors[2], tmp );
  387. VectorAdd( e->origin, bbox[i], bbox[i] );
  388. }
  389. {
  390. int p, f, aggregatemask = ~0;
  391. for ( p = 0; p < 8; p++ )
  392. {
  393. int mask = 0;
  394. for ( f = 0; f < 4; f++ )
  395. {
  396. float dp = DotProduct( frustum[f].normal, bbox[p] );
  397. if ( ( dp - frustum[f].dist ) < 0 )
  398. {
  399. mask |= ( 1 << f );
  400. }
  401. }
  402. aggregatemask &= mask;
  403. }
  404. if ( aggregatemask )
  405. {
  406. return true;
  407. }
  408. return false;
  409. }
  410. }
  411. /*
  412. =================
  413. R_DrawAliasModel
  414. =================
  415. */
  416. void R_DrawAliasModel (entity_t *e)
  417. {
  418. int i;
  419. dmdl_t *paliashdr;
  420. float an;
  421. vec3_t bbox[8];
  422. image_t *skin;
  423. if ( !( e->flags & RF_WEAPONMODEL ) )
  424. {
  425. if ( R_CullAliasModel( bbox, e ) )
  426. return;
  427. }
  428. if ( e->flags & RF_WEAPONMODEL )
  429. {
  430. if ( r_lefthand->value == 2 )
  431. return;
  432. }
  433. paliashdr = (dmdl_t *)currentmodel->extradata;
  434. //
  435. // get lighting information
  436. //
  437. // PMM - rewrote, reordered to handle new shells & mixing
  438. //
  439. if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) )
  440. {
  441. // PMM -special case for godmode
  442. if ( (currententity->flags & RF_SHELL_RED) &&
  443. (currententity->flags & RF_SHELL_BLUE) &&
  444. (currententity->flags & RF_SHELL_GREEN) )
  445. {
  446. for (i=0 ; i<3 ; i++)
  447. shadelight[i] = 1.0;
  448. }
  449. else if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) )
  450. {
  451. VectorClear (shadelight);
  452. if ( currententity->flags & RF_SHELL_RED )
  453. {
  454. shadelight[0] = 1.0;
  455. if (currententity->flags & (RF_SHELL_BLUE|RF_SHELL_DOUBLE) )
  456. shadelight[2] = 1.0;
  457. }
  458. else if ( currententity->flags & RF_SHELL_BLUE )
  459. {
  460. if ( currententity->flags & RF_SHELL_DOUBLE )
  461. {
  462. shadelight[1] = 1.0;
  463. shadelight[2] = 1.0;
  464. }
  465. else
  466. {
  467. shadelight[2] = 1.0;
  468. }
  469. }
  470. else if ( currententity->flags & RF_SHELL_DOUBLE )
  471. {
  472. shadelight[0] = 0.9;
  473. shadelight[1] = 0.7;
  474. }
  475. }
  476. else if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN ) )
  477. {
  478. VectorClear (shadelight);
  479. // PMM - new colors
  480. if ( currententity->flags & RF_SHELL_HALF_DAM )
  481. {
  482. shadelight[0] = 0.56;
  483. shadelight[1] = 0.59;
  484. shadelight[2] = 0.45;
  485. }
  486. if ( currententity->flags & RF_SHELL_GREEN )
  487. {
  488. shadelight[1] = 1.0;
  489. }
  490. }
  491. }
  492. //PMM - ok, now flatten these down to range from 0 to 1.0.
  493. // max_shell_val = max(shadelight[0], max(shadelight[1], shadelight[2]));
  494. // if (max_shell_val > 0)
  495. // {
  496. // for (i=0; i<3; i++)
  497. // {
  498. // shadelight[i] = shadelight[i] / max_shell_val;
  499. // }
  500. // }
  501. // pmm
  502. else if ( currententity->flags & RF_FULLBRIGHT )
  503. {
  504. for (i=0 ; i<3 ; i++)
  505. shadelight[i] = 1.0;
  506. }
  507. else
  508. {
  509. R_LightPoint (currententity->origin, shadelight);
  510. // player lighting hack for communication back to server
  511. // big hack!
  512. if ( currententity->flags & RF_WEAPONMODEL )
  513. {
  514. // pick the greatest component, which should be the same
  515. // as the mono value returned by software
  516. if (shadelight[0] > shadelight[1])
  517. {
  518. if (shadelight[0] > shadelight[2])
  519. r_lightlevel->value = 150*shadelight[0];
  520. else
  521. r_lightlevel->value = 150*shadelight[2];
  522. }
  523. else
  524. {
  525. if (shadelight[1] > shadelight[2])
  526. r_lightlevel->value = 150*shadelight[1];
  527. else
  528. r_lightlevel->value = 150*shadelight[2];
  529. }
  530. }
  531. if ( gl_monolightmap->string[0] != '0' )
  532. {
  533. float s = shadelight[0];
  534. if ( s < shadelight[1] )
  535. s = shadelight[1];
  536. if ( s < shadelight[2] )
  537. s = shadelight[2];
  538. shadelight[0] = s;
  539. shadelight[1] = s;
  540. shadelight[2] = s;
  541. }
  542. }
  543. if ( currententity->flags & RF_MINLIGHT )
  544. {
  545. for (i=0 ; i<3 ; i++)
  546. if (shadelight[i] > 0.1)
  547. break;
  548. if (i == 3)
  549. {
  550. shadelight[0] = 0.1;
  551. shadelight[1] = 0.1;
  552. shadelight[2] = 0.1;
  553. }
  554. }
  555. if ( currententity->flags & RF_GLOW )
  556. { // bonus items will pulse with time
  557. float scale;
  558. float min;
  559. scale = 0.1 * sin(r_newrefdef.time*7);
  560. for (i=0 ; i<3 ; i++)
  561. {
  562. min = shadelight[i] * 0.8;
  563. shadelight[i] += scale;
  564. if (shadelight[i] < min)
  565. shadelight[i] = min;
  566. }
  567. }
  568. // =================
  569. // PGM ir goggles color override
  570. if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
  571. {
  572. shadelight[0] = 1.0;
  573. shadelight[1] = 0.0;
  574. shadelight[2] = 0.0;
  575. }
  576. // PGM
  577. // =================
  578. shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
  579. an = currententity->angles[1]/180*M_PI;
  580. shadevector[0] = cos(-an);
  581. shadevector[1] = sin(-an);
  582. shadevector[2] = 1;
  583. VectorNormalize (shadevector);
  584. //
  585. // locate the proper data
  586. //
  587. c_alias_polys += paliashdr->num_tris;
  588. //
  589. // draw all the triangles
  590. //
  591. if (currententity->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls
  592. qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
  593. if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
  594. {
  595. extern void MYgluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar );
  596. qglMatrixMode( GL_PROJECTION );
  597. qglPushMatrix();
  598. qglLoadIdentity();
  599. qglScalef( -1, 1, 1 );
  600. MYgluPerspective( r_newrefdef.fov_y, ( float ) r_newrefdef.width / r_newrefdef.height, 4, 4096);
  601. qglMatrixMode( GL_MODELVIEW );
  602. qglCullFace( GL_BACK );
  603. }
  604. qglPushMatrix ();
  605. e->angles[PITCH] = -e->angles[PITCH]; // sigh.
  606. R_RotateForEntity (e);
  607. e->angles[PITCH] = -e->angles[PITCH]; // sigh.
  608. // select skin
  609. if (currententity->skin)
  610. skin = currententity->skin; // custom player skin
  611. else
  612. {
  613. if (currententity->skinnum >= MAX_MD2SKINS)
  614. skin = currentmodel->skins[0];
  615. else
  616. {
  617. skin = currentmodel->skins[currententity->skinnum];
  618. if (!skin)
  619. skin = currentmodel->skins[0];
  620. }
  621. }
  622. if (!skin)
  623. skin = r_notexture; // fallback...
  624. GL_Bind(skin->texnum);
  625. // draw it
  626. qglShadeModel (GL_SMOOTH);
  627. GL_TexEnv( GL_MODULATE );
  628. if ( currententity->flags & RF_TRANSLUCENT )
  629. {
  630. qglEnable (GL_BLEND);
  631. }
  632. if ( (currententity->frame >= paliashdr->num_frames)
  633. || (currententity->frame < 0) )
  634. {
  635. ri.Con_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n",
  636. currentmodel->name, currententity->frame);
  637. currententity->frame = 0;
  638. currententity->oldframe = 0;
  639. }
  640. if ( (currententity->oldframe >= paliashdr->num_frames)
  641. || (currententity->oldframe < 0))
  642. {
  643. ri.Con_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n",
  644. currentmodel->name, currententity->oldframe);
  645. currententity->frame = 0;
  646. currententity->oldframe = 0;
  647. }
  648. if ( !r_lerpmodels->value )
  649. currententity->backlerp = 0;
  650. GL_DrawAliasFrameLerp (paliashdr, currententity->backlerp);
  651. GL_TexEnv( GL_REPLACE );
  652. qglShadeModel (GL_FLAT);
  653. qglPopMatrix ();
  654. #if 0
  655. qglDisable( GL_CULL_FACE );
  656. qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
  657. qglDisable( GL_TEXTURE_2D );
  658. qglBegin( GL_TRIANGLE_STRIP );
  659. for ( i = 0; i < 8; i++ )
  660. {
  661. qglVertex3fv( bbox[i] );
  662. }
  663. qglEnd();
  664. qglEnable( GL_TEXTURE_2D );
  665. qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
  666. qglEnable( GL_CULL_FACE );
  667. #endif
  668. if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
  669. {
  670. qglMatrixMode( GL_PROJECTION );
  671. qglPopMatrix();
  672. qglMatrixMode( GL_MODELVIEW );
  673. qglCullFace( GL_FRONT );
  674. }
  675. if ( currententity->flags & RF_TRANSLUCENT )
  676. {
  677. qglDisable (GL_BLEND);
  678. }
  679. if (currententity->flags & RF_DEPTHHACK)
  680. qglDepthRange (gldepthmin, gldepthmax);
  681. #if 1
  682. if (gl_shadows->value && !(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL)))
  683. {
  684. qglPushMatrix ();
  685. R_RotateForEntity (e);
  686. qglDisable (GL_TEXTURE_2D);
  687. qglEnable (GL_BLEND);
  688. qglColor4f (0,0,0,0.5);
  689. GL_DrawAliasShadow (paliashdr, currententity->frame );
  690. qglEnable (GL_TEXTURE_2D);
  691. qglDisable (GL_BLEND);
  692. qglPopMatrix ();
  693. }
  694. #endif
  695. qglColor4f (1,1,1,1);
  696. }