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