gl_rmain.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145
  1. /*
  2. Copyright (C) 1996-1997 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. // r_main.c
  16. #include "quakedef.h"
  17. entity_t r_worldentity;
  18. qboolean r_cache_thrash; // compatability
  19. vec3_t modelorg, r_entorigin;
  20. entity_t *currententity;
  21. int r_visframecount; // bumped when going to a new PVS
  22. int r_framecount; // used for dlight push checking
  23. mplane_t frustum[4];
  24. int c_brush_polys, c_alias_polys;
  25. qboolean envmap; // true during envmap command capture
  26. int currenttexture = -1; // to avoid unnecessary texture sets
  27. int cnttextures[2] = {-1, -1}; // cached
  28. int particletexture; // little dot for particles
  29. int playertextures; // up to 16 color translated skins
  30. int mirrortexturenum; // quake texturenum, not gltexturenum
  31. qboolean mirror;
  32. mplane_t *mirror_plane;
  33. //
  34. // view origin
  35. //
  36. vec3_t vup;
  37. vec3_t vpn;
  38. vec3_t vright;
  39. vec3_t r_origin;
  40. float r_world_matrix[16];
  41. float r_base_world_matrix[16];
  42. //
  43. // screen size info
  44. //
  45. refdef_t r_refdef;
  46. mleaf_t *r_viewleaf, *r_oldviewleaf;
  47. texture_t *r_notexture_mip;
  48. int d_lightstylevalue[256]; // 8.8 fraction of base light value
  49. void R_MarkLeaves (void);
  50. cvar_t r_norefresh = {"r_norefresh","0"};
  51. cvar_t r_drawentities = {"r_drawentities","1"};
  52. cvar_t r_drawviewmodel = {"r_drawviewmodel","1"};
  53. cvar_t r_speeds = {"r_speeds","0"};
  54. cvar_t r_fullbright = {"r_fullbright","0"};
  55. cvar_t r_lightmap = {"r_lightmap","0"};
  56. cvar_t r_shadows = {"r_shadows","0"};
  57. cvar_t r_mirroralpha = {"r_mirroralpha","1"};
  58. cvar_t r_wateralpha = {"r_wateralpha","1"};
  59. cvar_t r_dynamic = {"r_dynamic","1"};
  60. cvar_t r_novis = {"r_novis","0"};
  61. cvar_t r_netgraph = {"r_netgraph","0"};
  62. cvar_t gl_clear = {"gl_clear","0"};
  63. cvar_t gl_cull = {"gl_cull","1"};
  64. cvar_t gl_texsort = {"gl_texsort","1"};
  65. cvar_t gl_smoothmodels = {"gl_smoothmodels","1"};
  66. cvar_t gl_affinemodels = {"gl_affinemodels","0"};
  67. cvar_t gl_polyblend = {"gl_polyblend","1"};
  68. cvar_t gl_flashblend = {"gl_flashblend","1"};
  69. cvar_t gl_playermip = {"gl_playermip","0"};
  70. cvar_t gl_nocolors = {"gl_nocolors","0"};
  71. cvar_t gl_keeptjunctions = {"gl_keeptjunctions","1"};
  72. cvar_t gl_reporttjunctions = {"gl_reporttjunctions","0"};
  73. cvar_t gl_finish = {"gl_finish","0"};
  74. extern cvar_t gl_ztrick;
  75. extern cvar_t scr_fov;
  76. /*
  77. =================
  78. R_CullBox
  79. Returns true if the box is completely outside the frustom
  80. =================
  81. */
  82. qboolean R_CullBox (vec3_t mins, vec3_t maxs)
  83. {
  84. int i;
  85. for (i=0 ; i<4 ; i++)
  86. if (BoxOnPlaneSide (mins, maxs, &frustum[i]) == 2)
  87. return true;
  88. return false;
  89. }
  90. void R_RotateForEntity (entity_t *e)
  91. {
  92. glTranslatef (e->origin[0], e->origin[1], e->origin[2]);
  93. glRotatef (e->angles[1], 0, 0, 1);
  94. glRotatef (-e->angles[0], 0, 1, 0);
  95. //ZOID: fixed z angle
  96. glRotatef (e->angles[2], 1, 0, 0);
  97. }
  98. /*
  99. =============================================================
  100. SPRITE MODELS
  101. =============================================================
  102. */
  103. /*
  104. ================
  105. R_GetSpriteFrame
  106. ================
  107. */
  108. mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
  109. {
  110. msprite_t *psprite;
  111. mspritegroup_t *pspritegroup;
  112. mspriteframe_t *pspriteframe;
  113. int i, numframes, frame;
  114. float *pintervals, fullinterval, targettime, time;
  115. psprite = currententity->model->cache.data;
  116. frame = currententity->frame;
  117. if ((frame >= psprite->numframes) || (frame < 0))
  118. {
  119. Con_Printf ("R_DrawSprite: no such frame %d\n", frame);
  120. frame = 0;
  121. }
  122. if (psprite->frames[frame].type == SPR_SINGLE)
  123. {
  124. pspriteframe = psprite->frames[frame].frameptr;
  125. }
  126. else
  127. {
  128. pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
  129. pintervals = pspritegroup->intervals;
  130. numframes = pspritegroup->numframes;
  131. fullinterval = pintervals[numframes-1];
  132. time = cl.time + currententity->syncbase;
  133. // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
  134. // are positive, so we don't have to worry about division by 0
  135. targettime = time - ((int)(time / fullinterval)) * fullinterval;
  136. for (i=0 ; i<(numframes-1) ; i++)
  137. {
  138. if (pintervals[i] > targettime)
  139. break;
  140. }
  141. pspriteframe = pspritegroup->frames[i];
  142. }
  143. return pspriteframe;
  144. }
  145. /*
  146. =================
  147. R_DrawSpriteModel
  148. =================
  149. */
  150. void R_DrawSpriteModel (entity_t *e)
  151. {
  152. vec3_t point;
  153. mspriteframe_t *frame;
  154. float *up, *right;
  155. vec3_t v_forward, v_right, v_up;
  156. msprite_t *psprite;
  157. // don't even bother culling, because it's just a single
  158. // polygon without a surface cache
  159. frame = R_GetSpriteFrame (e);
  160. psprite = currententity->model->cache.data;
  161. if (psprite->type == SPR_ORIENTED)
  162. { // bullet marks on walls
  163. AngleVectors (currententity->angles, v_forward, v_right, v_up);
  164. up = v_up;
  165. right = v_right;
  166. }
  167. else
  168. { // normal sprite
  169. up = vup;
  170. right = vright;
  171. }
  172. glColor3f (1,1,1);
  173. GL_DisableMultitexture();
  174. GL_Bind(frame->gl_texturenum);
  175. glEnable (GL_ALPHA_TEST);
  176. glBegin (GL_QUADS);
  177. glEnable (GL_ALPHA_TEST);
  178. glBegin (GL_QUADS);
  179. glTexCoord2f (0, 1);
  180. VectorMA (e->origin, frame->down, up, point);
  181. VectorMA (point, frame->left, right, point);
  182. glVertex3fv (point);
  183. glTexCoord2f (0, 0);
  184. VectorMA (e->origin, frame->up, up, point);
  185. VectorMA (point, frame->left, right, point);
  186. glVertex3fv (point);
  187. glTexCoord2f (1, 0);
  188. VectorMA (e->origin, frame->up, up, point);
  189. VectorMA (point, frame->right, right, point);
  190. glVertex3fv (point);
  191. glTexCoord2f (1, 1);
  192. VectorMA (e->origin, frame->down, up, point);
  193. VectorMA (point, frame->right, right, point);
  194. glVertex3fv (point);
  195. glEnd ();
  196. glDisable (GL_ALPHA_TEST);
  197. }
  198. /*
  199. =============================================================
  200. ALIAS MODELS
  201. =============================================================
  202. */
  203. #define NUMVERTEXNORMALS 162
  204. float r_avertexnormals[NUMVERTEXNORMALS][3] = {
  205. #include "anorms.h"
  206. };
  207. vec3_t shadevector;
  208. float shadelight, ambientlight;
  209. // precalculated dot products for quantized angles
  210. #define SHADEDOT_QUANT 16
  211. float r_avertexnormal_dots[SHADEDOT_QUANT][256] =
  212. #include "anorm_dots.h"
  213. ;
  214. float *shadedots = r_avertexnormal_dots[0];
  215. int lastposenum;
  216. /*
  217. =============
  218. GL_DrawAliasFrame
  219. =============
  220. */
  221. void GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum)
  222. {
  223. float l;
  224. trivertx_t *verts;
  225. int *order;
  226. int count;
  227. lastposenum = posenum;
  228. verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
  229. verts += posenum * paliashdr->poseverts;
  230. order = (int *)((byte *)paliashdr + paliashdr->commands);
  231. while (1)
  232. {
  233. // get the vertex count and primitive type
  234. count = *order++;
  235. if (!count)
  236. break; // done
  237. if (count < 0)
  238. {
  239. count = -count;
  240. glBegin (GL_TRIANGLE_FAN);
  241. }
  242. else
  243. glBegin (GL_TRIANGLE_STRIP);
  244. do
  245. {
  246. // texture coordinates come from the draw list
  247. glTexCoord2f (((float *)order)[0], ((float *)order)[1]);
  248. order += 2;
  249. // normals and vertexes come from the frame list
  250. l = shadedots[verts->lightnormalindex] * shadelight;
  251. glColor3f (l, l, l);
  252. glVertex3f (verts->v[0], verts->v[1], verts->v[2]);
  253. verts++;
  254. } while (--count);
  255. glEnd ();
  256. }
  257. }
  258. /*
  259. =============
  260. GL_DrawAliasShadow
  261. =============
  262. */
  263. extern vec3_t lightspot;
  264. void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
  265. {
  266. trivertx_t *verts;
  267. int *order;
  268. vec3_t point;
  269. float height, lheight;
  270. int count;
  271. lheight = currententity->origin[2] - lightspot[2];
  272. height = 0;
  273. verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
  274. verts += posenum * paliashdr->poseverts;
  275. order = (int *)((byte *)paliashdr + paliashdr->commands);
  276. height = -lheight + 1.0;
  277. while (1)
  278. {
  279. // get the vertex count and primitive type
  280. count = *order++;
  281. if (!count)
  282. break; // done
  283. if (count < 0)
  284. {
  285. count = -count;
  286. glBegin (GL_TRIANGLE_FAN);
  287. }
  288. else
  289. glBegin (GL_TRIANGLE_STRIP);
  290. do
  291. {
  292. // texture coordinates come from the draw list
  293. // (skipped for shadows) glTexCoord2fv ((float *)order);
  294. order += 2;
  295. // normals and vertexes come from the frame list
  296. point[0] = verts->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0];
  297. point[1] = verts->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1];
  298. point[2] = verts->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2];
  299. point[0] -= shadevector[0]*(point[2]+lheight);
  300. point[1] -= shadevector[1]*(point[2]+lheight);
  301. point[2] = height;
  302. // height -= 0.001;
  303. glVertex3fv (point);
  304. verts++;
  305. } while (--count);
  306. glEnd ();
  307. }
  308. }
  309. /*
  310. =================
  311. R_SetupAliasFrame
  312. =================
  313. */
  314. void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr)
  315. {
  316. int pose, numposes;
  317. float interval;
  318. if ((frame >= paliashdr->numframes) || (frame < 0))
  319. {
  320. Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
  321. frame = 0;
  322. }
  323. pose = paliashdr->frames[frame].firstpose;
  324. numposes = paliashdr->frames[frame].numposes;
  325. if (numposes > 1)
  326. {
  327. interval = paliashdr->frames[frame].interval;
  328. pose += (int)(cl.time / interval) % numposes;
  329. }
  330. GL_DrawAliasFrame (paliashdr, pose);
  331. }
  332. /*
  333. =================
  334. R_DrawAliasModel
  335. =================
  336. */
  337. void R_DrawAliasModel (entity_t *e)
  338. {
  339. int i;
  340. int lnum;
  341. vec3_t dist;
  342. float add;
  343. model_t *clmodel;
  344. vec3_t mins, maxs;
  345. aliashdr_t *paliashdr;
  346. float an;
  347. int anim;
  348. clmodel = currententity->model;
  349. VectorAdd (currententity->origin, clmodel->mins, mins);
  350. VectorAdd (currententity->origin, clmodel->maxs, maxs);
  351. if (R_CullBox (mins, maxs))
  352. return;
  353. VectorCopy (currententity->origin, r_entorigin);
  354. VectorSubtract (r_origin, r_entorigin, modelorg);
  355. //
  356. // get lighting information
  357. //
  358. ambientlight = shadelight = R_LightPoint (currententity->origin);
  359. // allways give the gun some light
  360. if (e == &cl.viewent && ambientlight < 24)
  361. ambientlight = shadelight = 24;
  362. for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
  363. {
  364. if (cl_dlights[lnum].die >= cl.time)
  365. {
  366. VectorSubtract (currententity->origin,
  367. cl_dlights[lnum].origin,
  368. dist);
  369. add = cl_dlights[lnum].radius - Length(dist);
  370. if (add > 0) {
  371. ambientlight += add;
  372. //ZOID models should be affected by dlights as well
  373. shadelight += add;
  374. }
  375. }
  376. }
  377. // clamp lighting so it doesn't overbright as much
  378. if (ambientlight > 128)
  379. ambientlight = 128;
  380. if (ambientlight + shadelight > 192)
  381. shadelight = 192 - ambientlight;
  382. // ZOID: never allow players to go totally black
  383. if (!strcmp(clmodel->name, "progs/player.mdl")) {
  384. if (ambientlight < 8)
  385. ambientlight = shadelight = 8;
  386. } else if (!strcmp (clmodel->name, "progs/flame2.mdl")
  387. || !strcmp (clmodel->name, "progs/flame.mdl") )
  388. // HACK HACK HACK -- no fullbright colors, so make torches full light
  389. ambientlight = shadelight = 256;
  390. shadedots = r_avertexnormal_dots[((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
  391. shadelight = shadelight / 200.0;
  392. an = e->angles[1]/180*M_PI;
  393. shadevector[0] = cos(-an);
  394. shadevector[1] = sin(-an);
  395. shadevector[2] = 1;
  396. VectorNormalize (shadevector);
  397. //
  398. // locate the proper data
  399. //
  400. paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model);
  401. c_alias_polys += paliashdr->numtris;
  402. //
  403. // draw all the triangles
  404. //
  405. GL_DisableMultitexture();
  406. glPushMatrix ();
  407. R_RotateForEntity (e);
  408. if (!strcmp (clmodel->name, "progs/eyes.mdl") ) {
  409. glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] - (22 + 8));
  410. // double size of eyes, since they are really hard to see in gl
  411. glScalef (paliashdr->scale[0]*2, paliashdr->scale[1]*2, paliashdr->scale[2]*2);
  412. } else {
  413. glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]);
  414. glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]);
  415. }
  416. anim = (int)(cl.time*10) & 3;
  417. GL_Bind(paliashdr->gl_texturenum[currententity->skinnum][anim]);
  418. // we can't dynamically colormap textures, so they are cached
  419. // seperately for the players. Heads are just uncolored.
  420. if (currententity->scoreboard && !gl_nocolors.value)
  421. {
  422. i = currententity->scoreboard - cl.players;
  423. if (!currententity->scoreboard->skin) {
  424. Skin_Find(currententity->scoreboard);
  425. R_TranslatePlayerSkin(i);
  426. }
  427. if (i >= 0 && i<MAX_CLIENTS)
  428. GL_Bind(playertextures + i);
  429. }
  430. if (gl_smoothmodels.value)
  431. glShadeModel (GL_SMOOTH);
  432. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  433. if (gl_affinemodels.value)
  434. glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  435. R_SetupAliasFrame (currententity->frame, paliashdr);
  436. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  437. glShadeModel (GL_FLAT);
  438. if (gl_affinemodels.value)
  439. glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  440. glPopMatrix ();
  441. if (r_shadows.value)
  442. {
  443. glPushMatrix ();
  444. R_RotateForEntity (e);
  445. glDisable (GL_TEXTURE_2D);
  446. glEnable (GL_BLEND);
  447. glColor4f (0,0,0,0.5);
  448. GL_DrawAliasShadow (paliashdr, lastposenum);
  449. glEnable (GL_TEXTURE_2D);
  450. glDisable (GL_BLEND);
  451. glColor4f (1,1,1,1);
  452. glPopMatrix ();
  453. }
  454. }
  455. //==================================================================================
  456. /*
  457. =============
  458. R_DrawEntitiesOnList
  459. =============
  460. */
  461. void R_DrawEntitiesOnList (void)
  462. {
  463. int i;
  464. if (!r_drawentities.value)
  465. return;
  466. // draw sprites seperately, because of alpha blending
  467. for (i=0 ; i<cl_numvisedicts ; i++)
  468. {
  469. currententity = &cl_visedicts[i];
  470. switch (currententity->model->type)
  471. {
  472. case mod_alias:
  473. R_DrawAliasModel (currententity);
  474. break;
  475. case mod_brush:
  476. R_DrawBrushModel (currententity);
  477. break;
  478. default:
  479. break;
  480. }
  481. }
  482. for (i=0 ; i<cl_numvisedicts ; i++)
  483. {
  484. currententity = &cl_visedicts[i];
  485. switch (currententity->model->type)
  486. {
  487. case mod_sprite:
  488. R_DrawSpriteModel (currententity);
  489. break;
  490. default :
  491. break;
  492. }
  493. }
  494. }
  495. /*
  496. =============
  497. R_DrawViewModel
  498. =============
  499. */
  500. void R_DrawViewModel (void)
  501. {
  502. float ambient[4], diffuse[4];
  503. int j;
  504. int lnum;
  505. vec3_t dist;
  506. float add;
  507. dlight_t *dl;
  508. int ambientlight, shadelight;
  509. if (!r_drawviewmodel.value || !Cam_DrawViewModel())
  510. return;
  511. if (envmap)
  512. return;
  513. if (!r_drawentities.value)
  514. return;
  515. if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
  516. return;
  517. if (cl.stats[STAT_HEALTH] <= 0)
  518. return;
  519. currententity = &cl.viewent;
  520. if (!currententity->model)
  521. return;
  522. j = R_LightPoint (currententity->origin);
  523. if (j < 24)
  524. j = 24; // allways give some light on gun
  525. ambientlight = j;
  526. shadelight = j;
  527. // add dynamic lights
  528. for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
  529. {
  530. dl = &cl_dlights[lnum];
  531. if (!dl->radius)
  532. continue;
  533. if (!dl->radius)
  534. continue;
  535. if (dl->die < cl.time)
  536. continue;
  537. VectorSubtract (currententity->origin, dl->origin, dist);
  538. add = dl->radius - Length(dist);
  539. if (add > 0)
  540. ambientlight += add;
  541. }
  542. ambient[0] = ambient[1] = ambient[2] = ambient[3] = (float)ambientlight / 128;
  543. diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = (float)shadelight / 128;
  544. // hack the depth range to prevent view model from poking into walls
  545. glDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
  546. R_DrawAliasModel (currententity);
  547. glDepthRange (gldepthmin, gldepthmax);
  548. }
  549. /*
  550. ============
  551. R_PolyBlend
  552. ============
  553. */
  554. void R_PolyBlend (void)
  555. {
  556. if (!gl_polyblend.value)
  557. return;
  558. if (!v_blend[3])
  559. return;
  560. //Con_Printf("R_PolyBlend(): %4.2f %4.2f %4.2f %4.2f\n",v_blend[0], v_blend[1], v_blend[2], v_blend[3]);
  561. GL_DisableMultitexture();
  562. glDisable (GL_ALPHA_TEST);
  563. glEnable (GL_BLEND);
  564. glDisable (GL_DEPTH_TEST);
  565. glDisable (GL_TEXTURE_2D);
  566. glLoadIdentity ();
  567. glRotatef (-90, 1, 0, 0); // put Z going up
  568. glRotatef (90, 0, 0, 1); // put Z going up
  569. glColor4fv (v_blend);
  570. glBegin (GL_QUADS);
  571. glVertex3f (10, 100, 100);
  572. glVertex3f (10, -100, 100);
  573. glVertex3f (10, -100, -100);
  574. glVertex3f (10, 100, -100);
  575. glEnd ();
  576. glDisable (GL_BLEND);
  577. glEnable (GL_TEXTURE_2D);
  578. glEnable (GL_ALPHA_TEST);
  579. }
  580. int SignbitsForPlane (mplane_t *out)
  581. {
  582. int bits, j;
  583. // for fast box on planeside test
  584. bits = 0;
  585. for (j=0 ; j<3 ; j++)
  586. {
  587. if (out->normal[j] < 0)
  588. bits |= 1<<j;
  589. }
  590. return bits;
  591. }
  592. void R_SetFrustum (void)
  593. {
  594. int i;
  595. if (r_refdef.fov_x == 90)
  596. {
  597. // front side is visible
  598. VectorAdd (vpn, vright, frustum[0].normal);
  599. VectorSubtract (vpn, vright, frustum[1].normal);
  600. VectorAdd (vpn, vup, frustum[2].normal);
  601. VectorSubtract (vpn, vup, frustum[3].normal);
  602. }
  603. else
  604. {
  605. // rotate VPN right by FOV_X/2 degrees
  606. RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_refdef.fov_x / 2 ) );
  607. // rotate VPN left by FOV_X/2 degrees
  608. RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_refdef.fov_x / 2 );
  609. // rotate VPN up by FOV_X/2 degrees
  610. RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_refdef.fov_y / 2 );
  611. // rotate VPN down by FOV_X/2 degrees
  612. RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_refdef.fov_y / 2 ) );
  613. }
  614. for (i=0 ; i<4 ; i++)
  615. {
  616. frustum[i].type = PLANE_ANYZ;
  617. frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
  618. frustum[i].signbits = SignbitsForPlane (&frustum[i]);
  619. }
  620. }
  621. /*
  622. ===============
  623. R_SetupFrame
  624. ===============
  625. */
  626. void R_SetupFrame (void)
  627. {
  628. // don't allow cheats in multiplayer
  629. r_fullbright.value = 0;
  630. r_lightmap.value = 0;
  631. if (!atoi(Info_ValueForKey(cl.serverinfo, "watervis")))
  632. r_wateralpha.value = 1;
  633. R_AnimateLight ();
  634. r_framecount++;
  635. // build the transformation matrix for the given view angles
  636. VectorCopy (r_refdef.vieworg, r_origin);
  637. AngleVectors (r_refdef.viewangles, vpn, vright, vup);
  638. // current viewleaf
  639. r_oldviewleaf = r_viewleaf;
  640. r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel);
  641. V_SetContentsColor (r_viewleaf->contents);
  642. V_CalcBlend ();
  643. r_cache_thrash = false;
  644. c_brush_polys = 0;
  645. c_alias_polys = 0;
  646. }
  647. void MYgluPerspective( GLdouble fovy, GLdouble aspect,
  648. GLdouble zNear, GLdouble zFar )
  649. {
  650. GLdouble xmin, xmax, ymin, ymax;
  651. ymax = zNear * tan( fovy * M_PI / 360.0 );
  652. ymin = -ymax;
  653. xmin = ymin * aspect;
  654. xmax = ymax * aspect;
  655. glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
  656. }
  657. /*
  658. =============
  659. R_SetupGL
  660. =============
  661. */
  662. void R_SetupGL (void)
  663. {
  664. float screenaspect;
  665. extern int glwidth, glheight;
  666. int x, x2, y2, y, w, h;
  667. //
  668. // set up viewpoint
  669. //
  670. glMatrixMode(GL_PROJECTION);
  671. glLoadIdentity ();
  672. x = r_refdef.vrect.x * glwidth/vid.width;
  673. x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/vid.width;
  674. y = (vid.height-r_refdef.vrect.y) * glheight/vid.height;
  675. y2 = (vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/vid.height;
  676. // fudge around because of frac screen scale
  677. if (x > 0)
  678. x--;
  679. if (x2 < glwidth)
  680. x2++;
  681. if (y2 < 0)
  682. y2--;
  683. if (y < glheight)
  684. y++;
  685. w = x2 - x;
  686. h = y - y2;
  687. if (envmap)
  688. {
  689. x = y2 = 0;
  690. w = h = 256;
  691. }
  692. glViewport (glx + x, gly + y2, w, h);
  693. screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
  694. // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI;
  695. // yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect;
  696. // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI;
  697. // MYgluPerspective (yfov, screenaspect, 4, 4096);
  698. MYgluPerspective (r_refdef.fov_y, screenaspect, 4, 4096);
  699. if (mirror)
  700. {
  701. if (mirror_plane->normal[2])
  702. glScalef (1, -1, 1);
  703. else
  704. glScalef (-1, 1, 1);
  705. glCullFace(GL_BACK);
  706. }
  707. else
  708. glCullFace(GL_FRONT);
  709. glMatrixMode(GL_MODELVIEW);
  710. glLoadIdentity ();
  711. glRotatef (-90, 1, 0, 0); // put Z going up
  712. glRotatef (90, 0, 0, 1); // put Z going up
  713. glRotatef (-r_refdef.viewangles[2], 1, 0, 0);
  714. glRotatef (-r_refdef.viewangles[0], 0, 1, 0);
  715. glRotatef (-r_refdef.viewangles[1], 0, 0, 1);
  716. glTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]);
  717. glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
  718. //
  719. // set drawing parms
  720. //
  721. if (gl_cull.value)
  722. glEnable(GL_CULL_FACE);
  723. else
  724. glDisable(GL_CULL_FACE);
  725. glDisable(GL_BLEND);
  726. glDisable(GL_ALPHA_TEST);
  727. glEnable(GL_DEPTH_TEST);
  728. }
  729. /*
  730. ================
  731. R_RenderScene
  732. r_refdef must be set before the first call
  733. ================
  734. */
  735. void R_RenderScene (void)
  736. {
  737. R_SetupFrame ();
  738. R_SetFrustum ();
  739. R_SetupGL ();
  740. R_MarkLeaves (); // done here so we know if we're in water
  741. R_DrawWorld (); // adds static entities to the list
  742. S_ExtraUpdate (); // don't let sound get messed up if going slow
  743. R_DrawEntitiesOnList ();
  744. GL_DisableMultitexture();
  745. R_RenderDlights ();
  746. R_DrawParticles ();
  747. #ifdef GLTEST
  748. Test_Draw ();
  749. #endif
  750. }
  751. /*
  752. =============
  753. R_Clear
  754. =============
  755. */
  756. void R_Clear (void)
  757. {
  758. if (r_mirroralpha.value != 1.0)
  759. {
  760. if (gl_clear.value)
  761. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  762. else
  763. glClear (GL_DEPTH_BUFFER_BIT);
  764. gldepthmin = 0;
  765. gldepthmax = 0.5;
  766. glDepthFunc (GL_LEQUAL);
  767. }
  768. else if (gl_ztrick.value)
  769. {
  770. static int trickframe;
  771. if (gl_clear.value)
  772. glClear (GL_COLOR_BUFFER_BIT);
  773. trickframe++;
  774. if (trickframe & 1)
  775. {
  776. gldepthmin = 0;
  777. gldepthmax = 0.49999;
  778. glDepthFunc (GL_LEQUAL);
  779. }
  780. else
  781. {
  782. gldepthmin = 1;
  783. gldepthmax = 0.5;
  784. glDepthFunc (GL_GEQUAL);
  785. }
  786. }
  787. else
  788. {
  789. if (gl_clear.value)
  790. glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  791. else
  792. glClear (GL_DEPTH_BUFFER_BIT);
  793. gldepthmin = 0;
  794. gldepthmax = 1;
  795. glDepthFunc (GL_LEQUAL);
  796. }
  797. glDepthRange (gldepthmin, gldepthmax);
  798. }
  799. #if 0 //!!! FIXME, Zoid, mirror is disabled for now
  800. /*
  801. =============
  802. R_Mirror
  803. =============
  804. */
  805. void R_Mirror (void)
  806. {
  807. float d;
  808. msurface_t *s;
  809. entity_t *ent;
  810. if (!mirror)
  811. return;
  812. memcpy (r_base_world_matrix, r_world_matrix, sizeof(r_base_world_matrix));
  813. d = DotProduct (r_refdef.vieworg, mirror_plane->normal) - mirror_plane->dist;
  814. VectorMA (r_refdef.vieworg, -2*d, mirror_plane->normal, r_refdef.vieworg);
  815. d = DotProduct (vpn, mirror_plane->normal);
  816. VectorMA (vpn, -2*d, mirror_plane->normal, vpn);
  817. r_refdef.viewangles[0] = -asin (vpn[2])/M_PI*180;
  818. r_refdef.viewangles[1] = atan2 (vpn[1], vpn[0])/M_PI*180;
  819. r_refdef.viewangles[2] = -r_refdef.viewangles[2];
  820. ent = &cl_entities[cl.viewentity];
  821. if (cl_numvisedicts < MAX_VISEDICTS)
  822. {
  823. cl_visedicts[cl_numvisedicts] = ent;
  824. cl_numvisedicts++;
  825. }
  826. gldepthmin = 0.5;
  827. gldepthmax = 1;
  828. glDepthRange (gldepthmin, gldepthmax);
  829. glDepthFunc (GL_LEQUAL);
  830. R_RenderScene ();
  831. R_DrawWaterSurfaces ();
  832. gldepthmin = 0;
  833. gldepthmax = 0.5;
  834. glDepthRange (gldepthmin, gldepthmax);
  835. glDepthFunc (GL_LEQUAL);
  836. // blend on top
  837. glEnable (GL_BLEND);
  838. glMatrixMode(GL_PROJECTION);
  839. if (mirror_plane->normal[2])
  840. glScalef (1,-1,1);
  841. else
  842. glScalef (-1,1,1);
  843. glCullFace(GL_FRONT);
  844. glMatrixMode(GL_MODELVIEW);
  845. glLoadMatrixf (r_base_world_matrix);
  846. glColor4f (1,1,1,r_mirroralpha.value);
  847. s = cl.worldmodel->textures[mirrortexturenum]->texturechain;
  848. for ( ; s ; s=s->texturechain)
  849. R_RenderBrushPoly (s);
  850. cl.worldmodel->textures[mirrortexturenum]->texturechain = NULL;
  851. glDisable (GL_BLEND);
  852. glColor4f (1,1,1,1);
  853. }
  854. #endif
  855. /*
  856. ================
  857. R_RenderView
  858. r_refdef must be set before the first call
  859. ================
  860. */
  861. void R_RenderView (void)
  862. {
  863. double time1 = 0, time2;
  864. if (r_norefresh.value)
  865. return;
  866. if (!r_worldentity.model || !cl.worldmodel)
  867. Sys_Error ("R_RenderView: NULL worldmodel");
  868. if (r_speeds.value)
  869. {
  870. glFinish ();
  871. time1 = Sys_DoubleTime ();
  872. c_brush_polys = 0;
  873. c_alias_polys = 0;
  874. }
  875. mirror = false;
  876. if (gl_finish.value)
  877. glFinish ();
  878. R_Clear ();
  879. // render normal view
  880. R_RenderScene ();
  881. R_DrawViewModel ();
  882. R_DrawWaterSurfaces ();
  883. // render mirror view
  884. // R_Mirror ();
  885. R_PolyBlend ();
  886. if (r_speeds.value)
  887. {
  888. // glFinish ();
  889. time2 = Sys_DoubleTime ();
  890. Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys);
  891. }
  892. }