gl_rmain.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693
  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. // r_main.c
  16. #include "gl_local.h"
  17. void R_Clear (void);
  18. viddef_t vid;
  19. refimport_t ri;
  20. model_t *r_worldmodel;
  21. float gldepthmin, gldepthmax;
  22. glconfig_t gl_config;
  23. glstate_t gl_state;
  24. image_t *r_notexture; // use for bad textures
  25. image_t *r_particletexture; // little dot for particles
  26. entity_t *currententity;
  27. model_t *currentmodel;
  28. cplane_t frustum[4];
  29. int r_visframecount; // bumped when going to a new PVS
  30. int r_framecount; // used for dlight push checking
  31. int c_brush_polys, c_alias_polys;
  32. float v_blend[4]; // final blending color
  33. void GL_Strings_f( void );
  34. //
  35. // view origin
  36. //
  37. vec3_t vup;
  38. vec3_t vpn;
  39. vec3_t vright;
  40. vec3_t r_origin;
  41. float r_world_matrix[16];
  42. float r_base_world_matrix[16];
  43. //
  44. // screen size info
  45. //
  46. refdef_t r_newrefdef;
  47. int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
  48. cvar_t *r_norefresh;
  49. cvar_t *r_drawentities;
  50. cvar_t *r_drawworld;
  51. cvar_t *r_speeds;
  52. cvar_t *r_fullbright;
  53. cvar_t *r_novis;
  54. cvar_t *r_nocull;
  55. cvar_t *r_lerpmodels;
  56. cvar_t *r_lefthand;
  57. cvar_t *r_lightlevel; // FIXME: This is a HACK to get the client's light level
  58. cvar_t *gl_nosubimage;
  59. cvar_t *gl_allow_software;
  60. cvar_t *gl_vertex_arrays;
  61. cvar_t *gl_particle_min_size;
  62. cvar_t *gl_particle_max_size;
  63. cvar_t *gl_particle_size;
  64. cvar_t *gl_particle_att_a;
  65. cvar_t *gl_particle_att_b;
  66. cvar_t *gl_particle_att_c;
  67. cvar_t *gl_ext_swapinterval;
  68. cvar_t *gl_ext_palettedtexture;
  69. cvar_t *gl_ext_multitexture;
  70. cvar_t *gl_ext_pointparameters;
  71. cvar_t *gl_ext_compiled_vertex_array;
  72. cvar_t *gl_log;
  73. cvar_t *gl_bitdepth;
  74. cvar_t *gl_drawbuffer;
  75. cvar_t *gl_driver;
  76. cvar_t *gl_lightmap;
  77. cvar_t *gl_shadows;
  78. cvar_t *gl_mode;
  79. cvar_t *gl_dynamic;
  80. cvar_t *gl_monolightmap;
  81. cvar_t *gl_modulate;
  82. cvar_t *gl_nobind;
  83. cvar_t *gl_round_down;
  84. cvar_t *gl_picmip;
  85. cvar_t *gl_skymip;
  86. cvar_t *gl_showtris;
  87. cvar_t *gl_ztrick;
  88. cvar_t *gl_finish;
  89. cvar_t *gl_clear;
  90. cvar_t *gl_cull;
  91. cvar_t *gl_polyblend;
  92. cvar_t *gl_flashblend;
  93. cvar_t *gl_playermip;
  94. cvar_t *gl_saturatelighting;
  95. cvar_t *gl_swapinterval;
  96. cvar_t *gl_texturemode;
  97. cvar_t *gl_texturealphamode;
  98. cvar_t *gl_texturesolidmode;
  99. cvar_t *gl_lockpvs;
  100. cvar_t *gl_3dlabs_broken;
  101. cvar_t *vid_fullscreen;
  102. cvar_t *vid_gamma;
  103. cvar_t *vid_ref;
  104. /*
  105. =================
  106. R_CullBox
  107. Returns true if the box is completely outside the frustom
  108. =================
  109. */
  110. qboolean R_CullBox (vec3_t mins, vec3_t maxs)
  111. {
  112. int i;
  113. if (r_nocull->value)
  114. return false;
  115. for (i=0 ; i<4 ; i++)
  116. if ( BOX_ON_PLANE_SIDE(mins, maxs, &frustum[i]) == 2)
  117. return true;
  118. return false;
  119. }
  120. void R_RotateForEntity (entity_t *e)
  121. {
  122. qglTranslatef (e->origin[0], e->origin[1], e->origin[2]);
  123. qglRotatef (e->angles[1], 0, 0, 1);
  124. qglRotatef (-e->angles[0], 0, 1, 0);
  125. qglRotatef (-e->angles[2], 1, 0, 0);
  126. }
  127. /*
  128. =============================================================
  129. SPRITE MODELS
  130. =============================================================
  131. */
  132. /*
  133. =================
  134. R_DrawSpriteModel
  135. =================
  136. */
  137. void R_DrawSpriteModel (entity_t *e)
  138. {
  139. float alpha = 1.0F;
  140. vec3_t point;
  141. dsprframe_t *frame;
  142. float *up, *right;
  143. dsprite_t *psprite;
  144. // don't even bother culling, because it's just a single
  145. // polygon without a surface cache
  146. psprite = (dsprite_t *)currentmodel->extradata;
  147. #if 0
  148. if (e->frame < 0 || e->frame >= psprite->numframes)
  149. {
  150. ri.Con_Printf (PRINT_ALL, "no such sprite frame %i\n", e->frame);
  151. e->frame = 0;
  152. }
  153. #endif
  154. e->frame %= psprite->numframes;
  155. frame = &psprite->frames[e->frame];
  156. #if 0
  157. if (psprite->type == SPR_ORIENTED)
  158. { // bullet marks on walls
  159. vec3_t v_forward, v_right, v_up;
  160. AngleVectors (currententity->angles, v_forward, v_right, v_up);
  161. up = v_up;
  162. right = v_right;
  163. }
  164. else
  165. #endif
  166. { // normal sprite
  167. up = vup;
  168. right = vright;
  169. }
  170. if ( e->flags & RF_TRANSLUCENT )
  171. alpha = e->alpha;
  172. if ( alpha != 1.0F )
  173. qglEnable( GL_BLEND );
  174. qglColor4f( 1, 1, 1, alpha );
  175. GL_Bind(currentmodel->skins[e->frame]->texnum);
  176. GL_TexEnv( GL_MODULATE );
  177. if ( alpha == 1.0 )
  178. qglEnable (GL_ALPHA_TEST);
  179. else
  180. qglDisable( GL_ALPHA_TEST );
  181. qglBegin (GL_QUADS);
  182. qglTexCoord2f (0, 1);
  183. VectorMA (e->origin, -frame->origin_y, up, point);
  184. VectorMA (point, -frame->origin_x, right, point);
  185. qglVertex3fv (point);
  186. qglTexCoord2f (0, 0);
  187. VectorMA (e->origin, frame->height - frame->origin_y, up, point);
  188. VectorMA (point, -frame->origin_x, right, point);
  189. qglVertex3fv (point);
  190. qglTexCoord2f (1, 0);
  191. VectorMA (e->origin, frame->height - frame->origin_y, up, point);
  192. VectorMA (point, frame->width - frame->origin_x, right, point);
  193. qglVertex3fv (point);
  194. qglTexCoord2f (1, 1);
  195. VectorMA (e->origin, -frame->origin_y, up, point);
  196. VectorMA (point, frame->width - frame->origin_x, right, point);
  197. qglVertex3fv (point);
  198. qglEnd ();
  199. qglDisable (GL_ALPHA_TEST);
  200. GL_TexEnv( GL_REPLACE );
  201. if ( alpha != 1.0F )
  202. qglDisable( GL_BLEND );
  203. qglColor4f( 1, 1, 1, 1 );
  204. }
  205. //==================================================================================
  206. /*
  207. =============
  208. R_DrawNullModel
  209. =============
  210. */
  211. void R_DrawNullModel (void)
  212. {
  213. vec3_t shadelight;
  214. int i;
  215. if ( currententity->flags & RF_FULLBRIGHT )
  216. shadelight[0] = shadelight[1] = shadelight[2] = 1.0F;
  217. else
  218. R_LightPoint (currententity->origin, shadelight);
  219. qglPushMatrix ();
  220. R_RotateForEntity (currententity);
  221. qglDisable (GL_TEXTURE_2D);
  222. qglColor3fv (shadelight);
  223. qglBegin (GL_TRIANGLE_FAN);
  224. qglVertex3f (0, 0, -16);
  225. for (i=0 ; i<=4 ; i++)
  226. qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0);
  227. qglEnd ();
  228. qglBegin (GL_TRIANGLE_FAN);
  229. qglVertex3f (0, 0, 16);
  230. for (i=4 ; i>=0 ; i--)
  231. qglVertex3f (16*cos(i*M_PI/2), 16*sin(i*M_PI/2), 0);
  232. qglEnd ();
  233. qglColor3f (1,1,1);
  234. qglPopMatrix ();
  235. qglEnable (GL_TEXTURE_2D);
  236. }
  237. /*
  238. =============
  239. R_DrawEntitiesOnList
  240. =============
  241. */
  242. void R_DrawEntitiesOnList (void)
  243. {
  244. int i;
  245. if (!r_drawentities->value)
  246. return;
  247. // draw non-transparent first
  248. for (i=0 ; i<r_newrefdef.num_entities ; i++)
  249. {
  250. currententity = &r_newrefdef.entities[i];
  251. if (currententity->flags & RF_TRANSLUCENT)
  252. continue; // solid
  253. if ( currententity->flags & RF_BEAM )
  254. {
  255. R_DrawBeam( currententity );
  256. }
  257. else
  258. {
  259. currentmodel = currententity->model;
  260. if (!currentmodel)
  261. {
  262. R_DrawNullModel ();
  263. continue;
  264. }
  265. switch (currentmodel->type)
  266. {
  267. case mod_alias:
  268. R_DrawAliasModel (currententity);
  269. break;
  270. case mod_brush:
  271. R_DrawBrushModel (currententity);
  272. break;
  273. case mod_sprite:
  274. R_DrawSpriteModel (currententity);
  275. break;
  276. default:
  277. ri.Sys_Error (ERR_DROP, "Bad modeltype");
  278. break;
  279. }
  280. }
  281. }
  282. // draw transparent entities
  283. // we could sort these if it ever becomes a problem...
  284. qglDepthMask (0); // no z writes
  285. for (i=0 ; i<r_newrefdef.num_entities ; i++)
  286. {
  287. currententity = &r_newrefdef.entities[i];
  288. if (!(currententity->flags & RF_TRANSLUCENT))
  289. continue; // solid
  290. if ( currententity->flags & RF_BEAM )
  291. {
  292. R_DrawBeam( currententity );
  293. }
  294. else
  295. {
  296. currentmodel = currententity->model;
  297. if (!currentmodel)
  298. {
  299. R_DrawNullModel ();
  300. continue;
  301. }
  302. switch (currentmodel->type)
  303. {
  304. case mod_alias:
  305. R_DrawAliasModel (currententity);
  306. break;
  307. case mod_brush:
  308. R_DrawBrushModel (currententity);
  309. break;
  310. case mod_sprite:
  311. R_DrawSpriteModel (currententity);
  312. break;
  313. default:
  314. ri.Sys_Error (ERR_DROP, "Bad modeltype");
  315. break;
  316. }
  317. }
  318. }
  319. qglDepthMask (1); // back to writing
  320. }
  321. /*
  322. ** GL_DrawParticles
  323. **
  324. */
  325. void GL_DrawParticles( int num_particles, const particle_t particles[], const unsigned colortable[768] )
  326. {
  327. const particle_t *p;
  328. int i;
  329. vec3_t up, right;
  330. float scale;
  331. byte color[4];
  332. GL_Bind(r_particletexture->texnum);
  333. qglDepthMask( GL_FALSE ); // no z buffering
  334. qglEnable( GL_BLEND );
  335. GL_TexEnv( GL_MODULATE );
  336. qglBegin( GL_TRIANGLES );
  337. VectorScale (vup, 1.5, up);
  338. VectorScale (vright, 1.5, right);
  339. for ( p = particles, i=0 ; i < num_particles ; i++,p++)
  340. {
  341. // hack a scale up to keep particles from disapearing
  342. scale = ( p->origin[0] - r_origin[0] ) * vpn[0] +
  343. ( p->origin[1] - r_origin[1] ) * vpn[1] +
  344. ( p->origin[2] - r_origin[2] ) * vpn[2];
  345. if (scale < 20)
  346. scale = 1;
  347. else
  348. scale = 1 + scale * 0.004;
  349. *(int *)color = colortable[p->color];
  350. color[3] = p->alpha*255;
  351. qglColor4ubv( color );
  352. qglTexCoord2f( 0.0625, 0.0625 );
  353. qglVertex3fv( p->origin );
  354. qglTexCoord2f( 1.0625, 0.0625 );
  355. qglVertex3f( p->origin[0] + up[0]*scale,
  356. p->origin[1] + up[1]*scale,
  357. p->origin[2] + up[2]*scale);
  358. qglTexCoord2f( 0.0625, 1.0625 );
  359. qglVertex3f( p->origin[0] + right[0]*scale,
  360. p->origin[1] + right[1]*scale,
  361. p->origin[2] + right[2]*scale);
  362. }
  363. qglEnd ();
  364. qglDisable( GL_BLEND );
  365. qglColor4f( 1,1,1,1 );
  366. qglDepthMask( 1 ); // back to normal Z buffering
  367. GL_TexEnv( GL_REPLACE );
  368. }
  369. /*
  370. ===============
  371. R_DrawParticles
  372. ===============
  373. */
  374. void R_DrawParticles (void)
  375. {
  376. if ( gl_ext_pointparameters->value && qglPointParameterfEXT )
  377. {
  378. int i;
  379. unsigned char color[4];
  380. const particle_t *p;
  381. qglDepthMask( GL_FALSE );
  382. qglEnable( GL_BLEND );
  383. qglDisable( GL_TEXTURE_2D );
  384. qglPointSize( gl_particle_size->value );
  385. qglBegin( GL_POINTS );
  386. for ( i = 0, p = r_newrefdef.particles; i < r_newrefdef.num_particles; i++, p++ )
  387. {
  388. *(int *)color = d_8to24table[p->color];
  389. color[3] = p->alpha*255;
  390. qglColor4ubv( color );
  391. qglVertex3fv( p->origin );
  392. }
  393. qglEnd();
  394. qglDisable( GL_BLEND );
  395. qglColor4f( 1.0F, 1.0F, 1.0F, 1.0F );
  396. qglDepthMask( GL_TRUE );
  397. qglEnable( GL_TEXTURE_2D );
  398. }
  399. else
  400. {
  401. GL_DrawParticles( r_newrefdef.num_particles, r_newrefdef.particles, d_8to24table );
  402. }
  403. }
  404. /*
  405. ============
  406. R_PolyBlend
  407. ============
  408. */
  409. void R_PolyBlend (void)
  410. {
  411. if (!gl_polyblend->value)
  412. return;
  413. if (!v_blend[3])
  414. return;
  415. qglDisable (GL_ALPHA_TEST);
  416. qglEnable (GL_BLEND);
  417. qglDisable (GL_DEPTH_TEST);
  418. qglDisable (GL_TEXTURE_2D);
  419. qglLoadIdentity ();
  420. // FIXME: get rid of these
  421. qglRotatef (-90, 1, 0, 0); // put Z going up
  422. qglRotatef (90, 0, 0, 1); // put Z going up
  423. qglColor4fv (v_blend);
  424. qglBegin (GL_QUADS);
  425. qglVertex3f (10, 100, 100);
  426. qglVertex3f (10, -100, 100);
  427. qglVertex3f (10, -100, -100);
  428. qglVertex3f (10, 100, -100);
  429. qglEnd ();
  430. qglDisable (GL_BLEND);
  431. qglEnable (GL_TEXTURE_2D);
  432. qglEnable (GL_ALPHA_TEST);
  433. qglColor4f(1,1,1,1);
  434. }
  435. //=======================================================================
  436. int SignbitsForPlane (cplane_t *out)
  437. {
  438. int bits, j;
  439. // for fast box on planeside test
  440. bits = 0;
  441. for (j=0 ; j<3 ; j++)
  442. {
  443. if (out->normal[j] < 0)
  444. bits |= 1<<j;
  445. }
  446. return bits;
  447. }
  448. void R_SetFrustum (void)
  449. {
  450. int i;
  451. #if 0
  452. /*
  453. ** this code is wrong, since it presume a 90 degree FOV both in the
  454. ** horizontal and vertical plane
  455. */
  456. // front side is visible
  457. VectorAdd (vpn, vright, frustum[0].normal);
  458. VectorSubtract (vpn, vright, frustum[1].normal);
  459. VectorAdd (vpn, vup, frustum[2].normal);
  460. VectorSubtract (vpn, vup, frustum[3].normal);
  461. // we theoretically don't need to normalize these vectors, but I do it
  462. // anyway so that debugging is a little easier
  463. VectorNormalize( frustum[0].normal );
  464. VectorNormalize( frustum[1].normal );
  465. VectorNormalize( frustum[2].normal );
  466. VectorNormalize( frustum[3].normal );
  467. #else
  468. // rotate VPN right by FOV_X/2 degrees
  469. RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_newrefdef.fov_x / 2 ) );
  470. // rotate VPN left by FOV_X/2 degrees
  471. RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_newrefdef.fov_x / 2 );
  472. // rotate VPN up by FOV_X/2 degrees
  473. RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_newrefdef.fov_y / 2 );
  474. // rotate VPN down by FOV_X/2 degrees
  475. RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_newrefdef.fov_y / 2 ) );
  476. #endif
  477. for (i=0 ; i<4 ; i++)
  478. {
  479. frustum[i].type = PLANE_ANYZ;
  480. frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
  481. frustum[i].signbits = SignbitsForPlane (&frustum[i]);
  482. }
  483. }
  484. //=======================================================================
  485. /*
  486. ===============
  487. R_SetupFrame
  488. ===============
  489. */
  490. void R_SetupFrame (void)
  491. {
  492. int i;
  493. mleaf_t *leaf;
  494. r_framecount++;
  495. // build the transformation matrix for the given view angles
  496. VectorCopy (r_newrefdef.vieworg, r_origin);
  497. AngleVectors (r_newrefdef.viewangles, vpn, vright, vup);
  498. // current viewcluster
  499. if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
  500. {
  501. r_oldviewcluster = r_viewcluster;
  502. r_oldviewcluster2 = r_viewcluster2;
  503. leaf = Mod_PointInLeaf (r_origin, r_worldmodel);
  504. r_viewcluster = r_viewcluster2 = leaf->cluster;
  505. // check above and below so crossing solid water doesn't draw wrong
  506. if (!leaf->contents)
  507. { // look down a bit
  508. vec3_t temp;
  509. VectorCopy (r_origin, temp);
  510. temp[2] -= 16;
  511. leaf = Mod_PointInLeaf (temp, r_worldmodel);
  512. if ( !(leaf->contents & CONTENTS_SOLID) &&
  513. (leaf->cluster != r_viewcluster2) )
  514. r_viewcluster2 = leaf->cluster;
  515. }
  516. else
  517. { // look up a bit
  518. vec3_t temp;
  519. VectorCopy (r_origin, temp);
  520. temp[2] += 16;
  521. leaf = Mod_PointInLeaf (temp, r_worldmodel);
  522. if ( !(leaf->contents & CONTENTS_SOLID) &&
  523. (leaf->cluster != r_viewcluster2) )
  524. r_viewcluster2 = leaf->cluster;
  525. }
  526. }
  527. for (i=0 ; i<4 ; i++)
  528. v_blend[i] = r_newrefdef.blend[i];
  529. c_brush_polys = 0;
  530. c_alias_polys = 0;
  531. // clear out the portion of the screen that the NOWORLDMODEL defines
  532. if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
  533. {
  534. qglEnable( GL_SCISSOR_TEST );
  535. qglClearColor( 0.3, 0.3, 0.3, 1 );
  536. qglScissor( r_newrefdef.x, vid.height - r_newrefdef.height - r_newrefdef.y, r_newrefdef.width, r_newrefdef.height );
  537. qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  538. qglClearColor( 1, 0, 0.5, 0.5 );
  539. qglDisable( GL_SCISSOR_TEST );
  540. }
  541. }
  542. void MYgluPerspective( GLdouble fovy, GLdouble aspect,
  543. GLdouble zNear, GLdouble zFar )
  544. {
  545. GLdouble xmin, xmax, ymin, ymax;
  546. ymax = zNear * tan( fovy * M_PI / 360.0 );
  547. ymin = -ymax;
  548. xmin = ymin * aspect;
  549. xmax = ymax * aspect;
  550. xmin += -( 2 * gl_state.camera_separation ) / zNear;
  551. xmax += -( 2 * gl_state.camera_separation ) / zNear;
  552. qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
  553. }
  554. /*
  555. =============
  556. R_SetupGL
  557. =============
  558. */
  559. void R_SetupGL (void)
  560. {
  561. float screenaspect;
  562. // float yfov;
  563. int x, x2, y2, y, w, h;
  564. //
  565. // set up viewport
  566. //
  567. x = floor(r_newrefdef.x * vid.width / vid.width);
  568. x2 = ceil((r_newrefdef.x + r_newrefdef.width) * vid.width / vid.width);
  569. y = floor(vid.height - r_newrefdef.y * vid.height / vid.height);
  570. y2 = ceil(vid.height - (r_newrefdef.y + r_newrefdef.height) * vid.height / vid.height);
  571. w = x2 - x;
  572. h = y - y2;
  573. qglViewport (x, y2, w, h);
  574. //
  575. // set up projection matrix
  576. //
  577. screenaspect = (float)r_newrefdef.width/r_newrefdef.height;
  578. // yfov = 2*atan((float)r_newrefdef.height/r_newrefdef.width)*180/M_PI;
  579. qglMatrixMode(GL_PROJECTION);
  580. qglLoadIdentity ();
  581. MYgluPerspective (r_newrefdef.fov_y, screenaspect, 4, 4096);
  582. qglCullFace(GL_FRONT);
  583. qglMatrixMode(GL_MODELVIEW);
  584. qglLoadIdentity ();
  585. qglRotatef (-90, 1, 0, 0); // put Z going up
  586. qglRotatef (90, 0, 0, 1); // put Z going up
  587. qglRotatef (-r_newrefdef.viewangles[2], 1, 0, 0);
  588. qglRotatef (-r_newrefdef.viewangles[0], 0, 1, 0);
  589. qglRotatef (-r_newrefdef.viewangles[1], 0, 0, 1);
  590. qglTranslatef (-r_newrefdef.vieworg[0], -r_newrefdef.vieworg[1], -r_newrefdef.vieworg[2]);
  591. // if ( gl_state.camera_separation != 0 && gl_state.stereo_enabled )
  592. // qglTranslatef ( gl_state.camera_separation, 0, 0 );
  593. qglGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
  594. //
  595. // set drawing parms
  596. //
  597. if (gl_cull->value)
  598. qglEnable(GL_CULL_FACE);
  599. else
  600. qglDisable(GL_CULL_FACE);
  601. qglDisable(GL_BLEND);
  602. qglDisable(GL_ALPHA_TEST);
  603. qglEnable(GL_DEPTH_TEST);
  604. }
  605. /*
  606. =============
  607. R_Clear
  608. =============
  609. */
  610. void R_Clear (void)
  611. {
  612. if (gl_ztrick->value)
  613. {
  614. static int trickframe;
  615. if (gl_clear->value)
  616. qglClear (GL_COLOR_BUFFER_BIT);
  617. trickframe++;
  618. if (trickframe & 1)
  619. {
  620. gldepthmin = 0;
  621. gldepthmax = 0.49999;
  622. qglDepthFunc (GL_LEQUAL);
  623. }
  624. else
  625. {
  626. gldepthmin = 1;
  627. gldepthmax = 0.5;
  628. qglDepthFunc (GL_GEQUAL);
  629. }
  630. }
  631. else
  632. {
  633. if (gl_clear->value)
  634. qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  635. else
  636. qglClear (GL_DEPTH_BUFFER_BIT);
  637. gldepthmin = 0;
  638. gldepthmax = 1;
  639. qglDepthFunc (GL_LEQUAL);
  640. }
  641. qglDepthRange (gldepthmin, gldepthmax);
  642. }
  643. void R_Flash( void )
  644. {
  645. R_PolyBlend ();
  646. }
  647. /*
  648. ================
  649. R_RenderView
  650. r_newrefdef must be set before the first call
  651. ================
  652. */
  653. void R_RenderView (refdef_t *fd)
  654. {
  655. if (r_norefresh->value)
  656. return;
  657. r_newrefdef = *fd;
  658. if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
  659. ri.Sys_Error (ERR_DROP, "R_RenderView: NULL worldmodel");
  660. if (r_speeds->value)
  661. {
  662. c_brush_polys = 0;
  663. c_alias_polys = 0;
  664. }
  665. R_PushDlights ();
  666. if (gl_finish->value)
  667. qglFinish ();
  668. R_SetupFrame ();
  669. R_SetFrustum ();
  670. R_SetupGL ();
  671. R_MarkLeaves (); // done here so we know if we're in water
  672. R_DrawWorld ();
  673. R_DrawEntitiesOnList ();
  674. R_RenderDlights ();
  675. R_DrawParticles ();
  676. R_DrawAlphaSurfaces ();
  677. R_Flash();
  678. if (r_speeds->value)
  679. {
  680. ri.Con_Printf (PRINT_ALL, "%4i wpoly %4i epoly %i tex %i lmaps\n",
  681. c_brush_polys,
  682. c_alias_polys,
  683. c_visible_textures,
  684. c_visible_lightmaps);
  685. }
  686. }
  687. void R_SetGL2D (void)
  688. {
  689. // set 2D virtual screen size
  690. qglViewport (0,0, vid.width, vid.height);
  691. qglMatrixMode(GL_PROJECTION);
  692. qglLoadIdentity ();
  693. qglOrtho (0, vid.width, vid.height, 0, -99999, 99999);
  694. qglMatrixMode(GL_MODELVIEW);
  695. qglLoadIdentity ();
  696. qglDisable (GL_DEPTH_TEST);
  697. qglDisable (GL_CULL_FACE);
  698. qglDisable (GL_BLEND);
  699. qglEnable (GL_ALPHA_TEST);
  700. qglColor4f (1,1,1,1);
  701. }
  702. static void GL_DrawColoredStereoLinePair( float r, float g, float b, float y )
  703. {
  704. qglColor3f( r, g, b );
  705. qglVertex2f( 0, y );
  706. qglVertex2f( vid.width, y );
  707. qglColor3f( 0, 0, 0 );
  708. qglVertex2f( 0, y + 1 );
  709. qglVertex2f( vid.width, y + 1 );
  710. }
  711. static void GL_DrawStereoPattern( void )
  712. {
  713. int i;
  714. if ( !( gl_config.renderer & GL_RENDERER_INTERGRAPH ) )
  715. return;
  716. if ( !gl_state.stereo_enabled )
  717. return;
  718. R_SetGL2D();
  719. qglDrawBuffer( GL_BACK_LEFT );
  720. for ( i = 0; i < 20; i++ )
  721. {
  722. qglBegin( GL_LINES );
  723. GL_DrawColoredStereoLinePair( 1, 0, 0, 0 );
  724. GL_DrawColoredStereoLinePair( 1, 0, 0, 2 );
  725. GL_DrawColoredStereoLinePair( 1, 0, 0, 4 );
  726. GL_DrawColoredStereoLinePair( 1, 0, 0, 6 );
  727. GL_DrawColoredStereoLinePair( 0, 1, 0, 8 );
  728. GL_DrawColoredStereoLinePair( 1, 1, 0, 10);
  729. GL_DrawColoredStereoLinePair( 1, 1, 0, 12);
  730. GL_DrawColoredStereoLinePair( 0, 1, 0, 14);
  731. qglEnd();
  732. GLimp_EndFrame();
  733. }
  734. }
  735. /*
  736. ====================
  737. R_SetLightLevel
  738. ====================
  739. */
  740. void R_SetLightLevel (void)
  741. {
  742. vec3_t shadelight;
  743. if (r_newrefdef.rdflags & RDF_NOWORLDMODEL)
  744. return;
  745. // save off light value for server to look at (BIG HACK!)
  746. R_LightPoint (r_newrefdef.vieworg, shadelight);
  747. // pick the greatest component, which should be the same
  748. // as the mono value returned by software
  749. if (shadelight[0] > shadelight[1])
  750. {
  751. if (shadelight[0] > shadelight[2])
  752. r_lightlevel->value = 150*shadelight[0];
  753. else
  754. r_lightlevel->value = 150*shadelight[2];
  755. }
  756. else
  757. {
  758. if (shadelight[1] > shadelight[2])
  759. r_lightlevel->value = 150*shadelight[1];
  760. else
  761. r_lightlevel->value = 150*shadelight[2];
  762. }
  763. }
  764. /*
  765. @@@@@@@@@@@@@@@@@@@@@
  766. R_RenderFrame
  767. @@@@@@@@@@@@@@@@@@@@@
  768. */
  769. void R_RenderFrame (refdef_t *fd)
  770. {
  771. R_RenderView( fd );
  772. R_SetLightLevel ();
  773. R_SetGL2D ();
  774. }
  775. void R_Register( void )
  776. {
  777. r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
  778. r_norefresh = ri.Cvar_Get ("r_norefresh", "0", 0);
  779. r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0);
  780. r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0);
  781. r_drawworld = ri.Cvar_Get ("r_drawworld", "1", 0);
  782. r_novis = ri.Cvar_Get ("r_novis", "0", 0);
  783. r_nocull = ri.Cvar_Get ("r_nocull", "0", 0);
  784. r_lerpmodels = ri.Cvar_Get ("r_lerpmodels", "1", 0);
  785. r_speeds = ri.Cvar_Get ("r_speeds", "0", 0);
  786. r_lightlevel = ri.Cvar_Get ("r_lightlevel", "0", 0);
  787. gl_nosubimage = ri.Cvar_Get( "gl_nosubimage", "0", 0 );
  788. gl_allow_software = ri.Cvar_Get( "gl_allow_software", "0", 0 );
  789. gl_particle_min_size = ri.Cvar_Get( "gl_particle_min_size", "2", CVAR_ARCHIVE );
  790. gl_particle_max_size = ri.Cvar_Get( "gl_particle_max_size", "40", CVAR_ARCHIVE );
  791. gl_particle_size = ri.Cvar_Get( "gl_particle_size", "40", CVAR_ARCHIVE );
  792. gl_particle_att_a = ri.Cvar_Get( "gl_particle_att_a", "0.01", CVAR_ARCHIVE );
  793. gl_particle_att_b = ri.Cvar_Get( "gl_particle_att_b", "0.0", CVAR_ARCHIVE );
  794. gl_particle_att_c = ri.Cvar_Get( "gl_particle_att_c", "0.01", CVAR_ARCHIVE );
  795. gl_modulate = ri.Cvar_Get ("gl_modulate", "1", CVAR_ARCHIVE );
  796. gl_log = ri.Cvar_Get( "gl_log", "0", 0 );
  797. gl_bitdepth = ri.Cvar_Get( "gl_bitdepth", "0", 0 );
  798. gl_mode = ri.Cvar_Get( "gl_mode", "3", CVAR_ARCHIVE );
  799. gl_lightmap = ri.Cvar_Get ("gl_lightmap", "0", 0);
  800. gl_shadows = ri.Cvar_Get ("gl_shadows", "0", CVAR_ARCHIVE );
  801. gl_dynamic = ri.Cvar_Get ("gl_dynamic", "1", 0);
  802. gl_nobind = ri.Cvar_Get ("gl_nobind", "0", 0);
  803. gl_round_down = ri.Cvar_Get ("gl_round_down", "1", 0);
  804. gl_picmip = ri.Cvar_Get ("gl_picmip", "0", 0);
  805. gl_skymip = ri.Cvar_Get ("gl_skymip", "0", 0);
  806. gl_showtris = ri.Cvar_Get ("gl_showtris", "0", 0);
  807. gl_ztrick = ri.Cvar_Get ("gl_ztrick", "0", 0);
  808. gl_finish = ri.Cvar_Get ("gl_finish", "0", CVAR_ARCHIVE);
  809. gl_clear = ri.Cvar_Get ("gl_clear", "0", 0);
  810. gl_cull = ri.Cvar_Get ("gl_cull", "1", 0);
  811. gl_polyblend = ri.Cvar_Get ("gl_polyblend", "1", 0);
  812. gl_flashblend = ri.Cvar_Get ("gl_flashblend", "0", 0);
  813. gl_playermip = ri.Cvar_Get ("gl_playermip", "0", 0);
  814. gl_monolightmap = ri.Cvar_Get( "gl_monolightmap", "0", 0 );
  815. gl_driver = ri.Cvar_Get( "gl_driver", "opengl32", CVAR_ARCHIVE );
  816. gl_texturemode = ri.Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE );
  817. gl_texturealphamode = ri.Cvar_Get( "gl_texturealphamode", "default", CVAR_ARCHIVE );
  818. gl_texturesolidmode = ri.Cvar_Get( "gl_texturesolidmode", "default", CVAR_ARCHIVE );
  819. gl_lockpvs = ri.Cvar_Get( "gl_lockpvs", "0", 0 );
  820. gl_vertex_arrays = ri.Cvar_Get( "gl_vertex_arrays", "0", CVAR_ARCHIVE );
  821. gl_ext_swapinterval = ri.Cvar_Get( "gl_ext_swapinterval", "1", CVAR_ARCHIVE );
  822. gl_ext_palettedtexture = ri.Cvar_Get( "gl_ext_palettedtexture", "1", CVAR_ARCHIVE );
  823. gl_ext_multitexture = ri.Cvar_Get( "gl_ext_multitexture", "1", CVAR_ARCHIVE );
  824. gl_ext_pointparameters = ri.Cvar_Get( "gl_ext_pointparameters", "1", CVAR_ARCHIVE );
  825. gl_ext_compiled_vertex_array = ri.Cvar_Get( "gl_ext_compiled_vertex_array", "1", CVAR_ARCHIVE );
  826. gl_drawbuffer = ri.Cvar_Get( "gl_drawbuffer", "GL_BACK", 0 );
  827. gl_swapinterval = ri.Cvar_Get( "gl_swapinterval", "1", CVAR_ARCHIVE );
  828. gl_saturatelighting = ri.Cvar_Get( "gl_saturatelighting", "0", 0 );
  829. gl_3dlabs_broken = ri.Cvar_Get( "gl_3dlabs_broken", "1", CVAR_ARCHIVE );
  830. vid_fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE );
  831. vid_gamma = ri.Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE );
  832. vid_ref = ri.Cvar_Get( "vid_ref", "soft", CVAR_ARCHIVE );
  833. ri.Cmd_AddCommand( "imagelist", GL_ImageList_f );
  834. ri.Cmd_AddCommand( "screenshot", GL_ScreenShot_f );
  835. ri.Cmd_AddCommand( "modellist", Mod_Modellist_f );
  836. ri.Cmd_AddCommand( "gl_strings", GL_Strings_f );
  837. }
  838. /*
  839. ==================
  840. R_SetMode
  841. ==================
  842. */
  843. qboolean R_SetMode (void)
  844. {
  845. rserr_t err;
  846. qboolean fullscreen;
  847. if ( vid_fullscreen->modified && !gl_config.allow_cds )
  848. {
  849. ri.Con_Printf( PRINT_ALL, "R_SetMode() - CDS not allowed with this driver\n" );
  850. ri.Cvar_SetValue( "vid_fullscreen", !vid_fullscreen->value );
  851. vid_fullscreen->modified = false;
  852. }
  853. fullscreen = vid_fullscreen->value;
  854. vid_fullscreen->modified = false;
  855. gl_mode->modified = false;
  856. if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, fullscreen ) ) == rserr_ok )
  857. {
  858. gl_state.prev_mode = gl_mode->value;
  859. }
  860. else
  861. {
  862. if ( err == rserr_invalid_fullscreen )
  863. {
  864. ri.Cvar_SetValue( "vid_fullscreen", 0);
  865. vid_fullscreen->modified = false;
  866. ri.Con_Printf( PRINT_ALL, "ref_gl::R_SetMode() - fullscreen unavailable in this mode\n" );
  867. if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_mode->value, false ) ) == rserr_ok )
  868. return true;
  869. }
  870. else if ( err == rserr_invalid_mode )
  871. {
  872. ri.Cvar_SetValue( "gl_mode", gl_state.prev_mode );
  873. gl_mode->modified = false;
  874. ri.Con_Printf( PRINT_ALL, "ref_gl::R_SetMode() - invalid mode\n" );
  875. }
  876. // try setting it back to something safe
  877. if ( ( err = GLimp_SetMode( &vid.width, &vid.height, gl_state.prev_mode, false ) ) != rserr_ok )
  878. {
  879. ri.Con_Printf( PRINT_ALL, "ref_gl::R_SetMode() - could not revert to safe mode\n" );
  880. return false;
  881. }
  882. }
  883. return true;
  884. }
  885. /*
  886. ===============
  887. R_Init
  888. ===============
  889. */
  890. int R_Init( void *hinstance, void *hWnd )
  891. {
  892. char renderer_buffer[1000];
  893. char vendor_buffer[1000];
  894. int err;
  895. int j;
  896. extern float r_turbsin[256];
  897. for ( j = 0; j < 256; j++ )
  898. {
  899. r_turbsin[j] *= 0.5;
  900. }
  901. ri.Con_Printf (PRINT_ALL, "ref_gl version: "REF_VERSION"\n");
  902. Draw_GetPalette ();
  903. R_Register();
  904. // initialize our QGL dynamic bindings
  905. if ( !QGL_Init( gl_driver->string ) )
  906. {
  907. QGL_Shutdown();
  908. ri.Con_Printf (PRINT_ALL, "ref_gl::R_Init() - could not load \"%s\"\n", gl_driver->string );
  909. return -1;
  910. }
  911. // initialize OS-specific parts of OpenGL
  912. if ( !GLimp_Init( hinstance, hWnd ) )
  913. {
  914. QGL_Shutdown();
  915. return -1;
  916. }
  917. // set our "safe" modes
  918. gl_state.prev_mode = 3;
  919. // create the window and set up the context
  920. if ( !R_SetMode () )
  921. {
  922. QGL_Shutdown();
  923. ri.Con_Printf (PRINT_ALL, "ref_gl::R_Init() - could not R_SetMode()\n" );
  924. return -1;
  925. }
  926. ri.Vid_MenuInit();
  927. /*
  928. ** get our various GL strings
  929. */
  930. gl_config.vendor_string = qglGetString (GL_VENDOR);
  931. ri.Con_Printf (PRINT_ALL, "GL_VENDOR: %s\n", gl_config.vendor_string );
  932. gl_config.renderer_string = qglGetString (GL_RENDERER);
  933. ri.Con_Printf (PRINT_ALL, "GL_RENDERER: %s\n", gl_config.renderer_string );
  934. gl_config.version_string = qglGetString (GL_VERSION);
  935. ri.Con_Printf (PRINT_ALL, "GL_VERSION: %s\n", gl_config.version_string );
  936. gl_config.extensions_string = qglGetString (GL_EXTENSIONS);
  937. ri.Con_Printf (PRINT_ALL, "GL_EXTENSIONS: %s\n", gl_config.extensions_string );
  938. strcpy( renderer_buffer, gl_config.renderer_string );
  939. strlwr( renderer_buffer );
  940. strcpy( vendor_buffer, gl_config.vendor_string );
  941. strlwr( vendor_buffer );
  942. if ( strstr( renderer_buffer, "voodoo" ) )
  943. {
  944. if ( !strstr( renderer_buffer, "rush" ) )
  945. gl_config.renderer = GL_RENDERER_VOODOO;
  946. else
  947. gl_config.renderer = GL_RENDERER_VOODOO_RUSH;
  948. }
  949. else if ( strstr( vendor_buffer, "sgi" ) )
  950. gl_config.renderer = GL_RENDERER_SGI;
  951. else if ( strstr( renderer_buffer, "permedia" ) )
  952. gl_config.renderer = GL_RENDERER_PERMEDIA2;
  953. else if ( strstr( renderer_buffer, "glint" ) )
  954. gl_config.renderer = GL_RENDERER_GLINT_MX;
  955. else if ( strstr( renderer_buffer, "glzicd" ) )
  956. gl_config.renderer = GL_RENDERER_REALIZM;
  957. else if ( strstr( renderer_buffer, "gdi" ) )
  958. gl_config.renderer = GL_RENDERER_MCD;
  959. else if ( strstr( renderer_buffer, "pcx2" ) )
  960. gl_config.renderer = GL_RENDERER_PCX2;
  961. else if ( strstr( renderer_buffer, "verite" ) )
  962. gl_config.renderer = GL_RENDERER_RENDITION;
  963. else
  964. gl_config.renderer = GL_RENDERER_OTHER;
  965. if ( toupper( gl_monolightmap->string[1] ) != 'F' )
  966. {
  967. if ( gl_config.renderer == GL_RENDERER_PERMEDIA2 )
  968. {
  969. ri.Cvar_Set( "gl_monolightmap", "A" );
  970. ri.Con_Printf( PRINT_ALL, "...using gl_monolightmap 'a'\n" );
  971. }
  972. else if ( gl_config.renderer & GL_RENDERER_POWERVR )
  973. {
  974. ri.Cvar_Set( "gl_monolightmap", "0" );
  975. }
  976. else
  977. {
  978. ri.Cvar_Set( "gl_monolightmap", "0" );
  979. }
  980. }
  981. // power vr can't have anything stay in the framebuffer, so
  982. // the screen needs to redraw the tiled background every frame
  983. if ( gl_config.renderer & GL_RENDERER_POWERVR )
  984. {
  985. ri.Cvar_Set( "scr_drawall", "1" );
  986. }
  987. else
  988. {
  989. ri.Cvar_Set( "scr_drawall", "0" );
  990. }
  991. // MCD has buffering issues
  992. if ( gl_config.renderer == GL_RENDERER_MCD )
  993. {
  994. ri.Cvar_SetValue( "gl_finish", 1 );
  995. }
  996. if ( gl_config.renderer & GL_RENDERER_3DLABS )
  997. {
  998. if ( gl_3dlabs_broken->value )
  999. gl_config.allow_cds = false;
  1000. else
  1001. gl_config.allow_cds = true;
  1002. }
  1003. else
  1004. {
  1005. gl_config.allow_cds = true;
  1006. }
  1007. if ( gl_config.allow_cds )
  1008. ri.Con_Printf( PRINT_ALL, "...allowing CDS\n" );
  1009. else
  1010. ri.Con_Printf( PRINT_ALL, "...disabling CDS\n" );
  1011. /*
  1012. ** grab extensions
  1013. */
  1014. #ifdef WIN32
  1015. if ( strstr( gl_config.extensions_string, "GL_EXT_compiled_vertex_array" ) ||
  1016. strstr( gl_config.extensions_string, "GL_SGI_compiled_vertex_array" ) )
  1017. {
  1018. ri.Con_Printf( PRINT_ALL, "...enabling GL_EXT_compiled_vertex_array\n" );
  1019. qglLockArraysEXT = ( void * ) qwglGetProcAddress( "glLockArraysEXT" );
  1020. qglUnlockArraysEXT = ( void * ) qwglGetProcAddress( "glUnlockArraysEXT" );
  1021. }
  1022. else
  1023. {
  1024. ri.Con_Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" );
  1025. }
  1026. if ( strstr( gl_config.extensions_string, "WGL_EXT_swap_control" ) )
  1027. {
  1028. qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" );
  1029. ri.Con_Printf( PRINT_ALL, "...enabling WGL_EXT_swap_control\n" );
  1030. }
  1031. else
  1032. {
  1033. ri.Con_Printf( PRINT_ALL, "...WGL_EXT_swap_control not found\n" );
  1034. }
  1035. if ( strstr( gl_config.extensions_string, "GL_EXT_point_parameters" ) )
  1036. {
  1037. if ( gl_ext_pointparameters->value )
  1038. {
  1039. qglPointParameterfEXT = ( void (APIENTRY *)( GLenum, GLfloat ) ) qwglGetProcAddress( "glPointParameterfEXT" );
  1040. qglPointParameterfvEXT = ( void (APIENTRY *)( GLenum, const GLfloat * ) ) qwglGetProcAddress( "glPointParameterfvEXT" );
  1041. ri.Con_Printf( PRINT_ALL, "...using GL_EXT_point_parameters\n" );
  1042. }
  1043. else
  1044. {
  1045. ri.Con_Printf( PRINT_ALL, "...ignoring GL_EXT_point_parameters\n" );
  1046. }
  1047. }
  1048. else
  1049. {
  1050. ri.Con_Printf( PRINT_ALL, "...GL_EXT_point_parameters not found\n" );
  1051. }
  1052. if ( strstr( gl_config.extensions_string, "GL_EXT_paletted_texture" ) &&
  1053. strstr( gl_config.extensions_string, "GL_EXT_shared_texture_palette" ) )
  1054. {
  1055. if ( gl_ext_palettedtexture->value )
  1056. {
  1057. ri.Con_Printf( PRINT_ALL, "...using GL_EXT_shared_texture_palette\n" );
  1058. qglColorTableEXT = ( void ( APIENTRY * ) ( int, int, int, int, int, const void * ) ) qwglGetProcAddress( "glColorTableEXT" );
  1059. }
  1060. else
  1061. {
  1062. ri.Con_Printf( PRINT_ALL, "...ignoring GL_EXT_shared_texture_palette\n" );
  1063. }
  1064. }
  1065. else
  1066. {
  1067. ri.Con_Printf( PRINT_ALL, "...GL_EXT_shared_texture_palette not found\n" );
  1068. }
  1069. if ( strstr( gl_config.extensions_string, "GL_SGIS_multitexture" ) )
  1070. {
  1071. if ( gl_ext_multitexture->value )
  1072. {
  1073. ri.Con_Printf( PRINT_ALL, "...using GL_SGIS_multitexture\n" );
  1074. qglMTexCoord2fSGIS = ( void * ) qwglGetProcAddress( "glMTexCoord2fSGIS" );
  1075. qglSelectTextureSGIS = ( void * ) qwglGetProcAddress( "glSelectTextureSGIS" );
  1076. }
  1077. else
  1078. {
  1079. ri.Con_Printf( PRINT_ALL, "...ignoring GL_SGIS_multitexture\n" );
  1080. }
  1081. }
  1082. else
  1083. {
  1084. ri.Con_Printf( PRINT_ALL, "...GL_SGIS_multitexture not found\n" );
  1085. }
  1086. #endif
  1087. GL_SetDefaultState();
  1088. /*
  1089. ** draw our stereo patterns
  1090. */
  1091. #if 0 // commented out until H3D pays us the money they owe us
  1092. GL_DrawStereoPattern();
  1093. #endif
  1094. GL_InitImages ();
  1095. Mod_Init ();
  1096. R_InitParticleTexture ();
  1097. Draw_InitLocal ();
  1098. err = qglGetError();
  1099. if ( err != GL_NO_ERROR )
  1100. ri.Con_Printf (PRINT_ALL, "glGetError() = 0x%x\n", err);
  1101. }
  1102. /*
  1103. ===============
  1104. R_Shutdown
  1105. ===============
  1106. */
  1107. void R_Shutdown (void)
  1108. {
  1109. ri.Cmd_RemoveCommand ("modellist");
  1110. ri.Cmd_RemoveCommand ("screenshot");
  1111. ri.Cmd_RemoveCommand ("imagelist");
  1112. ri.Cmd_RemoveCommand ("gl_strings");
  1113. Mod_FreeAll ();
  1114. GL_ShutdownImages ();
  1115. /*
  1116. ** shut down OS specific OpenGL stuff like contexts, etc.
  1117. */
  1118. GLimp_Shutdown();
  1119. /*
  1120. ** shutdown our QGL subsystem
  1121. */
  1122. QGL_Shutdown();
  1123. }
  1124. /*
  1125. @@@@@@@@@@@@@@@@@@@@@
  1126. R_BeginFrame
  1127. @@@@@@@@@@@@@@@@@@@@@
  1128. */
  1129. void R_BeginFrame( float camera_separation )
  1130. {
  1131. gl_state.camera_separation = camera_separation;
  1132. /*
  1133. ** change modes if necessary
  1134. */
  1135. if ( gl_mode->modified || vid_fullscreen->modified )
  1136. { // FIXME: only restart if CDS is required
  1137. cvar_t *ref;
  1138. ref = ri.Cvar_Get ("vid_ref", "gl", 0);
  1139. ref->modified = true;
  1140. }
  1141. if ( gl_log->modified )
  1142. {
  1143. GLimp_EnableLogging( gl_log->value );
  1144. gl_log->modified = false;
  1145. }
  1146. if ( gl_log->value )
  1147. {
  1148. GLimp_LogNewFrame();
  1149. }
  1150. /*
  1151. ** update 3Dfx gamma -- it is expected that a user will do a vid_restart
  1152. ** after tweaking this value
  1153. */
  1154. if ( vid_gamma->modified )
  1155. {
  1156. vid_gamma->modified = false;
  1157. if ( gl_config.renderer & ( GL_RENDERER_VOODOO ) )
  1158. {
  1159. char envbuffer[1024];
  1160. float g;
  1161. g = 2.00 * ( 0.8 - ( vid_gamma->value - 0.5 ) ) + 1.0F;
  1162. Com_sprintf( envbuffer, sizeof(envbuffer), "SSTV2_GAMMA=%f", g );
  1163. putenv( envbuffer );
  1164. Com_sprintf( envbuffer, sizeof(envbuffer), "SST_GAMMA=%f", g );
  1165. putenv( envbuffer );
  1166. }
  1167. }
  1168. GLimp_BeginFrame( camera_separation );
  1169. /*
  1170. ** go into 2D mode
  1171. */
  1172. qglViewport (0,0, vid.width, vid.height);
  1173. qglMatrixMode(GL_PROJECTION);
  1174. qglLoadIdentity ();
  1175. qglOrtho (0, vid.width, vid.height, 0, -99999, 99999);
  1176. qglMatrixMode(GL_MODELVIEW);
  1177. qglLoadIdentity ();
  1178. qglDisable (GL_DEPTH_TEST);
  1179. qglDisable (GL_CULL_FACE);
  1180. qglDisable (GL_BLEND);
  1181. qglEnable (GL_ALPHA_TEST);
  1182. qglColor4f (1,1,1,1);
  1183. /*
  1184. ** draw buffer stuff
  1185. */
  1186. if ( gl_drawbuffer->modified )
  1187. {
  1188. gl_drawbuffer->modified = false;
  1189. if ( gl_state.camera_separation == 0 || !gl_state.stereo_enabled )
  1190. {
  1191. if ( Q_stricmp( gl_drawbuffer->string, "GL_FRONT" ) == 0 )
  1192. qglDrawBuffer( GL_FRONT );
  1193. else
  1194. qglDrawBuffer( GL_BACK );
  1195. }
  1196. }
  1197. /*
  1198. ** texturemode stuff
  1199. */
  1200. if ( gl_texturemode->modified )
  1201. {
  1202. GL_TextureMode( gl_texturemode->string );
  1203. gl_texturemode->modified = false;
  1204. }
  1205. if ( gl_texturealphamode->modified )
  1206. {
  1207. GL_TextureAlphaMode( gl_texturealphamode->string );
  1208. gl_texturealphamode->modified = false;
  1209. }
  1210. if ( gl_texturesolidmode->modified )
  1211. {
  1212. GL_TextureSolidMode( gl_texturesolidmode->string );
  1213. gl_texturesolidmode->modified = false;
  1214. }
  1215. /*
  1216. ** swapinterval stuff
  1217. */
  1218. GL_UpdateSwapInterval();
  1219. //
  1220. // clear screen if desired
  1221. //
  1222. R_Clear ();
  1223. }
  1224. /*
  1225. =============
  1226. R_SetPalette
  1227. =============
  1228. */
  1229. unsigned r_rawpalette[256];
  1230. void R_SetPalette ( const unsigned char *palette)
  1231. {
  1232. int i;
  1233. byte *rp = ( byte * ) r_rawpalette;
  1234. if ( palette )
  1235. {
  1236. for ( i = 0; i < 256; i++ )
  1237. {
  1238. rp[i*4+0] = palette[i*3+0];
  1239. rp[i*4+1] = palette[i*3+1];
  1240. rp[i*4+2] = palette[i*3+2];
  1241. rp[i*4+3] = 0xff;
  1242. }
  1243. }
  1244. else
  1245. {
  1246. for ( i = 0; i < 256; i++ )
  1247. {
  1248. rp[i*4+0] = d_8to24table[i] & 0xff;
  1249. rp[i*4+1] = ( d_8to24table[i] >> 8 ) & 0xff;
  1250. rp[i*4+2] = ( d_8to24table[i] >> 16 ) & 0xff;
  1251. rp[i*4+3] = 0xff;
  1252. }
  1253. }
  1254. GL_SetTexturePalette( r_rawpalette );
  1255. qglClearColor (0,0,0,0);
  1256. qglClear (GL_COLOR_BUFFER_BIT);
  1257. qglClearColor (1,0, 0.5 , 0.5);
  1258. }
  1259. /*
  1260. ** R_DrawBeam
  1261. */
  1262. void R_DrawBeam( entity_t *e )
  1263. {
  1264. #define NUM_BEAM_SEGS 6
  1265. int i;
  1266. float r, g, b;
  1267. vec3_t perpvec;
  1268. vec3_t direction, normalized_direction;
  1269. vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
  1270. vec3_t oldorigin, origin;
  1271. oldorigin[0] = e->oldorigin[0];
  1272. oldorigin[1] = e->oldorigin[1];
  1273. oldorigin[2] = e->oldorigin[2];
  1274. origin[0] = e->origin[0];
  1275. origin[1] = e->origin[1];
  1276. origin[2] = e->origin[2];
  1277. normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
  1278. normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
  1279. normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
  1280. if ( VectorNormalize( normalized_direction ) == 0 )
  1281. return;
  1282. PerpendicularVector( perpvec, normalized_direction );
  1283. VectorScale( perpvec, e->frame / 2, perpvec );
  1284. for ( i = 0; i < 6; i++ )
  1285. {
  1286. RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
  1287. VectorAdd( start_points[i], origin, start_points[i] );
  1288. VectorAdd( start_points[i], direction, end_points[i] );
  1289. }
  1290. qglDisable( GL_TEXTURE_2D );
  1291. qglEnable( GL_BLEND );
  1292. qglDepthMask( GL_FALSE );
  1293. r = ( d_8to24table[e->skinnum & 0xFF] ) & 0xFF;
  1294. g = ( d_8to24table[e->skinnum & 0xFF] >> 8 ) & 0xFF;
  1295. b = ( d_8to24table[e->skinnum & 0xFF] >> 16 ) & 0xFF;
  1296. r *= 1/255.0F;
  1297. g *= 1/255.0F;
  1298. b *= 1/255.0F;
  1299. qglColor4f( r, g, b, e->alpha );
  1300. qglBegin( GL_TRIANGLE_STRIP );
  1301. for ( i = 0; i < NUM_BEAM_SEGS; i++ )
  1302. {
  1303. qglVertex3fv( start_points[i] );
  1304. qglVertex3fv( end_points[i] );
  1305. qglVertex3fv( start_points[(i+1)%NUM_BEAM_SEGS] );
  1306. qglVertex3fv( end_points[(i+1)%NUM_BEAM_SEGS] );
  1307. }
  1308. qglEnd();
  1309. qglEnable( GL_TEXTURE_2D );
  1310. qglDisable( GL_BLEND );
  1311. qglDepthMask( GL_TRUE );
  1312. }
  1313. //===================================================================
  1314. void R_BeginRegistration (char *map);
  1315. struct model_s *R_RegisterModel (char *name);
  1316. struct image_s *R_RegisterSkin (char *name);
  1317. void R_SetSky (char *name, float rotate, vec3_t axis);
  1318. void R_EndRegistration (void);
  1319. void R_RenderFrame (refdef_t *fd);
  1320. struct image_s *Draw_FindPic (char *name);
  1321. void Draw_Pic (int x, int y, char *name);
  1322. void Draw_Char (int x, int y, int c);
  1323. void Draw_TileClear (int x, int y, int w, int h, char *name);
  1324. void Draw_Fill (int x, int y, int w, int h, int c);
  1325. void Draw_FadeScreen (void);
  1326. /*
  1327. @@@@@@@@@@@@@@@@@@@@@
  1328. GetRefAPI
  1329. @@@@@@@@@@@@@@@@@@@@@
  1330. */
  1331. refexport_t GetRefAPI (refimport_t rimp )
  1332. {
  1333. refexport_t re;
  1334. ri = rimp;
  1335. re.api_version = API_VERSION;
  1336. re.BeginRegistration = R_BeginRegistration;
  1337. re.RegisterModel = R_RegisterModel;
  1338. re.RegisterSkin = R_RegisterSkin;
  1339. re.RegisterPic = Draw_FindPic;
  1340. re.SetSky = R_SetSky;
  1341. re.EndRegistration = R_EndRegistration;
  1342. re.RenderFrame = R_RenderFrame;
  1343. re.DrawGetPicSize = Draw_GetPicSize;
  1344. re.DrawPic = Draw_Pic;
  1345. re.DrawStretchPic = Draw_StretchPic;
  1346. re.DrawChar = Draw_Char;
  1347. re.DrawTileClear = Draw_TileClear;
  1348. re.DrawFill = Draw_Fill;
  1349. re.DrawFadeScreen= Draw_FadeScreen;
  1350. re.DrawStretchRaw = Draw_StretchRaw;
  1351. re.Init = R_Init;
  1352. re.Shutdown = R_Shutdown;
  1353. re.CinematicSetPalette = R_SetPalette;
  1354. re.BeginFrame = R_BeginFrame;
  1355. re.EndFrame = GLimp_EndFrame;
  1356. re.AppActivate = GLimp_AppActivate;
  1357. Swap_Init ();
  1358. return re;
  1359. }
  1360. #ifndef REF_HARD_LINKED
  1361. // this is only here so the functions in q_shared.c and q_shwin.c can link
  1362. void Sys_Error (char *error, ...)
  1363. {
  1364. va_list argptr;
  1365. char text[1024];
  1366. va_start (argptr, error);
  1367. vsprintf (text, error, argptr);
  1368. va_end (argptr);
  1369. ri.Sys_Error (ERR_FATAL, "%s", text);
  1370. }
  1371. void Com_Printf (char *fmt, ...)
  1372. {
  1373. va_list argptr;
  1374. char text[1024];
  1375. va_start (argptr, fmt);
  1376. vsprintf (text, fmt, argptr);
  1377. va_end (argptr);
  1378. ri.Con_Printf (PRINT_ALL, "%s", text);
  1379. }
  1380. #endif