gl_warp.c 20 KB

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