gl_warp.c 21 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093
  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. // gl_warp.c -- sky and water polygons
  16. #include "quakedef.h"
  17. extern model_t *loadmodel;
  18. int skytexturenum;
  19. int solidskytexture;
  20. int alphaskytexture;
  21. float speedscale; // for top sky and bottom sky
  22. msurface_t *warpface;
  23. extern cvar_t gl_subdivide_size;
  24. void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
  25. {
  26. int i, j;
  27. float *v;
  28. mins[0] = mins[1] = mins[2] = 9999;
  29. maxs[0] = maxs[1] = maxs[2] = -9999;
  30. v = verts;
  31. for (i=0 ; i<numverts ; i++)
  32. for (j=0 ; j<3 ; j++, v++)
  33. {
  34. if (*v < mins[j])
  35. mins[j] = *v;
  36. if (*v > maxs[j])
  37. maxs[j] = *v;
  38. }
  39. }
  40. void SubdividePolygon (int numverts, float *verts)
  41. {
  42. int i, j, k;
  43. vec3_t mins, maxs;
  44. float m;
  45. float *v;
  46. vec3_t front[64], back[64];
  47. int f, b;
  48. float dist[64];
  49. float frac;
  50. glpoly_t *poly;
  51. float s, t;
  52. if (numverts > 60)
  53. Sys_Error ("numverts = %i", numverts);
  54. BoundPoly (numverts, verts, mins, maxs);
  55. for (i=0 ; i<3 ; i++)
  56. {
  57. m = (mins[i] + maxs[i]) * 0.5;
  58. m = gl_subdivide_size.value * floor (m/gl_subdivide_size.value + 0.5);
  59. if (maxs[i] - m < 8)
  60. continue;
  61. if (m - mins[i] < 8)
  62. continue;
  63. // cut it
  64. v = verts + i;
  65. for (j=0 ; j<numverts ; j++, v+= 3)
  66. dist[j] = *v - m;
  67. // wrap cases
  68. dist[j] = dist[0];
  69. v-=i;
  70. VectorCopy (verts, v);
  71. f = b = 0;
  72. v = verts;
  73. for (j=0 ; j<numverts ; j++, v+= 3)
  74. {
  75. if (dist[j] >= 0)
  76. {
  77. VectorCopy (v, front[f]);
  78. f++;
  79. }
  80. if (dist[j] <= 0)
  81. {
  82. VectorCopy (v, back[b]);
  83. b++;
  84. }
  85. if (dist[j] == 0 || dist[j+1] == 0)
  86. continue;
  87. if ( (dist[j] > 0) != (dist[j+1] > 0) )
  88. {
  89. // clip point
  90. frac = dist[j] / (dist[j] - dist[j+1]);
  91. for (k=0 ; k<3 ; k++)
  92. front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]);
  93. f++;
  94. b++;
  95. }
  96. }
  97. SubdividePolygon (f, front[0]);
  98. SubdividePolygon (b, back[0]);
  99. return;
  100. }
  101. poly = Hunk_Alloc (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float));
  102. poly->next = warpface->polys;
  103. warpface->polys = poly;
  104. poly->numverts = numverts;
  105. for (i=0 ; i<numverts ; i++, verts+= 3)
  106. {
  107. VectorCopy (verts, poly->verts[i]);
  108. s = DotProduct (verts, warpface->texinfo->vecs[0]);
  109. t = DotProduct (verts, warpface->texinfo->vecs[1]);
  110. poly->verts[i][3] = s;
  111. poly->verts[i][4] = t;
  112. }
  113. }
  114. /*
  115. ================
  116. GL_SubdivideSurface
  117. Breaks a polygon up along axial 64 unit
  118. boundaries so that turbulent and sky warps
  119. can be done reasonably.
  120. ================
  121. */
  122. void GL_SubdivideSurface (msurface_t *fa)
  123. {
  124. vec3_t verts[64];
  125. int numverts;
  126. int i;
  127. int lindex;
  128. float *vec;
  129. texture_t *t;
  130. warpface = fa;
  131. //
  132. // convert edges back to a normal polygon
  133. //
  134. numverts = 0;
  135. for (i=0 ; i<fa->numedges ; i++)
  136. {
  137. lindex = loadmodel->surfedges[fa->firstedge + i];
  138. if (lindex > 0)
  139. vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position;
  140. else
  141. vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position;
  142. VectorCopy (vec, verts[numverts]);
  143. numverts++;
  144. }
  145. SubdividePolygon (numverts, verts[0]);
  146. }
  147. //=========================================================
  148. // speed up sin calculations - Ed
  149. float turbsin[] =
  150. {
  151. #include "gl_warp_sin.h"
  152. };
  153. #define TURBSCALE (256.0 / (2 * M_PI))
  154. /*
  155. =============
  156. EmitWaterPolys
  157. Does a water warp on the pre-fragmented glpoly_t chain
  158. =============
  159. */
  160. void EmitWaterPolys (msurface_t *fa)
  161. {
  162. glpoly_t *p;
  163. float *v;
  164. int i;
  165. float s, t, os, ot;
  166. for (p=fa->polys ; p ; p=p->next)
  167. {
  168. glBegin (GL_POLYGON);
  169. for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
  170. {
  171. os = v[3];
  172. ot = v[4];
  173. s = os + turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255];
  174. s *= (1.0/64);
  175. t = ot + turbsin[(int)((os*0.125+realtime) * TURBSCALE) & 255];
  176. t *= (1.0/64);
  177. glTexCoord2f (s, t);
  178. glVertex3fv (v);
  179. }
  180. glEnd ();
  181. }
  182. }
  183. /*
  184. =============
  185. EmitSkyPolys
  186. =============
  187. */
  188. void EmitSkyPolys (msurface_t *fa)
  189. {
  190. glpoly_t *p;
  191. float *v;
  192. int i;
  193. float s, t;
  194. vec3_t dir;
  195. float length;
  196. for (p=fa->polys ; p ; p=p->next)
  197. {
  198. glBegin (GL_POLYGON);
  199. for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
  200. {
  201. VectorSubtract (v, r_origin, dir);
  202. dir[2] *= 3; // flatten the sphere
  203. length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2];
  204. length = sqrt (length);
  205. length = 6*63/length;
  206. dir[0] *= length;
  207. dir[1] *= length;
  208. s = (speedscale + dir[0]) * (1.0/128);
  209. t = (speedscale + dir[1]) * (1.0/128);
  210. glTexCoord2f (s, t);
  211. glVertex3fv (v);
  212. }
  213. glEnd ();
  214. }
  215. }
  216. /*
  217. ===============
  218. EmitBothSkyLayers
  219. Does a sky warp on the pre-fragmented glpoly_t chain
  220. This will be called for brushmodels, the world
  221. will have them chained together.
  222. ===============
  223. */
  224. void EmitBothSkyLayers (msurface_t *fa)
  225. {
  226. int i;
  227. int lindex;
  228. float *vec;
  229. GL_DisableMultitexture();
  230. GL_Bind (solidskytexture);
  231. speedscale = realtime*8;
  232. speedscale -= (int)speedscale & ~127 ;
  233. EmitSkyPolys (fa);
  234. glEnable (GL_BLEND);
  235. GL_Bind (alphaskytexture);
  236. speedscale = realtime*16;
  237. speedscale -= (int)speedscale & ~127 ;
  238. EmitSkyPolys (fa);
  239. glDisable (GL_BLEND);
  240. }
  241. #ifndef QUAKE2
  242. /*
  243. =================
  244. R_DrawSkyChain
  245. =================
  246. */
  247. void R_DrawSkyChain (msurface_t *s)
  248. {
  249. msurface_t *fa;
  250. GL_DisableMultitexture();
  251. // used when gl_texsort is on
  252. GL_Bind(solidskytexture);
  253. speedscale = realtime*8;
  254. speedscale -= (int)speedscale & ~127 ;
  255. for (fa=s ; fa ; fa=fa->texturechain)
  256. EmitSkyPolys (fa);
  257. glEnable (GL_BLEND);
  258. GL_Bind (alphaskytexture);
  259. speedscale = realtime*16;
  260. speedscale -= (int)speedscale & ~127 ;
  261. for (fa=s ; fa ; fa=fa->texturechain)
  262. EmitSkyPolys (fa);
  263. glDisable (GL_BLEND);
  264. }
  265. #endif
  266. /*
  267. =================================================================
  268. Quake 2 environment sky
  269. =================================================================
  270. */
  271. #ifdef QUAKE2
  272. #define SKY_TEX 2000
  273. /*
  274. =================================================================
  275. PCX Loading
  276. =================================================================
  277. */
  278. typedef struct
  279. {
  280. char manufacturer;
  281. char version;
  282. char encoding;
  283. char bits_per_pixel;
  284. unsigned short xmin,ymin,xmax,ymax;
  285. unsigned short hres,vres;
  286. unsigned char palette[48];
  287. char reserved;
  288. char color_planes;
  289. unsigned short bytes_per_line;
  290. unsigned short palette_type;
  291. char filler[58];
  292. unsigned data; // unbounded
  293. } pcx_t;
  294. byte *pcx_rgb;
  295. /*
  296. ============
  297. LoadPCX
  298. ============
  299. */
  300. void LoadPCX (FILE *f)
  301. {
  302. pcx_t *pcx, pcxbuf;
  303. byte palette[768];
  304. byte *pix;
  305. int x, y;
  306. int dataByte, runLength;
  307. int count;
  308. //
  309. // parse the PCX file
  310. //
  311. fread (&pcxbuf, 1, sizeof(pcxbuf), f);
  312. pcx = &pcxbuf;
  313. if (pcx->manufacturer != 0x0a
  314. || pcx->version != 5
  315. || pcx->encoding != 1
  316. || pcx->bits_per_pixel != 8
  317. || pcx->xmax >= 320
  318. || pcx->ymax >= 256)
  319. {
  320. Con_Printf ("Bad pcx file\n");
  321. return;
  322. }
  323. // seek to palette
  324. fseek (f, -768, SEEK_END);
  325. fread (palette, 1, 768, f);
  326. fseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
  327. count = (pcx->xmax+1) * (pcx->ymax+1);
  328. pcx_rgb = malloc( count * 4);
  329. for (y=0 ; y<=pcx->ymax ; y++)
  330. {
  331. pix = pcx_rgb + 4*y*(pcx->xmax+1);
  332. for (x=0 ; x<=pcx->ymax ; )
  333. {
  334. dataByte = fgetc(f);
  335. if((dataByte & 0xC0) == 0xC0)
  336. {
  337. runLength = dataByte & 0x3F;
  338. dataByte = fgetc(f);
  339. }
  340. else
  341. runLength = 1;
  342. while(runLength-- > 0)
  343. {
  344. pix[0] = palette[dataByte*3];
  345. pix[1] = palette[dataByte*3+1];
  346. pix[2] = palette[dataByte*3+2];
  347. pix[3] = 255;
  348. pix += 4;
  349. x++;
  350. }
  351. }
  352. }
  353. }
  354. /*
  355. =========================================================
  356. TARGA LOADING
  357. =========================================================
  358. */
  359. typedef struct _TargaHeader {
  360. unsigned char id_length, colormap_type, image_type;
  361. unsigned short colormap_index, colormap_length;
  362. unsigned char colormap_size;
  363. unsigned short x_origin, y_origin, width, height;
  364. unsigned char pixel_size, attributes;
  365. } TargaHeader;
  366. TargaHeader targa_header;
  367. byte *targa_rgba;
  368. int fgetLittleShort (FILE *f)
  369. {
  370. byte b1, b2;
  371. b1 = fgetc(f);
  372. b2 = fgetc(f);
  373. return (short)(b1 + b2*256);
  374. }
  375. int fgetLittleLong (FILE *f)
  376. {
  377. byte b1, b2, b3, b4;
  378. b1 = fgetc(f);
  379. b2 = fgetc(f);
  380. b3 = fgetc(f);
  381. b4 = fgetc(f);
  382. return b1 + (b2<<8) + (b3<<16) + (b4<<24);
  383. }
  384. /*
  385. =============
  386. LoadTGA
  387. =============
  388. */
  389. void LoadTGA (FILE *fin)
  390. {
  391. int columns, rows, numPixels;
  392. byte *pixbuf;
  393. int row, column;
  394. targa_header.id_length = fgetc(fin);
  395. targa_header.colormap_type = fgetc(fin);
  396. targa_header.image_type = fgetc(fin);
  397. targa_header.colormap_index = fgetLittleShort(fin);
  398. targa_header.colormap_length = fgetLittleShort(fin);
  399. targa_header.colormap_size = fgetc(fin);
  400. targa_header.x_origin = fgetLittleShort(fin);
  401. targa_header.y_origin = fgetLittleShort(fin);
  402. targa_header.width = fgetLittleShort(fin);
  403. targa_header.height = fgetLittleShort(fin);
  404. targa_header.pixel_size = fgetc(fin);
  405. targa_header.attributes = fgetc(fin);
  406. if (targa_header.image_type!=2
  407. && targa_header.image_type!=10)
  408. Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
  409. if (targa_header.colormap_type !=0
  410. || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
  411. Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
  412. columns = targa_header.width;
  413. rows = targa_header.height;
  414. numPixels = columns * rows;
  415. targa_rgba = malloc (numPixels*4);
  416. if (targa_header.id_length != 0)
  417. fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
  418. if (targa_header.image_type==2) { // Uncompressed, RGB images
  419. for(row=rows-1; row>=0; row--) {
  420. pixbuf = targa_rgba + row*columns*4;
  421. for(column=0; column<columns; column++) {
  422. unsigned char red,green,blue,alphabyte;
  423. switch (targa_header.pixel_size) {
  424. case 24:
  425. blue = getc(fin);
  426. green = getc(fin);
  427. red = getc(fin);
  428. *pixbuf++ = red;
  429. *pixbuf++ = green;
  430. *pixbuf++ = blue;
  431. *pixbuf++ = 255;
  432. break;
  433. case 32:
  434. blue = getc(fin);
  435. green = getc(fin);
  436. red = getc(fin);
  437. alphabyte = getc(fin);
  438. *pixbuf++ = red;
  439. *pixbuf++ = green;
  440. *pixbuf++ = blue;
  441. *pixbuf++ = alphabyte;
  442. break;
  443. }
  444. }
  445. }
  446. }
  447. else if (targa_header.image_type==10) { // Runlength encoded RGB images
  448. unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
  449. for(row=rows-1; row>=0; row--) {
  450. pixbuf = targa_rgba + row*columns*4;
  451. for(column=0; column<columns; ) {
  452. packetHeader=getc(fin);
  453. packetSize = 1 + (packetHeader & 0x7f);
  454. if (packetHeader & 0x80) { // run-length packet
  455. switch (targa_header.pixel_size) {
  456. case 24:
  457. blue = getc(fin);
  458. green = getc(fin);
  459. red = getc(fin);
  460. alphabyte = 255;
  461. break;
  462. case 32:
  463. blue = getc(fin);
  464. green = getc(fin);
  465. red = getc(fin);
  466. alphabyte = getc(fin);
  467. break;
  468. }
  469. for(j=0;j<packetSize;j++) {
  470. *pixbuf++=red;
  471. *pixbuf++=green;
  472. *pixbuf++=blue;
  473. *pixbuf++=alphabyte;
  474. column++;
  475. if (column==columns) { // run spans across rows
  476. column=0;
  477. if (row>0)
  478. row--;
  479. else
  480. goto breakOut;
  481. pixbuf = targa_rgba + row*columns*4;
  482. }
  483. }
  484. }
  485. else { // non run-length packet
  486. for(j=0;j<packetSize;j++) {
  487. switch (targa_header.pixel_size) {
  488. case 24:
  489. blue = getc(fin);
  490. green = getc(fin);
  491. red = getc(fin);
  492. *pixbuf++ = red;
  493. *pixbuf++ = green;
  494. *pixbuf++ = blue;
  495. *pixbuf++ = 255;
  496. break;
  497. case 32:
  498. blue = getc(fin);
  499. green = getc(fin);
  500. red = getc(fin);
  501. alphabyte = getc(fin);
  502. *pixbuf++ = red;
  503. *pixbuf++ = green;
  504. *pixbuf++ = blue;
  505. *pixbuf++ = alphabyte;
  506. break;
  507. }
  508. column++;
  509. if (column==columns) { // pixel packet run spans across rows
  510. column=0;
  511. if (row>0)
  512. row--;
  513. else
  514. goto breakOut;
  515. pixbuf = targa_rgba + row*columns*4;
  516. }
  517. }
  518. }
  519. }
  520. breakOut:;
  521. }
  522. }
  523. fclose(fin);
  524. }
  525. /*
  526. ==================
  527. R_LoadSkys
  528. ==================
  529. */
  530. char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
  531. void R_LoadSkys (void)
  532. {
  533. int i;
  534. FILE *f;
  535. char name[64];
  536. for (i=0 ; i<6 ; i++)
  537. {
  538. GL_Bind (SKY_TEX + i);
  539. sprintf (name, "gfx/env/bkgtst%s.tga", suf[i]);
  540. COM_FOpenFile (name, &f);
  541. if (!f)
  542. {
  543. Con_Printf ("Couldn't load %s\n", name);
  544. continue;
  545. }
  546. LoadTGA (f);
  547. // LoadPCX (f);
  548. glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);
  549. // glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pcx_rgb);
  550. free (targa_rgba);
  551. // free (pcx_rgb);
  552. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  553. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  554. }
  555. }
  556. vec3_t skyclip[6] = {
  557. {1,1,0},
  558. {1,-1,0},
  559. {0,-1,1},
  560. {0,1,1},
  561. {1,0,1},
  562. {-1,0,1}
  563. };
  564. int c_sky;
  565. // 1 = s, 2 = t, 3 = 2048
  566. int st_to_vec[6][3] =
  567. {
  568. {3,-1,2},
  569. {-3,1,2},
  570. {1,3,2},
  571. {-1,-3,2},
  572. {-2,-1,3}, // 0 degrees yaw, look straight up
  573. {2,-1,-3} // look straight down
  574. // {-1,2,3},
  575. // {1,2,-3}
  576. };
  577. // s = [0]/[2], t = [1]/[2]
  578. int vec_to_st[6][3] =
  579. {
  580. {-2,3,1},
  581. {2,3,-1},
  582. {1,3,2},
  583. {-1,3,-2},
  584. {-2,-1,3},
  585. {-2,1,-3}
  586. // {-1,2,3},
  587. // {1,2,-3}
  588. };
  589. float skymins[2][6], skymaxs[2][6];
  590. void DrawSkyPolygon (int nump, vec3_t vecs)
  591. {
  592. int i,j;
  593. vec3_t v, av;
  594. float s, t, dv;
  595. int axis;
  596. float *vp;
  597. c_sky++;
  598. #if 0
  599. glBegin (GL_POLYGON);
  600. for (i=0 ; i<nump ; i++, vecs+=3)
  601. {
  602. VectorAdd(vecs, r_origin, v);
  603. glVertex3fv (v);
  604. }
  605. glEnd();
  606. return;
  607. #endif
  608. // decide which face it maps to
  609. VectorCopy (vec3_origin, v);
  610. for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
  611. {
  612. VectorAdd (vp, v, v);
  613. }
  614. av[0] = fabs(v[0]);
  615. av[1] = fabs(v[1]);
  616. av[2] = fabs(v[2]);
  617. if (av[0] > av[1] && av[0] > av[2])
  618. {
  619. if (v[0] < 0)
  620. axis = 1;
  621. else
  622. axis = 0;
  623. }
  624. else if (av[1] > av[2] && av[1] > av[0])
  625. {
  626. if (v[1] < 0)
  627. axis = 3;
  628. else
  629. axis = 2;
  630. }
  631. else
  632. {
  633. if (v[2] < 0)
  634. axis = 5;
  635. else
  636. axis = 4;
  637. }
  638. // project new texture coords
  639. for (i=0 ; i<nump ; i++, vecs+=3)
  640. {
  641. j = vec_to_st[axis][2];
  642. if (j > 0)
  643. dv = vecs[j - 1];
  644. else
  645. dv = -vecs[-j - 1];
  646. j = vec_to_st[axis][0];
  647. if (j < 0)
  648. s = -vecs[-j -1] / dv;
  649. else
  650. s = vecs[j-1] / dv;
  651. j = vec_to_st[axis][1];
  652. if (j < 0)
  653. t = -vecs[-j -1] / dv;
  654. else
  655. t = vecs[j-1] / dv;
  656. if (s < skymins[0][axis])
  657. skymins[0][axis] = s;
  658. if (t < skymins[1][axis])
  659. skymins[1][axis] = t;
  660. if (s > skymaxs[0][axis])
  661. skymaxs[0][axis] = s;
  662. if (t > skymaxs[1][axis])
  663. skymaxs[1][axis] = t;
  664. }
  665. }
  666. #define MAX_CLIP_VERTS 64
  667. void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
  668. {
  669. float *norm;
  670. float *v;
  671. qboolean front, back;
  672. float d, e;
  673. float dists[MAX_CLIP_VERTS];
  674. int sides[MAX_CLIP_VERTS];
  675. vec3_t newv[2][MAX_CLIP_VERTS];
  676. int newc[2];
  677. int i, j;
  678. if (nump > MAX_CLIP_VERTS-2)
  679. Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS");
  680. if (stage == 6)
  681. { // fully clipped, so draw it
  682. DrawSkyPolygon (nump, vecs);
  683. return;
  684. }
  685. front = back = false;
  686. norm = skyclip[stage];
  687. for (i=0, v = vecs ; i<nump ; i++, v+=3)
  688. {
  689. d = DotProduct (v, norm);
  690. if (d > ON_EPSILON)
  691. {
  692. front = true;
  693. sides[i] = SIDE_FRONT;
  694. }
  695. else if (d < ON_EPSILON)
  696. {
  697. back = true;
  698. sides[i] = SIDE_BACK;
  699. }
  700. else
  701. sides[i] = SIDE_ON;
  702. dists[i] = d;
  703. }
  704. if (!front || !back)
  705. { // not clipped
  706. ClipSkyPolygon (nump, vecs, stage+1);
  707. return;
  708. }
  709. // clip it
  710. sides[i] = sides[0];
  711. dists[i] = dists[0];
  712. VectorCopy (vecs, (vecs+(i*3)) );
  713. newc[0] = newc[1] = 0;
  714. for (i=0, v = vecs ; i<nump ; i++, v+=3)
  715. {
  716. switch (sides[i])
  717. {
  718. case SIDE_FRONT:
  719. VectorCopy (v, newv[0][newc[0]]);
  720. newc[0]++;
  721. break;
  722. case SIDE_BACK:
  723. VectorCopy (v, newv[1][newc[1]]);
  724. newc[1]++;
  725. break;
  726. case SIDE_ON:
  727. VectorCopy (v, newv[0][newc[0]]);
  728. newc[0]++;
  729. VectorCopy (v, newv[1][newc[1]]);
  730. newc[1]++;
  731. break;
  732. }
  733. if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
  734. continue;
  735. d = dists[i] / (dists[i] - dists[i+1]);
  736. for (j=0 ; j<3 ; j++)
  737. {
  738. e = v[j] + d*(v[j+3] - v[j]);
  739. newv[0][newc[0]][j] = e;
  740. newv[1][newc[1]][j] = e;
  741. }
  742. newc[0]++;
  743. newc[1]++;
  744. }
  745. // continue
  746. ClipSkyPolygon (newc[0], newv[0][0], stage+1);
  747. ClipSkyPolygon (newc[1], newv[1][0], stage+1);
  748. }
  749. /*
  750. =================
  751. R_DrawSkyChain
  752. =================
  753. */
  754. void R_DrawSkyChain (msurface_t *s)
  755. {
  756. msurface_t *fa;
  757. int i;
  758. vec3_t verts[MAX_CLIP_VERTS];
  759. glpoly_t *p;
  760. c_sky = 0;
  761. GL_Bind(solidskytexture);
  762. // calculate vertex values for sky box
  763. for (fa=s ; fa ; fa=fa->texturechain)
  764. {
  765. for (p=fa->polys ; p ; p=p->next)
  766. {
  767. for (i=0 ; i<p->numverts ; i++)
  768. {
  769. VectorSubtract (p->verts[i], r_origin, verts[i]);
  770. }
  771. ClipSkyPolygon (p->numverts, verts[0], 0);
  772. }
  773. }
  774. }
  775. /*
  776. ==============
  777. R_ClearSkyBox
  778. ==============
  779. */
  780. void R_ClearSkyBox (void)
  781. {
  782. int i;
  783. for (i=0 ; i<6 ; i++)
  784. {
  785. skymins[0][i] = skymins[1][i] = 9999;
  786. skymaxs[0][i] = skymaxs[1][i] = -9999;
  787. }
  788. }
  789. void MakeSkyVec (float s, float t, int axis)
  790. {
  791. vec3_t v, b;
  792. int j, k;
  793. b[0] = s*2048;
  794. b[1] = t*2048;
  795. b[2] = 2048;
  796. for (j=0 ; j<3 ; j++)
  797. {
  798. k = st_to_vec[axis][j];
  799. if (k < 0)
  800. v[j] = -b[-k - 1];
  801. else
  802. v[j] = b[k - 1];
  803. v[j] += r_origin[j];
  804. }
  805. // avoid bilerp seam
  806. s = (s+1)*0.5;
  807. t = (t+1)*0.5;
  808. if (s < 1.0/512)
  809. s = 1.0/512;
  810. else if (s > 511.0/512)
  811. s = 511.0/512;
  812. if (t < 1.0/512)
  813. t = 1.0/512;
  814. else if (t > 511.0/512)
  815. t = 511.0/512;
  816. t = 1.0 - t;
  817. glTexCoord2f (s, t);
  818. glVertex3fv (v);
  819. }
  820. /*
  821. ==============
  822. R_DrawSkyBox
  823. ==============
  824. */
  825. int skytexorder[6] = {0,2,1,3,4,5};
  826. void R_DrawSkyBox (void)
  827. {
  828. int i, j, k;
  829. vec3_t v;
  830. float s, t;
  831. #if 0
  832. glEnable (GL_BLEND);
  833. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  834. glColor4f (1,1,1,0.5);
  835. glDisable (GL_DEPTH_TEST);
  836. #endif
  837. for (i=0 ; i<6 ; i++)
  838. {
  839. if (skymins[0][i] >= skymaxs[0][i]
  840. || skymins[1][i] >= skymaxs[1][i])
  841. continue;
  842. GL_Bind (SKY_TEX+skytexorder[i]);
  843. #if 0
  844. skymins[0][i] = -1;
  845. skymins[1][i] = -1;
  846. skymaxs[0][i] = 1;
  847. skymaxs[1][i] = 1;
  848. #endif
  849. glBegin (GL_QUADS);
  850. MakeSkyVec (skymins[0][i], skymins[1][i], i);
  851. MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
  852. MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
  853. MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
  854. glEnd ();
  855. }
  856. #if 0
  857. glDisable (GL_BLEND);
  858. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  859. glColor4f (1,1,1,0.5);
  860. glEnable (GL_DEPTH_TEST);
  861. #endif
  862. }
  863. #endif
  864. //===============================================================
  865. /*
  866. =============
  867. R_InitSky
  868. A sky texture is 256*128, with the right side being a masked overlay
  869. ==============
  870. */
  871. void R_InitSky (texture_t *mt)
  872. {
  873. int i, j, p;
  874. byte *src;
  875. unsigned trans[128*128];
  876. unsigned transpix;
  877. int r, g, b;
  878. unsigned *rgba;
  879. extern int skytexturenum;
  880. src = (byte *)mt + mt->offsets[0];
  881. // make an average value for the back to avoid
  882. // a fringe on the top level
  883. r = g = b = 0;
  884. for (i=0 ; i<128 ; i++)
  885. for (j=0 ; j<128 ; j++)
  886. {
  887. p = src[i*256 + j + 128];
  888. rgba = &d_8to24table[p];
  889. trans[(i*128) + j] = *rgba;
  890. r += ((byte *)rgba)[0];
  891. g += ((byte *)rgba)[1];
  892. b += ((byte *)rgba)[2];
  893. }
  894. ((byte *)&transpix)[0] = r/(128*128);
  895. ((byte *)&transpix)[1] = g/(128*128);
  896. ((byte *)&transpix)[2] = b/(128*128);
  897. ((byte *)&transpix)[3] = 0;
  898. if (!solidskytexture)
  899. solidskytexture = texture_extension_number++;
  900. GL_Bind (solidskytexture );
  901. glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  902. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  903. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  904. for (i=0 ; i<128 ; i++)
  905. for (j=0 ; j<128 ; j++)
  906. {
  907. p = src[i*256 + j];
  908. if (p == 0)
  909. trans[(i*128) + j] = transpix;
  910. else
  911. trans[(i*128) + j] = d_8to24table[p];
  912. }
  913. if (!alphaskytexture)
  914. alphaskytexture = texture_extension_number++;
  915. GL_Bind(alphaskytexture);
  916. glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  917. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  918. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  919. }