1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20 // gl_warp.c -- sky and water polygons
21
22 //#define NO_PNG
23 #ifndef NO_PNG
24 #include <png.h>
25 #endif
26
27 #include "quakedef.h"
28
29 extern model_t *loadmodel;
30
31 int skytexturenum;
32
33 int solidskytexture;
34 int alphaskytexture;
35 float speedscale; // for top sky and bottom sky
36
37 int newwatertex,newslimetex,newlavatex,newteletex,newenvmap; //PENTA: texture id's for the new fluid textures
38
39 msurface_t *warpface;
40
41 extern cvar_t gl_subdivide_size;
42
43
BoundPoly(int numverts,float * verts,vec3_t mins,vec3_t maxs)44 void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
45 {
46 int i, j;
47 float *v;
48
49 mins[0] = mins[1] = mins[2] = 9999;
50 maxs[0] = maxs[1] = maxs[2] = -9999;
51 v = verts;
52 for (i=0 ; i<numverts ; i++)
53 for (j=0 ; j<3 ; j++, v++)
54 {
55 if (*v < mins[j])
56 mins[j] = *v;
57 if (*v > maxs[j])
58 maxs[j] = *v;
59 }
60 }
61
SubdividePolygon(int numverts,float * verts)62 void SubdividePolygon (int numverts, float *verts)
63 {
64 int i, j, k;
65 vec3_t mins, maxs;
66 float m;
67 float *v;
68 vec3_t front[64], back[64];
69 int f, b;
70 float dist[64];
71 float frac;
72 glpoly_t *poly;
73 float s, t;
74 float tex[2];
75
76 if (numverts > 60)
77 Sys_Error ("numverts = %i", numverts);
78
79 BoundPoly (numverts, verts, mins, maxs);
80
81 for (i=0 ; i<3 ; i++)
82 {
83 m = (mins[i] + maxs[i]) * 0.5;
84 m = gl_subdivide_size.value * floor (m/gl_subdivide_size.value + 0.5);
85 if (maxs[i] - m < 8)
86 continue;
87 if (m - mins[i] < 8)
88 continue;
89
90 // cut it
91 v = verts + i;
92 for (j=0 ; j<numverts ; j++, v+= 3)
93 dist[j] = *v - m;
94
95 // wrap cases
96 dist[j] = dist[0];
97 v-=i;
98 VectorCopy (verts, v);
99
100 f = b = 0;
101 v = verts;
102 for (j=0 ; j<numverts ; j++, v+= 3)
103 {
104 if (dist[j] >= 0)
105 {
106 VectorCopy (v, front[f]);
107 f++;
108 }
109 if (dist[j] <= 0)
110 {
111 VectorCopy (v, back[b]);
112 b++;
113 }
114 if (dist[j] == 0 || dist[j+1] == 0)
115 continue;
116 if ( (dist[j] > 0) != (dist[j+1] > 0) )
117 {
118 // clip point
119 frac = dist[j] / (dist[j] - dist[j+1]);
120 for (k=0 ; k<3 ; k++)
121 front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]);
122 f++;
123 b++;
124 }
125 }
126
127 SubdividePolygon (f, front[0]);
128 SubdividePolygon (b, back[0]);
129 return;
130 }
131
132 poly = Hunk_Alloc(sizeof(glpoly_t));
133
134 poly->next = warpface->polys;
135 warpface->polys = poly;
136 poly->numverts = numverts;
137 poly->firstvertex = R_GetNextVertexIndex();
138 for (i=0 ; i<numverts ; i++, verts+= 3)
139 {
140 tex[0] = DotProduct (verts, warpface->texinfo->vecs[0]);
141 tex[1] = DotProduct (verts, warpface->texinfo->vecs[1]);
142 //Penta: lighmap coords are ignored...
143 R_AllocateVertexInTemp(verts,tex,tex);
144 }
145 }
146
147 /*
148 ================
149 GL_SubdivideSurface
150
151 Breaks a polygon up along axial 64 unit
152 boundaries so that turbulent and sky warps
153 can be done reasonably.
154 ================
155 */
GL_SubdivideSurface(msurface_t * fa)156 void GL_SubdivideSurface (msurface_t *fa)
157 {
158 vec3_t verts[64];
159 int numverts;
160 int i;
161 int lindex;
162 float *vec;
163
164 warpface = fa;
165
166 //
167 // convert edges back to a normal polygon
168 //
169 numverts = 0;
170 for (i=0 ; i<fa->numedges ; i++)
171 {
172 lindex = loadmodel->surfedges[fa->firstedge + i];
173
174 if (lindex > 0)
175 vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position;
176 else
177 vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position;
178 VectorCopy (vec, verts[numverts]);
179 numverts++;
180 }
181
182 SubdividePolygon (numverts, verts[0]);
183 }
184
185 //=========================================================
186
187
188
189 // speed up sin calculations - Ed
190 float turbsin[] =
191 {
192 #include "gl_warp_sin.h"
193 };
194 #define TURBSCALE (256.0 / (2 * M_PI))
195
196 /*
197 =============
198 EmitWaterPolys
199
200 Does a water warp on the pre-fragmented glpoly_t chain
201 =============
202 */
EmitWaterPolys(msurface_t * fa)203 void EmitWaterPolys (msurface_t *fa)
204 {
205 glpoly_t *p;
206 float *v;
207 int i;
208 float s, t, os, ot;
209
210
211 for (p=fa->polys ; p ; p=p->next)
212 {
213 glBegin (GL_TRIANGLE_FAN);
214 for (i=0,v=(float *)(&globalVertexTable[p->firstvertex]) ; i<p->numverts ; i++, v+=VERTEXSIZE)
215 {
216 os = v[3];
217 ot = v[4];
218
219
220 s = os + (turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255])*0.25;
221 s *= (1.0/64);
222
223 t = ot + (turbsin[(int)((os*0.125+realtime) * TURBSCALE) & 255])*0.25;
224 t *= (1.0/64);
225
226 glTexCoord2f (s, t);
227
228 if (gl_mtexable)
229 qglMultiTexCoord2fARB (GL_TEXTURE1_ARB, s, t);
230
231 glVertex3f (v[0],v[1],v[2]);
232 }
233 glEnd ();
234 }
235 }
236
RandomXY(float x,float y,int seedlike)237 float RandomXY(float x, float y, int seedlike)
238 {
239 float ret;
240 int n = (int)x+(int)y*seedlike;
241 n = (n<<13)^n;
242 ret = (1- ( (n * (n * n * 19417 + 189851) + 4967243) & 4945007) / 3354521.0);
243 return ret;
244 }
245
EmitMirrorWaterPolys(msurface_t * fa)246 void EmitMirrorWaterPolys (msurface_t *fa)
247 {
248 glpoly_t *p;
249 float *v;
250 int i;
251 float s, t, os, ot;
252
253 for (p=fa->polys ; p ; p=p->next)
254 {
255 glBegin (GL_TRIANGLE_FAN);
256 for (i=0,v=(float *)(&globalVertexTable[p->firstvertex]) ; i<p->numverts ; i++, v+=VERTEXSIZE)
257 {
258 os = v[0];
259 ot = v[1];
260
261 //Fake the tex coords a bit so it looks a bit like water
262
263 s = RandomXY(os,ot,57)*turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255];
264 s *=0.25;
265 t = RandomXY(os,ot,63)*turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255];
266 t *=0.25;
267
268 glTexCoord3f (v[0]+s, v[1]+t, v[2]);
269 glVertex3f (v[0],v[1],v[2]);
270 }
271 glEnd ();
272 }
273 }
274
EmitMirrorPolys(msurface_t * fa)275 void EmitMirrorPolys (msurface_t *fa)
276 {
277 glpoly_t *p;
278 float *v;
279 int i;
280
281 for (p=fa->polys ; p ; p=p->next)
282 {
283 glBegin (GL_TRIANGLE_FAN);
284 for (i=0,v=(float *)(&globalVertexTable[p->firstvertex]); i<p->numverts ; i++, v+=VERTEXSIZE)
285 {
286 qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, v[3]/64, v[4]/64);
287 glTexCoord3fv(v);
288 glVertex3fv(v);
289 }
290 glEnd ();
291 }
292 }
293
294
295 /*
296 =============
297 PENTA:
298
299 Binds a water shader
300 =============
301 */
OverrideFluidTex(char * name)302 qboolean OverrideFluidTex(char *name)
303 {
304 if (gl_watershader.value < 1) return false;
305 if (r_wateralpha.value == 1) return false;
306
307 if (strstr (name, "water")) {
308 glEnable(GL_BLEND);
309 //glBlendFunc(GL_DST_COLOR,GL_ONE);
310 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
311
312 GL_Bind(newwatertex);
313 glScalef(0.5,0.5,1);
314 glTranslatef(-0.025*realtime,-0.025*realtime,0);
315
316 GL_EnableMultitexture() ;
317 GL_Bind(newwatertex);
318 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
319 glTranslatef(0.05*realtime,0.05*realtime,0);
320 glScalef(0.25,0.25,1);
321 return true;
322
323 }
324
325 if (strstr (name, "tele")) {
326 glEnable(GL_BLEND);
327 glBlendFunc(GL_ONE,GL_ONE);
328 GL_Bind(newteletex);
329 glTranslatef(realtime,0.5*realtime,0);
330 //glScalef(0.5,0.25,1);
331
332 GL_EnableMultitexture() ;
333 GL_Bind(newteletex);
334 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
335 glTranslatef(-realtime,0.5*realtime,0);
336 //glScalef(0.5,0.25,1);
337 glFogfv(GL_FOG_COLOR, color_black);
338 return true;
339
340 }
341
342 if (strstr (name, "lava")) {
343 //lava is never transparent
344 glDisable(GL_BLEND);
345 GL_Bind(newlavatex);
346 glColor4f(1,1,1,1);
347 return true;
348
349 }
350
351 if (strstr (name, "slime")) {
352 glEnable(GL_BLEND);
353 //glBlendFunc(GL_DST_COLOR,GL_ONE);
354 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
355
356 GL_Bind(newslimetex);
357 glScalef(0.5,0.5,1);
358 glTranslatef(-0.05*realtime,-0.05*realtime,0);
359
360 GL_EnableMultitexture() ;
361 GL_Bind(newslimetex);
362 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
363 glScalef(0.25,0.25,1);
364 glTranslatef(0.05*realtime,0.05*realtime,0);
365 return true;
366
367 }
368
369 if (strstr (name, "glass")) {
370 glEnable(GL_BLEND);
371 glBlendFunc(GL_DST_COLOR,GL_ONE);
372 GL_Bind(newenvmap);
373 glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
374 glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
375 glEnable(GL_TEXTURE_GEN_S);
376 glEnable(GL_TEXTURE_GEN_T);
377 glFogfv(GL_FOG_COLOR, color_black);
378 return true;
379
380 }
381
382 return false;
383 }
384
385 /*
386 ==================
387 PENTA:
388 Loads textures needed for the fluid shaders
389 ==================
390 */
InitShaderTex(void)391 void InitShaderTex(void)
392 {
393 newwatertex = EasyTgaLoad("penta/q3water.tga");
394 newslimetex = EasyTgaLoad("penta/q3slime.tga");
395 newlavatex = EasyTgaLoad("penta/q3lava.tga");
396 newteletex = EasyTgaLoad("penta/newtele.tga");
397 newenvmap = EasyTgaLoad("penta/q3envmap.tga");
398 }
399
400 /*
401 =============
402 EmitSkyPolys
403 =============
404 */
EmitSkyPolys(msurface_t * fa)405 void EmitSkyPolys (msurface_t *fa)
406 {
407 glpoly_t *p;
408 float *v;
409 int i;
410 float s, t;
411 vec3_t dir;
412 float length;
413
414 for (p=fa->polys ; p ; p=p->next)
415 {
416 glBegin (GL_TRIANGLE_FAN);
417 for (i=0,v=(float *)(&globalVertexTable[p->firstvertex]) ; i<p->numverts ; i++, v+=VERTEXSIZE)
418 {
419 VectorSubtract (v, r_origin, dir);
420 dir[2] *= 3; // flatten the sphere
421
422 length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2];
423 length = sqrt (length);
424 length = 6*63/length;
425
426 dir[0] *= length;
427 dir[1] *= length;
428
429 s = (speedscale + dir[0]) * (1.0/128);
430 t = (speedscale + dir[1]) * (1.0/128);
431
432 glTexCoord2f (s, t);
433 glVertex3fv (v);
434 }
435 glEnd ();
436 }
437 }
438
439 /*
440 ===============
441 EmitBothSkyLayers
442
443 Does a sky warp on the pre-fragmented glpoly_t chain
444 This will be called for brushmodels, the world
445 will have them chained together.
446 ===============
447 */
EmitBothSkyLayers(msurface_t * fa)448 void EmitBothSkyLayers (msurface_t *fa)
449 {
450 GL_DisableMultitexture();
451
452 GL_Bind (solidskytexture);
453 speedscale = realtime*8;
454 speedscale -= (int)speedscale & ~127 ;
455
456 EmitSkyPolys (fa);
457
458 glEnable (GL_BLEND);
459 GL_Bind (alphaskytexture);
460 speedscale = realtime*16;
461 speedscale -= (int)speedscale & ~127 ;
462
463 EmitSkyPolys (fa);
464
465 // glDisable (GL_BLEND);
466 }
467
468 //#ifndef QUAKE2
469 /*
470 =================
471 R_DrawSkyChain
472 =================
473 */
474 /*
475 void R_DrawSkyChain (msurface_t *s)
476 {
477 msurface_t *fa;
478
479 GL_DisableMultitexture();
480
481 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
482 // used when gl_texsort is on
483 GL_Bind(solidskytexture);
484 speedscale = realtime*8;
485 speedscale -= (int)speedscale & ~127 ;
486
487 for (fa=s ; fa ; fa=fa->texturechain)
488 EmitSkyPolys (fa);
489
490 glEnable (GL_BLEND);
491
492
493 GL_Bind (alphaskytexture);
494 speedscale = realtime*16;
495 speedscale -= (int)speedscale & ~127 ;
496
497 for (fa=s ; fa ; fa=fa->texturechain)
498 EmitSkyPolys (fa);
499
500 //glBlendFunc(GL_ZERO,GL_SRC_COLOR);
501 glDisable (GL_BLEND);
502 }
503
504 #endif
505 */
506
507 /*
508 =================================================================
509
510 Quake 2 environment sky
511
512 =================================================================
513 */
514
515 #ifdef QUAKE2
516
517
518 #define SKY_TEX 2000
519
520 /*
521 =================================================================
522
523 PCX Loading
524
525 =================================================================
526 */
527
528 typedef struct
529 {
530 char manufacturer;
531 char version;
532 char encoding;
533 char bits_per_pixel;
534 unsigned short xmin,ymin,xmax,ymax;
535 unsigned short hres,vres;
536 unsigned char palette[48];
537 char reserved;
538 char color_planes;
539 unsigned short bytes_per_line;
540 unsigned short palette_type;
541 char filler[58];
542 unsigned data; // unbounded
543 } pcx_t;
544
545 byte *pcx_rgb;
546
547 /*
548 ============
549 LoadPCX
550 ============
551 */
LoadPCX(FILE * f)552 void LoadPCX (FILE *f)
553 {
554 pcx_t *pcx, pcxbuf;
555 byte palette[768];
556 byte *pix;
557 int x, y;
558 int dataByte, runLength;
559 int count;
560
561 //
562 // parse the PCX file
563 //
564 fread (&pcxbuf, 1, sizeof(pcxbuf), f);
565
566 pcx = &pcxbuf;
567
568 if (pcx->manufacturer != 0x0a
569 || pcx->version != 5
570 || pcx->encoding != 1
571 || pcx->bits_per_pixel != 8
572 || pcx->xmax >= 320
573 || pcx->ymax >= 256)
574 {
575 Con_Printf ("Bad pcx file\n");
576 return;
577 }
578
579 // seek to palette
580 fseek (f, -768, SEEK_END);
581 fread (palette, 1, 768, f);
582
583 fseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
584
585 count = (pcx->xmax+1) * (pcx->ymax+1);
586 pcx_rgb = malloc( count * 4);
587
588 for (y=0 ; y<=pcx->ymax ; y++)
589 {
590 pix = pcx_rgb + 4*y*(pcx->xmax+1);
591 for (x=0 ; x<=pcx->ymax ; )
592 {
593 dataByte = fgetc(f);
594
595 if((dataByte & 0xC0) == 0xC0)
596 {
597 runLength = dataByte & 0x3F;
598 dataByte = fgetc(f);
599 }
600 else
601 runLength = 1;
602
603 while(runLength-- > 0)
604 {
605 pix[0] = palette[dataByte*3];
606 pix[1] = palette[dataByte*3+1];
607 pix[2] = palette[dataByte*3+2];
608 pix[3] = 255;
609 pix += 4;
610 x++;
611 }
612 }
613 }
614 }
615
616 #endif
617
618 //PENTA: removed this from the ifdef QUAKE2
619 /*
620 =========================================================
621
622 TARGA LOADING
623
624 =========================================================
625 */
626
627 typedef struct _TargaHeader
628 {
629 unsigned char id_length, colormap_type, image_type;
630 unsigned short colormap_index, colormap_length;
631 unsigned char colormap_size;
632 unsigned short x_origin, y_origin, width, height;
633 unsigned char pixel_size, attributes;
634 } TargaHeader;
635
636
637 TargaHeader targa_header;
638 byte *targa_rgba;
639
fgetLittleShort(FILE * f)640 int fgetLittleShort (FILE *f)
641 {
642 byte b1, b2;
643
644 b1 = fgetc(f);
645 b2 = fgetc(f);
646
647 return (short)(b1 + b2*256);
648 }
649
fgetLittleLong(FILE * f)650 int fgetLittleLong (FILE *f)
651 {
652 byte b1, b2, b3, b4;
653
654 b1 = fgetc(f);
655 b2 = fgetc(f);
656 b3 = fgetc(f);
657 b4 = fgetc(f);
658
659 return b1 + (b2<<8) + (b3<<16) + (b4<<24);
660 }
661
662 static char argh[MAX_OSPATH];
663
664 // Proper replacement for LoadTGA and friends
LoadTexture(char * filename,int size)665 int LoadTexture(char* filename, int size)
666 {
667 FILE *f;
668 char* tmp;
669
670 // Check for *.png first, then *.jpg, fall back to *.tga if not found...
671 // first replace the last three letters with png (yeah, hack)
672 strncpy(argh, filename,sizeof(argh));
673 tmp = argh + strlen(filename) - 3;
674 #ifndef NO_PNG
675 tmp[0] = 'p';
676 tmp[1] = 'n';
677 tmp[2] = 'g';
678 COM_FOpenFile (argh, &f);
679 if ( f )
680 {
681 png_infop info_ptr;
682 png_structp png_ptr;
683 char* mem;
684 unsigned long width, height;
685
686 int bit_depth;
687 int color_type;
688 unsigned char** rows;
689 int i;
690 png_color_16 background = {0, 0, 0};
691 png_color_16p image_background;
692
693 Con_DPrintf("Loading %s\n", argh);
694
695 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
696 info_ptr = png_create_info_struct(png_ptr);
697 png_init_io(png_ptr, f);
698 png_set_sig_bytes(png_ptr, 0);
699
700 png_read_info(png_ptr, info_ptr);
701 png_get_IHDR(png_ptr, info_ptr, &width, &height,
702 &bit_depth, &color_type, 0, 0, 0);
703
704
705 // Allocate memory and get data there
706 mem = malloc(size*height*width);
707 rows = malloc(height*sizeof(char*));
708
709 if ( bit_depth == 16)
710 png_set_strip_16(png_ptr);
711
712 if ( color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8 )
713 png_set_expand_gray_1_2_4_to_8(png_ptr);
714
715 png_set_gamma(png_ptr, 1.0, 1.0);
716
717
718
719 if ( size == 4 )
720 {
721 if ( color_type & PNG_COLOR_MASK_PALETTE )
722 png_set_palette_to_rgb(png_ptr);
723
724 if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) )
725 png_set_tRNS_to_alpha(png_ptr);
726
727 if ( (color_type & PNG_COLOR_MASK_COLOR) == 0 )
728 png_set_gray_to_rgb(png_ptr);
729
730 if ( (color_type & PNG_COLOR_MASK_ALPHA) == 0 )
731 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
732 }
733 else
734 {
735 if ( color_type & PNG_COLOR_MASK_ALPHA )
736 png_set_strip_alpha(png_ptr);
737
738 if ( color_type & PNG_COLOR_MASK_PALETTE )
739 {
740 png_set_palette_to_rgb(png_ptr);
741
742 }
743
744 if ( color_type & PNG_COLOR_MASK_COLOR )
745 png_set_rgb_to_gray_fixed(png_ptr, 1, -1, -1);
746 }
747
748 for ( i = 0; i < height; i++ )
749 {
750 rows[i] = mem + size * width * i;
751 }
752 png_read_image(png_ptr, rows);
753
754 png_destroy_read_struct(&png_ptr, &info_ptr, 0);
755 free(rows);
756 targa_header.width = width;
757 targa_header.height = height;
758 targa_rgba = mem;
759 fclose(f);
760 return 1;
761 }
762 #endif
763
764 tmp[0] = 't';
765 tmp[1] = 'g';
766 tmp[2] = 'a';
767 COM_FOpenFile (argh, &f);
768 if (!f)
769 {
770 return 0;
771 }
772 LoadTGA(f);
773 return 1;
774 }
775
776
LoadTextureInPlace(char * filename,int size,byte * mem,int * width,int * height)777 int LoadTextureInPlace(char* filename, int size, byte* mem, int* width, int* height)
778 {
779 FILE *f;
780 char* tmp;
781
782 // Check for *.png first, then *.jpg, fall back to *.tga if not found...
783 // first replace the last three letters with png (yeah, hack)
784 strncpy(argh, filename,sizeof(argh));
785 tmp = argh + strlen(filename) - 3;
786 #ifndef NO_PNG
787 tmp[0] = 'p';
788 tmp[1] = 'n';
789 tmp[2] = 'g';
790 COM_FOpenFile (argh, &f);
791 if ( f )
792 {
793 png_infop info_ptr;
794 png_structp png_ptr;
795 int bit_depth;
796 int color_type;
797 unsigned long mywidth, myheight;
798
799 unsigned char** rows;
800 int i;
801 png_color_16 background = {0, 0, 0};
802 png_color_16p image_background;
803
804 Con_DPrintf("Loading %s\n", argh);
805
806 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
807 info_ptr = png_create_info_struct(png_ptr);
808 png_init_io(png_ptr, f);
809 png_set_sig_bytes(png_ptr, 0);
810
811 png_read_info(png_ptr, info_ptr);
812 png_get_IHDR(png_ptr, info_ptr, &mywidth, &myheight,
813 &bit_depth, &color_type, 0, 0, 0);
814 *width=mywidth;
815 *height=myheight;
816
817
818 // Allocate memory and get data there
819 rows = malloc(*height*sizeof(char*));
820
821 if ( bit_depth == 16)
822 png_set_strip_16(png_ptr);
823
824 if ( color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8 )
825 png_set_expand_gray_1_2_4_to_8(png_ptr);
826
827 png_set_gamma(png_ptr, 1.0, 1.0);
828
829
830
831 if ( size == 4 )
832 {
833 if ( color_type & PNG_COLOR_MASK_PALETTE )
834 png_set_palette_to_rgb(png_ptr);
835
836 if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) )
837 png_set_tRNS_to_alpha(png_ptr);
838
839 if ( (color_type & PNG_COLOR_MASK_COLOR) == 0 )
840 png_set_gray_to_rgb(png_ptr);
841
842 if ( (color_type & PNG_COLOR_MASK_ALPHA) == 0 )
843 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
844 }
845 else
846 {
847 if ( color_type & PNG_COLOR_MASK_ALPHA )
848 png_set_strip_alpha(png_ptr);
849
850 if ( color_type & PNG_COLOR_MASK_PALETTE )
851 {
852 png_set_palette_to_rgb(png_ptr);
853
854 }
855
856 if ( color_type & PNG_COLOR_MASK_COLOR )
857 png_set_rgb_to_gray_fixed(png_ptr, 1, -1, -1);
858 }
859
860 for ( i = 0; i < *height; i++ )
861 {
862 rows[i] = mem + size * *width * i;
863 }
864 png_read_image(png_ptr, rows);
865
866 png_destroy_read_struct(&png_ptr, &info_ptr, 0);
867 free(rows);
868 fclose(f);
869 return 1;
870 }
871 #endif
872 tmp[0] = 't';
873 tmp[1] = 'g';
874 tmp[2] = 'a';
875 COM_FOpenFile (argh, &f);
876 if (!f)
877 {
878 // Con_SafePrintf ("Couldn't load %s\n", argh);
879 return 0;
880 }
881 if ( size == 4 )
882 LoadColorTGA(f, mem, width, height, argh);
883 else
884 LoadGrayTGA(f, mem, width, height, argh);
885 return 1;
886 }
887
888 /*
889 =============
890 LoadTGA
891 =============
892 */
LoadTGA(FILE * fin)893 void LoadTGA (FILE *fin)
894 {
895 int columns, rows, numPixels;
896 byte *pixbuf;
897 int row, column;
898 int row_inc;
899
900 targa_header.id_length = fgetc(fin);
901 targa_header.colormap_type = fgetc(fin);
902 targa_header.image_type = fgetc(fin);
903
904 targa_header.colormap_index = fgetLittleShort(fin);
905 targa_header.colormap_length = fgetLittleShort(fin);
906 targa_header.colormap_size = fgetc(fin);
907 targa_header.x_origin = fgetLittleShort(fin);
908 targa_header.y_origin = fgetLittleShort(fin);
909 targa_header.width = fgetLittleShort(fin);
910 targa_header.height = fgetLittleShort(fin);
911 targa_header.pixel_size = fgetc(fin);
912 targa_header.attributes = fgetc(fin);
913
914 if (targa_header.image_type!=2
915 && targa_header.image_type!=10)
916 Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
917
918 if (targa_header.colormap_type !=0
919 || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
920 Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
921
922 columns = targa_header.width;
923 rows = targa_header.height;
924 numPixels = columns * rows;
925
926 targa_rgba = malloc (numPixels*4);
927
928 if (targa_header.id_length != 0)
929 fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
930
931 // If bit 5 of attributes isn't set, the image has been stored from bottom to top
932 if ((targa_header.attributes & 0x20) == 0)
933 {
934 pixbuf = targa_rgba + (rows - 1)*columns*4;
935 row_inc = -columns*4*2;
936 }
937 else
938 {
939 pixbuf = targa_rgba;
940 row_inc = 0;
941 }
942
943 if (targa_header.image_type==2) { // Uncompressed, RGB images
944 for(row=rows-1; row>=0; row--, pixbuf += row_inc) {
945 for(column=0; column<columns; column++) {
946 unsigned char red,green,blue,alphabyte;
947 switch (targa_header.pixel_size) {
948 case 24:
949
950 blue = getc(fin);
951 green = getc(fin);
952 red = getc(fin);
953 *pixbuf++ = red;
954 *pixbuf++ = green;
955 *pixbuf++ = blue;
956 *pixbuf++ = 255;
957 break;
958 case 32:
959 blue = getc(fin);
960 green = getc(fin);
961 red = getc(fin);
962 alphabyte = getc(fin);
963 *pixbuf++ = red;
964 *pixbuf++ = green;
965 *pixbuf++ = blue;
966 *pixbuf++ = alphabyte;
967 break;
968 }
969 }
970 }
971 }
972 else if (targa_header.image_type==10) { // Runlength encoded RGB images
973 unsigned char red = 0x00,green = 0x00,blue = 0x00,alphabyte = 0x00,packetHeader,packetSize,j;
974 for(row=rows-1; row>=0; row--, pixbuf += row_inc) {
975 for(column=0; column<columns; ) {
976 packetHeader=getc(fin);
977 packetSize = 1 + (packetHeader & 0x7f);
978 if (packetHeader & 0x80) { // run-length packet
979 switch (targa_header.pixel_size) {
980 case 24:
981 blue = getc(fin);
982 green = getc(fin);
983 red = getc(fin);
984 alphabyte = 255;
985 break;
986 case 32:
987 blue = getc(fin);
988 green = getc(fin);
989 red = getc(fin);
990 alphabyte = getc(fin);
991 break;
992 }
993
994 for(j=0;j<packetSize;j++) {
995 *pixbuf++=red;
996 *pixbuf++=green;
997 *pixbuf++=blue;
998 *pixbuf++=alphabyte;
999 column++;
1000 if (column==columns) { // run spans across rows
1001 column=0;
1002 if (row>0) {
1003 row--;
1004 pixbuf += row_inc;
1005 }
1006 else
1007 goto breakOut;
1008 }
1009 }
1010 }
1011 else { // non run-length packet
1012 for(j=0;j<packetSize;j++) {
1013 switch (targa_header.pixel_size) {
1014 case 24:
1015 blue = getc(fin);
1016 green = getc(fin);
1017 red = getc(fin);
1018 *pixbuf++ = red;
1019 *pixbuf++ = green;
1020 *pixbuf++ = blue;
1021 *pixbuf++ = 255;
1022 break;
1023 case 32:
1024 blue = getc(fin);
1025 green = getc(fin);
1026 red = getc(fin);
1027 alphabyte = getc(fin);
1028 *pixbuf++ = red;
1029 *pixbuf++ = green;
1030 *pixbuf++ = blue;
1031 *pixbuf++ = alphabyte;
1032 break;
1033 }
1034 column++;
1035 if (column==columns) { // pixel packet run spans across rows
1036 column=0;
1037 if (row>0) {
1038 row--;
1039 pixbuf += row_inc;
1040 }
1041 else
1042 goto breakOut;
1043 }
1044 }
1045 }
1046 }
1047 breakOut:;
1048 }
1049 }
1050
1051 fclose(fin);
1052 }
1053
1054 /*
1055 =============
1056 LoadColorTGA
1057 PENTA: loads a color tga (rgb/rgba/or quake palette)
1058 returns width & height in the references.
1059 =============
1060 */
LoadColorTGA(FILE * fin,byte * pixels,int * width,int * height,char * fname)1061 void LoadColorTGA (FILE *fin, byte *pixels, int *width, int *height, char* fname)
1062 {
1063 int columns, rows, numPixels;
1064 byte *pixbuf;
1065 int row, column;
1066 int row_inc;
1067
1068 targa_header.id_length = fgetc(fin);
1069 targa_header.colormap_type = fgetc(fin);
1070 targa_header.image_type = fgetc(fin);
1071
1072 targa_header.colormap_index = fgetLittleShort(fin);
1073 targa_header.colormap_length = fgetLittleShort(fin);
1074 targa_header.colormap_size = fgetc(fin);
1075 targa_header.x_origin = fgetLittleShort(fin);
1076 targa_header.y_origin = fgetLittleShort(fin);
1077 targa_header.width = fgetLittleShort(fin);
1078 targa_header.height = fgetLittleShort(fin);
1079 targa_header.pixel_size = fgetc(fin);
1080 targa_header.attributes = fgetc(fin);
1081
1082 if (targa_header.image_type!=2
1083 && targa_header.image_type!=10 && targa_header.image_type!=1)
1084 Sys_Error ("LoadTGA: Only type 1, 2 and 10 targa images supported\n%s\n",fname);
1085
1086 /*
1087 if (targa_header.colormap_type !=0
1088 || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
1089 Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
1090 */
1091 if (targa_header.image_type==1 && targa_header.pixel_size != 8 &&
1092 targa_header.colormap_size != 24 && targa_header.colormap_length != 256)
1093 Sys_Error ("LoadGrayTGA: Strange palette type\n");
1094
1095 columns = targa_header.width;
1096 rows = targa_header.height;
1097 numPixels = columns * rows;
1098
1099 targa_rgba = pixels;
1100
1101 if (targa_header.id_length != 0)
1102 fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
1103
1104 // If bit 5 of attributes isn't set, the image has been stored from bottom to top
1105 if ((targa_header.attributes & 0x20) == 0)
1106 {
1107 pixbuf = targa_rgba + (rows - 1)*columns*4;
1108 row_inc = -columns*4*2;
1109 }
1110 else
1111 {
1112 pixbuf = targa_rgba;
1113 row_inc = 0;
1114 }
1115
1116 if (targa_header.image_type==1) { // Color mapped
1117 fseek(fin, 768, SEEK_CUR); // skip palette
1118 for(row=rows-1; row>=0; row--, pixbuf += row_inc) {
1119 for(column=0; column<columns; column++) {
1120 unsigned char index;
1121 index = getc(fin);
1122 *(int *)pixbuf = d_8to24table[index];
1123 pixbuf+=4;
1124 }
1125 }
1126 } else if (targa_header.image_type==2) { // Uncompressed, RGB images
1127 for(row=rows-1; row>=0; row--, pixbuf += row_inc) {
1128 for(column=0; column<columns; column++) {
1129 unsigned char red,green,blue,alphabyte;
1130 switch (targa_header.pixel_size) {
1131 case 24:
1132
1133 blue = getc(fin);
1134 green = getc(fin);
1135 red = getc(fin);
1136 *pixbuf++ = red;
1137 *pixbuf++ = green;
1138 *pixbuf++ = blue;
1139 *pixbuf++ = 255;
1140 break;
1141 case 32:
1142 blue = getc(fin);
1143 green = getc(fin);
1144 red = getc(fin);
1145 alphabyte = getc(fin);
1146 *pixbuf++ = red;
1147 *pixbuf++ = green;
1148 *pixbuf++ = blue;
1149 *pixbuf++ = alphabyte;
1150 break;
1151 }
1152 }
1153 }
1154 }
1155 else if (targa_header.image_type==10) { // Runlength encoded RGB images
1156 unsigned char red = 0x00,green = 0x00,blue = 0x00,alphabyte = 0x00,packetHeader,packetSize,j;
1157 for(row=rows-1; row>=0; row--, pixbuf += row_inc) {
1158 for(column=0; column<columns; ) {
1159 packetHeader=getc(fin);
1160 packetSize = 1 + (packetHeader & 0x7f);
1161 if (packetHeader & 0x80) { // run-length packet
1162 switch (targa_header.pixel_size) {
1163 case 24:
1164 blue = getc(fin);
1165 green = getc(fin);
1166 red = getc(fin);
1167 alphabyte = 255;
1168 break;
1169 case 32:
1170 blue = getc(fin);
1171 green = getc(fin);
1172 red = getc(fin);
1173 alphabyte = getc(fin);
1174 break;
1175 }
1176
1177 for(j=0;j<packetSize;j++) {
1178 *pixbuf++=red;
1179 *pixbuf++=green;
1180 *pixbuf++=blue;
1181 *pixbuf++=alphabyte;
1182 column++;
1183 if (column==columns) { // run spans across rows
1184 column=0;
1185 if (row>0) {
1186 row--;
1187 pixbuf += row_inc;
1188 }
1189 else
1190 goto breakOut;
1191 }
1192 }
1193 }
1194 else { // non run-length packet
1195 for(j=0;j<packetSize;j++) {
1196 switch (targa_header.pixel_size) {
1197 case 24:
1198 blue = getc(fin);
1199 green = getc(fin);
1200 red = getc(fin);
1201 *pixbuf++ = red;
1202 *pixbuf++ = green;
1203 *pixbuf++ = blue;
1204 *pixbuf++ = 255;
1205 break;
1206 case 32:
1207 blue = getc(fin);
1208 green = getc(fin);
1209 red = getc(fin);
1210 alphabyte = getc(fin);
1211 *pixbuf++ = red;
1212 *pixbuf++ = green;
1213 *pixbuf++ = blue;
1214 *pixbuf++ = alphabyte;
1215 break;
1216 }
1217 column++;
1218 if (column==columns) { // pixel packet run spans across rows
1219 column=0;
1220 if (row>0) {
1221 row--;
1222 pixbuf += row_inc;
1223 }
1224 else
1225 goto breakOut;
1226 }
1227 }
1228 }
1229 }
1230 breakOut:;
1231 }
1232 }
1233
1234 //we didn't load a paletted image so we still have to fix the gamma
1235 /*
1236 Just let the uses specify the gamma in the image editor
1237 if (targa_header.image_type != 1) {
1238 int i;
1239 float f, inf;
1240 for (i=0 ; i<numPixels*4; i++)
1241 {
1242 f = pow ( (targa_rgba[i]+1)/256.0 , 0.7 );
1243 inf = f*255 + 0.5;
1244 if (inf < 0)
1245 inf = 0;
1246 if (inf > 255)
1247 inf = 255;
1248 targa_rgba[i] = inf;
1249 }
1250 }
1251 */
1252 fclose(fin);
1253 *width = targa_header.width;
1254 *height = targa_header.height;
1255 }
1256
1257 /*
1258 =============
1259 LoadGrayTGA
1260 PENTA: Load a grayscale tga for bump maps
1261 Copies the result to pixbuf (bytes not rgb) and puts the width & height in the references.
1262 =============
1263 */
LoadGrayTGA(FILE * fin,byte * pixels,int * width,int * height,char * fname)1264 void LoadGrayTGA (FILE *fin,byte *pixels,int *width, int *height, char *fname)
1265 {
1266 int columns, rows, numPixels;
1267 int row, column;
1268 byte *pixbuf;
1269 int row_inc;
1270
1271 targa_header.id_length = fgetc(fin);
1272 targa_header.colormap_type = fgetc(fin);
1273 targa_header.image_type = fgetc(fin);
1274
1275 targa_header.colormap_index = fgetLittleShort(fin);
1276 targa_header.colormap_length = fgetLittleShort(fin);
1277 targa_header.colormap_size = fgetc(fin);
1278 targa_header.x_origin = fgetLittleShort(fin);
1279 targa_header.y_origin = fgetLittleShort(fin);
1280 targa_header.width = fgetLittleShort(fin);
1281 targa_header.height = fgetLittleShort(fin);
1282 targa_header.pixel_size = fgetc(fin);
1283 targa_header.attributes = fgetc(fin);
1284
1285 if (targa_header.image_type!=1
1286 && targa_header.image_type!=3)
1287 Sys_Error ("LoadGrayTGA: Only type 1 and 3 targa images supported for bump maps.\n%s\n",fname);
1288
1289 if (targa_header.image_type==1 && targa_header.pixel_size != 8 &&
1290 targa_header.colormap_size != 24 && targa_header.colormap_length != 256)
1291 Sys_Error ("LoadGrayTGA: Strange palette type\n");
1292
1293 columns = targa_header.width;
1294 rows = targa_header.height;
1295 numPixels = columns * rows;
1296
1297 // If bit 5 of attributes isn't set, the image has been stored from bottom to top
1298 if ((targa_header.attributes & 0x20) == 0)
1299 {
1300 pixbuf = pixels + (rows - 1)*columns;
1301 row_inc = -columns*2;
1302 }
1303 else
1304 {
1305 pixbuf = pixels;
1306 row_inc = 0;
1307 }
1308
1309 if (targa_header.id_length != 0)
1310 fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
1311
1312 if (targa_header.image_type == 1) {
1313 fseek(fin, 768, SEEK_CUR);//skip palette
1314 }
1315
1316 //fread(pixbuf,1,numPixels,fin);
1317 for(row=rows-1; row>=0; row--, pixbuf += row_inc) {
1318 for(column=0; column<columns; column++) {
1319 *pixbuf++= getc(fin);
1320 }
1321 }
1322
1323 fclose(fin);
1324 *width = targa_header.width;
1325 *height = targa_header.height;
1326 }
1327 /*
1328 ==================
1329 PENTA:
1330 Loads the tga in filename and returns the texture object
1331 in gl texture object.
1332 ==================
1333 */
EasyTgaLoad(char * filename)1334 int EasyTgaLoad(char *filename)
1335 {
1336 FILE *f;
1337 int texturemode;
1338 unsigned long width, height;
1339 char* tmp;
1340 char* mem;
1341
1342 if ( gl_texcomp && ((int)gl_compress_textures.value) & 1 )
1343 {
1344 texturemode = GL_COMPRESSED_RGBA_ARB;
1345 }
1346 else
1347 {
1348 texturemode = GL_RGBA8;
1349 }
1350
1351 GL_Bind (texture_extension_number);
1352 // Check for *.png first, then *.jpg, fall back to *.tga if not found...
1353 // first replace the last three letters with png (yeah, hack)
1354 strncpy(argh, filename,sizeof(argh));
1355 tmp = argh + strlen(filename) - 3;
1356 #ifndef NO_PNG
1357 tmp[0] = 'p';
1358 tmp[1] = 'n';
1359 tmp[2] = 'g';
1360 COM_FOpenFile (argh, &f);
1361 if ( f )
1362 {
1363 png_infop info_ptr;
1364 png_structp png_ptr;
1365 int bit_depth;
1366 int color_type;
1367 unsigned char** rows;
1368 int i;
1369 png_color_16 background = {0, 0, 0};
1370 png_color_16p image_background;
1371
1372 Con_DPrintf("Loading %s\n", argh);
1373
1374 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
1375 info_ptr = png_create_info_struct(png_ptr);
1376 png_init_io(png_ptr, f);
1377 png_set_sig_bytes(png_ptr, 0);
1378
1379 png_read_info(png_ptr, info_ptr);
1380 png_get_IHDR(png_ptr, info_ptr, &width, &height,
1381 &bit_depth, &color_type, 0, 0, 0);
1382
1383
1384 // Allocate memory and get data there
1385 mem = malloc(4*height*width);
1386 rows = malloc(height*sizeof(char*));
1387
1388 if ( bit_depth == 16)
1389 png_set_strip_16(png_ptr);
1390
1391 if ( color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8 )
1392 png_set_expand_gray_1_2_4_to_8(png_ptr);
1393
1394 png_set_gamma(png_ptr, 1.0, 1.0);
1395
1396
1397
1398 if ( color_type & PNG_COLOR_MASK_PALETTE )
1399 png_set_palette_to_rgb(png_ptr);
1400
1401 if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) )
1402 png_set_tRNS_to_alpha(png_ptr);
1403
1404 if ( (color_type & PNG_COLOR_MASK_COLOR) == 0 )
1405 png_set_gray_to_rgb(png_ptr);
1406
1407 if ( (color_type & PNG_COLOR_MASK_ALPHA) == 0 )
1408 png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
1409
1410
1411 for ( i = 0; i < height; i++ )
1412 {
1413 rows[i] = mem + 4 * width * i;
1414 }
1415 png_read_image(png_ptr, rows);
1416
1417 png_destroy_read_struct(&png_ptr, &info_ptr, 0);
1418 free(rows);
1419 fclose(f);
1420 }
1421 else
1422 #endif
1423 {
1424 tmp[0] = 't';
1425 tmp[1] = 'g';
1426 tmp[2] = 'a';
1427 COM_FOpenFile (argh, &f);
1428 if (!f)
1429 {
1430 Con_SafePrintf ("Couldn't load %s\n", argh);
1431 return 0;
1432 }
1433 LoadTGA (f);
1434 width = targa_header.width;
1435 height = targa_header.height;
1436 mem = targa_rgba;
1437 }
1438 glTexImage2D (GL_TEXTURE_2D, 0, texturemode, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, mem);
1439 free (mem);
1440
1441 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1442 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1443
1444 texture_extension_number++;
1445 return texture_extension_number-1;
1446 }
1447
1448 //#ifdef QUAKE2 PENTA: enable skyboxes again
1449
1450 #define SKY_TEX 10000
1451
1452 char skybox_name[64];
1453 float skybox_cloudspeed;
1454 qboolean skybox_hasclouds;
1455
1456 /*
1457 ==================
1458 R_LoadSkys
1459 ==================
1460 */
1461 char *suf[7] = {"rt", "bk", "lf", "ft", "up", "dn","tile"};
R_LoadSkys(void)1462 void R_LoadSkys (void)
1463 {
1464 int i;
1465 FILE *f;
1466 char name[64];
1467
1468 skybox_hasclouds = true;
1469
1470 for (i=0 ; i<7 ; i++)
1471 {
1472 sprintf (name, "env/%s%s.tga", skybox_name, suf[i]);
1473 // Con_Printf("Loading file: %s\n",name);
1474
1475 if (!LoadTexture(name, 4))
1476 {
1477 if (i == 6) {
1478 skybox_hasclouds = false;
1479 } else {
1480 Con_Printf ("Couldn't load %s\n", name);
1481 }
1482 continue;
1483 }
1484 else
1485 {
1486 GL_Bind (SKY_TEX + i);
1487 glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, targa_header.width, targa_header.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);
1488
1489 free (targa_rgba);
1490
1491 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1492 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1493 }
1494 }
1495 }
1496
1497
1498 vec3_t skyclip[6] =
1499 {
1500 {1,1,0},
1501 {1,-1,0},
1502 {0,-1,1},
1503 {0,1,1},
1504 {1,0,1},
1505 {-1,0,1}
1506 };
1507 int c_sky;
1508
1509 // 1 = s, 2 = t, 3 = 2048
1510 int st_to_vec[6][3] =
1511 {
1512 {3,-1,2},
1513 {-3,1,2},
1514
1515 {1,3,2},
1516 {-1,-3,2},
1517
1518 {-2,-1,3}, // 0 degrees yaw, look straight up
1519 {2,-1,-3} // look straight down
1520
1521 // {-1,2,3},
1522 // {1,2,-3}
1523 };
1524
1525 // s = [0]/[2], t = [1]/[2]
1526 int vec_to_st[6][3] =
1527 {
1528 {-2,3,1},
1529 {2,3,-1},
1530
1531 {1,3,2},
1532 {-1,3,-2},
1533
1534 {-2,-1,3},
1535 {-2,1,-3}
1536
1537 // {-1,2,3},
1538 // {1,2,-3}
1539 };
1540
1541 float skymins[2][6], skymaxs[2][6];
1542
DrawSkyPolygon(int nump,vec3_t vecs)1543 void DrawSkyPolygon (int nump, vec3_t vecs)
1544 {
1545 int i,j;
1546 vec3_t v, av;
1547 float s, t, dv;
1548 int axis;
1549 float *vp;
1550
1551 c_sky++;
1552 #if 0
1553 glBegin (GL_POLYGON);
1554 for (i=0 ; i<nump ; i++, vecs+=3)
1555 {
1556 VectorAdd(vecs, r_origin, v);
1557 glVertex3fv (v);
1558 }
1559 glEnd();
1560 return;
1561 #endif
1562 // decide which face it maps to
1563 VectorCopy (vec3_origin, v);
1564 for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
1565 {
1566 VectorAdd (vp, v, v);
1567 }
1568 av[0] = fabs(v[0]);
1569 av[1] = fabs(v[1]);
1570 av[2] = fabs(v[2]);
1571 if (av[0] > av[1] && av[0] > av[2])
1572 {
1573 if (v[0] < 0)
1574 axis = 1;
1575 else
1576 axis = 0;
1577 }
1578 else if (av[1] > av[2] && av[1] > av[0])
1579 {
1580 if (v[1] < 0)
1581 axis = 3;
1582 else
1583 axis = 2;
1584 }
1585 else
1586 {
1587 if (v[2] < 0)
1588 axis = 5;
1589 else
1590 axis = 4;
1591 }
1592
1593 // project new texture coords
1594 for (i=0 ; i<nump ; i++, vecs+=3)
1595 {
1596 j = vec_to_st[axis][2];
1597 if (j > 0)
1598 dv = vecs[j - 1];
1599 else
1600 dv = -vecs[-j - 1];
1601
1602 j = vec_to_st[axis][0];
1603 if (j < 0)
1604 s = -vecs[-j -1] / dv;
1605 else
1606 s = vecs[j-1] / dv;
1607 j = vec_to_st[axis][1];
1608 if (j < 0)
1609 t = -vecs[-j -1] / dv;
1610 else
1611 t = vecs[j-1] / dv;
1612
1613 if (s < skymins[0][axis])
1614 skymins[0][axis] = s;
1615 if (t < skymins[1][axis])
1616 skymins[1][axis] = t;
1617 if (s > skymaxs[0][axis])
1618 skymaxs[0][axis] = s;
1619 if (t > skymaxs[1][axis])
1620 skymaxs[1][axis] = t;
1621 }
1622 }
1623
1624 #define MAX_CLIP_VERTS 64
ClipSkyPolygon(int nump,vec3_t vecs,int stage)1625 void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
1626 {
1627 float *norm;
1628 float *v;
1629 qboolean front, back;
1630 float d, e;
1631 float dists[MAX_CLIP_VERTS];
1632 int sides[MAX_CLIP_VERTS];
1633 vec3_t newv[2][MAX_CLIP_VERTS];
1634 int newc[2];
1635 int i, j;
1636
1637 if (nump > MAX_CLIP_VERTS-2)
1638 Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS");
1639 if (stage == 6)
1640 { // fully clipped, so draw it
1641 DrawSkyPolygon (nump, vecs);
1642 return;
1643 }
1644
1645 front = back = false;
1646 norm = skyclip[stage];
1647 for (i=0, v = vecs ; i<nump ; i++, v+=3)
1648 {
1649 d = DotProduct (v, norm);
1650 if (d > ON_EPSILON)
1651 {
1652 front = true;
1653 sides[i] = SIDE_FRONT;
1654 }
1655 else if (d < ON_EPSILON)
1656 {
1657 back = true;
1658 sides[i] = SIDE_BACK;
1659 }
1660 else
1661 sides[i] = SIDE_ON;
1662 dists[i] = d;
1663 }
1664
1665 if (!front || !back)
1666 { // not clipped
1667 ClipSkyPolygon (nump, vecs, stage+1);
1668 return;
1669 }
1670
1671 // clip it
1672 sides[i] = sides[0];
1673 dists[i] = dists[0];
1674 VectorCopy (vecs, (vecs+(i*3)) );
1675 newc[0] = newc[1] = 0;
1676
1677 for (i=0, v = vecs ; i<nump ; i++, v+=3)
1678 {
1679 switch (sides[i])
1680 {
1681 case SIDE_FRONT:
1682 VectorCopy (v, newv[0][newc[0]]);
1683 newc[0]++;
1684 break;
1685 case SIDE_BACK:
1686 VectorCopy (v, newv[1][newc[1]]);
1687 newc[1]++;
1688 break;
1689 case SIDE_ON:
1690 VectorCopy (v, newv[0][newc[0]]);
1691 newc[0]++;
1692 VectorCopy (v, newv[1][newc[1]]);
1693 newc[1]++;
1694 break;
1695 }
1696
1697 if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
1698 continue;
1699
1700 d = dists[i] / (dists[i] - dists[i+1]);
1701 for (j=0 ; j<3 ; j++)
1702 {
1703 e = v[j] + d*(v[j+3] - v[j]);
1704 newv[0][newc[0]][j] = e;
1705 newv[1][newc[1]][j] = e;
1706 }
1707 newc[0]++;
1708 newc[1]++;
1709 }
1710
1711 // continue
1712 ClipSkyPolygon (newc[0], newv[0][0], stage+1);
1713 ClipSkyPolygon (newc[1], newv[1][0], stage+1);
1714 }
1715
1716 /*
1717 =================
1718 R_DrawSkyChain
1719 =================
1720 */
R_DrawSkyChain(msurface_t * s)1721 void R_DrawSkyChain (msurface_t *s)
1722 {
1723 msurface_t *fa;
1724
1725 int i;
1726 vec3_t verts[MAX_CLIP_VERTS];
1727 glpoly_t *p;
1728 float *v;
1729
1730 c_sky = 0;
1731 GL_Bind(solidskytexture);
1732
1733 // calculate vertex values for sky box
1734
1735
1736 for (fa=s ; fa ; fa=fa->texturechain)
1737 {
1738 for (p=fa->polys ; p ; p=p->next)
1739 {
1740 v = (float *)(&globalVertexTable[p->firstvertex]);
1741
1742 for (i=0 ; i<p->numverts ; i++, v+=VERTEXSIZE)
1743 {
1744 VectorSubtract (v, r_origin, verts[i]);
1745 }
1746 ClipSkyPolygon (p->numverts, v, 0);
1747 }
1748 }
1749 }
1750
1751
1752 /*
1753 ==============
1754 R_ClearSkyBox
1755 ==============
1756 */
R_ClearSkyBox(void)1757 void R_ClearSkyBox (void)
1758 {
1759 int i;
1760
1761 for (i=0 ; i<6 ; i++)
1762 {
1763 skymins[0][i] = skymins[1][i] = 9999;
1764 skymaxs[0][i] = skymaxs[1][i] = -9999;
1765 }
1766 }
1767
1768
MakeSkyVec(float s,float t,int axis)1769 void MakeSkyVec (float s, float t, int axis)
1770 {
1771 vec3_t v, b;
1772 int j, k;
1773
1774 b[0] = s*1024;
1775 b[1] = t*1024;
1776 b[2] = 1024;
1777
1778 for (j=0 ; j<3 ; j++)
1779 {
1780 k = st_to_vec[axis][j];
1781 if (k < 0)
1782 v[j] = -b[-k - 1];
1783 else
1784 v[j] = b[k - 1];
1785 v[j] += r_origin[j];
1786 }
1787
1788 // avoid bilerp seam
1789 s = (s+1)*0.5;
1790 t = (t+1)*0.5;
1791
1792 if (s < 1.0/512)
1793 s = 1.0/512;
1794 else if (s > 511.0/512)
1795 s = 511.0/512;
1796 if (t < 1.0/512)
1797 t = 1.0/512;
1798 else if (t > 511.0/512)
1799 t = 511.0/512;
1800
1801 t = 1.0 - t;
1802 glTexCoord2f (s, t);
1803 glVertex3fv (v);
1804 }
1805
1806 /*
1807 ==============
1808 R_DrawSkyBox
1809 ==============
1810 */
1811 int skytexorder[6] = {0,2,1,3,4,5};
R_DrawSkyBox(void)1812 void R_DrawSkyBox (void)
1813 {
1814 int i, j, k;
1815 vec3_t v;
1816 float s, t;
1817
1818 if (skytexturenum >= 0) {
1819 // glColor3f(1,1,1);
1820 if (!cl.worldmodel->textures[skytexturenum]->texturechain) return;
1821 // R_DrawSkyChain (cl.worldmodel->textures[skytexturenum]->texturechain);
1822 cl.worldmodel->textures[skytexturenum]->texturechain = NULL;
1823 }
1824
1825 glDepthMask(0);
1826
1827 if (fog_enabled.value && !gl_wireframe.value)
1828 glDisable(GL_FOG);
1829
1830 for (i=0 ; i<6 ; i++)
1831 {
1832 /*
1833 if (skymins[0][i] >= skymaxs[0][i]
1834 || skymins[1][i] >= skymaxs[1][i])
1835 continue;
1836 */
1837 GL_Bind (SKY_TEX+skytexorder[i]);
1838
1839 skymins[0][i] = -1;
1840 skymins[1][i] = -1;
1841 skymaxs[0][i] = 1;
1842 skymaxs[1][i] = 1;
1843
1844 glBegin (GL_QUADS);
1845 MakeSkyVec (skymins[0][i], skymins[1][i], i);
1846 MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
1847 MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
1848 MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
1849 glEnd ();
1850 }
1851
1852 if (fog_enabled.value && !gl_wireframe.value)
1853 glEnable(GL_FOG);
1854
1855 if (!skybox_hasclouds) {
1856 glDepthMask(1);
1857 return;
1858 }
1859
1860 GL_Bind (SKY_TEX+6);
1861
1862 glEnable(GL_BLEND);
1863 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
1864
1865 glMatrixMode(GL_TEXTURE);
1866 glPushMatrix();
1867 glTranslatef(cl.time*skybox_cloudspeed,0,0);
1868 glColor4ub(255,255,255,255);
1869 glBegin(GL_TRIANGLE_FAN);
1870 glTexCoord2f(0,0);
1871 glVertex3f(-800.0 + r_origin[0], -800.0 + r_origin[1], 20.0 + r_origin[2]);
1872
1873 glTexCoord2f(0,40);
1874 glVertex3f(800.0 + r_origin[0], -800.0 + r_origin[1], 20.0 + r_origin[2]);
1875
1876 glTexCoord2f(40,40);
1877 glVertex3f(800.0 + r_origin[0], 800.0 + r_origin[1], 20.0 + r_origin[2]);
1878
1879 glTexCoord2f(40,0);
1880 glVertex3f(-800.0 + r_origin[0], 800.0 + r_origin[1], 20.0 + r_origin[2]);
1881
1882 glEnd();
1883 glPopMatrix();
1884 glMatrixMode(GL_MODELVIEW);
1885
1886 glDisable(GL_ALPHA_TEST);
1887 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1888 for (i=0 ; i<6 ; i++)
1889 {
1890 /*
1891 if (skymins[0][i] >= skymaxs[0][i]
1892 || skymins[1][i] >= skymaxs[1][i])
1893 continue;
1894 */
1895 GL_Bind (SKY_TEX+skytexorder[i]);
1896
1897
1898 skymins[0][i] = -1;
1899 skymins[1][i] = -1;
1900 skymaxs[0][i] = 1;
1901 skymaxs[1][i] = 1;
1902
1903 glBegin (GL_QUADS);
1904 MakeSkyVec (skymins[0][i], skymins[1][i], i);
1905 MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
1906 MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
1907 MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
1908 glEnd ();
1909 }
1910
1911 glDisable(GL_BLEND);
1912 glDepthMask(1);
1913 }
1914
1915
1916 //#endif
1917
1918 //===============================================================
1919
1920 /*
1921 =============
1922 R_InitSky
1923
1924 A sky texture is 256*128, with the right side being a masked overlay
1925 ==============
1926 */
R_InitSky(texture_t * mt)1927 void R_InitSky (texture_t *mt)
1928 {
1929 int i, j, p;
1930 byte *src;
1931 unsigned trans[128*128];
1932 unsigned transpix;
1933 int r, g, b;
1934 unsigned *rgba;
1935
1936 src = (byte *)mt + mt->offsets[0];
1937
1938 // make an average value for the back to avoid
1939 // a fringe on the top level
1940
1941 r = g = b = 0;
1942 for (i=0 ; i<128 ; i++)
1943 for (j=0 ; j<128 ; j++)
1944 {
1945 p = src[i*256 + j + 128];
1946 rgba = &d_8to24table[p];
1947 trans[(i*128) + j] = *rgba;
1948 r += ((byte *)rgba)[0];
1949 g += ((byte *)rgba)[1];
1950 b += ((byte *)rgba)[2];
1951 }
1952
1953 ((byte *)&transpix)[0] = r/(128*128);
1954 ((byte *)&transpix)[1] = g/(128*128);
1955 ((byte *)&transpix)[2] = b/(128*128);
1956 ((byte *)&transpix)[3] = 0;
1957
1958
1959 if (!solidskytexture)
1960 solidskytexture = texture_extension_number++;
1961 GL_Bind (solidskytexture );
1962 glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
1963 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1964 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1965
1966
1967 for (i=0 ; i<128 ; i++)
1968 for (j=0 ; j<128 ; j++)
1969 {
1970 p = src[i*256 + j];
1971 if (p == 0)
1972 trans[(i*128) + j] = transpix;
1973 else
1974 trans[(i*128) + j] = d_8to24table[p];
1975 }
1976
1977 if (!alphaskytexture)
1978 alphaskytexture = texture_extension_number++;
1979 GL_Bind(alphaskytexture);
1980 glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
1981 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1982 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1983 }
1984
1985