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