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 
21 // draw.c -- this is the only file outside the refresh that touches the
22 // vid buffer
23 
24 #include "quakedef.h"
25 #include <stdlib.h>
26 
27 #define GL_COLOR_INDEX8_EXT     0x80E5
28 
29 extern unsigned char d_15to8table[65536];
30 
31 cvar_t		gl_nobind = {"gl_nobind", "0"};
32 cvar_t		gl_max_size = {"gl_max_size", "1024"};
33 cvar_t		gl_picmip = {"gl_picmip", "0"};
34 cvar_t          gl_gloss = {"gl_gloss", "0.3"};
35 cvar_t          gl_compress_textures = {"gl_compress_textures", "0"};
36 cvar_t          willi_gray_colormaps = {"willi_gray_colormaps", "0"};
37 cvar_t          con_clock = {"con_clock", "1", true};
38 
39 byte		*draw_chars;				// 8*8 graphic characters
40 qpic_t		*draw_disc;
41 qpic_t		*draw_backtile;
42 
43 int			translate_texture;
44 int			char_texture;
45 int			glow_texture_object;	//PENTA: gl texture object of the glow texture
46 int			normcube_texture_object; //PENTA: normalization cubemap
47 int			atten1d_texture_object;
48 int			atten2d_texture_object;
49 int			atten3d_texture_object;
50 int			halo_texture_object;
51 
52 
53 typedef struct
54 {
55 	int		texnum;
56 	float	sl, tl, sh, th;
57 } glpic_t;
58 
59 byte		conback_buffer[sizeof(qpic_t) + sizeof(glpic_t)];
60 qpic_t		*conback = (qpic_t *)&conback_buffer;
61 
62 int		gl_lightmap_format = 4;
63 int		gl_solid_format = 3;
64 int		gl_alpha_format = 4;
65 
66 int		gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
67 int		gl_filter_max = GL_LINEAR;
68 
69 
70 int		texels;
71 
72 typedef struct
73 {
74 	int		texnum;
75 	char	identifier[64];
76 	int		width, height;
77 	qboolean	mipmap;
78 } gltexture_t;
79 
80 #define	MAX_GLTEXTURES	1024
81 gltexture_t	gltextures[MAX_GLTEXTURES];
82 int			numgltextures;
83 
84 qboolean is_overriden;
85 
86 // <AWE> added local prototypes.
87 int		GL_Load2DAttenTexture (void);
88 int		GL_Load3DAttenTexture (void);
89 int		GL_LoadBumpTexture (void);
90 int		GL_LoadNormalizationCubemap (void);
91 int		GL_LoadPicTexture (qpic_t *pic);
92 
GL_Bind(int texnum)93 void GL_Bind (int texnum)
94 {
95 	if (gl_nobind.value)
96 		texnum = char_texture;
97 	if (currenttexture == texnum)
98 		return;
99 	currenttexture = texnum;
100 //#ifdef _WIN32
101 //	bindTexFunc (GL_TEXTURE_2D, texnum);
102 //#else
103 	glBindTexture(GL_TEXTURE_2D, texnum);
104 //#endif
105 
106 /*
107 	Don't do this anisotropy is part of the texture state, it is set when you bind the texture
108 
109         if (gl_texturefilteranisotropic)	// <AWE> anisotropic texture filtering
110         {
111             glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl_textureanisotropylevel);
112         }
113 */
114 }
115 
116 
117 /*
118 =============================================================================
119 
120   scrap allocation
121 
122   Allocate all the little status bar obejcts into a single texture
123   to crutch up stupid hardware / drivers
124 
125 =============================================================================
126 */
127 
128 #define	MAX_SCRAPS		2
129 #define	BLOCK_WIDTH		256
130 #define	BLOCK_HEIGHT	256
131 
132 int			scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH];
133 byte		scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT*4];
134 qboolean	scrap_dirty;
135 int			scrap_texnum;
136 
137 // returns a texture number and the position inside it
Scrap_AllocBlock(int w,int h,int * x,int * y)138 int Scrap_AllocBlock (int w, int h, int *x, int *y)
139 {
140 	int		i, j;
141 	int		best, best2;
142 	int		texnum;
143 
144 	for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++)
145 	{
146 		best = BLOCK_HEIGHT;
147 
148 		for (i=0 ; i<BLOCK_WIDTH-w ; i++)
149 		{
150 			best2 = 0;
151 
152 			for (j=0 ; j<w ; j++)
153 			{
154 				if (scrap_allocated[texnum][i+j] >= best)
155 					break;
156 				if (scrap_allocated[texnum][i+j] > best2)
157 					best2 = scrap_allocated[texnum][i+j];
158 			}
159 			if (j == w)
160 			{	// this is a valid spot
161 				*x = i;
162 				*y = best = best2;
163 			}
164 		}
165 
166 		if (best + h > BLOCK_HEIGHT)
167 			continue;
168 
169 		for (i=0 ; i<w ; i++)
170 			scrap_allocated[texnum][*x + i] = best + h;
171 
172 		return texnum;
173 	}
174 
175 	Sys_Error ("Scrap_AllocBlock: full");
176 	return 0;
177 }
178 
179 int	scrap_uploads;
180 
Scrap_Upload(void)181 void Scrap_Upload (void)
182 {
183 	int		texnum;
184 
185 	scrap_uploads++;
186 
187 	for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++) {
188 		GL_Bind(scrap_texnum + texnum);
189 		GL_Upload8 (scrap_texels[texnum], "scrap", BLOCK_WIDTH, BLOCK_HEIGHT, false, true, false);
190 	}
191 	scrap_dirty = false;
192 }
193 
194 //=============================================================================
195 /* Support Routines */
196 
197 typedef struct cachepic_s
198 {
199 	char		name[MAX_QPATH];
200 	qpic_t		pic;
201 	byte		padding[32];	// for appended glpic
202 } cachepic_t;
203 
204 #define	MAX_CACHED_PICS		128
205 cachepic_t	menu_cachepics[MAX_CACHED_PICS];
206 int			menu_numcachepics;
207 
208 byte		menuplyr_pixels[4096];
209 
210 int		pic_texels;
211 int		pic_count;
212 
Draw_PicFromWad(char * name)213 qpic_t *Draw_PicFromWad (char *name)
214 {
215 	qpic_t	*p;
216 	glpic_t	*gl;
217 
218 	p = W_GetLumpName (name);
219 	gl = (glpic_t *)p->data;
220 
221 	// load little ones into the scrap
222 	if (p->width < 64 && p->height < 64)
223 	{
224 		int		x, y;
225 		int		i, j, k;
226 		int		texnum;
227 
228 		texnum = Scrap_AllocBlock (p->width, p->height, &x, &y);
229 		scrap_dirty = true;
230 		k = 0;
231 		for (i=0 ; i<p->height ; i++)
232 			for (j=0 ; j<p->width ; j++, k++)
233 				scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = p->data[k];
234 		texnum += scrap_texnum;
235 		gl->texnum = texnum;
236 		gl->sl = (x+0.01)/(float)BLOCK_WIDTH;
237 		gl->sh = (x+p->width-0.01)/(float)BLOCK_WIDTH;
238 		gl->tl = (y+0.01)/(float)BLOCK_WIDTH;
239 		gl->th = (y+p->height-0.01)/(float)BLOCK_WIDTH;
240 
241 		pic_count++;
242 		pic_texels += p->width*p->height;
243 	}
244 	else
245 	{
246 		gl->texnum = GL_LoadPicTexture (p);
247 		gl->sl = 0;
248 		gl->sh = 1;
249 		gl->tl = 0;
250 		gl->th = 1;
251 	}
252 	return p;
253 }
254 
255 
256 /*
257 ================
258 Draw_CachePic
259 ================
260 */
Draw_CachePic(char * path)261 qpic_t	*Draw_CachePic (char *path)
262 {
263 	cachepic_t	*pic;
264 	int			i;
265 	qpic_t		*dat;
266 	glpic_t		*gl;
267 
268 	for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
269 		if (!strcmp (path, pic->name))
270 			return &pic->pic;
271 
272 	if (menu_numcachepics == MAX_CACHED_PICS)
273 		Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
274 	menu_numcachepics++;
275 	strncpy (pic->name, path,sizeof(pic->name));
276 
277 //
278 // load the pic from disk
279 //
280 	dat = (qpic_t *)COM_LoadTempFile (path);
281 	if (!dat)
282 		Sys_Error ("Draw_CachePic: failed to load %s", path);
283 	SwapPic (dat);
284 
285 	// HACK HACK HACK --- we need to keep the bytes for
286 	// the translatable player picture just for the menu
287 	// configuration dialog
288 	if (!strcmp (path, "gfx/menuplyr.lmp"))
289 		memcpy (menuplyr_pixels, dat->data, dat->width*dat->height);
290 
291 	pic->pic.width = dat->width;
292 	pic->pic.height = dat->height;
293 
294 	gl = (glpic_t *)pic->pic.data;
295 	gl->texnum = GL_LoadPicTexture (dat);
296 	gl->sl = 0;
297 	gl->sh = 1;
298 	gl->tl = 0;
299 	gl->th = 1;
300 
301 	return &pic->pic;
302 }
303 
304 
Draw_CharToConback(int num,byte * dest)305 void Draw_CharToConback (int num, byte *dest)
306 {
307 	int		row, col;
308 	byte	*source;
309 	int		drawline;
310 	int		x;
311 
312 	row = num>>4;
313 	col = num&15;
314 	source = draw_chars + (row<<10) + (col<<3);
315 
316 	drawline = 8;
317 
318 	while (drawline--)
319 	{
320 		for (x=0 ; x<8 ; x++)
321 			if (source[x] != 255)
322 				dest[x] = 0x60 + source[x];
323 		source += 128;
324 		dest += 320;
325 	}
326 
327 }
328 
329 typedef struct
330 {
331 	char *name;
332 	int	minimize, maximize;
333 } glmode_t;
334 
335 glmode_t modes[] = {
336 	{"GL_NEAREST", GL_NEAREST, GL_NEAREST},
337 	{"GL_LINEAR", GL_LINEAR, GL_LINEAR},
338 	{"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
339 	{"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
340 	{"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
341 	{"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
342 };
343 
344 /*
345 ===============
346 Draw_TextureMode_f
347 ===============
348 */
Draw_TextureMode_f(void)349 void Draw_TextureMode_f (void)
350 {
351 	int		i;
352 	gltexture_t	*glt;
353 
354 	if (Cmd_Argc() == 1)
355 	{
356 		for (i=0 ; i< 6 ; i++)
357 			if (gl_filter_min == modes[i].minimize)
358 			{
359 				Con_Printf ("%s\n", modes[i].name);
360 				return;
361 			}
362 		Con_Printf ("current filter is unknown???\n");
363 		return;
364 	}
365 
366 	for (i=0 ; i< 6 ; i++)
367 	{
368 		if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) )
369 			break;
370 	}
371 	if (i == 6)
372 	{
373 		Con_Printf ("bad filter name\n");
374 		return;
375 	}
376 
377 	gl_filter_min = modes[i].minimize;
378 	gl_filter_max = modes[i].maximize;
379 
380 	// change all the existing mipmap texture objects
381 	for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
382 	{
383 		if (glt->mipmap)
384 		{
385 			GL_Bind (glt->texnum);
386 			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
387 			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
388 			//PENTA: also update bump maps
389 			GL_Bind (glt->texnum+1);
390 			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
391 			glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
392 		}
393 	}
394 }
395 
396 /*
397 ===============
398 Draw_Init
399 ===============
400 */
Draw_Init(void)401 void Draw_Init (void)
402 {
403 	int		i;
404 	qpic_t	*cb;
405 	byte	*dest /*, *src*/;	// <AWE> unused because of "#if 0".
406 	int		x, y;
407 	char	ver[40];
408 	glpic_t	*gl;
409 	int		start;
410 	byte	*ncdata;
411 //	int		fstep;		// <AWE> unused because of "#if 0".
412 
413 
414 	Cvar_RegisterVariable (&gl_nobind);
415 	Cvar_RegisterVariable (&gl_max_size);
416 	Cvar_RegisterVariable (&gl_picmip);
417 	Cvar_RegisterVariable (&gl_gloss);
418 	Cvar_RegisterVariable (&gl_compress_textures);
419 	Cvar_RegisterVariable (&willi_gray_colormaps);
420 	Cvar_RegisterVariable (&con_clock);
421 
422 	// 3dfx can only handle 256 wide textures
423 	if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4) ||
424 		strstr((char *)gl_renderer, "Glide"))
425 		Cvar_Set ("gl_max_size", "256");
426 
427 	Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f);
428 
429 	// load the console background and the charset
430 	// by hand, because we need to write the version
431 	// string into the background before turning
432 	// it into a texture
433 	draw_chars = W_GetLumpName ("conchars");
434 	for (i=0 ; i<256*64 ; i++)
435 		if (draw_chars[i] == 0)
436 			draw_chars[i] = 255;	// proper transparent color
437 
438 	// now turn them into textures
439 	char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true, false);
440 
441 	start = Hunk_LowMark();
442 
443 	cb = (qpic_t *)COM_LoadTempFile ("gfx/conback.lmp");
444 	if (!cb)
445 		Sys_Error ("Couldn't load gfx/conback.lmp");
446 	SwapPic (cb);
447 
448 	// hack the version number directly into the pic
449 #if defined(__linux__)
450 	sprintf (ver, "(Linux %2.2f, gl %4.2f) %4.2f", (float)LINUX_VERSION, (float)GLQUAKE_VERSION, (float)VERSION);
451 #elif defined (__APPLE__) || defined (MACOSX)
452 	sprintf (ver, "(MACOS X %2.2f, gl %4.2f) %4.2f", (float)MACOSX_VERSION, (float)GLQUAKE_VERSION, (float)VERSION);
453 #else
454 	sprintf (ver, "(st %4.2f) %4.2f", (float)STQUAKE_VERSION, (float)VERSION);
455 #endif
456 	dest = cb->data + 320*186 + 320 - 11 - 8*strlen(ver);
457 	y = strlen(ver);
458 	for (x=0 ; x<y ; x++)
459 		Draw_CharToConback (ver[x], dest+(x<<3));
460 
461 #if 0
462 	conback->width = vid.conwidth;
463 	conback->height = vid.conheight;
464 
465  	// scale console to vid size
466  	dest = ncdata = Hunk_AllocName(vid.conwidth * vid.conheight, "conback");
467 
468  	for (y=0 ; y<vid.conheight ; y++, dest += vid.conwidth)
469  	{
470  		src = cb->data + cb->width * (y*cb->height/vid.conheight);
471  		if (vid.conwidth == cb->width)
472  			memcpy (dest, src, vid.conwidth);
473  		else
474  		{
475  			f = 0;
476  			fstep = cb->width*0x10000/vid.conwidth;
477  			for (x=0 ; x<vid.conwidth ; x+=4)
478  			{
479  				dest[x] = src[f>>16];
480  				f += fstep;
481  				dest[x+1] = src[f>>16];
482  				f += fstep;
483  				dest[x+2] = src[f>>16];
484  				f += fstep;
485  				dest[x+3] = src[f>>16];
486  				f += fstep;
487  			}
488  		}
489  	}
490 #else
491 	conback->width = cb->width;
492 	conback->height = cb->height;
493 	ncdata = cb->data;
494 #endif
495 
496 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
497 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
498 
499 	gl = (glpic_t *)conback->data;
500 	gl->texnum = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, false, false, false);
501 	gl->sl = 0;
502 	gl->sh = 1;
503 	gl->tl = 0;
504 	gl->th = 1;
505 	conback->width = vid.width;
506 	conback->height = vid.height;
507 
508 	// free loaded console
509 	Hunk_FreeToLowMark(start);
510 
511 	// save a texture slot for translated picture
512 	translate_texture = texture_extension_number++;
513 
514 	// save slots for scraps
515 	scrap_texnum = texture_extension_number;
516 	texture_extension_number += MAX_SCRAPS;
517 
518 	//
519 	// get the other pics we need
520 	//
521 	draw_disc = Draw_PicFromWad ("disc");
522 	draw_backtile = Draw_PicFromWad ("backtile");
523 
524 	//PENTA: load fallof glow
525 	glow_texture_object = GL_Load2DAttenTexture();
526 	atten3d_texture_object = GL_Load3DAttenTexture();
527 
528 	//Load nomalization cube map
529 	normcube_texture_object = GL_LoadNormalizationCubemap();
530 
531 	//load diffuse vertex program
532 	R_LoadVertexProgram();
533 
534 	halo_texture_object = EasyTgaLoad("penta/utflare5.tga");
535 
536 	for (i=0; i<8; i++) {
537 		char name[32];
538 		sprintf(name,"penta/caust%02.2i.tga",i*4);
539 		caustics_textures[i] = EasyTgaLoad(name);
540 	}
541 
542 	//Load water shader textures
543 	InitShaderTex();
544 	//load mirror dummys
545 	R_InitMirrorChains();
546 
547 	R_InitGlare();
548 }
549 
550 
551 
552 /*
553 ================
554 Draw_Character
555 
556 Draws one 8*8 graphics character with 0 being transparent.
557 It can be clipped to the top of the screen to allow the console to be
558 smoothly scrolled off.
559 ================
560 */
Draw_Character(int x,int y,int num)561 void Draw_Character (int x, int y, int num)
562 {
563 	int		row, col;
564 	float		frow, fcol, size;
565 
566 	if (num == 32)
567 		return;		// space
568 
569 	num &= 255;
570 
571 	if (y <= -8)
572 		return;			// totally off screen
573 
574 	row = num>>4;
575 	col = num&15;
576 
577 	frow = row*0.0625;
578 	fcol = col*0.0625;
579 	size = 0.0625;
580 
581 	glEnable(GL_BLEND);
582 	GL_Bind (char_texture);
583 
584 	glBegin (GL_QUADS);
585 	glTexCoord2f (fcol, frow);
586 	glVertex2f (x, y);
587 	glTexCoord2f (fcol + size, frow);
588 	glVertex2f (x+8, y);
589 	glTexCoord2f (fcol + size, frow + size);
590 	glVertex2f (x+8, y+8);
591 	glTexCoord2f (fcol, frow + size);
592 	glVertex2f (x, y+8);
593 	glEnd ();
594 	glDisable(GL_BLEND);
595 }
596 
597 /*
598 ================
599 Draw_String
600 ================
601 */
Draw_String(int x,int y,char * str)602 void Draw_String (int x, int y, char *str)
603 {
604 	while (*str)
605 	{
606 		Draw_Character (x, y, *str);
607 		str++;
608 		x += 8;
609 	}
610 }
611 
612 /*
613 ================
614 Draw_DebugChar
615 
616 Draws a single character directly to the upper right corner of the screen.
617 This is for debugging lockups by drawing different chars in different parts
618 of the code.
619 ================
620 */
Draw_DebugChar(char num)621 void Draw_DebugChar (char num)
622 {
623 }
624 
625 /*
626 =============
627 Draw_AlphaPic
628 =============
629 */
Draw_AlphaPic(int x,int y,qpic_t * pic,float alpha)630 void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha)
631 {
632 	glpic_t			*gl;
633 
634 	if (scrap_dirty)
635 		Scrap_Upload ();
636 	gl = (glpic_t *)pic->data;
637 	glDisable(GL_ALPHA_TEST);
638 	glEnable (GL_BLEND);
639 //	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
640 //	glCullFace(GL_FRONT);
641 	glColor4f (1,1,1,alpha);
642 	GL_Bind (gl->texnum);
643 	glBegin (GL_QUADS);
644 	glTexCoord2f (gl->sl, gl->tl);
645 	glVertex2f (x, y);
646 	glTexCoord2f (gl->sh, gl->tl);
647 	glVertex2f (x+pic->width, y);
648 	glTexCoord2f (gl->sh, gl->th);
649 	glVertex2f (x+pic->width, y+pic->height);
650 	glTexCoord2f (gl->sl, gl->th);
651 	glVertex2f (x, y+pic->height);
652 	glEnd ();
653 	glColor4f (1,1,1,1);
654 	glEnable(GL_ALPHA_TEST);
655 	glDisable (GL_BLEND);
656 }
657 
658 
659 /*
660 =============
661 Draw_Pic
662 =============
663 */
Draw_Pic(int x,int y,qpic_t * pic)664 void Draw_Pic (int x, int y, qpic_t *pic)
665 {
666 	glpic_t			*gl;
667 
668 	if (scrap_dirty)
669 		Scrap_Upload ();
670 	gl = (glpic_t *)pic->data;
671 	glColor4f (1,1,1,1);
672 	GL_Bind (gl->texnum);
673 	glBegin (GL_QUADS);
674 	glTexCoord2f (gl->sl, gl->tl);
675 	glVertex2f (x, y);
676 	glTexCoord2f (gl->sh, gl->tl);
677 	glVertex2f (x+pic->width, y);
678 	glTexCoord2f (gl->sh, gl->th);
679 	glVertex2f (x+pic->width, y+pic->height);
680 	glTexCoord2f (gl->sl, gl->th);
681 	glVertex2f (x, y+pic->height);
682 	glEnd ();
683 }
684 
685 
686 /*
687 =============
688 Draw_TransPic
689 =============
690 */
Draw_TransPic(int x,int y,qpic_t * pic)691 void Draw_TransPic (int x, int y, qpic_t *pic)
692 {
693 	if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
694 		 (unsigned)(y + pic->height) > vid.height)
695 	{
696 		Sys_Error ("Draw_TransPic: bad coordinates");
697 	}
698 
699 	Draw_Pic (x, y, pic);
700 }
701 
702 
703 /*
704 =============
705 Draw_TransPicTranslate
706 
707 Only used for the player color selection menu
708 =============
709 */
Draw_TransPicTranslate(int x,int y,qpic_t * pic,byte * translation)710 void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation)
711 {
712 	int				v, u, c;
713 	unsigned		trans[64*64], *dest;
714 	byte			*src;
715 	int				p;
716 
717 	GL_Bind (translate_texture);
718 
719 	c = pic->width * pic->height;
720 
721 	dest = trans;
722 	for (v=0 ; v<64 ; v++, dest += 64)
723 	{
724 		src = &menuplyr_pixels[ ((v*pic->height)>>6) *pic->width];
725 		for (u=0 ; u<64 ; u++)
726 		{
727 			p = src[(u*pic->width)>>6];
728 			if (p == 255)
729 				dest[u] = p;
730 			else
731 				dest[u] =  d_8to24table[translation[p]];
732 		}
733 	}
734 
735 	glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
736 
737 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
738 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
739 
740 	glColor3f (1,1,1);
741 	glBegin (GL_QUADS);
742 	glTexCoord2f (0, 0);
743 	glVertex2f (x, y);
744 	glTexCoord2f (1, 0);
745 	glVertex2f (x+pic->width, y);
746 	glTexCoord2f (1, 1);
747 	glVertex2f (x+pic->width, y+pic->height);
748 	glTexCoord2f (0, 1);
749 	glVertex2f (x, y+pic->height);
750 	glEnd ();
751 }
752 
753 
754 /*
755 ================
756 Draw_ConsoleBackground
757 
758 ================
759 */
Draw_ConsoleBackground(int lines)760 void Draw_ConsoleBackground (int lines)
761 {
762 	int y = (vid.height * 3) >> 2;
763 	int x, i;
764 
765 	char tl[80]; //Console Clock - Eradicator
766 	char timebuf[20];
767 
768 	if (lines > y)
769 		Draw_Pic(0, lines - vid.height, conback);
770 	else
771 		Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y);
772 
773 	if ( con_clock.value )
774 	{
775                 Sys_Strtime( timebuf );
776 		y = lines-14;
777 		sprintf (tl, "Time: %s",timebuf); //Console Clock - Eradicator
778 		x = vid.conwidth - (vid.conwidth*12/vid.width*12) + 30;
779 		for (i=0 ; i < strlen(tl) ; i++)
780 		   Draw_Character (x + i * 8, y, tl[i] | 0x80);
781 	}
782 }
783 
Draw_SpiralConsoleBackground(int lines)784 void Draw_SpiralConsoleBackground (int lines) //Spiral Console - Eradicator
785 {
786    int x, i;
787    int y;
788    static float xangle = 0, xfactor = .3f, xstep = .01f;
789 
790    char tl[80]; //Console Clock - Eradicator
791    char timebuf[20];
792    Sys_Strtime( timebuf );
793 
794 
795    glPushMatrix();
796    glMatrixMode(GL_TEXTURE);
797    glPushMatrix();
798    glLoadIdentity();
799    xangle += 1.0f;
800    xfactor += xstep;
801    if (xfactor > 8 || xfactor < .3f)
802       xstep = -xstep;
803    glRotatef(xangle, 0, 0, 1);
804    glScalef(xfactor, xfactor, xfactor);
805    y = (vid.height * 3) >> 2;
806    if (lines > y)
807       Draw_Pic(0, lines-vid.height, conback);
808    else
809       Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y);
810    glPopMatrix();
811    glMatrixMode(GL_MODELVIEW);
812    glPopMatrix();
813 
814    	if ( con_clock.value )
815 	{
816 		y = lines-14;
817 		sprintf (tl, "Time: %s",timebuf); //Console Clock - Eradicator
818 		x = vid.conwidth - (vid.conwidth*12/vid.width*12) + 30;
819 		for (i=0 ; i < strlen(tl) ; i++)
820 			Draw_Character (x + i * 8, y, tl[i] | 0x80);
821 	}
822 }
823 
824 
825 /*
826 =============
827 Draw_TileClear
828 
829 This repeats a 64*64 tile graphic to fill the screen around a sized down
830 refresh window.
831 =============
832 */
Draw_TileClear(int x,int y,int w,int h)833 void Draw_TileClear (int x, int y, int w, int h)
834 {
835 	glColor3f (1,1,1);
836 	GL_Bind (*(int *)draw_backtile->data);
837 	glBegin (GL_QUADS);
838 	glTexCoord2f (x/64.0, y/64.0);
839 	glVertex2f (x, y);
840 	glTexCoord2f ( (x+w)/64.0, y/64.0);
841 	glVertex2f (x+w, y);
842 	glTexCoord2f ( (x+w)/64.0, (y+h)/64.0);
843 	glVertex2f (x+w, y+h);
844 	glTexCoord2f ( x/64.0, (y+h)/64.0 );
845 	glVertex2f (x, y+h);
846 	glEnd ();
847 }
848 
849 
850 /*
851 =============
852 Draw_Fill
853 
854 Fills a box of pixels with a single color
855 =============
856 */
Draw_Fill(int x,int y,int w,int h,int c)857 void Draw_Fill (int x, int y, int w, int h, int c)
858 {
859 	glDisable (GL_TEXTURE_2D);
860 	glColor3f (host_basepal[c*3]/255.0,
861 		host_basepal[c*3+1]/255.0,
862 		host_basepal[c*3+2]/255.0);
863 
864 	glBegin (GL_QUADS);
865 
866 	glVertex2f (x,y);
867 	glVertex2f (x+w, y);
868 	glVertex2f (x+w, y+h);
869 	glVertex2f (x, y+h);
870 
871 	glEnd ();
872 	glColor3f (1,1,1);
873 	glEnable (GL_TEXTURE_2D);
874 }
875 //=============================================================================
876 
877 /*
878 ================
879 Draw_FadeScreen
880 
881 ================
882 */
Draw_FadeScreen(void)883 void Draw_FadeScreen (void)
884 {
885 	glEnable (GL_BLEND);
886 	glDisable (GL_TEXTURE_2D);
887 	glColor4f (0, 0, 0, 0.8);
888 	glBegin (GL_QUADS);
889 
890 	glVertex2f (0,0);
891 	glVertex2f (vid.width, 0);
892 	glVertex2f (vid.width, vid.height);
893 	glVertex2f (0, vid.height);
894 
895 	glEnd ();
896 	glColor4f (1,1,1,1);
897 	glEnable (GL_TEXTURE_2D);
898 	glDisable (GL_BLEND);
899 
900 	Sbar_Changed();
901 }
902 
903 //=============================================================================
904 
905 /*
906 ================
907 Draw_BeginDisc
908 
909 Draws the little blue disc in the corner of the screen.
910 Call before beginning any disc IO.
911 ================
912 */
Draw_BeginDisc(void)913 void Draw_BeginDisc (void)
914 {
915 	if (!draw_disc)
916 		return;
917 	glDrawBuffer  (GL_FRONT);
918 	Draw_Pic (vid.width - 24, 0, draw_disc);
919 	glDrawBuffer  (GL_BACK);
920 }
921 
922 
923 /*
924 ================
925 Draw_EndDisc
926 
927 Erases the disc icon.
928 Call after completing any disc IO
929 ================
930 */
Draw_EndDisc(void)931 void Draw_EndDisc (void)
932 {
933 }
934 
935 /*
936 ================
937 GL_Set2D
938 
939 Setup as if the screen was 320*200
940 ================
941 */
GL_Set2D(void)942 void GL_Set2D (void)
943 {
944 	glViewport (glx, gly, glwidth, glheight);
945 
946 	glMatrixMode(GL_PROJECTION);
947     glLoadIdentity ();
948 	glOrtho  (0, vid.width, vid.height, 0, -99999, 99999);
949 
950 	glMatrixMode(GL_MODELVIEW);
951     glLoadIdentity ();
952 
953 	glDisable (GL_DEPTH_TEST);
954 	glDisable (GL_CULL_FACE);
955 //	glDisable (GL_BLEND);
956 	glEnable (GL_ALPHA_TEST);
957 
958 	glEnable(GL_BLEND);
959 	glAlphaFunc(GL_GREATER,0.666);
960 //	glDisable (GL_ALPHA_TEST);
961 
962 	glColor4f (1,1,1,1);
963 }
964 
965 //====================================================================
966 
967 /*
968 ================
969 GL_FindTexture
970 ================
971 */
GL_FindTexture(char * identifier)972 int GL_FindTexture (char *identifier)
973 {
974 	int		i;
975 	gltexture_t	*glt;
976 
977 	for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
978 	{
979 		if (!strcmp (identifier, glt->identifier))
980 			return gltextures[i].texnum;
981 	}
982 
983 	return -1;
984 }
985 
986 /*
987 ================
988 GL_ResampleTextureLerpLine
989 
990 Interpolates between pixels on line - Eradicator
991 ================
992 */
GL_ResampleTextureLerpLine(byte * in,byte * out,int inwidth,int outwidth)993 void GL_ResampleTextureLerpLine (byte *in, byte *out, int inwidth, int outwidth)
994 {
995 	int		j, xi, oldx = 0, f, fstep, endx;
996 	fstep = (int) (inwidth*65536.0f/outwidth);
997 	endx = (inwidth-1);
998 	for (j = 0,f = 0;j < outwidth;j++, f += fstep)
999 	{
1000 		xi = (int) f >> 16;
1001 		if (xi != oldx)
1002 		{
1003 			in += (xi - oldx) * 4;
1004 			oldx = xi;
1005 		}
1006 		if (xi < endx)
1007 		{
1008 			int lerp = f & 0xFFFF;
1009 			*out++ = (byte) ((((in[4] - in[0]) * lerp) >> 16) + in[0]);
1010 			*out++ = (byte) ((((in[5] - in[1]) * lerp) >> 16) + in[1]);
1011 			*out++ = (byte) ((((in[6] - in[2]) * lerp) >> 16) + in[2]);
1012 			*out++ = (byte) ((((in[7] - in[3]) * lerp) >> 16) + in[3]);
1013 		}
1014 		else
1015 		{
1016 			*out++ = in[0];
1017 			*out++ = in[1];
1018 			*out++ = in[2];
1019 			*out++ = in[3];
1020 		}
1021 	}
1022 }
1023 
1024 /*
1025 ================
1026 GL_ResampleTexture
1027 ================
1028 */
GL_ResampleTexture(void * indata,int inwidth,int inheight,void * outdata,int outwidth,int outheight)1029 void GL_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata,  int outwidth, int outheight)
1030 {
1031 	//New Interpolated Texture Code - Eradicator
1032 	int		i, j, yi, oldy, f, fstep, endy = (inheight-1);
1033 	byte	*inrow, *out, *row1, *row2;
1034 	out = outdata;
1035 	fstep = (int) (inheight*65536.0f/outheight);
1036 
1037 	row1 = malloc(outwidth*4);
1038 	row2 = malloc(outwidth*4);
1039 	inrow = indata;
1040 	oldy = 0;
1041 	GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
1042 	GL_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth);
1043 	for (i = 0, f = 0;i < outheight;i++,f += fstep)
1044 	{
1045 		yi = f >> 16;
1046 		if (yi < endy)
1047 		{
1048 			int lerp = f & 0xFFFF;
1049 			if (yi != oldy)
1050 			{
1051 				inrow = (byte *)indata + inwidth*4*yi;
1052 				if (yi == oldy+1)
1053 					memcpy(row1, row2, outwidth*4);
1054 				else
1055 					GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
1056 				GL_ResampleTextureLerpLine (inrow + inwidth*4, row2, inwidth, outwidth);
1057 				oldy = yi;
1058 			}
1059 			j = outwidth - 4;
1060 			while(j >= 0)
1061 			{
1062 				out[ 0] = (byte) ((((row2[ 0] - row1[ 0]) * lerp) >> 16) + row1[ 0]);
1063 				out[ 1] = (byte) ((((row2[ 1] - row1[ 1]) * lerp) >> 16) + row1[ 1]);
1064 				out[ 2] = (byte) ((((row2[ 2] - row1[ 2]) * lerp) >> 16) + row1[ 2]);
1065 				out[ 3] = (byte) ((((row2[ 3] - row1[ 3]) * lerp) >> 16) + row1[ 3]);
1066 				out[ 4] = (byte) ((((row2[ 4] - row1[ 4]) * lerp) >> 16) + row1[ 4]);
1067 				out[ 5] = (byte) ((((row2[ 5] - row1[ 5]) * lerp) >> 16) + row1[ 5]);
1068 				out[ 6] = (byte) ((((row2[ 6] - row1[ 6]) * lerp) >> 16) + row1[ 6]);
1069 				out[ 7] = (byte) ((((row2[ 7] - row1[ 7]) * lerp) >> 16) + row1[ 7]);
1070 				out[ 8] = (byte) ((((row2[ 8] - row1[ 8]) * lerp) >> 16) + row1[ 8]);
1071 				out[ 9] = (byte) ((((row2[ 9] - row1[ 9]) * lerp) >> 16) + row1[ 9]);
1072 				out[10] = (byte) ((((row2[10] - row1[10]) * lerp) >> 16) + row1[10]);
1073 				out[11] = (byte) ((((row2[11] - row1[11]) * lerp) >> 16) + row1[11]);
1074 				out[12] = (byte) ((((row2[12] - row1[12]) * lerp) >> 16) + row1[12]);
1075 				out[13] = (byte) ((((row2[13] - row1[13]) * lerp) >> 16) + row1[13]);
1076 				out[14] = (byte) ((((row2[14] - row1[14]) * lerp) >> 16) + row1[14]);
1077 				out[15] = (byte) ((((row2[15] - row1[15]) * lerp) >> 16) + row1[15]);
1078 				out += 16;
1079 				row1 += 16;
1080 				row2 += 16;
1081 				j -= 4;
1082 			}
1083 			if (j & 2)
1084 			{
1085 				out[ 0] = (byte) ((((row2[ 0] - row1[ 0]) * lerp) >> 16) + row1[ 0]);
1086 				out[ 1] = (byte) ((((row2[ 1] - row1[ 1]) * lerp) >> 16) + row1[ 1]);
1087 				out[ 2] = (byte) ((((row2[ 2] - row1[ 2]) * lerp) >> 16) + row1[ 2]);
1088 				out[ 3] = (byte) ((((row2[ 3] - row1[ 3]) * lerp) >> 16) + row1[ 3]);
1089 				out[ 4] = (byte) ((((row2[ 4] - row1[ 4]) * lerp) >> 16) + row1[ 4]);
1090 				out[ 5] = (byte) ((((row2[ 5] - row1[ 5]) * lerp) >> 16) + row1[ 5]);
1091 				out[ 6] = (byte) ((((row2[ 6] - row1[ 6]) * lerp) >> 16) + row1[ 6]);
1092 				out[ 7] = (byte) ((((row2[ 7] - row1[ 7]) * lerp) >> 16) + row1[ 7]);
1093 				out += 8;
1094 				row1 += 8;
1095 				row2 += 8;
1096 			}
1097 			if (j & 1)
1098 			{
1099 				out[ 0] = (byte) ((((row2[ 0] - row1[ 0]) * lerp) >> 16) + row1[ 0]);
1100 				out[ 1] = (byte) ((((row2[ 1] - row1[ 1]) * lerp) >> 16) + row1[ 1]);
1101 				out[ 2] = (byte) ((((row2[ 2] - row1[ 2]) * lerp) >> 16) + row1[ 2]);
1102 				out[ 3] = (byte) ((((row2[ 3] - row1[ 3]) * lerp) >> 16) + row1[ 3]);
1103 				out += 4;
1104 				row1 += 4;
1105 				row2 += 4;
1106 			}
1107 			row1 -= outwidth*4;
1108 			row2 -= outwidth*4;
1109 		}
1110 		else
1111 		{
1112 			if (yi != oldy)
1113 			{
1114 				inrow = (byte *)indata + inwidth*4*yi;
1115 				if (yi == oldy+1)
1116 					memcpy(row1, row2, outwidth*4);
1117 				else
1118 					GL_ResampleTextureLerpLine (inrow, row1, inwidth, outwidth);
1119 				oldy = yi;
1120 			}
1121 			memcpy(out, row1, outwidth * 4);
1122 		}
1123 	}
1124 	free(row1);
1125 	free(row2);
1126 
1127 	//Old Code - Eradicator
1128 	/*int		i, j;
1129 	unsigned	*inrow;
1130 	unsigned	frac, fracstep;
1131 
1132 	fracstep = inwidth*0x10000/outwidth;
1133 	for (i=0 ; i<outheight ; i++, out += outwidth)
1134 	{
1135 		inrow = in + inwidth*(i*inheight/outheight);
1136 		frac = fracstep >> 1;
1137 		for (j=0 ; j<outwidth ; j+=4)
1138 		{
1139 			out[j] = inrow[frac>>16];
1140 			frac += fracstep;
1141 			out[j+1] = inrow[frac>>16];
1142 			frac += fracstep;
1143 			out[j+2] = inrow[frac>>16];
1144 			frac += fracstep;
1145 			out[j+3] = inrow[frac>>16];
1146 			frac += fracstep;
1147 		}
1148 	}*/
1149 }
1150 
1151 
1152 /*
1153 ================
1154 GL_Resample8BitTexture -- JACK
1155 ================
1156 */
GL_Resample8BitTexture(unsigned char * in,int inwidth,int inheight,unsigned char * out,int outwidth,int outheight)1157 void GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, unsigned char *out,  int outwidth, int outheight)
1158 {
1159 	int		i, j;
1160 	unsigned	char *inrow;
1161 	unsigned	frac, fracstep;
1162 
1163 	fracstep = inwidth*0x10000/outwidth;
1164 	for (i=0 ; i<outheight ; i++, out += outwidth)
1165 	{
1166 		inrow = in + inwidth*(i*inheight/outheight);
1167 		frac = fracstep >> 1;
1168 		for (j=0 ; j<outwidth ; j+=4)
1169 		{
1170 			out[j] = inrow[frac>>16];
1171 			frac += fracstep;
1172 			out[j+1] = inrow[frac>>16];
1173 			frac += fracstep;
1174 			out[j+2] = inrow[frac>>16];
1175 			frac += fracstep;
1176 			out[j+3] = inrow[frac>>16];
1177 			frac += fracstep;
1178 		}
1179 	}
1180 }
1181 
1182 
1183 
1184 /*
1185 ================
1186 GL_MipMap
1187 
1188 Operates in place, quartering the size of the texture
1189 ================
1190 */
GL_MipMap(byte * in,int width,int height)1191 void GL_MipMap (byte *in, int width, int height)
1192 {
1193 	int		i, j;
1194 	byte	*out;
1195 
1196 	width <<=2;
1197 	height >>= 1;
1198 	out = in;
1199 	for (i=0 ; i<height ; i++, in+=width)
1200 	{
1201 		for (j=0 ; j<width ; j+=8, out+=4, in+=8)
1202 		{
1203 			out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
1204 			out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
1205 			out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
1206 			out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
1207 		}
1208 	}
1209 }
1210 
1211 /*
1212 ================
1213 PENTA:
1214 GL_MipMapGray
1215 
1216 Operates in place, quartering the size of the texture
1217 ================
1218 */
GL_MipMapGray(byte * in,int width,int height)1219 void GL_MipMapGray (byte *in, int width, int height)
1220 {
1221 	int		i, j;
1222 	byte	*out;
1223 
1224 	width <<=2;
1225 	height >>= 1;
1226 	out = in;
1227 	for (i=0 ; i<height ; i++, in+=width)
1228 	{
1229 		for (j=0 ; j<width ; j+=2, out+=1, in+=2)
1230 		{
1231 			out[0] = (in[0] + in[1] + in[width+0] + in[width+1])>>2;
1232 		}
1233 	}
1234 }
1235 
1236 /*
1237 ================
1238 GL_MipMapNormal
1239 
1240 Operates in place, quartering the size of the texture
1241 Works on normal maps instead of rgb
1242 ================
1243 */
GL_MipMapNormal(byte * in,int width,int height)1244 void GL_MipMapNormal (byte *in, int width, int height)
1245 {
1246     int		i, j;
1247     byte	*out;
1248     float	inv255	= 1.0f/255.0f;
1249     float	inv127	= 1.0f/127.0f;
1250     float	x,y,z,l,g;
1251 
1252 
1253     width <<=2;
1254     height >>= 1;
1255     out = in;
1256     for (i=0 ; i<height ; i++, in+=width)
1257     {
1258 	for (j=0 ; j<width ; j+=8, out+=4, in+=8)
1259 	{
1260 	    x = (inv127*in[0]-1.0)+
1261 		(inv127*in[4]-1.0)+
1262 		(inv127*in[width+0]-1.0)+
1263 		(inv127*in[width+4]-1.0);
1264 	    y = (inv127*in[1]-1.0)+
1265 		(inv127*in[5]-1.0)+
1266 		(inv127*in[width+1]-1.0)+
1267 		(inv127*in[width+5]-1.0);
1268 	    z = (inv127*in[2]-1.0)+
1269 		(inv127*in[6]-1.0)+
1270 		(inv127*in[width+2]-1.0)+
1271 		(inv127*in[width+6]-1.0);
1272 
1273 	    g = (inv255*in[3])+
1274 
1275 		(inv255*in[7])+
1276 
1277 		(inv255*in[width+3])+
1278 
1279 		(inv255*in[width+7]);
1280 
1281 
1282             l = sqrt(x*x+y*y+z*z);
1283 	    if (l == 0.0) {
1284 		x = 0.0;
1285 		y = 0.0;
1286 		z = 1.0;
1287 	    } else {
1288 		//normalize it.
1289 		l=1/l;
1290 		x *=l;
1291 		y *=l;
1292 		z *=l;
1293 	    }
1294 	    out[0] = (unsigned char)128 + 127*x;
1295 	    out[1] = (unsigned char)128 + 127*y;
1296 	    out[2] = (unsigned char)128 + 127*z;
1297 	    out[3] = (byte)(g * 255.0/4.0);
1298 	}
1299     }
1300 
1301 }
1302 
GL_Normalize(byte * in,int width,int height)1303 void GL_Normalize(byte *in, int width, int height)
1304 {
1305     int		i, j;
1306     byte	*out;
1307     float	inv255	= 1.0f/255.0f;
1308     float	inv127	= 1.0f/127.0f;
1309     float	x,y,z,l;
1310 
1311     width <<=2;
1312     out = in;
1313     for (i=0 ; i<height ; i++)
1314     {
1315 	for (j=0 ; j<width ; j+=4, out+=4, in+=4)
1316 	{
1317 	    x = (inv127*in[0]-1.0);
1318 	    y = (inv127*in[1]-1.0);
1319             z = (inv127*in[2]-1.0);
1320 
1321             l = sqrt(x*x+y*y+z*z);
1322 	    if (l == 0.0) {
1323 		x = 0.0;
1324 		y = 0.0;
1325 		z = 1.0;
1326 	    } else {
1327 		//normalize it.
1328 		l=1/l;
1329 		x *=l;
1330 		y *=l;
1331 		z *=l;
1332 	    }
1333 	    out[0] = (unsigned char)128 + 127*x;
1334 	    out[1] = (unsigned char)128 + 127*y;
1335 	    out[2] = (unsigned char)128 + 127*z;
1336 	}
1337     }
1338 
1339 }
1340 
1341 /*
1342 ================
1343 GL_MipMap8Bit
1344 
1345 Mipping for 8 bit textures
1346 ================
1347 */
GL_MipMap8Bit(byte * in,int width,int height)1348 void GL_MipMap8Bit (byte *in, int width, int height)
1349 {
1350 	int		i, j;
1351 	unsigned short     r,g,b;
1352 	byte	*out, *at1, *at2, *at3, *at4;
1353 
1354 //	width <<=2;
1355 	height >>= 1;
1356 	out = in;
1357 	for (i=0 ; i<height ; i++, in+=width)
1358 	{
1359 		for (j=0 ; j<width ; j+=2, out+=1, in+=2)
1360 		{
1361 			at1 = (byte *) (d_8to24table + in[0]);
1362 			at2 = (byte *) (d_8to24table + in[1]);
1363 			at3 = (byte *) (d_8to24table + in[width+0]);
1364 			at4 = (byte *) (d_8to24table + in[width+1]);
1365 
1366  			r = (at1[0]+at2[0]+at3[0]+at4[0]); r>>=5;
1367  			g = (at1[1]+at2[1]+at3[1]+at4[1]); g>>=5;
1368  			b = (at1[2]+at2[2]+at3[2]+at4[2]); b>>=5;
1369 
1370 			out[0] = d_15to8table[(r<<0) + (g<<5) + (b<<10)];
1371 		}
1372 	}
1373 }
1374 
1375 /*
1376 ===============
1377 PENTA:
1378 Packs the byte values in gloss in the alpha channel of dest
1379 <AWE> : added "void" as return type.
1380 ===============
1381 */
GL_PackGloss(byte * gloss,unsigned * dest,int length)1382 void	GL_PackGloss(byte *gloss,unsigned *dest,int length)
1383 {
1384     int i;
1385 
1386     for (i=0; i<length; i++, gloss++, dest++)
1387 
1388     {
1389         *dest = *dest & LittleLong (0x00FFFFFF);	// <AWE> Added support for big endian.
1390         *dest = *dest | LittleLong (*gloss << 24);	// <AWE> Added support for big endian.
1391     }
1392 }
1393 
1394 /*
1395 ===============
1396 GL_Upload32
1397 ===============
1398 */
GL_Upload32(unsigned * data,int width,int height,qboolean mipmap,qboolean alpha)1399 void GL_Upload32 (unsigned *data, int width, int height,  qboolean mipmap, qboolean alpha)
1400 {
1401 	int			texturemode;
1402 	//XYZ
1403 static	unsigned	scaled[1024*1024];	// [512*256];
1404 	int			scaled_width, scaled_height;
1405 
1406         if ( willi_gray_colormaps.value )
1407         {
1408 	    Q_memset(data, 0x7f, width*height*4);
1409         }
1410 
1411 	for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
1412 		;
1413 	for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
1414 		;
1415 
1416 	scaled_width >>= (int)gl_picmip.value;
1417 	scaled_height >>= (int)gl_picmip.value;
1418 
1419 	if (scaled_width > gl_max_size.value)
1420 		scaled_width = gl_max_size.value;
1421 	if (scaled_height > gl_max_size.value)
1422 		scaled_height = gl_max_size.value;
1423 
1424 	if (scaled_width * scaled_height > sizeof(scaled)/4)
1425 		Sys_Error ("GL_LoadTexture: too big");
1426 
1427         if ( gl_texcomp && ((int)gl_compress_textures.value) & 1 )
1428         {
1429             texturemode = GL_COMPRESSED_RGBA_ARB;
1430         }
1431         else
1432         {
1433             texturemode = GL_RGBA;//PENTA: Always upload rgb it doesn't make any difference for nvidia cards (& others)
1434 	    //texturemode = alpha ? gl_alpha_format : gl_solid_format;
1435         }
1436 #if 0
1437 	if (mipmap)
1438 		gluBuild2DMipmaps (GL_TEXTURE_2D, texturemode, width, height, GL_RGBA, GL_UNSIGNED_BYTE, trans);
1439 	else if (scaled_width == width && scaled_height == height)
1440 		glTexImage2D (GL_TEXTURE_2D, 0, texturemode, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
1441 	else
1442 	{
1443 		gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, trans,
1444 			scaled_width, scaled_height, GL_UNSIGNED_BYTE, scaled);
1445 		glTexImage2D (GL_TEXTURE_2D, 0, texturemode, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
1446 	}
1447 #else
1448 texels += scaled_width * scaled_height;
1449 
1450 	if (scaled_width == width && scaled_height == height)
1451 	{
1452 		if (!mipmap)
1453 		{
1454 			glTexImage2D (GL_TEXTURE_2D, 0, texturemode, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
1455 			goto done;
1456 		}
1457 		memcpy (scaled, data, width*height*4);
1458 	}
1459 	else
1460 		GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
1461 
1462 	glTexImage2D (GL_TEXTURE_2D, 0, texturemode, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
1463 	if (mipmap)
1464 	{
1465 		int		miplevel;
1466 
1467 		miplevel = 0;
1468 		while (scaled_width > 1 || scaled_height > 1)
1469 		{
1470 			GL_MipMap ((byte *)scaled, scaled_width, scaled_height);
1471 			scaled_width >>= 1;
1472 			scaled_height >>= 1;
1473 			if (scaled_width < 1)
1474 				scaled_width = 1;
1475 			if (scaled_height < 1)
1476 				scaled_height = 1;
1477 			miplevel++;
1478 			glTexImage2D (GL_TEXTURE_2D, miplevel, texturemode, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
1479                 }
1480 	}
1481 done: ;
1482 #endif
1483 
1484 
1485 	if (mipmap)
1486 	{
1487 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
1488 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1489 	}
1490 	else
1491 	{
1492 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
1493 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1494 	}
1495 
1496 	if (gl_texturefilteranisotropic)
1497 		glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl_textureanisotropylevel);
1498 }
1499 
GL_Upload8_EXT(byte * data,int width,int height,qboolean mipmap,qboolean alpha)1500 void GL_Upload8_EXT (byte *data, int width, int height,  qboolean mipmap, qboolean alpha)
1501 {
1502 	int			i, s;
1503 	qboolean		noalpha;
1504 	int			samples;
1505         static unsigned char 	scaled[1024*512];	// [512*256];
1506 	int			scaled_width, scaled_height;
1507 
1508 	s = width*height;
1509 
1510         // if there are no transparent pixels, make it a 3 component
1511 	// texture even if it was specified as otherwise
1512 	if (alpha)
1513 	{
1514 		noalpha = true;
1515 		for (i=0 ; i<s ; i++)
1516 		{
1517 			if (data[i] == 255)
1518 				noalpha = false;
1519 		}
1520 
1521 		if (alpha && noalpha)
1522 			alpha = false;
1523 	}
1524 	for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
1525 		;
1526 	for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
1527 		;
1528 
1529 	scaled_width >>= (int)gl_picmip.value;
1530 	scaled_height >>= (int)gl_picmip.value;
1531 
1532 	if (scaled_width > gl_max_size.value)
1533 		scaled_width = gl_max_size.value;
1534 	if (scaled_height > gl_max_size.value)
1535 		scaled_height = gl_max_size.value;
1536 
1537 	if (scaled_width * scaled_height > sizeof(scaled))
1538 		Sys_Error ("GL_LoadTexture: too big");
1539 
1540 	samples = 1; // alpha ? gl_alpha_format : gl_solid_format;
1541 
1542 	texels += scaled_width * scaled_height;
1543 
1544 	if (scaled_width == width && scaled_height == height)
1545 	{
1546 		if (!mipmap)
1547 		{
1548 			glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX , GL_UNSIGNED_BYTE, data);
1549 			goto done;
1550 		}
1551 		memcpy (scaled, data, width*height);
1552 	}
1553 	else
1554 		GL_Resample8BitTexture (data, width, height, scaled, scaled_width, scaled_height);
1555 
1556 	glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
1557 	if (mipmap)
1558 	{
1559 		int		miplevel;
1560 
1561 		miplevel = 0;
1562 		while (scaled_width > 1 || scaled_height > 1)
1563 		{
1564 			GL_MipMap8Bit ((byte *)scaled, scaled_width, scaled_height);
1565 			scaled_width >>= 1;
1566 			scaled_height >>= 1;
1567 			if (scaled_width < 1)
1568 				scaled_width = 1;
1569 			if (scaled_height < 1)
1570 				scaled_height = 1;
1571 			miplevel++;
1572 			glTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
1573 		}
1574 	}
1575 done: ;
1576 
1577 
1578 	if (mipmap)
1579 	{
1580 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
1581 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1582 	}
1583 	else
1584 	{
1585 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
1586 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1587 	}
1588 
1589 	if (gl_texturefilteranisotropic)
1590 		glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl_textureanisotropylevel);
1591 
1592 }
1593 
1594 //PENTA
1595 
genNormalMap(byte * pixels,int w,int h,float scale)1596 unsigned int * genNormalMap(byte *pixels, int w, int h, float scale)
1597 {
1598   int i, j, wr, hr;
1599   unsigned char r, g, b;
1600   static unsigned nmap[512*512];
1601   float sqlen, reciplen, nx, ny, nz;
1602 
1603   const float oneOver255 = 1.0f/255.0f;
1604 
1605   float c, cx, cy, dcx, dcy;
1606 
1607   wr = w;
1608   hr = h;
1609 
1610   for (i=0; i<h; i++) {
1611     for (j=0; j<w; j++) {
1612       /* Expand [0,255] texel values to the [0,1] range. */
1613       c = pixels[i*wr + j] * oneOver255;
1614       /* Expand the texel to its right. */
1615       cx = pixels[i*wr + (j+1)%wr] * oneOver255;
1616       /* Expand the texel one up. */
1617       cy = pixels[((i+1)%hr)*wr + j] * oneOver255;
1618       dcx = scale * (c - cx);
1619       dcy = scale * (c - cy);
1620 
1621       /* Normalize the vector. */
1622       sqlen = dcx*dcx + dcy*dcy + 1;
1623       reciplen = 1.0f/(float)sqrt(sqlen);
1624       nx = dcx*reciplen;
1625       ny = -dcy*reciplen;
1626       nz = reciplen;
1627 
1628       /* Repack the normalized vector into an RGB unsigned byte
1629          vector in the normal map image. */
1630       r = (byte) (128 + 127*nx);
1631       g = (byte) (128 + 127*ny);
1632       b = (byte) (128 + 127*nz);
1633 
1634       /* The highest resolution mipmap level always has a
1635          unit length magnitude. */
1636       nmap[i*w+j] = LittleLong ((255 << 24)|(b << 16)|(g << 8)|(r));	// <AWE> Added support for big endian.
1637     }
1638   }
1639 
1640   return &nmap[0];
1641 }
1642 
1643 //PENTA
GL_UploadBump(byte * data,int width,int height,qboolean mipmap,byte * gloss)1644 void GL_UploadBump(byte *data, int width, int height, qboolean mipmap, byte* gloss)
1645 {
1646     static unsigned char	scaled[1024*1024];	// [512*256];
1647     static unsigned char	scaledgloss[1024*1024];	// [512*256];
1648     int			scaled_width, scaled_height;
1649     byte			*nmap;
1650     int			texturemode;
1651 
1652     if ( gl_texcomp && ((int)gl_compress_textures.value) & 2 )
1653     {
1654 	texturemode = GL_COMPRESSED_RGBA_ARB;
1655     }
1656     else
1657     {
1658 	texturemode = GL_RGBA;
1659     }
1660 
1661     //Resize to power of 2 and maximum texture size
1662     for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
1663 	;
1664     for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
1665 	;
1666 
1667     scaled_width >>= (int)gl_picmip.value;
1668     scaled_height >>= (int)gl_picmip.value;
1669 
1670     if (scaled_width > gl_max_size.value)
1671 	scaled_width = gl_max_size.value;
1672     if (scaled_height > gl_max_size.value)
1673 	scaled_height = gl_max_size.value;
1674 
1675     if (scaled_width * scaled_height > sizeof(scaled))
1676 	Sys_Error ("GL_LoadTexture: too big");
1677 
1678     //To resize or not to resize
1679     if (scaled_width == width && scaled_height == height)
1680     {
1681 	memcpy (scaled, data, width*height);
1682 	memcpy (scaledgloss, gloss, width*height);
1683 	scaled_width = width;
1684 	scaled_height = height;
1685     }
1686     else
1687     {
1688 	//Just picks pixels so grayscale is equivalent with 8 bit.
1689 	GL_Resample8BitTexture (data, width, height, scaled, scaled_width, scaled_height);
1690 	GL_Resample8BitTexture (gloss, width, height, scaledgloss, scaled_width, scaled_height);
1691     }
1692 
1693     if (is_overriden)
1694 	nmap = (byte *)genNormalMap(scaled,scaled_width,scaled_height,10.0f);
1695     else
1696 	nmap = (byte *)genNormalMap(scaled,scaled_width,scaled_height,4.0f);
1697 
1698     GL_PackGloss(scaledgloss, (unsigned int*)nmap, scaled_width*scaled_height);
1699 
1700     glTexImage2D (GL_TEXTURE_2D, 0, texturemode, scaled_width, scaled_height, 0,
1701 		  GL_RGBA, GL_UNSIGNED_BYTE, nmap);
1702 
1703     //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1704     //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1705     if (mipmap)
1706     {
1707 	int		miplevel;
1708 
1709 	miplevel = 0;
1710 	while (scaled_width > 1 || scaled_height > 1)
1711 	{
1712 	    GL_MipMapNormal(nmap,scaled_width,scaled_height);
1713 	    //GL_MipMapGray((byte *)scaled, scaled_width, scaled_height);
1714 	    scaled_width >>= 1;
1715 	    scaled_height >>= 1;
1716 	    if (scaled_width < 1)
1717 		scaled_width = 1;
1718 	    if (scaled_height < 1)
1719 		scaled_height = 1;
1720 	    miplevel++;
1721 
1722 	    glTexImage2D (GL_TEXTURE_2D, miplevel, texturemode, scaled_width, scaled_height, 0, GL_RGBA,
1723 			  GL_UNSIGNED_BYTE, nmap);
1724 	}
1725     }
1726 
1727     if (mipmap)
1728     {
1729 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
1730 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1731     }
1732     else
1733     {
1734 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
1735 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1736     }
1737 
1738 
1739     if (gl_texturefilteranisotropic)
1740 	glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl_textureanisotropylevel);
1741 
1742 }
1743 
1744 
1745 //PENTA
GL_UploadNormal(unsigned int * data,int width,int height,qboolean mipmap)1746 void GL_UploadNormal(unsigned int *data, int width, int height, qboolean mipmap)
1747 {
1748     static unsigned int	scaled[1024*1024];	// [512*256];
1749     int			scaled_width, scaled_height;
1750     int			texturemode;
1751 
1752     if ( gl_texcomp && ((int)gl_compress_textures.value) & 2 )
1753     {
1754         texturemode = GL_COMPRESSED_RGBA_ARB;
1755     }
1756     else
1757     {
1758         texturemode = GL_RGBA;
1759     }
1760 
1761     //Resize to power of 2 and maximum texture size
1762     for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
1763 	;
1764     for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
1765 	;
1766 
1767     scaled_width >>= (int)gl_picmip.value;
1768     scaled_height >>= (int)gl_picmip.value;
1769 
1770     if (scaled_width > gl_max_size.value)
1771 		scaled_width = gl_max_size.value;
1772     if (scaled_height > gl_max_size.value)
1773 		scaled_height = gl_max_size.value;
1774 
1775     if (scaled_width * scaled_height > sizeof(scaled))
1776 		Sys_Error ("GL_LoadTexture: too big");
1777 
1778     //To resize or not to resize
1779     if (scaled_width == width && scaled_height == height)
1780     {
1781 		memcpy (scaled, data, width*height*4);
1782 		scaled_width = width;
1783 		scaled_height = height;
1784     }
1785     else {
1786 		GL_ResampleTexture ((unsigned*)data, width, height, scaled, scaled_width, scaled_height);
1787     }
1788 
1789     GL_Normalize((byte*)scaled, scaled_width, scaled_height);
1790     glTexImage2D (GL_TEXTURE_2D, 0, texturemode, scaled_width, scaled_height, 0,
1791 		  GL_RGBA, GL_UNSIGNED_BYTE, scaled);
1792 
1793     //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1794     //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1795     if (mipmap)
1796     {
1797 		int		miplevel;
1798 
1799 		miplevel = 0;
1800 		while (scaled_width > 1 || scaled_height > 1)
1801 		{
1802 			GL_MipMapNormal((byte*)scaled,scaled_width,scaled_height);
1803 			scaled_width >>= 1;
1804 			scaled_height >>= 1;
1805 			if (scaled_width < 1)
1806 			scaled_width = 1;
1807 			if (scaled_height < 1)
1808 			scaled_height = 1;
1809 			miplevel++;
1810 
1811 			glTexImage2D (GL_TEXTURE_2D, miplevel, texturemode, scaled_width, scaled_height, 0, GL_RGBA,
1812 				  GL_UNSIGNED_BYTE, scaled);
1813 		}
1814     }
1815 
1816     if (mipmap)
1817     {
1818 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
1819 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1820     }
1821     else
1822     {
1823 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
1824 		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
1825     }
1826 
1827     if (gl_texturefilteranisotropic)
1828 		glTexParameterfv (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, &gl_textureanisotropylevel);
1829 
1830 }
1831 
1832 /*
1833 ===============
1834 PENTA:
1835 get the name of an overriden file
1836 <AWE> : added "void" as return type.
1837 ===============
1838 */
GL_GetOverrideName(char * identifier,char * tail,char * dest)1839 void	GL_GetOverrideName(char *identifier,char *tail, char *dest) {
1840 	int i;
1841 
1842 	sprintf(dest,"override/%s%s.tga", identifier, tail);
1843 	for (i=0; i<strlen(dest); i++) {
1844 		if (dest[i] == '*')
1845 			dest[i] = '%';
1846 	}
1847 
1848 }
1849 
1850 
1851 
1852 /*
1853 ===============
1854 GL_Upload8
1855 ===============
1856 */
1857 	//XYZ
1858 static	unsigned	trans[1024*1024];		// FIXME, temporary
1859 
1860 #define RED_MASK 0x00FF0000
1861 #define GREEN_MASK 0x0000FF00
1862 #define BLUE_MASK 0x000000FF
1863 
GL_Upload8(byte * data,char * identifier,int width,int height,qboolean mipmap,qboolean alpha,qboolean bump)1864 void GL_Upload8 (byte *data,char *identifier, int width, int height,  qboolean mipmap, qboolean alpha, qboolean bump)
1865 {
1866 	//XYZ
1867 static	unsigned char	bumppix[1024*1024];	// PENTA: bumped texture (it seems the previous one never got fixed anyway)
1868 static	unsigned char	glosspix[1024*1024];	// PENTA: bumped texture (it seems the previous one never got fixed anyway)
1869 
1870 	int			i, s;
1871 	qboolean	noalpha;
1872 	int			p;
1873 	FILE		*f;
1874 	char filename[MAX_OSPATH];
1875 	byte		r, g, b;
1876 	s = width*height;
1877 
1878 	//try to load an overrided texture
1879 
1880 	GL_GetOverrideName(identifier,"",filename);
1881 	if ( LoadTextureInPlace(filename, 4, (unsigned char*)&trans[0], &width, &height) )
1882 	{
1883 		Con_DPrintf("Overriding colormap for %s\n",identifier);
1884 
1885 		is_overriden = true;
1886 		//force it to upload a 32 bit texture
1887 		alpha = true;
1888 
1889 		for (i=0; i<width*height; i++) {
1890 			r = (trans[i] & RED_MASK) >> 16;
1891 			g = (trans[i] & GREEN_MASK) >> 8;
1892 			b = (trans[i] & BLUE_MASK);
1893 			bumppix[i] = (r+g+b)/3;
1894 		}
1895 	}
1896 	// if there are no transparent pixels, make it a 3 component
1897 	// texture even if it was specified as otherwise
1898 	else if (alpha)
1899 	{
1900 		is_overriden = false;
1901 
1902 		noalpha = true;
1903 		for (i=0 ; i<s ; i++)
1904 		{
1905 			p = data[i];
1906 			if (p == 255)
1907 				noalpha = false;
1908 			trans[i] = d_8to24table[p];
1909 			//PENTA: Grayscale for autobumps
1910 			bumppix[i] = d_8to8graytable[p];
1911 		}
1912 
1913 		if (alpha && noalpha)
1914 			alpha = false;
1915 	}
1916 	else
1917 	{
1918 		is_overriden = false;
1919 
1920 		if (s&3)
1921 			Sys_Error ("GL_Upload8: s&3");
1922 		for (i=0 ; i<s ; i+=4)
1923 		{
1924 			trans[i] = d_8to24table[data[i]];
1925 			trans[i+1] = d_8to24table[data[i+1]];
1926 			trans[i+2] = d_8to24table[data[i+2]];
1927 			trans[i+3] = d_8to24table[data[i+3]];
1928 			//PENTA: Grayscale for autobumps
1929 			bumppix[i] = d_8to8graytable[data[i]];
1930 			bumppix[i+1] = d_8to8graytable[data[i+1]];
1931 			bumppix[i+2] = d_8to8graytable[data[i+2]];
1932 			bumppix[i+3] = d_8to8graytable[data[i+3]];
1933 		}
1934 	}
1935 
1936 	if (!strcmp("scrap",identifier)) {
1937 		GL_Upload32 (trans, width, height, mipmap, alpha);
1938 		return;
1939 	}
1940 
1941 	//upload color map
1942 	GL_Bind(texture_extension_number);
1943 
1944 	GL_Upload32 (trans, width, height, mipmap, alpha);
1945 
1946 	texture_extension_number++;
1947 
1948 	//Disable Bumpmapping parameter and now bumpmap cvar slightly
1949 	//works. this only prevents textures from loading, but if it
1950 	//has already loaded bumpmaps will not turn off) - Eradicator
1951 	if (!COM_CheckParm("-nobumpmaps") && ( sh_bumpmaps.value ) && bump )
1952 	{
1953 	    //upload bump map (if any)
1954 	    char filename[MAX_OSPATH];
1955 
1956 	    GL_Bind(texture_extension_number);
1957 	    // first check for normal map
1958 	    GL_GetOverrideName(identifier,"_norm",filename);
1959 	    if ( LoadTextureInPlace(filename, 4, (unsigned char*)&trans[0], &width, &height) )
1960 	    {
1961 		char filename[MAX_OSPATH];
1962 		int gloss_width, gloss_height;
1963 		Con_DPrintf("Overriding normal map for %s\n",identifier);
1964 
1965 		GL_GetOverrideName(identifier,"_gloss",filename);
1966 		if ( LoadTextureInPlace(filename, 1, &glosspix[0], &gloss_width, &gloss_height) )
1967 		{
1968 		    Con_DPrintf("Using gloss map for %s\n",identifier);
1969 		}
1970 		else
1971 		{
1972 		    //set some gloss by default
1973 		    gloss_width = width;
1974 		    gloss_height = height;
1975 		    Q_memset(&glosspix[0], 255*gl_gloss.value, width*height);
1976 		}
1977 
1978 		if ((gloss_width == width) && (gloss_height == height))
1979 		{
1980 		    GL_PackGloss(glosspix, trans, width*height);
1981 		}
1982 		else
1983 		{
1984 		    Con_SafePrintf("Error loading gloss map %s: Gloss map bust be the same size as normal map\n", identifier);
1985 		}
1986 		GL_UploadNormal (trans, width, height, mipmap);
1987 	    }
1988 	    else
1989 	    {
1990 		//See if we can override the bump map
1991 		GL_GetOverrideName(identifier,"_bump",filename);
1992 		//See if we can override the bump map
1993 		if ( LoadTextureInPlace(filename, 1, &bumppix[0], &width, &height) )
1994 		{
1995 		    char filename[MAX_OSPATH];
1996 		    int gloss_width, gloss_height;
1997 		    Con_DPrintf("Overriding bumpmap for %s\n",identifier);
1998 		    GL_GetOverrideName(identifier,"_gloss",filename);
1999 		    if ( LoadTextureInPlace(filename, 1, &glosspix[0], &gloss_width, &gloss_height) )
2000 		    {
2001 			Con_DPrintf("Using gloss map for %s\n",identifier);
2002 		    }
2003 		    else
2004 		    {
2005 			//set some gloss by default
2006 			gloss_width = width;
2007 			gloss_height = height;
2008 			Q_memset(&glosspix[0], 255*gl_gloss.value, width*height);
2009 		    }
2010 
2011 		    if ((gloss_width == width) && (gloss_height == height))
2012 		    {
2013 		    }
2014 		    else
2015 		    {
2016 			Con_SafePrintf("Error loading gloss map %s: Gloss map bust be the same size as bump map\n", identifier);
2017                         Q_memset(&glosspix[0], 255*gl_gloss.value, width*height);
2018 		    }
2019 		}
2020                 else
2021                 {
2022                     Q_memset(&glosspix[0], 255*gl_gloss.value, width*height);
2023 
2024                 }
2025 		GL_UploadBump (bumppix, width, height, mipmap, &glosspix[0]);
2026 	    }
2027 	}
2028 	texture_extension_number++;
2029 }
2030 
2031 /*
2032 ================
2033 GL_LoadTexture
2034 ================
2035 */
GL_LoadTexture(char * identifier,int width,int height,byte * data,qboolean mipmap,qboolean alpha,qboolean bump)2036 int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha, qboolean bump)
2037 {
2038 	int			i;
2039 	gltexture_t	*glt;
2040 
2041 	// see if the texture is allready present
2042 	if (identifier[0])
2043 	{
2044 		for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
2045 		{
2046 			if (!strcmp (identifier, glt->identifier))
2047 			{
2048 				if (width != glt->width || height != glt->height)
2049 					Con_Printf ("%s: warning: cache mismatch\n",identifier);
2050 				//Con_Printf("reuse: %s\n",identifier);
2051 				return gltextures[i].texnum;
2052 			}
2053 		}
2054 	}
2055 	//else {
2056 		glt = &gltextures[numgltextures];
2057 		numgltextures++;
2058 	//}
2059 
2060 	//Con_Printf("Load texture: %s %i %i\n",identifier,width,height);
2061 
2062 	strncpy (glt->identifier, identifier, sizeof(glt->identifier));
2063 	glt->texnum = texture_extension_number;
2064 	glt->width = width;
2065 	glt->height = height;
2066 	glt->mipmap = mipmap;
2067 
2068 	GL_Bind(texture_extension_number );
2069 
2070 	GL_Upload8 (data, identifier, width, height, mipmap, alpha, bump);
2071 
2072 	//texture_extension_number++;
2073 
2074 	return texture_extension_number-2;
2075 }
2076 
2077 
GL_LoadLuma(char * identifier,qboolean mipmap)2078 int GL_LoadLuma(char *identifier, qboolean mipmap)
2079 {
2080 	qboolean	alpha;
2081 	FILE		*f;
2082 	char filename[MAX_OSPATH];
2083 	int			width, height;
2084 
2085         if ( willi_gray_colormaps.value )
2086             return 0;
2087 
2088 	//try to load an overrided texture
2089 	GL_GetOverrideName(identifier,"_luma",filename);
2090 	if ( LoadTextureInPlace(filename, 4, (unsigned char*)&trans[0], &width, &height) )
2091 	{
2092 
2093 		Con_DPrintf("Using luma map for %s\n",identifier);
2094 
2095 		is_overriden = true;
2096 		//force it to upload a 32 bit texture
2097 		alpha = true;
2098 
2099 		GL_Bind(texture_extension_number);
2100 		GL_Upload32 (trans, width, height, mipmap, alpha);
2101 		texture_extension_number++;
2102 		return texture_extension_number-1;
2103 	} else {
2104 		return 0;
2105 	}
2106 }
2107 
2108 
2109 char *face_names[] =
2110 {
2111 	"posx",
2112 	"negx",
2113 	"posy",
2114 	"negy",
2115 	"posz",
2116 	"negz",
2117 };
2118 
2119 /*
2120 ================
2121 GL_LoadCubeMap
2122 ================
2123 */
GL_LoadCubeMap(int identifier)2124 int GL_LoadCubeMap (int identifier)
2125 {
2126 	int			i, width, height;
2127 	gltexture_t	*glt;
2128 	FILE		*f;
2129 	char filename[MAX_OSPATH];
2130         int			texturemode;
2131 
2132         if ( gl_texcomp && ((int)gl_compress_textures.value) & 4 )
2133         {
2134             texturemode = GL_COMPRESSED_RGBA_ARB;
2135         }
2136         else
2137         {
2138             texturemode = GL_RGBA;
2139         }
2140 
2141 	width = 0;
2142 	height = 0;
2143 	// see if the texture is allready present
2144 	//Con_Printf("Texnum %i\n",numgltextures);
2145 	sprintf(filename,"cubemaps/%i", identifier);
2146 
2147 	if (filename[0])
2148 	{
2149 		for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
2150 		{
2151 			if (!strcmp (filename, glt->identifier))
2152 			{
2153 				//Con_Printf("Found cubemap: %s %i\n",identifier,i);
2154 				return gltextures[i].texnum;
2155 			}
2156 		}
2157 	}
2158 	//else {
2159 		glt = &gltextures[numgltextures];
2160 		numgltextures++;
2161 	strncpy (glt->identifier, filename,sizeof(glt->identifier));
2162 
2163 		//Con_Printf("Texnum2 %i\n",numgltextures);
2164 	//}
2165 
2166 //	Con_Printf("Loading cubemap from: %i %i\n",identifier,numgltextures);
2167 	glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2168 	glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texture_extension_number);
2169 	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
2170 	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
2171 	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2172 	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2173 
2174 	for (i = 0; i < 6; i++)
2175 	{
2176 		sprintf(filename,"cubemaps/%i%s.tga", identifier, face_names[i]);
2177 		LoadTextureInPlace(filename, 4, (unsigned char*)&trans[0], &width, &height);
2178 		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB+i, 0, texturemode, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &trans[0]);
2179 	}
2180 
2181 	//glEnable(GL_TEXTURE_2D);
2182 	glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2183 
2184 	glt->texnum = texture_extension_number;
2185 	glt->width = width;
2186 	glt->height = height;
2187 	glt->mipmap = false;
2188 
2189 	texture_extension_number++;
2190 
2191 	return texture_extension_number-1;
2192 }
2193 
2194 /*
2195 ================
2196 GL_LoadPicTexture
2197 ================
2198 */
GL_LoadPicTexture(qpic_t * pic)2199 int GL_LoadPicTexture (qpic_t *pic)
2200 {
2201 	return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true, false);
2202 }
2203 
2204 /****************************************/
2205 
2206 static GLenum oldtarget = GL_TEXTURE0_ARB;
2207 
GL_SelectTexture(GLenum target)2208 void GL_SelectTexture (GLenum target)
2209 {
2210 	if (!gl_mtexable)
2211 		return;
2212 	qglActiveTextureARB(target);
2213 	if (target == oldtarget)
2214 		return;
2215 	cnttextures[oldtarget-GL_TEXTURE0_ARB] = currenttexture;
2216 	currenttexture = cnttextures[target-GL_TEXTURE0_ARB];
2217 	oldtarget = target;
2218 }
2219 
2220 #define ATTEN_VOLUME_SIZE 64
2221 
sqr(float p)2222 float sqr(float p) {
2223 	return p*p;
2224 }
2225 
2226 /*
2227 ===============
2228 PENTA:
2229 
2230 Load texture for 2d atten
2231 ===============
2232 */
GL_Load2DAttenTexture(void)2233 int GL_Load2DAttenTexture(void)
2234 {
2235 
2236 	float centerx, centery, radiussq;
2237 	int s,t, err;
2238 	byte *data;
2239 
2240 	data = malloc(ATTEN_VOLUME_SIZE*ATTEN_VOLUME_SIZE);
2241         if (!data) return 0;							// <AWE> check memory here!
2242 
2243 	centerx = ATTEN_VOLUME_SIZE/2.0;
2244 	centery = ATTEN_VOLUME_SIZE/2.0;
2245 	radiussq = ATTEN_VOLUME_SIZE/2.0;
2246 	radiussq = radiussq*radiussq;
2247 
2248 	for (s = 0; s < ATTEN_VOLUME_SIZE; s++) {
2249 		for (t = 0; t < ATTEN_VOLUME_SIZE; t++) {
2250 			float DistSq = sqr(s-centerx)+sqr(t-centery);
2251 			if (DistSq < radiussq) {
2252 				byte value;
2253 				float FallOff = (radiussq - DistSq) / radiussq;
2254 				FallOff *= FallOff;
2255 				value = FallOff*255.0;
2256 				data[t * ATTEN_VOLUME_SIZE + s] = value;
2257 			} else {
2258 				data[t * ATTEN_VOLUME_SIZE + s] = 0;
2259 			}
2260 		}
2261 	}
2262 
2263 	GL_Bind(texture_extension_number);
2264 
2265 	glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, ATTEN_VOLUME_SIZE, ATTEN_VOLUME_SIZE,
2266 					0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
2267 
2268 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
2269 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
2270 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2271 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2272 
2273 	free(data);
2274 	texture_extension_number++;
2275 
2276 	err  = glGetError();
2277 
2278 	if (err != GL_NO_ERROR) {
2279 		Con_Printf("%s",gluErrorString(err));
2280 	}
2281 
2282 	return texture_extension_number-1;
2283 }
2284 
2285 /*
2286 ===============
2287 PENTA:
2288 
2289 Load texture for 3d atten (on gf3)
2290 ===============
2291 */
GL_Load3DAttenTexture(void)2292 int GL_Load3DAttenTexture(void)
2293 {
2294 
2295 	float centerx, centery, centerz, radiussq;
2296 	int s,t,r, err;
2297 	byte *data;
2298 
2299 	if (gl_cardtype == GENERIC || gl_cardtype == GEFORCE) return 0;//PA:
2300 
2301 	data = malloc(ATTEN_VOLUME_SIZE*ATTEN_VOLUME_SIZE*ATTEN_VOLUME_SIZE*4);
2302         if (!data) return 0;							// <AWE> check memory here!
2303 
2304 	centerx = ATTEN_VOLUME_SIZE/2.0;
2305 	centery = ATTEN_VOLUME_SIZE/2.0;
2306 	centerz = ATTEN_VOLUME_SIZE/2.0;
2307 	radiussq = ATTEN_VOLUME_SIZE/2.0;
2308 	radiussq = radiussq*radiussq;
2309 
2310 	for (s = 0; s < ATTEN_VOLUME_SIZE; s++) {
2311 		for (t = 0; t < ATTEN_VOLUME_SIZE; t++) {
2312 			for (r = 0; r < ATTEN_VOLUME_SIZE; r++) {
2313 				float DistSq = sqr(s-centerx)+sqr(t-centery)+sqr(r-centerz);
2314 				if (DistSq < radiussq) {
2315 					byte value;
2316 					float FallOff = (radiussq - DistSq) / radiussq;
2317 					FallOff *= FallOff;
2318 					value = FallOff*255.0;
2319 					data[r * ATTEN_VOLUME_SIZE * ATTEN_VOLUME_SIZE *4+ t * ATTEN_VOLUME_SIZE *4+ s *4+ 0] = value;
2320 					data[r * ATTEN_VOLUME_SIZE * ATTEN_VOLUME_SIZE *4+ t * ATTEN_VOLUME_SIZE *4+ s *4+ 1] = value;
2321 					data[r * ATTEN_VOLUME_SIZE * ATTEN_VOLUME_SIZE *4+ t * ATTEN_VOLUME_SIZE *4+ s *4+ 2] = value;
2322 					data[r * ATTEN_VOLUME_SIZE * ATTEN_VOLUME_SIZE *4+ t * ATTEN_VOLUME_SIZE *4+ s *4+ 3] = value;
2323 				} else {
2324 					data[r * ATTEN_VOLUME_SIZE * ATTEN_VOLUME_SIZE *4+ t * ATTEN_VOLUME_SIZE *4+ s *4+ 0] = 0;
2325 					data[r * ATTEN_VOLUME_SIZE * ATTEN_VOLUME_SIZE *4+ t * ATTEN_VOLUME_SIZE *4+ s *4+ 1] = 0;
2326 					data[r * ATTEN_VOLUME_SIZE * ATTEN_VOLUME_SIZE *4+ t * ATTEN_VOLUME_SIZE *4+ s *4+ 2] = 0;
2327 					data[r * ATTEN_VOLUME_SIZE * ATTEN_VOLUME_SIZE *4+ t * ATTEN_VOLUME_SIZE *4+ s *4+ 3] = 0;
2328 				}
2329 
2330 			}
2331 		}
2332 	}
2333 
2334 	glBindTexture(GL_TEXTURE_3D, texture_extension_number);
2335 
2336 	qglTexImage3DEXT(GL_TEXTURE_3D, 0, 4,
2337 					ATTEN_VOLUME_SIZE, ATTEN_VOLUME_SIZE, ATTEN_VOLUME_SIZE,
2338 					0, GL_RGBA, GL_UNSIGNED_BYTE, data);
2339 
2340 	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
2341 	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
2342 	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
2343 	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2344 	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2345 
2346 	free(data);
2347 	texture_extension_number++;
2348 
2349 	err  = glGetError();
2350 
2351 	if (err != GL_NO_ERROR) {
2352 		Con_Printf("%s",gluErrorString(err));
2353 	}
2354 
2355 	return texture_extension_number-1;
2356 }
2357 
2358 /*
2359 Code from:
2360 
2361 bumpdemo.c - glamour demo of "normal perturbation" mapping
2362 by Nvidia
2363 
2364 */
2365 
getCubeVector(int i,int cubesize,int x,int y,float * vector)2366 void getCubeVector(int i, int cubesize, int x, int y, float *vector)
2367 {
2368   float s, t, sc, tc, mag;
2369 
2370   s = ((float)x + 0.5f) / (float)cubesize;
2371   t = ((float)y + 0.5f) / (float)cubesize;
2372   sc = s*2.0f - 1.0f;
2373   tc = t*2.0f - 1.0f;
2374 
2375   switch (i) {
2376   case 0:
2377     vector[0] = 1.0f;
2378     vector[1] = -tc;
2379     vector[2] = -sc;
2380     break;
2381   case 1:
2382     vector[0] = -1.0;
2383     vector[1] = -tc;
2384     vector[2] = sc;
2385     break;
2386   case 2:
2387     vector[0] = sc;
2388     vector[1] = 1.0;
2389     vector[2] = tc;
2390     break;
2391   case 3:
2392     vector[0] = sc;
2393     vector[1] = -1.0;
2394     vector[2] = -tc;
2395     break;
2396   case 4:
2397     vector[0] = sc;
2398     vector[1] = -tc;
2399     vector[2] = 1.0;
2400     break;
2401   case 5:
2402     vector[0] = -sc;
2403     vector[1] = -tc;
2404     vector[2] = -1.0;
2405     break;
2406   }
2407 
2408   mag = 1.0f/sqrt(vector[0]*vector[0] + vector[1]*vector[1] + vector[2]*vector[2]);
2409   vector[0] *= mag;
2410   vector[1] *= mag;
2411   vector[2] *= mag;
2412 }
2413 
2414 #define NC_SIZE 128//Size of the cube faces
2415 
GL_LoadNormalizationCubemap()2416 int GL_LoadNormalizationCubemap()
2417 {
2418 	vec3_t vec;
2419 	int i, x, y;
2420 	char pixels [NC_SIZE*NC_SIZE*3];
2421 
2422 	glEnable(GL_TEXTURE_CUBE_MAP_ARB);
2423 	glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, texture_extension_number);
2424 	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
2425 	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
2426 	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2427 	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2428 
2429 	for (i = 0; i < 6; i++) {
2430 		for (y = 0; y < NC_SIZE; y++) {
2431 			for (x = 0; x < NC_SIZE; x++)
2432 			{
2433 				getCubeVector(i, NC_SIZE, x, y, vec);
2434 				pixels[3*(y*NC_SIZE+x) + 0] = (unsigned char)(128 + 127*vec[0]);
2435 				pixels[3*(y*NC_SIZE+x) + 1] = (unsigned char)(128 + 127*vec[1]);
2436 				pixels[3*(y*NC_SIZE+x) + 2] = (unsigned char)(128 + 127*vec[2]);
2437 			}
2438 		}
2439 		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB+i, 0, GL_RGB8, NC_SIZE, NC_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixels);
2440 	}
2441 
2442 	glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2443 	texture_extension_number++;
2444 	return texture_extension_number-1;
2445 }
2446