Annotation of quakeworld/client/gl_draw.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.