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