home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / gl_draw.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-07  |  30.0 KB  |  1,339 lines

  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.  
  26. #define GL_COLOR_INDEX8_EXT     0x80E5
  27.  
  28. extern unsigned char d_15to8table[65536];
  29.  
  30. cvar_t    gl_nobind = {"gl_nobind", "0"};
  31. //cvar_t    gl_max_size = {"gl_max_size", "1024"};
  32. cvar_t    gl_max_size = {"gl_max_size", "256"};
  33. cvar_t    gl_picmip = {"gl_picmip", "0"};
  34.  
  35. byte    *draw_chars;        // 8*8 graphic characters
  36. qpic_t    *draw_disc;
  37. qpic_t    *draw_backtile;
  38.  
  39. int     translate_texture;
  40. int     char_texture;
  41.  
  42. typedef struct
  43. {
  44.   int   texnum;
  45.   float sl, tl, sh, th;
  46. } glpic_t;
  47.  
  48. byte    conback_buffer[sizeof(qpic_t) + sizeof(glpic_t)];
  49. qpic_t    *conback = (qpic_t *)&conback_buffer;
  50.  
  51. int   gl_lightmap_format = 4;
  52. int   gl_solid_format = 3;
  53. int   gl_alpha_format = 4;
  54.  
  55. //int   gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
  56. int   gl_filter_min = GL_LINEAR;
  57. int   gl_filter_max = GL_LINEAR;
  58.  
  59.  
  60. int   texels;
  61.  
  62. typedef struct
  63. {
  64.   int   texnum;
  65.   char  identifier[64];
  66.   int   width, height;
  67.   qboolean  mipmap;
  68. } gltexture_t;
  69.  
  70. #define MAX_GLTEXTURES  1024
  71. gltexture_t gltextures[MAX_GLTEXTURES];
  72. int     numgltextures;
  73.  
  74.  
  75. void GL_Bind (int texnum)
  76. {
  77.   if (gl_nobind.value)
  78.     texnum = char_texture;
  79.   if (currenttexture == texnum)
  80.     return;
  81.   currenttexture = texnum;
  82. #ifdef _WIN32
  83.   bindTexFunc (GL_TEXTURE_2D, texnum);
  84. #else
  85.   glBindTexture(GL_TEXTURE_2D, texnum);
  86. #endif
  87. }
  88.  
  89.  
  90. /*
  91. =============================================================================
  92.  
  93.   scrap allocation
  94.  
  95.   Allocate all the little status bar obejcts into a single texture
  96.   to crutch up stupid hardware / drivers
  97.  
  98. =============================================================================
  99. */
  100.  
  101. #define MAX_SCRAPS    2
  102. #define BLOCK_WIDTH   256
  103. #define BLOCK_HEIGHT  256
  104.  
  105. int     scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH];
  106. byte    scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT*4];
  107. qboolean  scrap_dirty;
  108. int     scrap_texnum;
  109.  
  110. // returns a texture number and the position inside it
  111. int Scrap_AllocBlock (int w, int h, int *x, int *y)
  112. {
  113.   int   i, j;
  114.   int   best, best2;
  115.   int   bestx;
  116.   int   texnum;
  117.  
  118.   for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++)
  119.   {
  120.     best = BLOCK_HEIGHT;
  121.  
  122.     for (i=0 ; i<BLOCK_WIDTH-w ; i++)
  123.     {
  124.       best2 = 0;
  125.  
  126.       for (j=0 ; j<w ; j++)
  127.       {
  128.         if (scrap_allocated[texnum][i+j] >= best)
  129.           break;
  130.         if (scrap_allocated[texnum][i+j] > best2)
  131.           best2 = scrap_allocated[texnum][i+j];
  132.       }
  133.       if (j == w)
  134.       { // this is a valid spot
  135.         *x = i;
  136.         *y = best = best2;
  137.       }
  138.     }
  139.  
  140.     if (best + h > BLOCK_HEIGHT)
  141.       continue;
  142.  
  143.     for (i=0 ; i<w ; i++)
  144.       scrap_allocated[texnum][*x + i] = best + h;
  145.  
  146.     return texnum;
  147.   }
  148.  
  149.   Sys_Error ("Scrap_AllocBlock: full");
  150. }
  151.  
  152. int scrap_uploads;
  153.  
  154. void Scrap_Upload (void)
  155. {
  156.   int   texnum;
  157.  
  158.   scrap_uploads++;
  159.  
  160.   for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++) {
  161.     GL_Bind(scrap_texnum + texnum);
  162.     GL_Upload8 (scrap_texels[texnum], BLOCK_WIDTH, BLOCK_HEIGHT, false, true);
  163.   }
  164.   scrap_dirty = false;
  165. }
  166.  
  167. //=============================================================================
  168. /* Support Routines */
  169.  
  170. typedef struct cachepic_s
  171. {
  172.   char    name[MAX_QPATH];
  173.   qpic_t    pic;
  174.   byte    padding[32];  // for appended glpic
  175. } cachepic_t;
  176.  
  177. #define MAX_CACHED_PICS   128
  178. cachepic_t  menu_cachepics[MAX_CACHED_PICS];
  179. int     menu_numcachepics;
  180.  
  181. byte    menuplyr_pixels[4096];
  182.  
  183. int   pic_texels;
  184. int   pic_count;
  185.  
  186. qpic_t *Draw_PicFromWad (char *name)
  187. {
  188.   qpic_t  *p;
  189.   glpic_t *gl;
  190.  
  191.   p = W_GetLumpName (name);
  192.   gl = (glpic_t *)p->data;
  193.  
  194.   // load little ones into the scrap
  195. /*
  196. /* ATTENTION: 13/02/2000 removed: M.Tretene
  197. /* This way it looks much better ;-) */
  198.   if (p->width < 64 && p->height < 64)
  199.   {
  200.     int   x, y;
  201.     int   i, j, k;
  202.     int   texnum;
  203.  
  204.     texnum = Scrap_AllocBlock (p->width, p->height, &x, &y);
  205.     scrap_dirty = true;
  206.     k = 0;
  207.     for (i=0 ; i<p->height ; i++)
  208.       for (j=0 ; j<p->width ; j++, k++)
  209.         scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = p->data[k];
  210.     texnum += scrap_texnum;
  211.     gl->texnum = texnum;
  212.     gl->sl = (x+0.01)/(float)BLOCK_WIDTH;
  213.     gl->sh = (x+p->width-0.01)/(float)BLOCK_WIDTH;
  214.     gl->tl = (y+0.01)/(float)BLOCK_WIDTH;
  215.     gl->th = (y+p->height-0.01)/(float)BLOCK_WIDTH;
  216.  
  217.     pic_count++;
  218.     pic_texels += p->width*p->height;
  219.   }
  220.   else
  221.   {
  222.     gl->texnum = GL_LoadPicTexture (p);
  223.     gl->sl = 0;
  224.     gl->sh = 1;
  225.     gl->tl = 0;
  226.     gl->th = 1;
  227.   }
  228.   return p;
  229. }
  230.  
  231.  
  232. /*
  233. ================
  234. Draw_CachePic
  235. ================
  236. */
  237. qpic_t  *Draw_CachePic (char *path)
  238. {
  239.   cachepic_t  *pic;
  240.   int     i;
  241.   qpic_t    *dat;
  242.   glpic_t   *gl;
  243.  
  244.   for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
  245.     if (!strcmp (path, pic->name))
  246.       return &pic->pic;
  247.  
  248.   if (menu_numcachepics == MAX_CACHED_PICS)
  249.     Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
  250.   menu_numcachepics++;
  251.   strcpy (pic->name, path);
  252.  
  253. //
  254. // load the pic from disk
  255. //
  256.   dat = (qpic_t *)COM_LoadTempFile (path);  
  257.   if (!dat)
  258.     Sys_Error ("Draw_CachePic: failed to load %s", path);
  259.   SwapPic (dat);
  260.  
  261.   // HACK HACK HACK --- we need to keep the bytes for
  262.   // the translatable player picture just for the menu
  263.   // configuration dialog
  264.   if (!strcmp (path, "gfx/menuplyr.lmp"))
  265.     memcpy (menuplyr_pixels, dat->data, dat->width*dat->height);
  266.  
  267.   pic->pic.width = dat->width;
  268.   pic->pic.height = dat->height;
  269.  
  270.   gl = (glpic_t *)pic->pic.data;
  271.   gl->texnum = GL_LoadPicTexture (dat);
  272.   gl->sl = 0;
  273.   gl->sh = 1;
  274.   gl->tl = 0;
  275.   gl->th = 1;
  276.  
  277.   return &pic->pic;
  278. }
  279.  
  280.  
  281. void Draw_CharToConback (int num, byte *dest)
  282. {
  283.   int   row, col;
  284.   byte  *source;
  285.   int   drawline;
  286.   int   x;
  287.  
  288.   row = num>>4;
  289.   col = num&15;
  290.   source = draw_chars + (row<<10) + (col<<3);
  291.  
  292.   drawline = 8;
  293.  
  294.   while (drawline--)
  295.   {
  296.     for (x=0 ; x<8 ; x++)
  297.       if (source[x] != 255)
  298.         dest[x] = 0x60 + source[x];
  299.     source += 128;
  300.     dest += 320;
  301.   }
  302.  
  303. }
  304.  
  305. typedef struct
  306. {
  307.   char *name;
  308.   int minimize, maximize;
  309. } glmode_t;
  310.  
  311. glmode_t modes[] = {
  312.   {"GL_NEAREST", GL_NEAREST, GL_NEAREST},
  313.   {"GL_LINEAR", GL_LINEAR, GL_LINEAR},
  314.   {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
  315.   {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
  316.   {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
  317.   {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
  318. };
  319.  
  320. /*
  321. ===============
  322. Draw_TextureMode_f
  323. ===============
  324. */
  325. void Draw_TextureMode_f (void)
  326. {
  327.   int   i;
  328.   gltexture_t *glt;
  329.  
  330.   if (Cmd_Argc() == 1)
  331.   {
  332.     for (i=0 ; i< 6 ; i++)
  333.       if (gl_filter_min == modes[i].minimize)
  334.       {
  335.         Con_Printf ("%s\n", modes[i].name);
  336.         return;
  337.       }
  338.     Con_Printf ("current filter is unknown???\n");
  339.     return;
  340.   }
  341.  
  342.   for (i=0 ; i< 6 ; i++)
  343.   {
  344.     if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) )
  345.       break;
  346.   }
  347.   if (i == 6)
  348.   {
  349.     Con_Printf ("bad filter name\n");
  350.     return;
  351.   }
  352.  
  353.   gl_filter_min = modes[i].minimize;
  354.   gl_filter_max = modes[i].maximize;
  355.  
  356.   // change all the existing mipmap texture objects
  357.   for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
  358.   {
  359.     if (glt->mipmap)
  360.     {
  361.       GL_Bind (glt->texnum);
  362.       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  363.       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  364.     }
  365.   }
  366. }
  367.  
  368. /*
  369. ===============
  370. Draw_Init
  371. ===============
  372. */
  373. void Draw_Init (void)
  374. {
  375.   int   i;
  376.   qpic_t  *cb;
  377.   byte  *dest, *src;
  378.   int   x, y;
  379.   char  ver[40];
  380.   glpic_t *gl;
  381.   int   start;
  382.   byte  *ncdata;
  383.   int   f, fstep;
  384.   int    maxsize;
  385.  
  386.   Cvar_RegisterVariable (&gl_nobind);
  387.   Cvar_RegisterVariable (&gl_max_size);
  388.   Cvar_RegisterVariable (&gl_picmip);
  389.  
  390.   // 3dfx can only handle 256 wide textures
  391.   if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4) ||
  392.     strstr((char *)gl_renderer, "Glide"))
  393.     Cvar_Set ("gl_max_size", "256");
  394.  
  395.   // texture_max_size
  396.  
  397.   if ((i = COM_CheckParm("-maxsize")) != 0) {
  398.     maxsize = Q_atoi(com_argv[i+1]);
  399.     maxsize &= 0xff80;
  400.     Cvar_SetValue("gl_max_size", maxsize);
  401.     //gl_max_size.value = Q_atof(com_argv[i+1]);
  402.     //if (gl_max_size.value < 128)  gl_max_size.value = 128;
  403.     //if (gl_max_size.value > 1024) gl_max_size.value = 1024;
  404.     //Cvar_Set ("gl_max_size", com_argv[i+1]);
  405.     //printf("MAXSIZE:%f\n",gl_max_size.value);
  406.   }  
  407.  
  408.   Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f);
  409.  
  410.   // load the console background and the charset
  411.   // by hand, because we need to write the version
  412.   // string into the background before turning
  413.   // it into a texture
  414.   draw_chars = W_GetLumpName ("conchars");
  415.   for (i=0 ; i<256*64 ; i++)
  416.     if (draw_chars[i] == 0)
  417.       draw_chars[i] = 255;  // proper transparent color
  418.  
  419.   // now turn them into textures
  420.   char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true);
  421.  
  422.   start = Hunk_LowMark();
  423.  
  424.   cb = (qpic_t *)COM_LoadTempFile ("gfx/conback.lmp");  
  425.   if (!cb)
  426.     Sys_Error ("Couldn't load gfx/conback.lmp");
  427.   SwapPic (cb);
  428.  
  429.   // hack the version number directly into the pic
  430. #if defined(__linux__)
  431.   sprintf (ver, "(Linux %2.2f, gl %4.2f) %4.2f", (float)LINUX_VERSION, (float)GLQUAKE_VERSION, (float)VERSION);
  432. #else
  433.   sprintf (ver, "(gl %4.2f beta 6.2) %4.2f", (float)GLQUAKE_VERSION, (float)VERSION);
  434. #endif
  435.   dest = cb->data + 320*186 + 320 - 11 - 8*strlen(ver);
  436.   y = strlen(ver);
  437.   for (x=0 ; x<y ; x++)
  438.     Draw_CharToConback (ver[x], dest+(x<<3));
  439.  
  440. #if 0
  441.   conback->width = vid.conwidth;
  442.   conback->height = vid.conheight;
  443.  
  444.   // scale console to vid size
  445.   dest = ncdata = Hunk_AllocName(vid.conwidth * vid.conheight, "conback");
  446.  
  447.   for (y=0 ; y<vid.conheight ; y++, dest += vid.conwidth)
  448.   {
  449.     src = cb->data + cb->width * (y*cb->height/vid.conheight);
  450.     if (vid.conwidth == cb->width)
  451.       memcpy (dest, src, vid.conwidth);
  452.     else
  453.     {
  454.       f = 0;
  455.       fstep = cb->width*0x10000/vid.conwidth;
  456.       for (x=0 ; x<vid.conwidth ; x+=4)
  457.       {
  458.         dest[x] = src[f>>16];
  459.         f += fstep;
  460.         dest[x+1] = src[f>>16];
  461.         f += fstep;
  462.         dest[x+2] = src[f>>16];
  463.         f += fstep;
  464.         dest[x+3] = src[f>>16];
  465.         f += fstep;
  466.       }
  467.     }
  468.   }
  469. #else
  470.   conback->width = cb->width;
  471.   conback->height = cb->height;
  472.   ncdata = cb->data;
  473. #endif
  474.  
  475.   //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  476.   //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  477.   
  478.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);  // 13/02/2000 changed: M.Tretene
  479.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  480.  
  481.   gl = (glpic_t *)conback->data;
  482.   //gl->texnum = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, false, false);     //  30/01/2000 modified: M.Tretene
  483.   gl->texnum = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, false, true);
  484.   gl->sl = 0;
  485.   gl->sh = 1;
  486.   gl->tl = 0;
  487.   gl->th = 1;
  488.   conback->width = vid.width;
  489.   conback->height = vid.height;
  490.  
  491.   // free loaded console
  492.   Hunk_FreeToLowMark(start);
  493.  
  494.   // save a texture slot for translated picture
  495.   translate_texture = texture_extension_number++;
  496.  
  497.   // save slots for scraps
  498.   scrap_texnum = texture_extension_number;
  499.   texture_extension_number += MAX_SCRAPS;
  500.  
  501.   //
  502.   // get the other pics we need
  503.   //
  504.   draw_disc = Draw_PicFromWad ("disc");
  505.   draw_backtile = Draw_PicFromWad ("backtile");
  506. }
  507.  
  508.  
  509.  
  510. /*
  511. ================
  512. Draw_Character
  513.  
  514. Draws one 8*8 graphics character with 0 being transparent.
  515. It can be clipped to the top of the screen to allow the console to be
  516. smoothly scrolled off.
  517. ================
  518. */
  519. void Draw_Character (int x, int y, int num)
  520. {
  521.   byte      *dest;
  522.   byte      *source;
  523.   unsigned short  *pusdest;
  524.   int       drawline; 
  525.   int       row, col;
  526.   float     frow, fcol, size;
  527.  
  528.   if (num == 32)
  529.     return;   // space
  530.  
  531.   num &= 255;
  532.   
  533.   if (y <= -8)
  534.     return;     // totally off screen
  535.  
  536.   row = num>>4;
  537.   col = num&15;
  538.  
  539.   frow = row*0.0625;
  540.   fcol = col*0.0625;
  541.   size = 0.0625;
  542.  
  543.   glDisable(GL_ALPHA_TEST);         // 30/01/2000 added: M.Tretene
  544.   glEnable (GL_BLEND);
  545.   glColor4f (1,1,1,(float) 1);
  546.  
  547.   GL_Bind (char_texture);
  548.  
  549.   glBegin (GL_QUADS);
  550.   glTexCoord2f (fcol, frow);
  551.   glVertex2f (x, y);
  552.   glTexCoord2f (fcol + size, frow);
  553.   glVertex2f (x+8, y);
  554.   glTexCoord2f (fcol + size, frow + size);
  555.   glVertex2f (x+8, y+8);
  556.   glTexCoord2f (fcol, frow + size);
  557.   glVertex2f (x, y+8);
  558.   glEnd ();
  559.  
  560.   glColor4f (1,1,1,1);             // 30/01/2000 added: M.Tretene  
  561.   glEnable(GL_ALPHA_TEST);
  562.   glDisable (GL_BLEND);
  563. }
  564.  
  565. /*
  566. ================
  567. Draw_String
  568. ================
  569. */
  570. void Draw_String (int x, int y, char *str)
  571. {
  572.   while (*str)
  573.   {
  574.     Draw_Character (x, y, *str);
  575.     str++;
  576.     x += 8;
  577.   }
  578. }
  579.  
  580. /*
  581. ================
  582. Draw_DebugChar
  583.  
  584. Draws a single character directly to the upper right corner of the screen.
  585. This is for debugging lockups by drawing different chars in different parts
  586. of the code.
  587. ================
  588. */
  589. void Draw_DebugChar (char num)
  590. {
  591. }
  592.  
  593. /*
  594. =============
  595. Draw_AlphaPic
  596. =============
  597. */
  598. void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha)
  599. {
  600.   byte      *dest, *source;
  601.   unsigned short  *pusdest;
  602.   int       v, u;
  603.   glpic_t     *gl;
  604.  
  605.   if (scrap_dirty)
  606.     Scrap_Upload ();
  607.   gl = (glpic_t *)pic->data;
  608.   glDisable(GL_ALPHA_TEST);
  609.   glEnable (GL_BLEND);
  610. //  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  611. //  glCullFace(GL_FRONT);
  612.   glColor4f (1,1,1,alpha);
  613.   GL_Bind (gl->texnum);
  614.   glBegin (GL_QUADS);
  615.   glTexCoord2f (gl->sl, gl->tl);
  616.   glVertex2f (x, y);
  617.   glTexCoord2f (gl->sh, gl->tl);
  618.   glVertex2f (x+pic->width, y);
  619.   glTexCoord2f (gl->sh, gl->th);
  620.   glVertex2f (x+pic->width, y+pic->height);
  621.   glTexCoord2f (gl->sl, gl->th);
  622.   glVertex2f (x, y+pic->height);
  623.   glEnd ();
  624.   glColor4f (1,1,1,1);
  625.   glEnable(GL_ALPHA_TEST);
  626.   glDisable (GL_BLEND);
  627. }
  628.  
  629.  
  630. /*
  631. =============
  632. Draw_Pic
  633. =============
  634. */
  635. void Draw_Pic (int x, int y, qpic_t *pic)
  636. {
  637.   byte      *dest, *source;
  638.   unsigned short  *pusdest;
  639.   int       v, u;
  640.   glpic_t     *gl;
  641.  
  642.   if (scrap_dirty)
  643.     Scrap_Upload ();
  644.   gl = (glpic_t *)pic->data;
  645.   //glColor4f (1,1,1,1);                // 30/01/2000 removed: M.Tretene
  646.   GL_Bind (gl->texnum);
  647.   glBegin (GL_QUADS);
  648.   glTexCoord2f (gl->sl, gl->tl);
  649.   glVertex2f (x, y);
  650.   glTexCoord2f (gl->sh, gl->tl);
  651.   glVertex2f (x+pic->width, y);
  652.   glTexCoord2f (gl->sh, gl->th);
  653.   glVertex2f (x+pic->width, y+pic->height);
  654.   glTexCoord2f (gl->sl, gl->th);
  655.   glVertex2f (x, y+pic->height);
  656.   glEnd ();
  657. }
  658.  
  659.  
  660. /*
  661. =============
  662. Draw_TransPic
  663. =============
  664. */
  665. void Draw_TransPic (int x, int y, qpic_t *pic)
  666. {
  667.   byte  *dest, *source, tbyte;
  668.   unsigned short  *pusdest;
  669.   int       v, u;
  670.  
  671.   if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
  672.      (unsigned)(y + pic->height) > vid.height)
  673.   {
  674.     Sys_Error ("Draw_TransPic: bad coordinates");
  675.   }
  676.     
  677.   glDisable(GL_ALPHA_TEST);     // 30/01/2000 added: M.Tretene
  678.   glEnable (GL_BLEND);
  679.   glColor4f (1,1,1,1);
  680.  
  681.   Draw_Pic (x, y, pic);
  682.  
  683.   glColor4f (1,1,1,1);          // 30/01/2000 added: M.Tretene
  684.   glEnable(GL_ALPHA_TEST);
  685.   glDisable (GL_BLEND);
  686. }
  687.  
  688.  
  689. /*
  690. =============
  691. Draw_TransPicTranslate
  692.  
  693. Only used for the player color selection menu
  694. =============
  695. */
  696. void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation)
  697. {
  698.   int       v, u, c;
  699.   unsigned    trans[64*64], *dest;
  700.   byte      *src;
  701.   int       p;
  702.  
  703.   GL_Bind (translate_texture);
  704.  
  705.   c = pic->width * pic->height;
  706.  
  707.   dest = trans;
  708.   for (v=0 ; v<64 ; v++, dest += 64)
  709.   {
  710.     src = &menuplyr_pixels[ ((v*pic->height)>>6) *pic->width];
  711.     for (u=0 ; u<64 ; u++)
  712.     {
  713.       p = src[(u*pic->width)>>6];
  714.       if (p == 255)
  715.         dest[u] = p;
  716.       else
  717.         dest[u] =  d_8to24table[translation[p]];
  718.     }
  719.   }
  720.  
  721.   glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  722.  
  723.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  724.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  725.  
  726.   glColor3f (1,1,1);
  727.   glBegin (GL_QUADS);
  728.   glTexCoord2f (0, 0);
  729.   glVertex2f (x, y);
  730.   glTexCoord2f (1, 0);
  731.   glVertex2f (x+pic->width, y);
  732.   glTexCoord2f (1, 1);
  733.   glVertex2f (x+pic->width, y+pic->height);
  734.   glTexCoord2f (0, 1);
  735.   glVertex2f (x, y+pic->height);
  736.   glEnd ();
  737. }
  738.  
  739.  
  740. /*
  741. ================
  742. Draw_ConsoleBackground
  743.  
  744. ================
  745. */
  746. void Draw_ConsoleBackground (int lines)
  747. {
  748.   int y = (vid.height * 3) >> 2;
  749.  
  750.   if (lines > y)
  751.     Draw_Pic(0, lines - vid.height, conback);
  752.   else
  753.     Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y);
  754. }
  755.  
  756.  
  757. /*
  758. =============
  759. Draw_TileClear
  760.  
  761. This repeats a 64*64 tile graphic to fill the screen around a sized down
  762. refresh window.
  763. =============
  764. */
  765. void Draw_TileClear (int x, int y, int w, int h)
  766. {
  767.   glColor3f (1,1,1);
  768.   GL_Bind (*(int *)draw_backtile->data);
  769.   glBegin (GL_QUADS);
  770.   glTexCoord2f (x/64.0, y/64.0);
  771.   glVertex2f (x, y);
  772.   glTexCoord2f ( (x+w)/64.0, y/64.0);
  773.   glVertex2f (x+w, y);
  774.   glTexCoord2f ( (x+w)/64.0, (y+h)/64.0);
  775.   glVertex2f (x+w, y+h);
  776.   glTexCoord2f ( x/64.0, (y+h)/64.0 );
  777.   glVertex2f (x, y+h);
  778.   glEnd ();
  779. }
  780.  
  781.  
  782. /*
  783. =============
  784. Draw_Fill
  785.  
  786. Fills a box of pixels with a single color
  787. =============
  788. */
  789. void Draw_Fill (int x, int y, int w, int h, int c)
  790. {
  791.   glDisable (GL_TEXTURE_2D);
  792.   glColor3f (host_basepal[c*3]/255.0,
  793.     host_basepal[c*3+1]/255.0,
  794.     host_basepal[c*3+2]/255.0);
  795.  
  796.   glBegin (GL_QUADS);
  797.  
  798.   glVertex2f (x,y);
  799.   glVertex2f (x+w, y);
  800.   glVertex2f (x+w, y+h);
  801.   glVertex2f (x, y+h);
  802.  
  803.   glEnd ();
  804.   glColor3f (1,1,1);
  805.   glEnable (GL_TEXTURE_2D);
  806. }
  807. //=============================================================================
  808.  
  809. /*
  810. ================
  811. Draw_FadeScreen
  812.  
  813. ================
  814. */
  815. void Draw_FadeScreen (void)
  816. {
  817.   glEnable (GL_BLEND);
  818.   glDisable (GL_TEXTURE_2D);
  819.   glColor4f (0, 0, 0, 0.8);
  820.   glBegin (GL_QUADS);
  821.  
  822.   glVertex2f (0,0);
  823.   glVertex2f (vid.width, 0);
  824.   glVertex2f (vid.width, vid.height);
  825.   glVertex2f (0, vid.height);
  826.  
  827.   glEnd ();
  828.   glColor4f (1,1,1,1);
  829.   glEnable (GL_TEXTURE_2D);
  830.   glDisable (GL_BLEND);
  831.  
  832.   Sbar_Changed();
  833. }
  834.  
  835. //=============================================================================
  836.  
  837. /*
  838. ================
  839. Draw_BeginDisc
  840.  
  841. Draws the little blue disc in the corner of the screen.
  842. Call before beginning any disc IO.
  843. ================
  844. */
  845. void Draw_BeginDisc (void)
  846. {
  847.   if (!draw_disc)
  848.     return;
  849.   glDrawBuffer  (GL_FRONT);
  850.   Draw_Pic (vid.width - 24, 0, draw_disc);
  851.   glDrawBuffer  (GL_BACK);
  852. }
  853.  
  854.  
  855. /*
  856. ================
  857. Draw_EndDisc
  858.  
  859. Erases the disc icon.
  860. Call after completing any disc IO
  861. ================
  862. */
  863. void Draw_EndDisc (void)
  864. {
  865. }
  866.  
  867. /*
  868. ================
  869. GL_Set2D
  870.  
  871. Setup as if the screen was 320*200
  872. ================
  873. */
  874. void GL_Set2D (void)
  875. {
  876.   glViewport (glx, gly, glwidth, glheight);
  877.  
  878.   glMatrixMode(GL_PROJECTION);
  879.     glLoadIdentity ();
  880.   glOrtho  (0, vid.width, vid.height, 0, -99999, 99999);
  881.  
  882.   glMatrixMode(GL_MODELVIEW);
  883.     glLoadIdentity ();
  884.  
  885.   glDisable (GL_DEPTH_TEST);
  886.   glDisable (GL_CULL_FACE);
  887.   glDisable (GL_BLEND);
  888.   glEnable (GL_ALPHA_TEST);
  889.   //glDisable (GL_ALPHA_TEST);
  890.  
  891.   glColor4f (1,1,1,1);
  892. }
  893.  
  894. //====================================================================
  895.  
  896. /*
  897. ================
  898. GL_FindTexture
  899. ================
  900. */
  901. int GL_FindTexture (char *identifier)
  902. {
  903.   int   i;
  904.   gltexture_t *glt;
  905.  
  906.   for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
  907.   {
  908.     if (!strcmp (identifier, glt->identifier))
  909.       return gltextures[i].texnum;
  910.   }
  911.  
  912.   return -1;
  913. }
  914.  
  915. /*
  916. ================
  917. GL_ResampleTexture
  918. ================
  919. */
  920. void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out,  int outwidth, int outheight)
  921. {
  922.   int   i, j;
  923.   unsigned  *inrow;
  924.   unsigned  frac, fracstep;
  925.  
  926.   fracstep = inwidth*0x10000/outwidth;
  927.   for (i=0 ; i<outheight ; i++, out += outwidth)
  928.   {
  929.     inrow = in + inwidth*(i*inheight/outheight);
  930.     frac = fracstep >> 1;
  931.     for (j=0 ; j<outwidth ; j+=4)
  932.     {
  933.       out[j] = inrow[frac>>16];
  934.       frac += fracstep;
  935.       out[j+1] = inrow[frac>>16];
  936.       frac += fracstep;
  937.       out[j+2] = inrow[frac>>16];
  938.       frac += fracstep;
  939.       out[j+3] = inrow[frac>>16];
  940.       frac += fracstep;
  941.     }
  942.   }
  943. }
  944.  
  945. /*
  946. ================
  947. GL_Resample8BitTexture -- JACK
  948. ================
  949. */
  950. void GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, unsigned char *out,  int outwidth, int outheight)
  951. {
  952.   int   i, j;
  953.   unsigned  char *inrow;
  954.   unsigned  frac, fracstep;
  955.  
  956.   fracstep = inwidth*0x10000/outwidth;
  957.   for (i=0 ; i<outheight ; i++, out += outwidth)
  958.   {
  959.     inrow = in + inwidth*(i*inheight/outheight);
  960.     frac = fracstep >> 1;
  961.     for (j=0 ; j<outwidth ; j+=4)
  962.     {
  963.       out[j] = inrow[frac>>16];
  964.       frac += fracstep;
  965.       out[j+1] = inrow[frac>>16];
  966.       frac += fracstep;
  967.       out[j+2] = inrow[frac>>16];
  968.       frac += fracstep;
  969.       out[j+3] = inrow[frac>>16];
  970.       frac += fracstep;
  971.     }
  972.   }
  973. }
  974.  
  975.  
  976. /*
  977. ================
  978. GL_MipMap
  979.  
  980. Operates in place, quartering the size of the texture
  981. ================
  982. */
  983. void GL_MipMap (byte *in, int width, int height)
  984. {
  985.   int   i, j;
  986.   byte  *out;
  987.  
  988.   width <<=2;
  989.   height >>= 1;
  990.   out = in;
  991.   
  992.   for (i=0 ; i<height ; i++, in+=width)
  993.   {
  994.     for (j=0 ; j<width ; j+=8, out+=4, in+=8)
  995.     {
  996.       out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
  997.       out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
  998.       out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
  999.       out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
  1000.     }
  1001.   }
  1002. }
  1003.  
  1004. /*
  1005. ================
  1006. GL_MipMap8Bit
  1007.  
  1008. Mipping for 8 bit textures
  1009. ================
  1010. */
  1011. void GL_MipMap8Bit (byte *in, int width, int height)
  1012. {
  1013.   int   i, j;
  1014.   unsigned short     r,g,b;
  1015.   byte  *out, *at1, *at2, *at3, *at4;
  1016.  
  1017. //  width <<=2;
  1018.   height >>= 1;
  1019.   out = in;
  1020.   for (i=0 ; i<height ; i++, in+=width)
  1021.   {
  1022.     for (j=0 ; j<width ; j+=2, out+=1, in+=2)
  1023.     {
  1024.       at1 = (byte *) (d_8to24table + in[0]);
  1025.       at2 = (byte *) (d_8to24table + in[1]);
  1026.       at3 = (byte *) (d_8to24table + in[width+0]);
  1027.       at4 = (byte *) (d_8to24table + in[width+1]);
  1028.  
  1029.       r = (at1[0]+at2[0]+at3[0]+at4[0]); r>>=5;
  1030.       g = (at1[1]+at2[1]+at3[1]+at4[1]); g>>=5;
  1031.       b = (at1[2]+at2[2]+at3[2]+at4[2]); b>>=5;
  1032.  
  1033.       out[0] = d_15to8table[(r<<0) + (g<<5) + (b<<10)];
  1034.     }
  1035.   }
  1036. }
  1037.  
  1038. /*
  1039. ===============
  1040. GL_Upload32
  1041. ===============
  1042. */
  1043. void GL_Upload32 (unsigned *data, int width, int height,  qboolean mipmap, qboolean alpha)
  1044. {
  1045.   int     samples;
  1046. static  unsigned  scaled[1024*512]; // [512*256];
  1047.   int     scaled_width, scaled_height;
  1048.  
  1049.   for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
  1050.     ;
  1051.   for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
  1052.     ;
  1053.  
  1054.   scaled_width >>= (int)gl_picmip.value;
  1055.   scaled_height >>= (int)gl_picmip.value;
  1056.  
  1057.   if (scaled_width > gl_max_size.value)
  1058.     scaled_width = gl_max_size.value;
  1059.   if (scaled_height > gl_max_size.value)
  1060.     scaled_height = gl_max_size.value;
  1061.  
  1062.   if (scaled_width * scaled_height > sizeof(scaled)/4)
  1063.     Sys_Error ("GL_LoadTexture: too big");
  1064.  
  1065.   samples = alpha ? gl_alpha_format : gl_solid_format;
  1066.  
  1067. #if 0
  1068.   if (mipmap)
  1069.     gluBuild2DMipmaps (GL_TEXTURE_2D, samples, width, height, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  1070.   else if (scaled_width == width && scaled_height == height)
  1071.     glTexImage2D (GL_TEXTURE_2D, 0, samples, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  1072.   else
  1073.   {
  1074.     gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, trans,
  1075.       scaled_width, scaled_height, GL_UNSIGNED_BYTE, scaled);
  1076.     glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
  1077.   }
  1078. #else
  1079. texels += scaled_width * scaled_height;
  1080.  
  1081.   if (scaled_width == width && scaled_height == height)
  1082.   {
  1083.     if (!mipmap)
  1084.     {
  1085.       glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  1086.       goto done;
  1087.     }
  1088.     memcpy (scaled, data, width*height*4);
  1089.   }
  1090.   else
  1091.     GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
  1092.  
  1093.   glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
  1094.   if (mipmap)
  1095.   {
  1096.     int   miplevel;
  1097.  
  1098.     miplevel = 0;
  1099.     while (scaled_width > 1 || scaled_height > 1)
  1100.     {
  1101.       GL_MipMap ((byte *)scaled, scaled_width, scaled_height);
  1102.       scaled_width >>= 1;
  1103.       scaled_height >>= 1;
  1104.       if (scaled_width < 1)
  1105.         scaled_width = 1;
  1106.       if (scaled_height < 1)
  1107.         scaled_height = 1;
  1108.       miplevel++;
  1109.       glTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
  1110.     }
  1111.   }
  1112. done: ;
  1113. #endif
  1114.  
  1115.  
  1116.   if (mipmap)
  1117.   {
  1118.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  1119.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1120.   }
  1121.   else
  1122.   {
  1123.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
  1124.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1125.   }
  1126. }
  1127.  
  1128. void GL_Upload8_EXT (byte *data, int width, int height,  qboolean mipmap, qboolean alpha) 
  1129. {
  1130.   int     i, s;
  1131.   qboolean  noalpha;
  1132.   int     p;
  1133.   static unsigned j;
  1134.   int     samples;
  1135.     static  unsigned char scaled[1024*512]; // [512*256];
  1136.   int     scaled_width, scaled_height;
  1137.  
  1138.   s = width*height;
  1139.   // if there are no transparent pixels, make it a 3 component
  1140.   // texture even if it was specified as otherwise
  1141.   if (alpha)
  1142.   {
  1143.     noalpha = true;
  1144.     for (i=0 ; i<s ; i++)
  1145.     {
  1146.       if (data[i] == 255)
  1147.         noalpha = false;
  1148.     }
  1149.  
  1150.     if (alpha && noalpha)
  1151.       alpha = false;
  1152.   }
  1153.   for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
  1154.     ;
  1155.   for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
  1156.     ;
  1157.  
  1158.   scaled_width >>= (int)gl_picmip.value;
  1159.   scaled_height >>= (int)gl_picmip.value;
  1160.  
  1161.   if (scaled_width > gl_max_size.value)
  1162.     scaled_width = gl_max_size.value;
  1163.   if (scaled_height > gl_max_size.value)
  1164.     scaled_height = gl_max_size.value;
  1165.  
  1166.   if (scaled_width * scaled_height > sizeof(scaled))
  1167.     Sys_Error ("GL_LoadTexture: too big");
  1168.  
  1169.   samples = 1; // alpha ? gl_alpha_format : gl_solid_format;
  1170.  
  1171.   texels += scaled_width * scaled_height;
  1172.  
  1173.   if (scaled_width == width && scaled_height == height)
  1174.   {
  1175.     if (!mipmap)
  1176.     {
  1177.       glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX , GL_UNSIGNED_BYTE, data);
  1178.       goto done;
  1179.     }
  1180.     memcpy (scaled, data, width*height);
  1181.   }
  1182.   else
  1183.     GL_Resample8BitTexture (data, width, height, scaled, scaled_width, scaled_height);
  1184.  
  1185.   glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
  1186.   if (mipmap)
  1187.   {
  1188.     int   miplevel;
  1189.  
  1190.     miplevel = 0;
  1191.     while (scaled_width > 1 || scaled_height > 1)
  1192.     {
  1193.       GL_MipMap8Bit ((byte *)scaled, scaled_width, scaled_height);
  1194.       scaled_width >>= 1;
  1195.       scaled_height >>= 1;
  1196.       if (scaled_width < 1)
  1197.         scaled_width = 1;
  1198.       if (scaled_height < 1)
  1199.         scaled_height = 1;
  1200.       miplevel++;
  1201.       glTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
  1202.     }
  1203.   }
  1204. done: ;
  1205.  
  1206.  
  1207.   if (mipmap)
  1208.   {
  1209.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  1210.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1211.   }
  1212.   else
  1213.   {
  1214.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
  1215.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1216.   }
  1217. }
  1218.  
  1219. /*
  1220. ===============
  1221. GL_Upload8
  1222. ===============
  1223. */
  1224. void GL_Upload8 (byte *data, int width, int height,  qboolean mipmap, qboolean alpha)
  1225. {
  1226. static  unsigned  trans[640*480];   // FIXME, temporary
  1227.   int     i, s;
  1228.   qboolean  noalpha;
  1229.   int     p;
  1230.  
  1231.   s = width*height;
  1232.   // if there are no transparent pixels, make it a 3 component
  1233.   // texture even if it was specified as otherwise
  1234.   if (alpha)
  1235.   {
  1236.     noalpha = true;
  1237.     for (i=0 ; i<s ; i++)
  1238.     {
  1239.       p = data[i];
  1240.       if (p == 255)
  1241.         noalpha = false;
  1242.       trans[i] = d_8to24table[p];
  1243.     }
  1244.  
  1245.     //if (alpha && noalpha)     // 30/01/2000 removed: M.Tretene
  1246.     //  alpha = false;
  1247.   }
  1248.   else
  1249.   {
  1250.     if (s&3)
  1251.       Sys_Error ("GL_Upload8: s&3");
  1252.     for (i=0 ; i<s ; i+=4)
  1253.     {
  1254.       trans[i] = d_8to24table[data[i]];
  1255.       trans[i+1] = d_8to24table[data[i+1]];
  1256.       trans[i+2] = d_8to24table[data[i+2]];
  1257.       trans[i+3] = d_8to24table[data[i+3]];
  1258.     }
  1259.   }
  1260.  
  1261.   if (VID_Is8bit() && !alpha && (data!=scrap_texels[0])) {
  1262.     GL_Upload8_EXT (data, width, height, mipmap, alpha);
  1263.     return;
  1264.   } 
  1265.   GL_Upload32 (trans, width, height, mipmap, alpha);
  1266. }
  1267.  
  1268. /*
  1269. ================
  1270. GL_LoadTexture
  1271. ================
  1272. */
  1273. int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha)
  1274. {
  1275.   qboolean  noalpha;
  1276.   int     i, p, s;
  1277.   gltexture_t *glt;
  1278.   
  1279.   // see if the texture is allready present
  1280.   if (identifier[0])
  1281.   {
  1282.     for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
  1283.     {
  1284.       if (!strcmp (identifier, glt->identifier))
  1285.       {
  1286.         if (width != glt->width || height != glt->height)
  1287.           Sys_Error ("GL_LoadTexture: cache mismatch");
  1288.         return gltextures[i].texnum;
  1289.       }
  1290.     }
  1291.     
  1292.   }
  1293.   
  1294.   //else {                                    // 13/02/2000 removed: M.Tretene
  1295.     glt = &gltextures[numgltextures];
  1296.     numgltextures++;
  1297.   //}
  1298.  
  1299.   strcpy (glt->identifier, identifier);
  1300.   glt->texnum = texture_extension_number;
  1301.   glt->width = width;
  1302.   glt->height = height;
  1303.   glt->mipmap = mipmap;
  1304.  
  1305.   GL_Bind(texture_extension_number );
  1306.  
  1307.   GL_Upload8 (data, width, height, mipmap, alpha);
  1308.  
  1309.   texture_extension_number++;
  1310.  
  1311.   return texture_extension_number-1;
  1312. }
  1313.  
  1314. /*
  1315. ================
  1316. GL_LoadPicTexture
  1317. ================
  1318. */
  1319. int GL_LoadPicTexture (qpic_t *pic)
  1320. {
  1321.   return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true);
  1322. }
  1323.  
  1324. /****************************************/
  1325.  
  1326. static GLenum oldtarget = TEXTURE0_SGIS;
  1327.  
  1328. void GL_SelectTexture (GLenum target) 
  1329. {
  1330.   if (!gl_mtexable)
  1331.     return;
  1332.   qglSelectTextureSGIS(target);
  1333.   if (target == oldtarget) 
  1334.     return;
  1335.   cnttextures[oldtarget-TEXTURE0_SGIS] = currenttexture;
  1336.   currenttexture = cnttextures[target-TEXTURE0_SGIS];
  1337.   oldtarget = target;
  1338. }
  1339.